Home | History | Annotate | Download | only in perf
      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 (at) 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 
   1738 /* Global variable.  Only the name is significant.
   1740    To find the address, look in the corresponding external symbol.  */
   1741 __define_stab (N_GSYM, 0x20, "GSYM")
   1742 
   1743 /* Function name for BSD Fortran.  Only the name is significant.
   1744    To find the address, look in the corresponding external symbol.  */
   1745 __define_stab (N_FNAME, 0x22, "FNAME")
   1746 
   1747 /* Function name or text-segment variable for C.  Value is its address.
   1748    Desc is supposedly starting line number, but GCC doesn't set it
   1749    and DBX seems not to miss it.  */
   1750 __define_stab (N_FUN, 0x24, "FUN")
   1751 
   1752 /* Data-segment variable with internal linkage.  Value is its address.
   1753    "Static Sym".  */
   1754 __define_stab (N_STSYM, 0x26, "STSYM")
   1755 
   1756 /* BSS-segment variable with internal linkage.  Value is its address.  */
   1757 __define_stab (N_LCSYM, 0x28, "LCSYM")
   1758 
   1759 /* Name of main routine.  Only the name is significant.
   1760    This is not used in C.  */
   1761 __define_stab (N_MAIN, 0x2a, "MAIN")
   1762 
   1763 /* Global symbol in Pascal.
   1764    Supposedly the value is its line number; I'm skeptical.  */
   1765 __define_stab (N_PC, 0x30, "PC")
   1766 
   1767 /* Number of symbols:  0, files,,funcs,lines according to Ultrix V4.0. */
   1768 __define_stab (N_NSYMS, 0x32, "NSYMS")
   1769 
   1770 /* "No DST map for sym: name, ,0,type,ignored"  according to Ultrix V4.0. */
   1771 __define_stab (N_NOMAP, 0x34, "NOMAP")
   1772 
   1773 /* New stab from Solaris.  I don't know what it means, but it
   1774    don't seem to contain useful information.  */
   1775 __define_stab (N_OBJ, 0x38, "OBJ")
   1776 
   1777 /* New stab from Solaris.  I don't know what it means, but it
   1778    don't seem to contain useful information.  Possibly related to the
   1779    optimization flags used in this module.  */
   1780 __define_stab (N_OPT, 0x3c, "OPT")
   1781 
   1782 /* Register variable.  Value is number of register.  */
   1783 __define_stab (N_RSYM, 0x40, "RSYM")
   1784 
   1785 /* Modula-2 compilation unit.  Can someone say what info it contains?  */
   1786 __define_stab (N_M2C, 0x42, "M2C")
   1787 
   1788 /* Line number in text segment.  Desc is the line number;
   1789    value is corresponding address.  */
   1790 __define_stab (N_SLINE, 0x44, "SLINE")
   1791 
   1792 /* Similar, for data segment.  */
   1793 __define_stab (N_DSLINE, 0x46, "DSLINE")
   1794 
   1795 /* Similar, for bss segment.  */
   1796 __define_stab (N_BSLINE, 0x48, "BSLINE")
   1797 
   1798 /* Sun's source-code browser stabs.  ?? Don't know what the fields are.
   1799    Supposedly the field is "path to associated .cb file".  THIS VALUE
   1800    OVERLAPS WITH N_BSLINE!  */
   1801 __define_stab (N_BROWS, 0x48, "BROWS")
   1802 
   1803 /* GNU Modula-2 definition module dependency.  Value is the modification time
   1804    of the definition file.  Other is non-zero if it is imported with the
   1805    GNU M2 keyword %INITIALIZE.  Perhaps N_M2C can be used if there
   1806    are enough empty fields? */
   1807 __define_stab(N_DEFD, 0x4a, "DEFD")
   1808 
   1809 /* THE FOLLOWING TWO STAB VALUES CONFLICT.  Happily, one is for Modula-2
   1810    and one is for C++.   Still,... */
   1811 /* GNU C++ exception variable.  Name is variable name.  */
   1812 __define_stab (N_EHDECL, 0x50, "EHDECL")
   1813 /* Modula2 info "for imc":  name,,0,0,0  according to Ultrix V4.0.  */
   1814 __define_stab (N_MOD2, 0x50, "MOD2")
   1815 
   1816 /* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
   1817    this entry is immediately followed by a CAUGHT stab saying what exception
   1818    was caught.  Multiple CAUGHT stabs means that multiple exceptions
   1819    can be caught here.  If Desc is 0, it means all exceptions are caught
   1820    here.  */
   1821 __define_stab (N_CATCH, 0x54, "CATCH")
   1822 
   1823 /* Structure or union element.  Value is offset in the structure.  */
   1824 __define_stab (N_SSYM, 0x60, "SSYM")
   1825 
   1826 /* Name of main source file.
   1827    Value is starting text address of the compilation.  */
   1828 __define_stab (N_SO, 0x64, "SO")
   1829 
   1830 /* Automatic variable in the stack.  Value is offset from frame pointer.
   1831    Also used for type descriptions.  */
   1832 __define_stab (N_LSYM, 0x80, "LSYM")
   1833 
   1834 /* Beginning of an include file.  Only Sun uses this.
   1835    In an object file, only the name is significant.
   1836    The Sun linker puts data into some of the other fields.  */
   1837 __define_stab (N_BINCL, 0x82, "BINCL")
   1838 
   1839 /* Name of sub-source file (#include file).
   1840    Value is starting text address of the compilation.  */
   1841 __define_stab (N_SOL, 0x84, "SOL")
   1842 
   1843 /* Parameter variable.  Value is offset from argument pointer.
   1844    (On most machines the argument pointer is the same as the frame pointer.  */
   1845 __define_stab (N_PSYM, 0xa0, "PSYM")
   1846 
   1847 /* End of an include file.  No name.
   1848    This and N_BINCL act as brackets around the file's output.
   1849    In an object file, there is no significant data in this entry.
   1850    The Sun linker puts data into some of the fields.  */
   1851 __define_stab (N_EINCL, 0xa2, "EINCL")
   1852 
   1853 /* Alternate entry point.  Value is its address.  */
   1854 __define_stab (N_ENTRY, 0xa4, "ENTRY")
   1855 
   1856 /* Beginning of lexical block.
   1857    The desc is the nesting level in lexical blocks.
   1858    The value is the address of the start of the text for the block.
   1859    The variables declared inside the block *precede* the N_LBRAC symbol.  */
   1860 __define_stab (N_LBRAC, 0xc0, "LBRAC")
   1861 
   1862 /* Place holder for deleted include file.  Replaces a N_BINCL and everything
   1863    up to the corresponding N_EINCL.  The Sun linker generates these when
   1864    it finds multiple identical copies of the symbols from an include file.
   1865    This appears only in output from the Sun linker.  */
   1866 __define_stab (N_EXCL, 0xc2, "EXCL")
   1867 
   1868 /* Modula-2 scope information.  Can someone say what info it contains?  */
   1869 __define_stab (N_SCOPE, 0xc4, "SCOPE")
   1870 
   1871 /* End of a lexical block.  Desc matches the N_LBRAC's desc.
   1872    The value is the address of the end of the text for the block.  */
   1873 __define_stab (N_RBRAC, 0xe0, "RBRAC")
   1874 
   1875 /* Begin named common block.  Only the name is significant.  */
   1876 __define_stab (N_BCOMM, 0xe2, "BCOMM")
   1877 
   1878 /* End named common block.  Only the name is significant
   1879    (and it should match the N_BCOMM).  */
   1880 __define_stab (N_ECOMM, 0xe4, "ECOMM")
   1881 
   1882 /* End common (local name): value is address.
   1883    I'm not sure how this is used.  */
   1884 __define_stab (N_ECOML, 0xe8, "ECOML")
   1885 
   1886 /* These STAB's are used on Gould systems for Non-Base register symbols
   1887    or something like that.  FIXME.  I have assigned the values at random
   1888    since I don't have a Gould here.  Fixups from Gould folk welcome... */
   1889 __define_stab (N_NBTEXT, 0xF0, "NBTEXT")
   1890 __define_stab (N_NBDATA, 0xF2, "NBDATA")
   1891 __define_stab (N_NBBSS,  0xF4, "NBBSS")
   1892 __define_stab (N_NBSTS,  0xF6, "NBSTS")
   1893 __define_stab (N_NBLCS,  0xF8, "NBLCS")
   1894 
   1895 /* Second symbol entry containing a length-value for the preceding entry.
   1896    The value is the length.  */
   1897 __define_stab (N_LENG, 0xfe, "LENG")
   1898 
   1899 /* The above information, in matrix format.
   1901 
   1902 			STAB MATRIX
   1903 	_________________________________________________
   1904 	| 00 - 1F are not dbx stab symbols		|
   1905 	| In most cases, the low bit is the EXTernal bit|
   1906 
   1907 	| 00 UNDEF  | 02 ABS	| 04 TEXT   | 06 DATA	|
   1908 	| 01  |EXT  | 03  |EXT	| 05  |EXT  | 07  |EXT	|
   1909 
   1910 	| 08 BSS    | 0A INDR	| 0C FN_SEQ | 0E   	|
   1911 	| 09  |EXT  | 0B 	| 0D	    | 0F	|
   1912 
   1913 	| 10 	    | 12 COMM	| 14 SETA   | 16 SETT	|
   1914 	| 11	    | 13	| 15 	    | 17	|
   1915 
   1916 	| 18 SETD   | 1A SETB	| 1C SETV   | 1E WARNING|
   1917 	| 19	    | 1B	| 1D 	    | 1F FN	|
   1918 
   1919 	|_______________________________________________|
   1920 	| Debug entries with bit 01 set are unused.	|
   1921 	| 20 GSYM   | 22 FNAME	| 24 FUN    | 26 STSYM	|
   1922 	| 28 LCSYM  | 2A MAIN	| 2C	    | 2E	|
   1923 	| 30 PC	    | 32 NSYMS	| 34 NOMAP  | 36	|
   1924 	| 38 OBJ    | 3A	| 3C OPT    | 3E	|
   1925 	| 40 RSYM   | 42 M2C	| 44 SLINE  | 46 DSLINE |
   1926 	| 48 BSLINE*| 4A DEFD	| 4C        | 4E	|
   1927 	| 50 EHDECL*| 52	| 54 CATCH  | 56        |
   1928 	| 58        | 5A        | 5C        | 5E	|
   1929 	| 60 SSYM   | 62	| 64 SO	    | 66 	|
   1930 	| 68 	    | 6A	| 6C	    | 6E	|
   1931 	| 70	    | 72	| 74	    | 76	|
   1932 	| 78	    | 7A	| 7C	    | 7E	|
   1933 	| 80 LSYM   | 82 BINCL	| 84 SOL    | 86	|
   1934 	| 88	    | 8A	| 8C	    | 8E	|
   1935 	| 90	    | 92	| 94	    | 96	|
   1936 	| 98	    | 9A	| 9C	    | 9E	|
   1937 	| A0 PSYM   | A2 EINCL	| A4 ENTRY  | A6	|
   1938 	| A8	    | AA	| AC	    | AE	|
   1939 	| B0	    | B2	| B4	    | B6	|
   1940 	| B8	    | BA	| BC	    | BE	|
   1941 	| C0 LBRAC  | C2 EXCL	| C4 SCOPE  | C6	|
   1942 	| C8	    | CA	| CC	    | CE	|
   1943 	| D0	    | D2	| D4	    | D6	|
   1944 	| D8	    | DA	| DC	    | DE	|
   1945 	| E0 RBRAC  | E2 BCOMM	| E4 ECOMM  | E6	|
   1946 	| E8 ECOML  | EA	| EC	    | EE	|
   1947 	| F0	    | F2	| F4	    | F6	|
   1948 	| F8	    | FA	| FC	    | FE LENG	|
   1949 	+-----------------------------------------------+
   1950  * 50 EHDECL is also MOD2.
   1951  * 48 BSLINE is also BROWS.
   1952  */
   1953 //---------------------------------------------------------------------------
   1954 LAST_UNUSED_STAB_CODE
   1955 };
   1956 
   1957 #undef __define_stab
   1958 
   1959 #endif /* __GNU_STAB_ */
   1960 //---------------------------------------------------------------------------
   1961 
   1962 #ifndef O_BINARY
   1963 #define O_BINARY 0
   1964 #endif
   1965 
   1966 // njn: inlined libtcc.h
   1967 //#include "libtcc.h"
   1968 //---------------------------------------------------------------------------
   1969 #ifndef LIBTCC_H
   1970 #define LIBTCC_H
   1971 
   1972 #ifdef __cplusplus
   1973 extern "C" {
   1974 #endif
   1975 
   1976 struct TCCState;
   1977 
   1978 typedef struct TCCState TCCState;
   1979 
   1980 /* create a new TCC compilation context */
   1981 TCCState *tcc_new(void);
   1982 
   1983 /* free a TCC compilation context */
   1984 void tcc_delete(TCCState *s);
   1985 
   1986 /* add debug information in the generated code */
   1987 void tcc_enable_debug(TCCState *s);
   1988 
   1989 /* set error/warning display callback */
   1990 void tcc_set_error_func(TCCState *s, void *error_opaque,
   1991                         void (*error_func)(void *opaque, const char *msg));
   1992 
   1993 /* set/reset a warning */
   1994 int tcc_set_warning(TCCState *s, const char *warning_name, int value);
   1995 
   1996 /*****************************/
   1997 /* preprocessor */
   1998 
   1999 /* add include path */
   2000 int tcc_add_include_path(TCCState *s, const char *pathname);
   2001 
   2002 /* add in system include path */
   2003 int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
   2004 
   2005 /* define preprocessor symbol 'sym'. Can put optional value */
   2006 void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
   2007 
   2008 /* undefine preprocess symbol 'sym' */
   2009 void tcc_undefine_symbol(TCCState *s, const char *sym);
   2010 
   2011 /*****************************/
   2012 /* compiling */
   2013 
   2014 /* add a file (either a C file, dll, an object, a library or an ld
   2015    script). Return -1 if error. */
   2016 int tcc_add_file(TCCState *s, const char *filename);
   2017 
   2018 /* compile a string containing a C source. Return non zero if
   2019    error. */
   2020 int tcc_compile_string(TCCState *s, const char *buf);
   2021 
   2022 /*****************************/
   2023 /* linking commands */
   2024 
   2025 /* set output type. MUST BE CALLED before any compilation */
   2026 #define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
   2027                                  output file) (default) */
   2028 #define TCC_OUTPUT_EXE      1 /* executable file */
   2029 #define TCC_OUTPUT_DLL      2 /* dynamic library */
   2030 #define TCC_OUTPUT_OBJ      3 /* object file */
   2031 int tcc_set_output_type(TCCState *s, int output_type);
   2032 
   2033 #define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
   2034 #define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
   2035 #define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
   2036 
   2037 /* equivalent to -Lpath option */
   2038 int tcc_add_library_path(TCCState *s, const char *pathname);
   2039 
   2040 /* the library name is the same as the argument of the '-l' option */
   2041 int tcc_add_library(TCCState *s, const char *libraryname);
   2042 
   2043 /* add a symbol to the compiled program */
   2044 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
   2045 
   2046 /* output an executable, library or object file. DO NOT call
   2047    tcc_relocate() before. */
   2048 int tcc_output_file(TCCState *s, const char *filename);
   2049 
   2050 /* link and run main() function and return its value. DO NOT call
   2051    tcc_relocate() before. */
   2052 int tcc_run(TCCState *s, int argc, char **argv);
   2053 
   2054 /* do all relocations (needed before using tcc_get_symbol()). Return
   2055    non zero if link error. */
   2056 int tcc_relocate(TCCState *s);
   2057 
   2058 /* return symbol value. return 0 if OK, -1 if symbol not found */
   2059 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
   2060 
   2061 #ifdef __cplusplus
   2062 }
   2063 #endif
   2064 
   2065 #endif
   2066 //---------------------------------------------------------------------------
   2067 
   2068 /* parser debug */
   2069 //#define PARSE_DEBUG
   2070 /* preprocessor debug */
   2071 //#define PP_DEBUG
   2072 /* include file debug */
   2073 //#define INC_DEBUG
   2074 
   2075 //#define MEM_DEBUG
   2076 
   2077 /* assembler debug */
   2078 //#define ASM_DEBUG
   2079 
   2080 /* target selection */
   2081 //#define TCC_TARGET_I386   /* i386 code generator */
   2082 //#define TCC_TARGET_ARM    /* ARMv4 code generator */
   2083 //#define TCC_TARGET_C67    /* TMS320C67xx code generator */
   2084 
   2085 /* default target is I386 */
   2086 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
   2087     !defined(TCC_TARGET_C67)
   2088 #define TCC_TARGET_I386
   2089 #endif
   2090 
   2091 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
   2092     !defined(TCC_TARGET_C67)
   2093 #define CONFIG_TCC_BCHECK /* enable bound checking code */
   2094 #endif
   2095 
   2096 #if defined(WIN32) && !defined(TCC_TARGET_PE)
   2097 #define CONFIG_TCC_STATIC
   2098 #endif
   2099 
   2100 /* define it to include assembler support */
   2101 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
   2102 #define CONFIG_TCC_ASM
   2103 #endif
   2104 
   2105 /* object format selection */
   2106 #if defined(TCC_TARGET_C67)
   2107 #define TCC_TARGET_COFF
   2108 #endif
   2109 
   2110 #define FALSE 0
   2111 #define false 0
   2112 #define TRUE 1
   2113 #define true 1
   2114 typedef int BOOL;
   2115 
   2116 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating
   2117    executables or dlls */
   2118 #define CONFIG_TCC_CRT_PREFIX "/usr/lib"
   2119 
   2120 #define INCLUDE_STACK_SIZE  32
   2121 #define IFDEF_STACK_SIZE    64
   2122 #define VSTACK_SIZE         256
   2123 #define STRING_MAX_SIZE     1024
   2124 #define PACK_STACK_SIZE     8
   2125 
   2126 #define TOK_HASH_SIZE       8192 /* must be a power of two */
   2127 #define TOK_ALLOC_INCR      512  /* must be a power of two */
   2128 #define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
   2129 
   2130 /* token symbol management */
   2131 typedef struct TokenSym {
   2132     struct TokenSym *hash_next;
   2133     struct Sym *sym_define; /* direct pointer to define */
   2134     struct Sym *sym_label; /* direct pointer to label */
   2135     struct Sym *sym_struct; /* direct pointer to structure */
   2136     struct Sym *sym_identifier; /* direct pointer to identifier */
   2137     int tok; /* token number */
   2138     int len;
   2139     char str[1];
   2140 } TokenSym;
   2141 
   2142 typedef struct CString {
   2143     int size; /* size in bytes */
   2144     void *data; /* either 'char *' or 'int *' */
   2145     int size_allocated;
   2146     void *data_allocated; /* if non NULL, data has been malloced */
   2147 } CString;
   2148 
   2149 /* type definition */
   2150 typedef struct CType {
   2151     int t;
   2152     struct Sym *ref;
   2153 } CType;
   2154 
   2155 /* constant value */
   2156 typedef union CValue {
   2157     long double ld;
   2158     double d;
   2159     float f;
   2160     int i;
   2161     unsigned int ui;
   2162     unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
   2163     long long ll;
   2164     unsigned long long ull;
   2165     struct CString *cstr;
   2166     void *ptr;
   2167     int tab[sizeof(long double) / sizeof(int)];
   2168 } CValue;
   2169 
   2170 /* value on stack */
   2171 typedef struct SValue {
   2172     CType type;      /* type */
   2173     unsigned short r;      /* register + flags */
   2174     unsigned short r2;     /* second register, used for 'long long'
   2175                               type. If not used, set to VT_CONST */
   2176     CValue c;              /* constant, if VT_CONST */
   2177     struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
   2178 } SValue;
   2179 
   2180 /* symbol management */
   2181 typedef struct Sym {
   2182     long v;    /* symbol token */
   2183     long r;    /* associated register */
   2184     long c;    /* associated number */
   2185     CType type;    /* associated type */
   2186     struct Sym *next; /* next related symbol */
   2187     struct Sym *prev; /* prev symbol in stack */
   2188     struct Sym *prev_tok; /* previous symbol for this token */
   2189 } Sym;
   2190 
   2191 /* section definition */
   2192 /* XXX: use directly ELF structure for parameters ? */
   2193 /* special flag to indicate that the section should not be linked to
   2194    the other ones */
   2195 #define SHF_PRIVATE 0x80000000
   2196 
   2197 typedef struct Section {
   2198     unsigned long data_offset; /* current data offset */
   2199     unsigned char *data;       /* section data */
   2200     unsigned long data_allocated; /* used for realloc() handling */
   2201     int sh_name;             /* elf section name (only used during output) */
   2202     int sh_num;              /* elf section number */
   2203     int sh_type;             /* elf section type */
   2204     int sh_flags;            /* elf section flags */
   2205     int sh_info;             /* elf section info */
   2206     int sh_addralign;        /* elf section alignment */
   2207     int sh_entsize;          /* elf entry size */
   2208     unsigned long sh_size;   /* section size (only used during output) */
   2209     unsigned long sh_addr;      /* address at which the section is relocated */
   2210     unsigned long sh_offset;      /* address at which the section is relocated */
   2211     int nb_hashed_syms;      /* used to resize the hash table */
   2212     struct Section *link;    /* link to another section */
   2213     struct Section *reloc;   /* corresponding section for relocation, if any */
   2214     struct Section *hash;     /* hash table for symbols */
   2215     struct Section *next;
   2216     char name[1];           /* section name */
   2217 } Section;
   2218 
   2219 typedef struct DLLReference {
   2220     int level;
   2221     char name[1];
   2222 } DLLReference;
   2223 
   2224 /* GNUC attribute definition */
   2225 typedef struct AttributeDef {
   2226     int aligned;
   2227     int packed;
   2228     Section *section;
   2229     unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
   2230     unsigned char dllexport;
   2231 } AttributeDef;
   2232 
   2233 #define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
   2234 #define SYM_FIELD      0x20000000 /* struct/union field symbol space */
   2235 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
   2236 
   2237 /* stored in 'Sym.c' field */
   2238 #define FUNC_NEW       1 /* ansi function prototype */
   2239 #define FUNC_OLD       2 /* old function prototype */
   2240 #define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
   2241 
   2242 /* stored in 'Sym.r' field */
   2243 #define FUNC_CDECL     0 /* standard c call */
   2244 #define FUNC_STDCALL   1 /* pascal c call */
   2245 #define FUNC_FASTCALL1 2 /* first param in %eax */
   2246 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
   2247 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
   2248 
   2249 /* field 'Sym.t' for macros */
   2250 #define MACRO_OBJ      0 /* object like macro */
   2251 #define MACRO_FUNC     1 /* function like macro */
   2252 
   2253 /* field 'Sym.r' for C labels */
   2254 #define LABEL_DEFINED  0 /* label is defined */
   2255 #define LABEL_FORWARD  1 /* label is forward defined */
   2256 #define LABEL_DECLARED 2 /* label is declared but never used */
   2257 
   2258 /* type_decl() types */
   2259 #define TYPE_ABSTRACT  1 /* type without variable */
   2260 #define TYPE_DIRECT    2 /* type with variable */
   2261 
   2262 #define IO_BUF_SIZE 8192
   2263 
   2264 typedef struct BufferedFile {
   2265     uint8_t *buf_ptr;
   2266     uint8_t *buf_end;
   2267     int fd;
   2268     int line_num;    /* current line number - here to simplify code */
   2269     int ifndef_macro;  /* #ifndef macro / #endif search */
   2270     int ifndef_macro_saved; /* saved ifndef_macro */
   2271     int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
   2272     char inc_type;          /* type of include */
   2273     char inc_filename[512]; /* filename specified by the user */
   2274     char filename[1024];    /* current filename - here to simplify code */
   2275     unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
   2276 } BufferedFile;
   2277 
   2278 #define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
   2279 #define CH_EOF   (-1)   /* end of file */
   2280 
   2281 /* parsing state (used to save parser state to reparse part of the
   2282    source several times) */
   2283 typedef struct ParseState {
   2284     int *macro_ptr;
   2285     int line_num;
   2286     int tok;
   2287     CValue tokc;
   2288 } ParseState;
   2289 
   2290 /* used to record tokens */
   2291 typedef struct TokenString {
   2292     int *str;
   2293     int len;
   2294     int allocated_len;
   2295     int last_line_num;
   2296 } TokenString;
   2297 
   2298 /* include file cache, used to find files faster and also to eliminate
   2299    inclusion if the include file is protected by #ifndef ... #endif */
   2300 typedef struct CachedInclude {
   2301     int ifndef_macro;
   2302     int hash_next; /* -1 if none */
   2303     char type; /* '"' or '>' to give include type */
   2304     char filename[1]; /* path specified in #include */
   2305 } CachedInclude;
   2306 
   2307 #define CACHED_INCLUDES_HASH_SIZE 512
   2308 
   2309 /* parser */
   2310 static struct BufferedFile *file;
   2311 static int ch, tok;
   2312 static CValue tokc;
   2313 static CString tokcstr; /* current parsed string, if any */
   2314 /* additional information about token */
   2315 static int tok_flags;
   2316 #define TOK_FLAG_BOL   0x0001 /* beginning of line before */
   2317 #define TOK_FLAG_BOF   0x0002 /* beginning of file before */
   2318 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
   2319 
   2320 static int *macro_ptr, *macro_ptr_allocated;
   2321 static int *unget_saved_macro_ptr;
   2322 static int unget_saved_buffer[TOK_MAX_SIZE + 1];
   2323 static int unget_buffer_enabled;
   2324 static int parse_flags;
   2325 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
   2326 #define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
   2327 #define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
   2328                                         token. line feed is also
   2329                                         returned at eof */
   2330 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
   2331 
   2332 static Section *text_section, *data_section, *bss_section; /* predefined sections */
   2333 static Section *cur_text_section; /* current section where function code is
   2334                               generated */
   2335 #ifdef CONFIG_TCC_ASM
   2336 static Section *last_text_section; /* to handle .previous asm directive */
   2337 #endif
   2338 /* bound check related sections */
   2339 static Section *bounds_section; /* contains global data bound description */
   2340 static Section *lbounds_section; /* contains local data bound description */
   2341 /* symbol sections */
   2342 static Section *symtab_section, *strtab_section;
   2343 
   2344 /* debug sections */
   2345 static Section *stab_section, *stabstr_section;
   2346 
   2347 /* loc : local variable index
   2348    ind : output code index
   2349    rsym: return symbol
   2350    anon_sym: anonymous symbol index
   2351 */
   2352 static long rsym, anon_sym, ind, loc;
   2353 /* expression generation modifiers */
   2354 static int const_wanted; /* true if constant wanted */
   2355 static int nocode_wanted; /* true if no code generation wanted for an expression */
   2356 static int global_expr;  /* true if compound literals must be allocated
   2357                             globally (used during initializers parsing */
   2358 static CType func_vt; /* current function return type (used by return
   2359                          instruction) */
   2360 static int func_vc;
   2361 static long last_line_num, last_ind, func_ind; /* debug last line number and pc */
   2362 static int tok_ident;
   2363 static TokenSym **table_ident;
   2364 static TokenSym *hash_ident[TOK_HASH_SIZE];
   2365 static char token_buf[STRING_MAX_SIZE + 1];
   2366 static char *funcname;
   2367 static Sym *global_stack, *local_stack;
   2368 static Sym *define_stack;
   2369 static Sym *global_label_stack, *local_label_stack;
   2370 /* symbol allocator */
   2371 #define SYM_POOL_NB (8192 / sizeof(Sym))
   2372 static Sym *sym_free_first;
   2373 
   2374 static SValue vstack[VSTACK_SIZE], *vtop;
   2375 /* some predefined types */
   2376 static CType char_pointer_type, func_old_type, int_type;
   2377 /* true if isid(c) || isnum(c) */
   2378 static unsigned char isidnum_table[256];
   2379 
   2380 /* compile with debug symbol (and use them if error during execution) */
   2381 static int do_debug = 0;
   2382 
   2383 /* compile with built-in memory and bounds checker */
   2384 static int do_bounds_check = 0;
   2385 
   2386 /* display benchmark infos */
   2387 #if !defined(LIBTCC)
   2388 static int do_bench = 0;
   2389 #endif
   2390 static int total_lines;
   2391 static int total_bytes;
   2392 
   2393 /* use GNU C extensions */
   2394 static int gnu_ext = 1;
   2395 
   2396 /* use Tiny C extensions */
   2397 static int tcc_ext = 1;
   2398 
   2399 /* max number of callers shown if error */
   2400 static int num_callers = 6;
   2401 static const char **rt_bound_error_msg;
   2402 
   2403 /* XXX: get rid of this ASAP */
   2404 static struct TCCState *tcc_state;
   2405 
   2406 /* give the path of the tcc libraries */
   2407 static const char *tcc_lib_path = CONFIG_TCCDIR;
   2408 
   2409 struct TCCState {
   2410     int output_type;
   2411 
   2412     BufferedFile **include_stack_ptr;
   2413     int *ifdef_stack_ptr;
   2414 
   2415     /* include file handling */
   2416     char **include_paths;
   2417     int nb_include_paths;
   2418     char **sysinclude_paths;
   2419     int nb_sysinclude_paths;
   2420     CachedInclude **cached_includes;
   2421     int nb_cached_includes;
   2422 
   2423     char **library_paths;
   2424     int nb_library_paths;
   2425 
   2426     /* array of all loaded dlls (including those referenced by loaded
   2427        dlls) */
   2428     DLLReference **loaded_dlls;
   2429     int nb_loaded_dlls;
   2430 
   2431     /* sections */
   2432     Section **sections;
   2433     int nb_sections; /* number of sections, including first dummy section */
   2434 
   2435     /* got handling */
   2436     Section *got;
   2437     Section *plt;
   2438     unsigned long *got_offsets;
   2439     int nb_got_offsets;
   2440     /* give the correspondence from symtab indexes to dynsym indexes */
   2441     int *symtab_to_dynsym;
   2442 
   2443     /* temporary dynamic symbol sections (for dll loading) */
   2444     Section *dynsymtab_section;
   2445     /* exported dynamic symbol section */
   2446     Section *dynsym;
   2447 
   2448     int nostdinc; /* if true, no standard headers are added */
   2449     int nostdlib; /* if true, no standard libraries are added */
   2450 
   2451     int nocommon; /* if true, do not use common symbols for .bss data */
   2452 
   2453     /* if true, static linking is performed */
   2454     int static_link;
   2455 
   2456     /* if true, all symbols are exported */
   2457     int rdynamic;
   2458 
   2459     /* if true, only link in referenced objects from archive */
   2460     int alacarte_link;
   2461 
   2462     /* address of text section */
   2463     unsigned long text_addr;
   2464     int has_text_addr;
   2465 
   2466     /* output format, see TCC_OUTPUT_FORMAT_xxx */
   2467     int output_format;
   2468 
   2469     /* C language options */
   2470     int char_is_unsigned;
   2471     int leading_underscore;
   2472 
   2473     /* warning switches */
   2474     int warn_write_strings;
   2475     int warn_unsupported;
   2476     int warn_error;
   2477     int warn_none;
   2478     int warn_implicit_function_declaration;
   2479 
   2480     /* error handling */
   2481     void *error_opaque;
   2482     void (*error_func)(void *opaque, const char *msg);
   2483     int error_set_jmp_enabled;
   2484     jmp_buf error_jmp_buf;
   2485     int nb_errors;
   2486 
   2487     /* tiny assembler state */
   2488     Sym *asm_labels;
   2489 
   2490     /* see include_stack_ptr */
   2491     BufferedFile *include_stack[INCLUDE_STACK_SIZE];
   2492 
   2493     /* see ifdef_stack_ptr */
   2494     int ifdef_stack[IFDEF_STACK_SIZE];
   2495 
   2496     /* see cached_includes */
   2497     int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
   2498 
   2499     /* pack stack */
   2500     int pack_stack[PACK_STACK_SIZE];
   2501     int *pack_stack_ptr;
   2502 };
   2503 
   2504 /* The current value can be: */
   2505 #define VT_VALMASK   0x00ff
   2506 #define VT_CONST     0x00f0  /* constant in vc
   2507                               (must be first non register value) */
   2508 #define VT_LLOCAL    0x00f1  /* lvalue, offset on stack */
   2509 #define VT_LOCAL     0x00f2  /* offset on stack */
   2510 #define VT_CMP       0x00f3  /* the value is stored in processor flags (in vc) */
   2511 #define VT_JMP       0x00f4  /* value is the consequence of jmp true (even) */
   2512 #define VT_JMPI      0x00f5  /* value is the consequence of jmp false (odd) */
   2513 #define VT_LVAL      0x0100  /* var is an lvalue */
   2514 #define VT_SYM       0x0200  /* a symbol value is added */
   2515 #define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
   2516                                 char/short stored in integer registers) */
   2517 #define VT_MUSTBOUND 0x0800  /* bound checking must be done before
   2518                                 dereferencing value */
   2519 #define VT_BOUNDED   0x8000  /* value is bounded. The address of the
   2520                                 bounding function call point is in vc */
   2521 #define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
   2522 #define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
   2523 #define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
   2524 #define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
   2525 
   2526 /* types */
   2527 #define VT_INT        0  /* integer type */
   2528 #define VT_BYTE       1  /* signed byte type */
   2529 #define VT_SHORT      2  /* short type */
   2530 #define VT_VOID       3  /* void type */
   2531 #define VT_PTR        4  /* pointer */
   2532 #define VT_ENUM       5  /* enum definition */
   2533 #define VT_FUNC       6  /* function type */
   2534 #define VT_STRUCT     7  /* struct/union definition */
   2535 #define VT_FLOAT      8  /* IEEE float */
   2536 #define VT_DOUBLE     9  /* IEEE double */
   2537 #define VT_LDOUBLE   10  /* IEEE long double */
   2538 #define VT_BOOL      11  /* ISOC99 boolean type */
   2539 #define VT_LLONG     12  /* 64 bit integer */
   2540 #define VT_LONG      13  /* long integer (NEVER USED as type, only
   2541                             during parsing) */
   2542 #define VT_BTYPE      0x000f /* mask for basic type */
   2543 #define VT_UNSIGNED   0x0010  /* unsigned type */
   2544 #define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
   2545 #define VT_BITFIELD   0x0040  /* bitfield modifier */
   2546 #define VT_CONSTANT   0x0800  /* const modifier */
   2547 #define VT_VOLATILE   0x1000  /* volatile modifier */
   2548 #define VT_SIGNED     0x2000  /* signed type */
   2549 
   2550 /* storage */
   2551 #define VT_EXTERN  0x00000080  /* extern definition */
   2552 #define VT_STATIC  0x00000100  /* static variable */
   2553 #define VT_TYPEDEF 0x00000200  /* typedef definition */
   2554 #define VT_INLINE  0x00000400  /* inline definition */
   2555 
   2556 #define VT_STRUCT_SHIFT 16   /* shift for bitfield shift values */
   2557 
   2558 /* type mask (except storage) */
   2559 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
   2560 #define VT_TYPE    (~(VT_STORAGE))
   2561 
   2562 /* token values */
   2563 
   2564 /* warning: the following compare tokens depend on i386 asm code */
   2565 #define TOK_ULT 0x92
   2566 #define TOK_UGE 0x93
   2567 #define TOK_EQ  0x94
   2568 #define TOK_NE  0x95
   2569 #define TOK_ULE 0x96
   2570 #define TOK_UGT 0x97
   2571 #define TOK_LT  0x9c
   2572 #define TOK_GE  0x9d
   2573 #define TOK_LE  0x9e
   2574 #define TOK_GT  0x9f
   2575 
   2576 #define TOK_LAND  0xa0
   2577 #define TOK_LOR   0xa1
   2578 
   2579 #define TOK_DEC   0xa2
   2580 #define TOK_MID   0xa3 /* inc/dec, to void constant */
   2581 #define TOK_INC   0xa4
   2582 #define TOK_UDIV  0xb0 /* unsigned division */
   2583 #define TOK_UMOD  0xb1 /* unsigned modulo */
   2584 #define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
   2585 #define TOK_CINT   0xb3 /* number in tokc */
   2586 #define TOK_CCHAR 0xb4 /* char constant in tokc */
   2587 #define TOK_STR   0xb5 /* pointer to string in tokc */
   2588 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
   2589 #define TOK_LCHAR    0xb7
   2590 #define TOK_LSTR     0xb8
   2591 #define TOK_CFLOAT   0xb9 /* float constant */
   2592 #define TOK_LINENUM  0xba /* line number info */
   2593 #define TOK_CDOUBLE  0xc0 /* double constant */
   2594 #define TOK_CLDOUBLE 0xc1 /* long double constant */
   2595 #define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
   2596 #define TOK_ADDC1    0xc3 /* add with carry generation */
   2597 #define TOK_ADDC2    0xc4 /* add with carry use */
   2598 #define TOK_SUBC1    0xc5 /* add with carry generation */
   2599 #define TOK_SUBC2    0xc6 /* add with carry use */
   2600 #define TOK_CUINT    0xc8 /* unsigned int constant */
   2601 #define TOK_CLLONG   0xc9 /* long long constant */
   2602 #define TOK_CULLONG  0xca /* unsigned long long constant */
   2603 #define TOK_ARROW    0xcb
   2604 #define TOK_DOTS     0xcc /* three dots */
   2605 #define TOK_SHR      0xcd /* unsigned shift right */
   2606 #define TOK_PPNUM    0xce /* preprocessor number */
   2607 
   2608 #define TOK_SHL   0x01 /* shift left */
   2609 #define TOK_SAR   0x02 /* signed shift right */
   2610 
   2611 /* assignement operators : normal operator or 0x80 */
   2612 #define TOK_A_MOD 0xa5
   2613 #define TOK_A_AND 0xa6
   2614 #define TOK_A_MUL 0xaa
   2615 #define TOK_A_ADD 0xab
   2616 #define TOK_A_SUB 0xad
   2617 #define TOK_A_DIV 0xaf
   2618 #define TOK_A_XOR 0xde
   2619 #define TOK_A_OR  0xfc
   2620 #define TOK_A_SHL 0x81
   2621 #define TOK_A_SAR 0x82
   2622 
   2623 #ifndef offsetof
   2624 #define offsetof(type, field) ((size_t) &((type *)0)->field)
   2625 #endif
   2626 
   2627 #ifndef countof
   2628 #define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
   2629 #endif
   2630 
   2631 /* WARNING: the content of this string encodes token numbers */
   2632 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";
   2633 
   2634 #define TOK_EOF       (-1)  /* end of file */
   2635 #define TOK_LINEFEED  10    /* line feed */
   2636 
   2637 /* all identificators and strings have token above that */
   2638 #define TOK_IDENT 256
   2639 
   2640 /* only used for i386 asm opcodes definitions */
   2641 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
   2642 
   2643 #define DEF_BWL(x) \
   2644  DEF(TOK_ASM_ ## x ## b, #x "b") \
   2645  DEF(TOK_ASM_ ## x ## w, #x "w") \
   2646  DEF(TOK_ASM_ ## x ## l, #x "l") \
   2647  DEF(TOK_ASM_ ## x, #x)
   2648 
   2649 #define DEF_WL(x) \
   2650  DEF(TOK_ASM_ ## x ## w, #x "w") \
   2651  DEF(TOK_ASM_ ## x ## l, #x "l") \
   2652  DEF(TOK_ASM_ ## x, #x)
   2653 
   2654 #define DEF_FP1(x) \
   2655  DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
   2656  DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
   2657  DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
   2658  DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
   2659 
   2660 #define DEF_FP(x) \
   2661  DEF(TOK_ASM_ ## f ## x, "f" #x ) \
   2662  DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
   2663  DEF_FP1(x)
   2664 
   2665 #define DEF_ASMTEST(x) \
   2666  DEF_ASM(x ## o) \
   2667  DEF_ASM(x ## no) \
   2668  DEF_ASM(x ## b) \
   2669  DEF_ASM(x ## c) \
   2670  DEF_ASM(x ## nae) \
   2671  DEF_ASM(x ## nb) \
   2672  DEF_ASM(x ## nc) \
   2673  DEF_ASM(x ## ae) \
   2674  DEF_ASM(x ## e) \
   2675  DEF_ASM(x ## z) \
   2676  DEF_ASM(x ## ne) \
   2677  DEF_ASM(x ## nz) \
   2678  DEF_ASM(x ## be) \
   2679  DEF_ASM(x ## na) \
   2680  DEF_ASM(x ## nbe) \
   2681  DEF_ASM(x ## a) \
   2682  DEF_ASM(x ## s) \
   2683  DEF_ASM(x ## ns) \
   2684  DEF_ASM(x ## p) \
   2685  DEF_ASM(x ## pe) \
   2686  DEF_ASM(x ## np) \
   2687  DEF_ASM(x ## po) \
   2688  DEF_ASM(x ## l) \
   2689  DEF_ASM(x ## nge) \
   2690  DEF_ASM(x ## nl) \
   2691  DEF_ASM(x ## ge) \
   2692  DEF_ASM(x ## le) \
   2693  DEF_ASM(x ## ng) \
   2694  DEF_ASM(x ## nle) \
   2695  DEF_ASM(x ## g)
   2696 
   2697 #define TOK_ASM_int TOK_INT
   2698 
   2699 enum tcc_token {
   2700     TOK_LAST = TOK_IDENT - 1,
   2701 #define DEF(id, str) id,
   2702 // njn: inlined tcctok.h
   2703 //#include "tcctok.h"
   2704 //---------------------------------------------------------------------------
   2705 /* keywords */
   2706      DEF(TOK_INT, "int")
   2707      DEF(TOK_VOID, "void")
   2708      DEF(TOK_CHAR, "char")
   2709      DEF(TOK_IF, "if")
   2710      DEF(TOK_ELSE, "else")
   2711      DEF(TOK_WHILE, "while")
   2712      DEF(TOK_BREAK, "break")
   2713      DEF(TOK_RETURN, "return")
   2714      DEF(TOK_FOR, "for")
   2715      DEF(TOK_EXTERN, "extern")
   2716      DEF(TOK_STATIC, "static")
   2717      DEF(TOK_UNSIGNED, "unsigned")
   2718      DEF(TOK_GOTO, "goto")
   2719      DEF(TOK_DO, "do")
   2720      DEF(TOK_CONTINUE, "continue")
   2721      DEF(TOK_SWITCH, "switch")
   2722      DEF(TOK_CASE, "case")
   2723 
   2724      DEF(TOK_CONST1, "const")
   2725      DEF(TOK_CONST2, "__const") /* gcc keyword */
   2726      DEF(TOK_CONST3, "__const__") /* gcc keyword */
   2727      DEF(TOK_VOLATILE1, "volatile")
   2728      DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
   2729      DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
   2730      DEF(TOK_LONG, "long")
   2731      DEF(TOK_REGISTER, "register")
   2732      DEF(TOK_SIGNED1, "signed")
   2733      DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
   2734      DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
   2735      DEF(TOK_AUTO, "auto")
   2736      DEF(TOK_INLINE1, "inline")
   2737      DEF(TOK_INLINE2, "__inline") /* gcc keyword */
   2738      DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
   2739      DEF(TOK_RESTRICT1, "restrict")
   2740      DEF(TOK_RESTRICT2, "__restrict")
   2741      DEF(TOK_RESTRICT3, "__restrict__")
   2742      DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
   2743 
   2744      DEF(TOK_FLOAT, "float")
   2745      DEF(TOK_DOUBLE, "double")
   2746      DEF(TOK_BOOL, "_Bool")
   2747      DEF(TOK_SHORT, "short")
   2748      DEF(TOK_STRUCT, "struct")
   2749      DEF(TOK_UNION, "union")
   2750      DEF(TOK_TYPEDEF, "typedef")
   2751      DEF(TOK_DEFAULT, "default")
   2752      DEF(TOK_ENUM, "enum")
   2753      DEF(TOK_SIZEOF, "sizeof")
   2754      DEF(TOK_ATTRIBUTE1, "__attribute")
   2755      DEF(TOK_ATTRIBUTE2, "__attribute__")
   2756      DEF(TOK_ALIGNOF1, "__alignof")
   2757      DEF(TOK_ALIGNOF2, "__alignof__")
   2758      DEF(TOK_TYPEOF1, "typeof")
   2759      DEF(TOK_TYPEOF2, "__typeof")
   2760      DEF(TOK_TYPEOF3, "__typeof__")
   2761      DEF(TOK_LABEL, "__label__")
   2762      DEF(TOK_ASM1, "asm")
   2763      DEF(TOK_ASM2, "__asm")
   2764      DEF(TOK_ASM3, "__asm__")
   2765 
   2766 /*********************************************************************/
   2767 /* the following are not keywords. They are included to ease parsing */
   2768 /* preprocessor only */
   2769      DEF(TOK_DEFINE, "define")
   2770      DEF(TOK_INCLUDE, "include")
   2771      DEF(TOK_INCLUDE_NEXT, "include_next")
   2772      DEF(TOK_IFDEF, "ifdef")
   2773      DEF(TOK_IFNDEF, "ifndef")
   2774      DEF(TOK_ELIF, "elif")
   2775      DEF(TOK_ENDIF, "endif")
   2776      DEF(TOK_DEFINED, "defined")
   2777      DEF(TOK_UNDEF, "undef")
   2778      DEF(TOK_ERROR, "error")
   2779      DEF(TOK_WARNING, "warning")
   2780      DEF(TOK_LINE, "line")
   2781      DEF(TOK_PRAGMA, "pragma")
   2782      DEF(TOK___LINE__, "__LINE__")
   2783      DEF(TOK___FILE__, "__FILE__")
   2784      DEF(TOK___DATE__, "__DATE__")
   2785      DEF(TOK___TIME__, "__TIME__")
   2786      DEF(TOK___FUNCTION__, "__FUNCTION__")
   2787      DEF(TOK___VA_ARGS__, "__VA_ARGS__")
   2788 
   2789 /* special identifiers */
   2790      DEF(TOK___FUNC__, "__func__")
   2791 
   2792 /* attribute identifiers */
   2793 /* XXX: handle all tokens generically since speed is not critical */
   2794      DEF(TOK_SECTION1, "section")
   2795      DEF(TOK_SECTION2, "__section__")
   2796      DEF(TOK_ALIGNED1, "aligned")
   2797      DEF(TOK_ALIGNED2, "__aligned__")
   2798      DEF(TOK_PACKED1, "packed")
   2799      DEF(TOK_PACKED2, "__packed__")
   2800      DEF(TOK_UNUSED1, "unused")
   2801      DEF(TOK_UNUSED2, "__unused__")
   2802      DEF(TOK_CDECL1, "cdecl")
   2803      DEF(TOK_CDECL2, "__cdecl")
   2804      DEF(TOK_CDECL3, "__cdecl__")
   2805      DEF(TOK_STDCALL1, "stdcall")
   2806      DEF(TOK_STDCALL2, "__stdcall")
   2807      DEF(TOK_STDCALL3, "__stdcall__")
   2808      DEF(TOK_DLLEXPORT, "dllexport")
   2809      DEF(TOK_NORETURN1, "noreturn")
   2810      DEF(TOK_NORETURN2, "__noreturn__")
   2811      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
   2812      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
   2813      DEF(TOK_REGPARM1, "regparm")
   2814      DEF(TOK_REGPARM2, "__regparm__")
   2815 
   2816 /* pragma */
   2817      DEF(TOK_pack, "pack")
   2818 #if !defined(TCC_TARGET_I386)
   2819      /* already defined for assembler */
   2820      DEF(TOK_ASM_push, "push")
   2821      DEF(TOK_ASM_pop, "pop")
   2822 #endif
   2823 
   2824 /* builtin functions or variables */
   2825      DEF(TOK_memcpy, "memcpy")
   2826      DEF(TOK_memset, "memset")
   2827      DEF(TOK_alloca, "alloca")
   2828      DEF(TOK___divdi3, "__divdi3")
   2829      DEF(TOK___moddi3, "__moddi3")
   2830      DEF(TOK___udivdi3, "__udivdi3")
   2831      DEF(TOK___umoddi3, "__umoddi3")
   2832 #if defined(TCC_TARGET_ARM)
   2833      DEF(TOK___divsi3, "__divsi3")
   2834      DEF(TOK___modsi3, "__modsi3")
   2835      DEF(TOK___udivsi3, "__udivsi3")
   2836      DEF(TOK___umodsi3, "__umodsi3")
   2837      DEF(TOK___sardi3, "__ashrdi3")
   2838      DEF(TOK___shrdi3, "__lshrdi3")
   2839      DEF(TOK___shldi3, "__ashldi3")
   2840      DEF(TOK___slltold, "__slltold")
   2841      DEF(TOK___fixunssfsi, "__fixunssfsi")
   2842      DEF(TOK___fixunsdfsi, "__fixunsdfsi")
   2843      DEF(TOK___fixunsxfsi, "__fixunsxfsi")
   2844      DEF(TOK___fixsfdi, "__fixsfdi")
   2845      DEF(TOK___fixdfdi, "__fixdfdi")
   2846      DEF(TOK___fixxfdi, "__fixxfdi")
   2847 #elif defined(TCC_TARGET_C67)
   2848      DEF(TOK__divi, "_divi")
   2849      DEF(TOK__divu, "_divu")
   2850      DEF(TOK__divf, "_divf")
   2851      DEF(TOK__divd, "_divd")
   2852      DEF(TOK__remi, "_remi")
   2853      DEF(TOK__remu, "_remu")
   2854      DEF(TOK___sardi3, "__sardi3")
   2855      DEF(TOK___shrdi3, "__shrdi3")
   2856      DEF(TOK___shldi3, "__shldi3")
   2857 #else
   2858      /* XXX: same names on i386 ? */
   2859      DEF(TOK___sardi3, "__sardi3")
   2860      DEF(TOK___shrdi3, "__shrdi3")
   2861      DEF(TOK___shldi3, "__shldi3")
   2862 #endif
   2863      DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
   2864      DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
   2865      DEF(TOK___ulltof, "__ulltof")
   2866      DEF(TOK___ulltod, "__ulltod")
   2867      DEF(TOK___ulltold, "__ulltold")
   2868      DEF(TOK___fixunssfdi, "__fixunssfdi")
   2869      DEF(TOK___fixunsdfdi, "__fixunsdfdi")
   2870      DEF(TOK___fixunsxfdi, "__fixunsxfdi")
   2871      DEF(TOK___chkstk, "__chkstk")
   2872 
   2873 /* bound checking symbols */
   2874 #ifdef CONFIG_TCC_BCHECK
   2875      DEF(TOK___bound_ptr_add, "__bound_ptr_add")
   2876      DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
   2877      DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
   2878      DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
   2879      DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
   2880      DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
   2881      DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
   2882      DEF(TOK___bound_local_new, "__bound_local_new")
   2883      DEF(TOK___bound_local_delete, "__bound_local_delete")
   2884      DEF(TOK_malloc, "malloc")
   2885      DEF(TOK_free, "free")
   2886      DEF(TOK_realloc, "realloc")
   2887      DEF(TOK_memalign, "memalign")
   2888      DEF(TOK_calloc, "calloc")
   2889      DEF(TOK_memmove, "memmove")
   2890      DEF(TOK_strlen, "strlen")
   2891      DEF(TOK_strcpy, "strcpy")
   2892 #endif
   2893 
   2894 /* Tiny Assembler */
   2895 
   2896  DEF_ASM(byte)
   2897  DEF_ASM(align)
   2898  DEF_ASM(skip)
   2899  DEF_ASM(space)
   2900  DEF_ASM(string)
   2901  DEF_ASM(asciz)
   2902  DEF_ASM(ascii)
   2903  DEF_ASM(globl)
   2904  DEF_ASM(global)
   2905  DEF_ASM(text)
   2906  DEF_ASM(data)
   2907  DEF_ASM(bss)
   2908  DEF_ASM(previous)
   2909  DEF_ASM(fill)
   2910  DEF_ASM(org)
   2911  DEF_ASM(quad)
   2912 
   2913 #ifdef TCC_TARGET_I386
   2914 
   2915 /* WARNING: relative order of tokens is important. */
   2916  DEF_ASM(al)
   2917  DEF_ASM(cl)
   2918  DEF_ASM(dl)
   2919  DEF_ASM(bl)
   2920  DEF_ASM(ah)
   2921  DEF_ASM(ch)
   2922  DEF_ASM(dh)
   2923  DEF_ASM(bh)
   2924  DEF_ASM(ax)
   2925  DEF_ASM(cx)
   2926  DEF_ASM(dx)
   2927  DEF_ASM(bx)
   2928  DEF_ASM(sp)
   2929  DEF_ASM(bp)
   2930  DEF_ASM(si)
   2931  DEF_ASM(di)
   2932  DEF_ASM(eax)
   2933  DEF_ASM(ecx)
   2934  DEF_ASM(edx)
   2935  DEF_ASM(ebx)
   2936  DEF_ASM(esp)
   2937  DEF_ASM(ebp)
   2938  DEF_ASM(esi)
   2939  DEF_ASM(edi)
   2940  DEF_ASM(mm0)
   2941  DEF_ASM(mm1)
   2942  DEF_ASM(mm2)
   2943  DEF_ASM(mm3)
   2944  DEF_ASM(mm4)
   2945  DEF_ASM(mm5)
   2946  DEF_ASM(mm6)
   2947  DEF_ASM(mm7)
   2948  DEF_ASM(xmm0)
   2949  DEF_ASM(xmm1)
   2950  DEF_ASM(xmm2)
   2951  DEF_ASM(xmm3)
   2952  DEF_ASM(xmm4)
   2953  DEF_ASM(xmm5)
   2954  DEF_ASM(xmm6)
   2955  DEF_ASM(xmm7)
   2956  DEF_ASM(cr0)
   2957  DEF_ASM(cr1)
   2958  DEF_ASM(cr2)
   2959  DEF_ASM(cr3)
   2960  DEF_ASM(cr4)
   2961  DEF_ASM(cr5)
   2962  DEF_ASM(cr6)
   2963  DEF_ASM(cr7)
   2964  DEF_ASM(tr0)
   2965  DEF_ASM(tr1)
   2966  DEF_ASM(tr2)
   2967  DEF_ASM(tr3)
   2968  DEF_ASM(tr4)
   2969  DEF_ASM(tr5)
   2970  DEF_ASM(tr6)
   2971  DEF_ASM(tr7)
   2972  DEF_ASM(db0)
   2973  DEF_ASM(db1)
   2974  DEF_ASM(db2)
   2975  DEF_ASM(db3)
   2976  DEF_ASM(db4)
   2977  DEF_ASM(db5)
   2978  DEF_ASM(db6)
   2979  DEF_ASM(db7)
   2980  DEF_ASM(dr0)
   2981  DEF_ASM(dr1)
   2982  DEF_ASM(dr2)
   2983  DEF_ASM(dr3)
   2984  DEF_ASM(dr4)
   2985  DEF_ASM(dr5)
   2986  DEF_ASM(dr6)
   2987  DEF_ASM(dr7)
   2988  DEF_ASM(es)
   2989  DEF_ASM(cs)
   2990  DEF_ASM(ss)
   2991  DEF_ASM(ds)
   2992  DEF_ASM(fs)
   2993  DEF_ASM(gs)
   2994  DEF_ASM(st)
   2995 
   2996  DEF_BWL(mov)
   2997 
   2998  /* generic two operands */
   2999  DEF_BWL(add)
   3000  DEF_BWL(or)
   3001  DEF_BWL(adc)
   3002  DEF_BWL(sbb)
   3003  DEF_BWL(and)
   3004  DEF_BWL(sub)
   3005  DEF_BWL(xor)
   3006  DEF_BWL(cmp)
   3007 
   3008  /* unary ops */
   3009  DEF_BWL(inc)
   3010  DEF_BWL(dec)
   3011  DEF_BWL(not)
   3012  DEF_BWL(neg)
   3013  DEF_BWL(mul)
   3014  DEF_BWL(imul)
   3015  DEF_BWL(div)
   3016  DEF_BWL(idiv)
   3017 
   3018  DEF_BWL(xchg)
   3019  DEF_BWL(test)
   3020 
   3021  /* shifts */
   3022  DEF_BWL(rol)
   3023  DEF_BWL(ror)
   3024  DEF_BWL(rcl)
   3025  DEF_BWL(rcr)
   3026  DEF_BWL(shl)
   3027  DEF_BWL(shr)
   3028  DEF_BWL(sar)
   3029 
   3030  DEF_ASM(shldw)
   3031  DEF_ASM(shldl)
   3032  DEF_ASM(shld)
   3033  DEF_ASM(shrdw)
   3034  DEF_ASM(shrdl)
   3035  DEF_ASM(shrd)
   3036 
   3037  DEF_ASM(pushw)
   3038  DEF_ASM(pushl)
   3039  DEF_ASM(push)
   3040  DEF_ASM(popw)
   3041  DEF_ASM(popl)
   3042  DEF_ASM(pop)
   3043  DEF_BWL(in)
   3044  DEF_BWL(out)
   3045 
   3046  DEF_WL(movzb)
   3047 
   3048  DEF_ASM(movzwl)
   3049  DEF_ASM(movsbw)
   3050  DEF_ASM(movsbl)
   3051  DEF_ASM(movswl)
   3052 
   3053  DEF_WL(lea)
   3054 
   3055  DEF_ASM(les)
   3056  DEF_ASM(lds)
   3057  DEF_ASM(lss)
   3058  DEF_ASM(lfs)
   3059  DEF_ASM(lgs)
   3060 
   3061  DEF_ASM(call)
   3062  DEF_ASM(jmp)
   3063  DEF_ASM(lcall)
   3064  DEF_ASM(ljmp)
   3065 
   3066  DEF_ASMTEST(j)
   3067 
   3068  DEF_ASMTEST(set)
   3069  DEF_ASMTEST(cmov)
   3070 
   3071  DEF_WL(bsf)
   3072  DEF_WL(bsr)
   3073  DEF_WL(bt)
   3074  DEF_WL(bts)
   3075  DEF_WL(btr)
   3076  DEF_WL(btc)
   3077 
   3078  DEF_WL(lsl)
   3079 
   3080  /* generic FP ops */
   3081  DEF_FP(add)
   3082  DEF_FP(mul)
   3083 
   3084  DEF_ASM(fcom)
   3085  DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
   3086  DEF_FP1(com)
   3087 
   3088  DEF_FP(comp)
   3089  DEF_FP(sub)
   3090  DEF_FP(subr)
   3091  DEF_FP(div)
   3092  DEF_FP(divr)
   3093 
   3094  DEF_BWL(xadd)
   3095  DEF_BWL(cmpxchg)
   3096 
   3097  /* string ops */
   3098  DEF_BWL(cmps)
   3099  DEF_BWL(scmp)
   3100  DEF_BWL(ins)
   3101  DEF_BWL(outs)
   3102  DEF_BWL(lods)
   3103  DEF_BWL(slod)
   3104  DEF_BWL(movs)
   3105  DEF_BWL(smov)
   3106  DEF_BWL(scas)
   3107  DEF_BWL(ssca)
   3108  DEF_BWL(stos)
   3109  DEF_BWL(ssto)
   3110 
   3111  /* generic asm ops */
   3112 
   3113 #define ALT(x)
   3114 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
   3115 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
   3116 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
   3117 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
   3118 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
   3119 // njn: inlined i386-asm.h
   3120 //#include "i386-asm.h"
   3121 //---------------------------------------------------------------------------
   3122      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
   3123      DEF_ASM_OP0(popa, 0x61)
   3124      DEF_ASM_OP0(clc, 0xf8)
   3125      DEF_ASM_OP0(cld, 0xfc)
   3126      DEF_ASM_OP0(cli, 0xfa)
   3127      DEF_ASM_OP0(clts, 0x0f06)
   3128      DEF_ASM_OP0(cmc, 0xf5)
   3129      DEF_ASM_OP0(lahf, 0x9f)
   3130      DEF_ASM_OP0(sahf, 0x9e)
   3131      DEF_ASM_OP0(pushfl, 0x9c)
   3132      DEF_ASM_OP0(popfl, 0x9d)
   3133      DEF_ASM_OP0(pushf, 0x9c)
   3134      DEF_ASM_OP0(popf, 0x9d)
   3135      DEF_ASM_OP0(stc, 0xf9)
   3136      DEF_ASM_OP0(std, 0xfd)
   3137      DEF_ASM_OP0(sti, 0xfb)
   3138      DEF_ASM_OP0(aaa, 0x37)
   3139      DEF_ASM_OP0(aas, 0x3f)
   3140      DEF_ASM_OP0(daa, 0x27)
   3141      DEF_ASM_OP0(das, 0x2f)
   3142      DEF_ASM_OP0(aad, 0xd50a)
   3143      DEF_ASM_OP0(aam, 0xd40a)
   3144      DEF_ASM_OP0(cbw, 0x6698)
   3145      DEF_ASM_OP0(cwd, 0x6699)
   3146      DEF_ASM_OP0(cwde, 0x98)
   3147      DEF_ASM_OP0(cdq, 0x99)
   3148      DEF_ASM_OP0(cbtw, 0x6698)
   3149      DEF_ASM_OP0(cwtl, 0x98)
   3150      DEF_ASM_OP0(cwtd, 0x6699)
   3151      DEF_ASM_OP0(cltd, 0x99)
   3152      DEF_ASM_OP0(int3, 0xcc)
   3153      DEF_ASM_OP0(into, 0xce)
   3154      DEF_ASM_OP0(iret, 0xcf)
   3155      DEF_ASM_OP0(rsm, 0x0faa)
   3156      DEF_ASM_OP0(hlt, 0xf4)
   3157      DEF_ASM_OP0(wait, 0x9b)
   3158      DEF_ASM_OP0(nop, 0x90)
   3159      DEF_ASM_OP0(xlat, 0xd7)
   3160 
   3161      /* strings */
   3162 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
   3163 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
   3164 
   3165 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
   3166 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
   3167 
   3168 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
   3169 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
   3170 
   3171 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
   3172 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
   3173 
   3174 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
   3175 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
   3176 
   3177 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
   3178 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
   3179 
   3180      /* bits */
   3181 
   3182 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   3183 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   3184 
   3185 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3186 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3187 
   3188 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3189 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3190 
   3191 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3192 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3193 
   3194 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3195 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3196 
   3197      /* prefixes */
   3198      DEF_ASM_OP0(aword, 0x67)
   3199      DEF_ASM_OP0(addr16, 0x67)
   3200      DEF_ASM_OP0(word, 0x66)
   3201      DEF_ASM_OP0(data16, 0x66)
   3202      DEF_ASM_OP0(lock, 0xf0)
   3203      DEF_ASM_OP0(rep, 0xf3)
   3204      DEF_ASM_OP0(repe, 0xf3)
   3205      DEF_ASM_OP0(repz, 0xf3)
   3206      DEF_ASM_OP0(repne, 0xf2)
   3207      DEF_ASM_OP0(repnz, 0xf2)
   3208 
   3209      DEF_ASM_OP0(invd, 0x0f08)
   3210      DEF_ASM_OP0(wbinvd, 0x0f09)
   3211      DEF_ASM_OP0(cpuid, 0x0fa2)
   3212      DEF_ASM_OP0(wrmsr, 0x0f30)
   3213      DEF_ASM_OP0(rdtsc, 0x0f31)
   3214      DEF_ASM_OP0(rdmsr, 0x0f32)
   3215      DEF_ASM_OP0(rdpmc, 0x0f33)
   3216      DEF_ASM_OP0(ud2, 0x0f0b)
   3217 
   3218      /* NOTE: we took the same order as gas opcode definition order */
   3219 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
   3220 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
   3221 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   3222 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3223 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
   3224 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
   3225 
   3226 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
   3227 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
   3228 
   3229 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
   3230 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
   3231 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
   3232 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
   3233 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
   3234 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
   3235 
   3236 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
   3237 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
   3238 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   3239 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
   3240 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   3241 
   3242 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
   3243 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   3244 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
   3245 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
   3246 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
   3247 
   3248 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
   3249 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   3250 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
   3251 
   3252 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
   3253 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
   3254 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   3255 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3256 
   3257 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
   3258 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
   3259 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
   3260 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
   3261 
   3262 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
   3263 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
   3264 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
   3265 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
   3266 
   3267 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
   3268 
   3269 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3270 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3271 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3272 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3273 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3274 
   3275      /* arith */
   3276 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
   3277 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3278 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
   3279 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   3280 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
   3281 
   3282 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3283 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   3284 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
   3285 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   3286 
   3287 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
   3288 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3289 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
   3290 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3291 
   3292 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3293 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3294 
   3295 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3296 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3297 
   3298 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
   3299 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
   3300 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
   3301 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
   3302 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
   3303 
   3304 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3305 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   3306 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3307 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   3308 
   3309      /* shifts */
   3310 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
   3311 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
   3312 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
   3313 
   3314 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   3315 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   3316 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   3317 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   3318 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   3319 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   3320 
   3321 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
   3322 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
   3323 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
   3324 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
   3325 
   3326 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
   3327 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
   3328 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
   3329 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
   3330 
   3331 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
   3332 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
   3333     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
   3334     DEF_ASM_OP0(leave, 0xc9)
   3335     DEF_ASM_OP0(ret, 0xc3)
   3336 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
   3337     DEF_ASM_OP0(lret, 0xcb)
   3338 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
   3339 
   3340 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
   3341     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   3342     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   3343     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   3344     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   3345     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
   3346     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
   3347 
   3348      /* float */
   3349      /* specific fcomp handling */
   3350 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
   3351 
   3352 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   3353 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   3354 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
   3355 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   3356 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   3357 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
   3358 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
   3359 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3360 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3361 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3362 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3363 
   3364      DEF_ASM_OP0(fucompp, 0xdae9)
   3365      DEF_ASM_OP0(ftst, 0xd9e4)
   3366      DEF_ASM_OP0(fxam, 0xd9e5)
   3367      DEF_ASM_OP0(fld1, 0xd9e8)
   3368      DEF_ASM_OP0(fldl2t, 0xd9e9)
   3369      DEF_ASM_OP0(fldl2e, 0xd9ea)
   3370      DEF_ASM_OP0(fldpi, 0xd9eb)
   3371      DEF_ASM_OP0(fldlg2, 0xd9ec)
   3372      DEF_ASM_OP0(fldln2, 0xd9ed)
   3373      DEF_ASM_OP0(fldz, 0xd9ee)
   3374 
   3375      DEF_ASM_OP0(f2xm1, 0xd9f0)
   3376      DEF_ASM_OP0(fyl2x, 0xd9f1)
   3377      DEF_ASM_OP0(fptan, 0xd9f2)
   3378      DEF_ASM_OP0(fpatan, 0xd9f3)
   3379      DEF_ASM_OP0(fxtract, 0xd9f4)
   3380      DEF_ASM_OP0(fprem1, 0xd9f5)
   3381      DEF_ASM_OP0(fdecstp, 0xd9f6)
   3382      DEF_ASM_OP0(fincstp, 0xd9f7)
   3383      DEF_ASM_OP0(fprem, 0xd9f8)
   3384      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
   3385      DEF_ASM_OP0(fsqrt, 0xd9fa)
   3386      DEF_ASM_OP0(fsincos, 0xd9fb)
   3387      DEF_ASM_OP0(frndint, 0xd9fc)
   3388      DEF_ASM_OP0(fscale, 0xd9fd)
   3389      DEF_ASM_OP0(fsin, 0xd9fe)
   3390      DEF_ASM_OP0(fcos, 0xd9ff)
   3391      DEF_ASM_OP0(fchs, 0xd9e0)
   3392      DEF_ASM_OP0(fabs, 0xd9e1)
   3393      DEF_ASM_OP0(fninit, 0xdbe3)
   3394      DEF_ASM_OP0(fnclex, 0xdbe2)
   3395      DEF_ASM_OP0(fnop, 0xd9d0)
   3396      DEF_ASM_OP0(fwait, 0x9b)
   3397 
   3398     /* fp load */
   3399     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
   3400     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
   3401     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
   3402 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
   3403     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
   3404     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
   3405     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
   3406     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
   3407     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
   3408 
   3409     /* fp store */
   3410     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
   3411     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
   3412     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
   3413     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
   3414 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
   3415     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
   3416     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
   3417     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
   3418     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
   3419     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
   3420 
   3421     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
   3422     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
   3423     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
   3424     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
   3425     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
   3426 
   3427     /* exchange */
   3428     DEF_ASM_OP0(fxch, 0xd9c9)
   3429 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
   3430 
   3431     /* misc FPU */
   3432     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
   3433     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
   3434 
   3435     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
   3436     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
   3437     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
   3438     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
   3439     DEF_ASM_OP0(fnstsw, 0xdfe0)
   3440 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
   3441 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
   3442     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
   3443 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
   3444 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
   3445     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
   3446     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
   3447     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   3448     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
   3449     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
   3450     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   3451     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
   3452     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
   3453     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
   3454     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
   3455     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
   3456 
   3457     /* segments */
   3458     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
   3459     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
   3460     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
   3461     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
   3462     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
   3463     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
   3464 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
   3465     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
   3466     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
   3467     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
   3468     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
   3469     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
   3470     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
   3471     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
   3472     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
   3473 
   3474     /* 486 */
   3475     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
   3476 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   3477 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   3478     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
   3479 
   3480     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
   3481     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
   3482 
   3483     /* pentium */
   3484     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
   3485 
   3486     /* pentium pro */
   3487     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
   3488 
   3489     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3490     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3491     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3492     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3493     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3494     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3495     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3496     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3497 
   3498     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3499     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3500     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3501     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3502 
   3503     /* mmx */
   3504     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
   3505     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
   3506 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
   3507     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3508 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
   3509     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3510     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3511     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3512     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3513     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3514     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3515     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3516     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3517     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3518     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3519     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3520     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3521     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3522     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3523     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3524     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3525     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3526     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3527     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3528     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3529     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3530     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3531     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3532 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3533     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3534 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3535     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3536 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3537     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3538 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3539     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3540 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3541     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3542 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3543     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3544 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3545     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3546 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3547     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3548     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3549     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3550     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3551     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3552     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3553     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3554     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3555     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3556     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3557     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3558     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3559     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3560     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3561 
   3562 #undef ALT
   3563 #undef DEF_ASM_OP0
   3564 #undef DEF_ASM_OP0L
   3565 #undef DEF_ASM_OP1
   3566 #undef DEF_ASM_OP2
   3567 #undef DEF_ASM_OP3
   3568 //---------------------------------------------------------------------------
   3569 
   3570 #define ALT(x)
   3571 #define DEF_ASM_OP0(name, opcode)
   3572 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
   3573 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
   3574 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
   3575 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
   3576 // njn: inlined i386-asm.h
   3577 //#include "i386-asm.h"
   3578 //---------------------------------------------------------------------------
   3579      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
   3580      DEF_ASM_OP0(popa, 0x61)
   3581      DEF_ASM_OP0(clc, 0xf8)
   3582      DEF_ASM_OP0(cld, 0xfc)
   3583      DEF_ASM_OP0(cli, 0xfa)
   3584      DEF_ASM_OP0(clts, 0x0f06)
   3585      DEF_ASM_OP0(cmc, 0xf5)
   3586      DEF_ASM_OP0(lahf, 0x9f)
   3587      DEF_ASM_OP0(sahf, 0x9e)
   3588      DEF_ASM_OP0(pushfl, 0x9c)
   3589      DEF_ASM_OP0(popfl, 0x9d)
   3590      DEF_ASM_OP0(pushf, 0x9c)
   3591      DEF_ASM_OP0(popf, 0x9d)
   3592      DEF_ASM_OP0(stc, 0xf9)
   3593      DEF_ASM_OP0(std, 0xfd)
   3594      DEF_ASM_OP0(sti, 0xfb)
   3595      DEF_ASM_OP0(aaa, 0x37)
   3596      DEF_ASM_OP0(aas, 0x3f)
   3597      DEF_ASM_OP0(daa, 0x27)
   3598      DEF_ASM_OP0(das, 0x2f)
   3599      DEF_ASM_OP0(aad, 0xd50a)
   3600      DEF_ASM_OP0(aam, 0xd40a)
   3601      DEF_ASM_OP0(cbw, 0x6698)
   3602      DEF_ASM_OP0(cwd, 0x6699)
   3603      DEF_ASM_OP0(cwde, 0x98)
   3604      DEF_ASM_OP0(cdq, 0x99)
   3605      DEF_ASM_OP0(cbtw, 0x6698)
   3606      DEF_ASM_OP0(cwtl, 0x98)
   3607      DEF_ASM_OP0(cwtd, 0x6699)
   3608      DEF_ASM_OP0(cltd, 0x99)
   3609      DEF_ASM_OP0(int3, 0xcc)
   3610      DEF_ASM_OP0(into, 0xce)
   3611      DEF_ASM_OP0(iret, 0xcf)
   3612      DEF_ASM_OP0(rsm, 0x0faa)
   3613      DEF_ASM_OP0(hlt, 0xf4)
   3614      DEF_ASM_OP0(wait, 0x9b)
   3615      DEF_ASM_OP0(nop, 0x90)
   3616      DEF_ASM_OP0(xlat, 0xd7)
   3617 
   3618      /* strings */
   3619 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
   3620 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
   3621 
   3622 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
   3623 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
   3624 
   3625 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
   3626 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
   3627 
   3628 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
   3629 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
   3630 
   3631 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
   3632 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
   3633 
   3634 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
   3635 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
   3636 
   3637      /* bits */
   3638 
   3639 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   3640 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   3641 
   3642 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3643 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3644 
   3645 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3646 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3647 
   3648 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3649 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3650 
   3651 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   3652 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   3653 
   3654      /* prefixes */
   3655      DEF_ASM_OP0(aword, 0x67)
   3656      DEF_ASM_OP0(addr16, 0x67)
   3657      DEF_ASM_OP0(word, 0x66)
   3658      DEF_ASM_OP0(data16, 0x66)
   3659      DEF_ASM_OP0(lock, 0xf0)
   3660      DEF_ASM_OP0(rep, 0xf3)
   3661      DEF_ASM_OP0(repe, 0xf3)
   3662      DEF_ASM_OP0(repz, 0xf3)
   3663      DEF_ASM_OP0(repne, 0xf2)
   3664      DEF_ASM_OP0(repnz, 0xf2)
   3665 
   3666      DEF_ASM_OP0(invd, 0x0f08)
   3667      DEF_ASM_OP0(wbinvd, 0x0f09)
   3668      DEF_ASM_OP0(cpuid, 0x0fa2)
   3669      DEF_ASM_OP0(wrmsr, 0x0f30)
   3670      DEF_ASM_OP0(rdtsc, 0x0f31)
   3671      DEF_ASM_OP0(rdmsr, 0x0f32)
   3672      DEF_ASM_OP0(rdpmc, 0x0f33)
   3673      DEF_ASM_OP0(ud2, 0x0f0b)
   3674 
   3675      /* NOTE: we took the same order as gas opcode definition order */
   3676 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
   3677 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
   3678 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   3679 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3680 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
   3681 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
   3682 
   3683 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
   3684 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
   3685 
   3686 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
   3687 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
   3688 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
   3689 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
   3690 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
   3691 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
   3692 
   3693 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
   3694 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
   3695 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   3696 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
   3697 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   3698 
   3699 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
   3700 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   3701 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
   3702 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
   3703 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
   3704 
   3705 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
   3706 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   3707 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
   3708 
   3709 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
   3710 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
   3711 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   3712 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3713 
   3714 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
   3715 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
   3716 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
   3717 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
   3718 
   3719 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
   3720 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
   3721 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
   3722 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
   3723 
   3724 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
   3725 
   3726 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3727 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3728 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3729 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3730 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   3731 
   3732      /* arith */
   3733 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
   3734 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3735 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
   3736 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   3737 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
   3738 
   3739 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   3740 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   3741 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
   3742 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   3743 
   3744 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
   3745 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3746 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
   3747 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3748 
   3749 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3750 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3751 
   3752 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3753 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3754 
   3755 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
   3756 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
   3757 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
   3758 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
   3759 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
   3760 
   3761 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3762 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   3763 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   3764 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   3765 
   3766      /* shifts */
   3767 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
   3768 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
   3769 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
   3770 
   3771 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   3772 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   3773 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   3774 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   3775 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   3776 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   3777 
   3778 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
   3779 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
   3780 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
   3781 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
   3782 
   3783 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
   3784 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
   3785 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
   3786 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
   3787 
   3788 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
   3789 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
   3790     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
   3791     DEF_ASM_OP0(leave, 0xc9)
   3792     DEF_ASM_OP0(ret, 0xc3)
   3793 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
   3794     DEF_ASM_OP0(lret, 0xcb)
   3795 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
   3796 
   3797 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
   3798     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   3799     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   3800     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   3801     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   3802     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
   3803     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
   3804 
   3805      /* float */
   3806      /* specific fcomp handling */
   3807 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
   3808 
   3809 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   3810 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   3811 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
   3812 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   3813 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   3814 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
   3815 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
   3816 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3817 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3818 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3819 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   3820 
   3821      DEF_ASM_OP0(fucompp, 0xdae9)
   3822      DEF_ASM_OP0(ftst, 0xd9e4)
   3823      DEF_ASM_OP0(fxam, 0xd9e5)
   3824      DEF_ASM_OP0(fld1, 0xd9e8)
   3825      DEF_ASM_OP0(fldl2t, 0xd9e9)
   3826      DEF_ASM_OP0(fldl2e, 0xd9ea)
   3827      DEF_ASM_OP0(fldpi, 0xd9eb)
   3828      DEF_ASM_OP0(fldlg2, 0xd9ec)
   3829      DEF_ASM_OP0(fldln2, 0xd9ed)
   3830      DEF_ASM_OP0(fldz, 0xd9ee)
   3831 
   3832      DEF_ASM_OP0(f2xm1, 0xd9f0)
   3833      DEF_ASM_OP0(fyl2x, 0xd9f1)
   3834      DEF_ASM_OP0(fptan, 0xd9f2)
   3835      DEF_ASM_OP0(fpatan, 0xd9f3)
   3836      DEF_ASM_OP0(fxtract, 0xd9f4)
   3837      DEF_ASM_OP0(fprem1, 0xd9f5)
   3838      DEF_ASM_OP0(fdecstp, 0xd9f6)
   3839      DEF_ASM_OP0(fincstp, 0xd9f7)
   3840      DEF_ASM_OP0(fprem, 0xd9f8)
   3841      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
   3842      DEF_ASM_OP0(fsqrt, 0xd9fa)
   3843      DEF_ASM_OP0(fsincos, 0xd9fb)
   3844      DEF_ASM_OP0(frndint, 0xd9fc)
   3845      DEF_ASM_OP0(fscale, 0xd9fd)
   3846      DEF_ASM_OP0(fsin, 0xd9fe)
   3847      DEF_ASM_OP0(fcos, 0xd9ff)
   3848      DEF_ASM_OP0(fchs, 0xd9e0)
   3849      DEF_ASM_OP0(fabs, 0xd9e1)
   3850      DEF_ASM_OP0(fninit, 0xdbe3)
   3851      DEF_ASM_OP0(fnclex, 0xdbe2)
   3852      DEF_ASM_OP0(fnop, 0xd9d0)
   3853      DEF_ASM_OP0(fwait, 0x9b)
   3854 
   3855     /* fp load */
   3856     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
   3857     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
   3858     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
   3859 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
   3860     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
   3861     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
   3862     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
   3863     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
   3864     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
   3865 
   3866     /* fp store */
   3867     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
   3868     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
   3869     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
   3870     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
   3871 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
   3872     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
   3873     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
   3874     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
   3875     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
   3876     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
   3877 
   3878     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
   3879     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
   3880     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
   3881     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
   3882     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
   3883 
   3884     /* exchange */
   3885     DEF_ASM_OP0(fxch, 0xd9c9)
   3886 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
   3887 
   3888     /* misc FPU */
   3889     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
   3890     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
   3891 
   3892     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
   3893     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
   3894     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
   3895     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
   3896     DEF_ASM_OP0(fnstsw, 0xdfe0)
   3897 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
   3898 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
   3899     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
   3900 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
   3901 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
   3902     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
   3903     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
   3904     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   3905     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
   3906     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
   3907     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   3908     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
   3909     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
   3910     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
   3911     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
   3912     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
   3913 
   3914     /* segments */
   3915     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
   3916     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
   3917     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
   3918     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
   3919     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
   3920     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
   3921 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
   3922     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
   3923     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
   3924     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
   3925     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
   3926     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
   3927     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
   3928     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
   3929     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
   3930 
   3931     /* 486 */
   3932     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
   3933 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   3934 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   3935     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
   3936 
   3937     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
   3938     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
   3939 
   3940     /* pentium */
   3941     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
   3942 
   3943     /* pentium pro */
   3944     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
   3945 
   3946     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3947     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3948     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3949     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3950     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3951     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3952     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3953     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3954 
   3955     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3956     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3957     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3958     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   3959 
   3960     /* mmx */
   3961     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
   3962     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
   3963 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
   3964     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3965 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
   3966     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3967     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3968     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3969     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3970     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3971     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3972     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3973     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3974     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3975     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3976     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3977     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3978     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3979     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3980     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3981     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3982     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3983     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3984     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3985     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3986     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3987     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3988     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3989 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3990     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3991 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3992     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3993 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3994     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3995 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3996     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3997 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   3998     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   3999 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4000     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4001 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4002     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4003 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4004     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4005     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4006     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4007     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4008     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4009     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4010     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4011     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4012     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4013     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4014     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4015     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4016     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4017     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4018 
   4019 #undef ALT
   4020 #undef DEF_ASM_OP0
   4021 #undef DEF_ASM_OP0L
   4022 #undef DEF_ASM_OP1
   4023 #undef DEF_ASM_OP2
   4024 #undef DEF_ASM_OP3
   4025 //---------------------------------------------------------------------------
   4026 
   4027 #endif
   4028 //---------------------------------------------------------------------------
   4029 #undef DEF
   4030 };
   4031 
   4032 static const char tcc_keywords[] =
   4033 #define DEF(id, str) str "\0"
   4034 // njn: inlined tcctok.h
   4035 //#include "tcctok.h"
   4036 //---------------------------------------------------------------------------
   4037 /* keywords */
   4038      DEF(TOK_INT, "int")
   4039      DEF(TOK_VOID, "void")
   4040      DEF(TOK_CHAR, "char")
   4041      DEF(TOK_IF, "if")
   4042      DEF(TOK_ELSE, "else")
   4043      DEF(TOK_WHILE, "while")
   4044      DEF(TOK_BREAK, "break")
   4045      DEF(TOK_RETURN, "return")
   4046      DEF(TOK_FOR, "for")
   4047      DEF(TOK_EXTERN, "extern")
   4048      DEF(TOK_STATIC, "static")
   4049      DEF(TOK_UNSIGNED, "unsigned")
   4050      DEF(TOK_GOTO, "goto")
   4051      DEF(TOK_DO, "do")
   4052      DEF(TOK_CONTINUE, "continue")
   4053      DEF(TOK_SWITCH, "switch")
   4054      DEF(TOK_CASE, "case")
   4055 
   4056      DEF(TOK_CONST1, "const")
   4057      DEF(TOK_CONST2, "__const") /* gcc keyword */
   4058      DEF(TOK_CONST3, "__const__") /* gcc keyword */
   4059      DEF(TOK_VOLATILE1, "volatile")
   4060      DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
   4061      DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
   4062      DEF(TOK_LONG, "long")
   4063      DEF(TOK_REGISTER, "register")
   4064      DEF(TOK_SIGNED1, "signed")
   4065      DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
   4066      DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
   4067      DEF(TOK_AUTO, "auto")
   4068      DEF(TOK_INLINE1, "inline")
   4069      DEF(TOK_INLINE2, "__inline") /* gcc keyword */
   4070      DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
   4071      DEF(TOK_RESTRICT1, "restrict")
   4072      DEF(TOK_RESTRICT2, "__restrict")
   4073      DEF(TOK_RESTRICT3, "__restrict__")
   4074      DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
   4075 
   4076      DEF(TOK_FLOAT, "float")
   4077      DEF(TOK_DOUBLE, "double")
   4078      DEF(TOK_BOOL, "_Bool")
   4079      DEF(TOK_SHORT, "short")
   4080      DEF(TOK_STRUCT, "struct")
   4081      DEF(TOK_UNION, "union")
   4082      DEF(TOK_TYPEDEF, "typedef")
   4083      DEF(TOK_DEFAULT, "default")
   4084      DEF(TOK_ENUM, "enum")
   4085      DEF(TOK_SIZEOF, "sizeof")
   4086      DEF(TOK_ATTRIBUTE1, "__attribute")
   4087      DEF(TOK_ATTRIBUTE2, "__attribute__")
   4088      DEF(TOK_ALIGNOF1, "__alignof")
   4089      DEF(TOK_ALIGNOF2, "__alignof__")
   4090      DEF(TOK_TYPEOF1, "typeof")
   4091      DEF(TOK_TYPEOF2, "__typeof")
   4092      DEF(TOK_TYPEOF3, "__typeof__")
   4093      DEF(TOK_LABEL, "__label__")
   4094      DEF(TOK_ASM1, "asm")
   4095      DEF(TOK_ASM2, "__asm")
   4096      DEF(TOK_ASM3, "__asm__")
   4097 
   4098 /*********************************************************************/
   4099 /* the following are not keywords. They are included to ease parsing */
   4100 /* preprocessor only */
   4101      DEF(TOK_DEFINE, "define")
   4102      DEF(TOK_INCLUDE, "include")
   4103      DEF(TOK_INCLUDE_NEXT, "include_next")
   4104      DEF(TOK_IFDEF, "ifdef")
   4105      DEF(TOK_IFNDEF, "ifndef")
   4106      DEF(TOK_ELIF, "elif")
   4107      DEF(TOK_ENDIF, "endif")
   4108      DEF(TOK_DEFINED, "defined")
   4109      DEF(TOK_UNDEF, "undef")
   4110      DEF(TOK_ERROR, "error")
   4111      DEF(TOK_WARNING, "warning")
   4112      DEF(TOK_LINE, "line")
   4113      DEF(TOK_PRAGMA, "pragma")
   4114      DEF(TOK___LINE__, "__LINE__")
   4115      DEF(TOK___FILE__, "__FILE__")
   4116      DEF(TOK___DATE__, "__DATE__")
   4117      DEF(TOK___TIME__, "__TIME__")
   4118      DEF(TOK___FUNCTION__, "__FUNCTION__")
   4119      DEF(TOK___VA_ARGS__, "__VA_ARGS__")
   4120 
   4121 /* special identifiers */
   4122      DEF(TOK___FUNC__, "__func__")
   4123 
   4124 /* attribute identifiers */
   4125 /* XXX: handle all tokens generically since speed is not critical */
   4126      DEF(TOK_SECTION1, "section")
   4127      DEF(TOK_SECTION2, "__section__")
   4128      DEF(TOK_ALIGNED1, "aligned")
   4129      DEF(TOK_ALIGNED2, "__aligned__")
   4130      DEF(TOK_PACKED1, "packed")
   4131      DEF(TOK_PACKED2, "__packed__")
   4132      DEF(TOK_UNUSED1, "unused")
   4133      DEF(TOK_UNUSED2, "__unused__")
   4134      DEF(TOK_CDECL1, "cdecl")
   4135      DEF(TOK_CDECL2, "__cdecl")
   4136      DEF(TOK_CDECL3, "__cdecl__")
   4137      DEF(TOK_STDCALL1, "stdcall")
   4138      DEF(TOK_STDCALL2, "__stdcall")
   4139      DEF(TOK_STDCALL3, "__stdcall__")
   4140      DEF(TOK_DLLEXPORT, "dllexport")
   4141      DEF(TOK_NORETURN1, "noreturn")
   4142      DEF(TOK_NORETURN2, "__noreturn__")
   4143      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
   4144      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
   4145      DEF(TOK_REGPARM1, "regparm")
   4146      DEF(TOK_REGPARM2, "__regparm__")
   4147 
   4148 /* pragma */
   4149      DEF(TOK_pack, "pack")
   4150 #if !defined(TCC_TARGET_I386)
   4151      /* already defined for assembler */
   4152      DEF(TOK_ASM_push, "push")
   4153      DEF(TOK_ASM_pop, "pop")
   4154 #endif
   4155 
   4156 /* builtin functions or variables */
   4157      DEF(TOK_memcpy, "memcpy")
   4158      DEF(TOK_memset, "memset")
   4159      DEF(TOK_alloca, "alloca")
   4160      DEF(TOK___divdi3, "__divdi3")
   4161      DEF(TOK___moddi3, "__moddi3")
   4162      DEF(TOK___udivdi3, "__udivdi3")
   4163      DEF(TOK___umoddi3, "__umoddi3")
   4164 #if defined(TCC_TARGET_ARM)
   4165      DEF(TOK___divsi3, "__divsi3")
   4166      DEF(TOK___modsi3, "__modsi3")
   4167      DEF(TOK___udivsi3, "__udivsi3")
   4168      DEF(TOK___umodsi3, "__umodsi3")
   4169      DEF(TOK___sardi3, "__ashrdi3")
   4170      DEF(TOK___shrdi3, "__lshrdi3")
   4171      DEF(TOK___shldi3, "__ashldi3")
   4172      DEF(TOK___slltold, "__slltold")
   4173      DEF(TOK___fixunssfsi, "__fixunssfsi")
   4174      DEF(TOK___fixunsdfsi, "__fixunsdfsi")
   4175      DEF(TOK___fixunsxfsi, "__fixunsxfsi")
   4176      DEF(TOK___fixsfdi, "__fixsfdi")
   4177      DEF(TOK___fixdfdi, "__fixdfdi")
   4178      DEF(TOK___fixxfdi, "__fixxfdi")
   4179 #elif defined(TCC_TARGET_C67)
   4180      DEF(TOK__divi, "_divi")
   4181      DEF(TOK__divu, "_divu")
   4182      DEF(TOK__divf, "_divf")
   4183      DEF(TOK__divd, "_divd")
   4184      DEF(TOK__remi, "_remi")
   4185      DEF(TOK__remu, "_remu")
   4186      DEF(TOK___sardi3, "__sardi3")
   4187      DEF(TOK___shrdi3, "__shrdi3")
   4188      DEF(TOK___shldi3, "__shldi3")
   4189 #else
   4190      /* XXX: same names on i386 ? */
   4191      DEF(TOK___sardi3, "__sardi3")
   4192      DEF(TOK___shrdi3, "__shrdi3")
   4193      DEF(TOK___shldi3, "__shldi3")
   4194 #endif
   4195      DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
   4196      DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
   4197      DEF(TOK___ulltof, "__ulltof")
   4198      DEF(TOK___ulltod, "__ulltod")
   4199      DEF(TOK___ulltold, "__ulltold")
   4200      DEF(TOK___fixunssfdi, "__fixunssfdi")
   4201      DEF(TOK___fixunsdfdi, "__fixunsdfdi")
   4202      DEF(TOK___fixunsxfdi, "__fixunsxfdi")
   4203      DEF(TOK___chkstk, "__chkstk")
   4204 
   4205 /* bound checking symbols */
   4206 #ifdef CONFIG_TCC_BCHECK
   4207      DEF(TOK___bound_ptr_add, "__bound_ptr_add")
   4208      DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
   4209      DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
   4210      DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
   4211      DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
   4212      DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
   4213      DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
   4214      DEF(TOK___bound_local_new, "__bound_local_new")
   4215      DEF(TOK___bound_local_delete, "__bound_local_delete")
   4216      DEF(TOK_malloc, "malloc")
   4217      DEF(TOK_free, "free")
   4218      DEF(TOK_realloc, "realloc")
   4219      DEF(TOK_memalign, "memalign")
   4220      DEF(TOK_calloc, "calloc")
   4221      DEF(TOK_memmove, "memmove")
   4222      DEF(TOK_strlen, "strlen")
   4223      DEF(TOK_strcpy, "strcpy")
   4224 #endif
   4225 
   4226 /* Tiny Assembler */
   4227 
   4228  DEF_ASM(byte)
   4229  DEF_ASM(align)
   4230  DEF_ASM(skip)
   4231  DEF_ASM(space)
   4232  DEF_ASM(string)
   4233  DEF_ASM(asciz)
   4234  DEF_ASM(ascii)
   4235  DEF_ASM(globl)
   4236  DEF_ASM(global)
   4237  DEF_ASM(text)
   4238  DEF_ASM(data)
   4239  DEF_ASM(bss)
   4240  DEF_ASM(previous)
   4241  DEF_ASM(fill)
   4242  DEF_ASM(org)
   4243  DEF_ASM(quad)
   4244 
   4245 #ifdef TCC_TARGET_I386
   4246 
   4247 /* WARNING: relative order of tokens is important. */
   4248  DEF_ASM(al)
   4249  DEF_ASM(cl)
   4250  DEF_ASM(dl)
   4251  DEF_ASM(bl)
   4252  DEF_ASM(ah)
   4253  DEF_ASM(ch)
   4254  DEF_ASM(dh)
   4255  DEF_ASM(bh)
   4256  DEF_ASM(ax)
   4257  DEF_ASM(cx)
   4258  DEF_ASM(dx)
   4259  DEF_ASM(bx)
   4260  DEF_ASM(sp)
   4261  DEF_ASM(bp)
   4262  DEF_ASM(si)
   4263  DEF_ASM(di)
   4264  DEF_ASM(eax)
   4265  DEF_ASM(ecx)
   4266  DEF_ASM(edx)
   4267  DEF_ASM(ebx)
   4268  DEF_ASM(esp)
   4269  DEF_ASM(ebp)
   4270  DEF_ASM(esi)
   4271  DEF_ASM(edi)
   4272  DEF_ASM(mm0)
   4273  DEF_ASM(mm1)
   4274  DEF_ASM(mm2)
   4275  DEF_ASM(mm3)
   4276  DEF_ASM(mm4)
   4277  DEF_ASM(mm5)
   4278  DEF_ASM(mm6)
   4279  DEF_ASM(mm7)
   4280  DEF_ASM(xmm0)
   4281  DEF_ASM(xmm1)
   4282  DEF_ASM(xmm2)
   4283  DEF_ASM(xmm3)
   4284  DEF_ASM(xmm4)
   4285  DEF_ASM(xmm5)
   4286  DEF_ASM(xmm6)
   4287  DEF_ASM(xmm7)
   4288  DEF_ASM(cr0)
   4289  DEF_ASM(cr1)
   4290  DEF_ASM(cr2)
   4291  DEF_ASM(cr3)
   4292  DEF_ASM(cr4)
   4293  DEF_ASM(cr5)
   4294  DEF_ASM(cr6)
   4295  DEF_ASM(cr7)
   4296  DEF_ASM(tr0)
   4297  DEF_ASM(tr1)
   4298  DEF_ASM(tr2)
   4299  DEF_ASM(tr3)
   4300  DEF_ASM(tr4)
   4301  DEF_ASM(tr5)
   4302  DEF_ASM(tr6)
   4303  DEF_ASM(tr7)
   4304  DEF_ASM(db0)
   4305  DEF_ASM(db1)
   4306  DEF_ASM(db2)
   4307  DEF_ASM(db3)
   4308  DEF_ASM(db4)
   4309  DEF_ASM(db5)
   4310  DEF_ASM(db6)
   4311  DEF_ASM(db7)
   4312  DEF_ASM(dr0)
   4313  DEF_ASM(dr1)
   4314  DEF_ASM(dr2)
   4315  DEF_ASM(dr3)
   4316  DEF_ASM(dr4)
   4317  DEF_ASM(dr5)
   4318  DEF_ASM(dr6)
   4319  DEF_ASM(dr7)
   4320  DEF_ASM(es)
   4321  DEF_ASM(cs)
   4322  DEF_ASM(ss)
   4323  DEF_ASM(ds)
   4324  DEF_ASM(fs)
   4325  DEF_ASM(gs)
   4326  DEF_ASM(st)
   4327 
   4328  DEF_BWL(mov)
   4329 
   4330  /* generic two operands */
   4331  DEF_BWL(add)
   4332  DEF_BWL(or)
   4333  DEF_BWL(adc)
   4334  DEF_BWL(sbb)
   4335  DEF_BWL(and)
   4336  DEF_BWL(sub)
   4337  DEF_BWL(xor)
   4338  DEF_BWL(cmp)
   4339 
   4340  /* unary ops */
   4341  DEF_BWL(inc)
   4342  DEF_BWL(dec)
   4343  DEF_BWL(not)
   4344  DEF_BWL(neg)
   4345  DEF_BWL(mul)
   4346  DEF_BWL(imul)
   4347  DEF_BWL(div)
   4348  DEF_BWL(idiv)
   4349 
   4350  DEF_BWL(xchg)
   4351  DEF_BWL(test)
   4352 
   4353  /* shifts */
   4354  DEF_BWL(rol)
   4355  DEF_BWL(ror)
   4356  DEF_BWL(rcl)
   4357  DEF_BWL(rcr)
   4358  DEF_BWL(shl)
   4359  DEF_BWL(shr)
   4360  DEF_BWL(sar)
   4361 
   4362  DEF_ASM(shldw)
   4363  DEF_ASM(shldl)
   4364  DEF_ASM(shld)
   4365  DEF_ASM(shrdw)
   4366  DEF_ASM(shrdl)
   4367  DEF_ASM(shrd)
   4368 
   4369  DEF_ASM(pushw)
   4370  DEF_ASM(pushl)
   4371  DEF_ASM(push)
   4372  DEF_ASM(popw)
   4373  DEF_ASM(popl)
   4374  DEF_ASM(pop)
   4375  DEF_BWL(in)
   4376  DEF_BWL(out)
   4377 
   4378  DEF_WL(movzb)
   4379 
   4380  DEF_ASM(movzwl)
   4381  DEF_ASM(movsbw)
   4382  DEF_ASM(movsbl)
   4383  DEF_ASM(movswl)
   4384 
   4385  DEF_WL(lea)
   4386 
   4387  DEF_ASM(les)
   4388  DEF_ASM(lds)
   4389  DEF_ASM(lss)
   4390  DEF_ASM(lfs)
   4391  DEF_ASM(lgs)
   4392 
   4393  DEF_ASM(call)
   4394  DEF_ASM(jmp)
   4395  DEF_ASM(lcall)
   4396  DEF_ASM(ljmp)
   4397 
   4398  DEF_ASMTEST(j)
   4399 
   4400  DEF_ASMTEST(set)
   4401  DEF_ASMTEST(cmov)
   4402 
   4403  DEF_WL(bsf)
   4404  DEF_WL(bsr)
   4405  DEF_WL(bt)
   4406  DEF_WL(bts)
   4407  DEF_WL(btr)
   4408  DEF_WL(btc)
   4409 
   4410  DEF_WL(lsl)
   4411 
   4412  /* generic FP ops */
   4413  DEF_FP(add)
   4414  DEF_FP(mul)
   4415 
   4416  DEF_ASM(fcom)
   4417  DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
   4418  DEF_FP1(com)
   4419 
   4420  DEF_FP(comp)
   4421  DEF_FP(sub)
   4422  DEF_FP(subr)
   4423  DEF_FP(div)
   4424  DEF_FP(divr)
   4425 
   4426  DEF_BWL(xadd)
   4427  DEF_BWL(cmpxchg)
   4428 
   4429  /* string ops */
   4430  DEF_BWL(cmps)
   4431  DEF_BWL(scmp)
   4432  DEF_BWL(ins)
   4433  DEF_BWL(outs)
   4434  DEF_BWL(lods)
   4435  DEF_BWL(slod)
   4436  DEF_BWL(movs)
   4437  DEF_BWL(smov)
   4438  DEF_BWL(scas)
   4439  DEF_BWL(ssca)
   4440  DEF_BWL(stos)
   4441  DEF_BWL(ssto)
   4442 
   4443  /* generic asm ops */
   4444 
   4445 #define ALT(x)
   4446 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
   4447 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
   4448 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
   4449 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
   4450 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
   4451 // njn: inlined i386-asm.h
   4452 //#include "i386-asm.h"
   4453 //---------------------------------------------------------------------------
   4454      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
   4455      DEF_ASM_OP0(popa, 0x61)
   4456      DEF_ASM_OP0(clc, 0xf8)
   4457      DEF_ASM_OP0(cld, 0xfc)
   4458      DEF_ASM_OP0(cli, 0xfa)
   4459      DEF_ASM_OP0(clts, 0x0f06)
   4460      DEF_ASM_OP0(cmc, 0xf5)
   4461      DEF_ASM_OP0(lahf, 0x9f)
   4462      DEF_ASM_OP0(sahf, 0x9e)
   4463      DEF_ASM_OP0(pushfl, 0x9c)
   4464      DEF_ASM_OP0(popfl, 0x9d)
   4465      DEF_ASM_OP0(pushf, 0x9c)
   4466      DEF_ASM_OP0(popf, 0x9d)
   4467      DEF_ASM_OP0(stc, 0xf9)
   4468      DEF_ASM_OP0(std, 0xfd)
   4469      DEF_ASM_OP0(sti, 0xfb)
   4470      DEF_ASM_OP0(aaa, 0x37)
   4471      DEF_ASM_OP0(aas, 0x3f)
   4472      DEF_ASM_OP0(daa, 0x27)
   4473      DEF_ASM_OP0(das, 0x2f)
   4474      DEF_ASM_OP0(aad, 0xd50a)
   4475      DEF_ASM_OP0(aam, 0xd40a)
   4476      DEF_ASM_OP0(cbw, 0x6698)
   4477      DEF_ASM_OP0(cwd, 0x6699)
   4478      DEF_ASM_OP0(cwde, 0x98)
   4479      DEF_ASM_OP0(cdq, 0x99)
   4480      DEF_ASM_OP0(cbtw, 0x6698)
   4481      DEF_ASM_OP0(cwtl, 0x98)
   4482      DEF_ASM_OP0(cwtd, 0x6699)
   4483      DEF_ASM_OP0(cltd, 0x99)
   4484      DEF_ASM_OP0(int3, 0xcc)
   4485      DEF_ASM_OP0(into, 0xce)
   4486      DEF_ASM_OP0(iret, 0xcf)
   4487      DEF_ASM_OP0(rsm, 0x0faa)
   4488      DEF_ASM_OP0(hlt, 0xf4)
   4489      DEF_ASM_OP0(wait, 0x9b)
   4490      DEF_ASM_OP0(nop, 0x90)
   4491      DEF_ASM_OP0(xlat, 0xd7)
   4492 
   4493      /* strings */
   4494 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
   4495 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
   4496 
   4497 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
   4498 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
   4499 
   4500 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
   4501 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
   4502 
   4503 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
   4504 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
   4505 
   4506 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
   4507 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
   4508 
   4509 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
   4510 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
   4511 
   4512      /* bits */
   4513 
   4514 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   4515 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   4516 
   4517 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4518 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4519 
   4520 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4521 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4522 
   4523 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4524 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4525 
   4526 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4527 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4528 
   4529      /* prefixes */
   4530      DEF_ASM_OP0(aword, 0x67)
   4531      DEF_ASM_OP0(addr16, 0x67)
   4532      DEF_ASM_OP0(word, 0x66)
   4533      DEF_ASM_OP0(data16, 0x66)
   4534      DEF_ASM_OP0(lock, 0xf0)
   4535      DEF_ASM_OP0(rep, 0xf3)
   4536      DEF_ASM_OP0(repe, 0xf3)
   4537      DEF_ASM_OP0(repz, 0xf3)
   4538      DEF_ASM_OP0(repne, 0xf2)
   4539      DEF_ASM_OP0(repnz, 0xf2)
   4540 
   4541      DEF_ASM_OP0(invd, 0x0f08)
   4542      DEF_ASM_OP0(wbinvd, 0x0f09)
   4543      DEF_ASM_OP0(cpuid, 0x0fa2)
   4544      DEF_ASM_OP0(wrmsr, 0x0f30)
   4545      DEF_ASM_OP0(rdtsc, 0x0f31)
   4546      DEF_ASM_OP0(rdmsr, 0x0f32)
   4547      DEF_ASM_OP0(rdpmc, 0x0f33)
   4548      DEF_ASM_OP0(ud2, 0x0f0b)
   4549 
   4550      /* NOTE: we took the same order as gas opcode definition order */
   4551 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
   4552 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
   4553 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   4554 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   4555 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
   4556 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
   4557 
   4558 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
   4559 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
   4560 
   4561 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
   4562 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
   4563 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
   4564 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
   4565 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
   4566 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
   4567 
   4568 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
   4569 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
   4570 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   4571 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
   4572 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   4573 
   4574 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
   4575 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   4576 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
   4577 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
   4578 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
   4579 
   4580 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
   4581 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   4582 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
   4583 
   4584 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
   4585 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
   4586 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   4587 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   4588 
   4589 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
   4590 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
   4591 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
   4592 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
   4593 
   4594 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
   4595 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
   4596 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
   4597 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
   4598 
   4599 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
   4600 
   4601 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   4602 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   4603 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   4604 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   4605 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   4606 
   4607      /* arith */
   4608 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
   4609 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   4610 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
   4611 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   4612 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
   4613 
   4614 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   4615 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   4616 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
   4617 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   4618 
   4619 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
   4620 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4621 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
   4622 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4623 
   4624 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4625 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4626 
   4627 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4628 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4629 
   4630 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
   4631 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
   4632 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
   4633 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
   4634 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
   4635 
   4636 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4637 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   4638 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   4639 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   4640 
   4641      /* shifts */
   4642 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
   4643 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
   4644 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
   4645 
   4646 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   4647 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   4648 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   4649 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   4650 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   4651 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   4652 
   4653 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
   4654 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
   4655 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
   4656 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
   4657 
   4658 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
   4659 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
   4660 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
   4661 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
   4662 
   4663 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
   4664 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
   4665     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
   4666     DEF_ASM_OP0(leave, 0xc9)
   4667     DEF_ASM_OP0(ret, 0xc3)
   4668 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
   4669     DEF_ASM_OP0(lret, 0xcb)
   4670 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
   4671 
   4672 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
   4673     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   4674     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   4675     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   4676     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   4677     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
   4678     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
   4679 
   4680      /* float */
   4681      /* specific fcomp handling */
   4682 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
   4683 
   4684 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   4685 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   4686 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
   4687 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   4688 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   4689 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
   4690 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
   4691 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   4692 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   4693 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   4694 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   4695 
   4696      DEF_ASM_OP0(fucompp, 0xdae9)
   4697      DEF_ASM_OP0(ftst, 0xd9e4)
   4698      DEF_ASM_OP0(fxam, 0xd9e5)
   4699      DEF_ASM_OP0(fld1, 0xd9e8)
   4700      DEF_ASM_OP0(fldl2t, 0xd9e9)
   4701      DEF_ASM_OP0(fldl2e, 0xd9ea)
   4702      DEF_ASM_OP0(fldpi, 0xd9eb)
   4703      DEF_ASM_OP0(fldlg2, 0xd9ec)
   4704      DEF_ASM_OP0(fldln2, 0xd9ed)
   4705      DEF_ASM_OP0(fldz, 0xd9ee)
   4706 
   4707      DEF_ASM_OP0(f2xm1, 0xd9f0)
   4708      DEF_ASM_OP0(fyl2x, 0xd9f1)
   4709      DEF_ASM_OP0(fptan, 0xd9f2)
   4710      DEF_ASM_OP0(fpatan, 0xd9f3)
   4711      DEF_ASM_OP0(fxtract, 0xd9f4)
   4712      DEF_ASM_OP0(fprem1, 0xd9f5)
   4713      DEF_ASM_OP0(fdecstp, 0xd9f6)
   4714      DEF_ASM_OP0(fincstp, 0xd9f7)
   4715      DEF_ASM_OP0(fprem, 0xd9f8)
   4716      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
   4717      DEF_ASM_OP0(fsqrt, 0xd9fa)
   4718      DEF_ASM_OP0(fsincos, 0xd9fb)
   4719      DEF_ASM_OP0(frndint, 0xd9fc)
   4720      DEF_ASM_OP0(fscale, 0xd9fd)
   4721      DEF_ASM_OP0(fsin, 0xd9fe)
   4722      DEF_ASM_OP0(fcos, 0xd9ff)
   4723      DEF_ASM_OP0(fchs, 0xd9e0)
   4724      DEF_ASM_OP0(fabs, 0xd9e1)
   4725      DEF_ASM_OP0(fninit, 0xdbe3)
   4726      DEF_ASM_OP0(fnclex, 0xdbe2)
   4727      DEF_ASM_OP0(fnop, 0xd9d0)
   4728      DEF_ASM_OP0(fwait, 0x9b)
   4729 
   4730     /* fp load */
   4731     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
   4732     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
   4733     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
   4734 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
   4735     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
   4736     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
   4737     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
   4738     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
   4739     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
   4740 
   4741     /* fp store */
   4742     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
   4743     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
   4744     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
   4745     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
   4746 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
   4747     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
   4748     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
   4749     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
   4750     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
   4751     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
   4752 
   4753     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
   4754     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
   4755     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
   4756     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
   4757     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
   4758 
   4759     /* exchange */
   4760     DEF_ASM_OP0(fxch, 0xd9c9)
   4761 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
   4762 
   4763     /* misc FPU */
   4764     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
   4765     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
   4766 
   4767     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
   4768     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
   4769     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
   4770     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
   4771     DEF_ASM_OP0(fnstsw, 0xdfe0)
   4772 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
   4773 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
   4774     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
   4775 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
   4776 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
   4777     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
   4778     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
   4779     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   4780     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
   4781     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
   4782     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   4783     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
   4784     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
   4785     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
   4786     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
   4787     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
   4788 
   4789     /* segments */
   4790     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
   4791     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
   4792     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
   4793     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
   4794     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
   4795     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
   4796 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
   4797     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
   4798     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
   4799     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
   4800     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
   4801     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
   4802     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
   4803     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
   4804     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
   4805 
   4806     /* 486 */
   4807     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
   4808 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   4809 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   4810     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
   4811 
   4812     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
   4813     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
   4814 
   4815     /* pentium */
   4816     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
   4817 
   4818     /* pentium pro */
   4819     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
   4820 
   4821     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4822     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4823     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4824     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4825     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4826     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4827     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4828     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4829 
   4830     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4831     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4832     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4833     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   4834 
   4835     /* mmx */
   4836     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
   4837     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
   4838 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
   4839     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4840 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
   4841     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4842     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4843     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4844     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4845     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4846     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4847     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4848     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4849     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4850     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4851     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4852     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4853     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4854     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4855     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4856     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4857     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4858     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4859     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4860     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4861     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4862     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4863     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4864 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4865     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4866 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4867     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4868 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4869     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4870 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4871     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4872 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4873     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4874 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4875     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4876 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4877     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4878 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   4879     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4880     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4881     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4882     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4883     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4884     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4885     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4886     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4887     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4888     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4889     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4890     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4891     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4892     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   4893 
   4894 #undef ALT
   4895 #undef DEF_ASM_OP0
   4896 #undef DEF_ASM_OP0L
   4897 #undef DEF_ASM_OP1
   4898 #undef DEF_ASM_OP2
   4899 #undef DEF_ASM_OP3
   4900 //---------------------------------------------------------------------------
   4901 
   4902 #define ALT(x)
   4903 #define DEF_ASM_OP0(name, opcode)
   4904 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
   4905 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
   4906 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
   4907 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
   4908 // njn: inlined i386-asm.h
   4909 //#include "i386-asm.h"
   4910 //---------------------------------------------------------------------------
   4911      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
   4912      DEF_ASM_OP0(popa, 0x61)
   4913      DEF_ASM_OP0(clc, 0xf8)
   4914      DEF_ASM_OP0(cld, 0xfc)
   4915      DEF_ASM_OP0(cli, 0xfa)
   4916      DEF_ASM_OP0(clts, 0x0f06)
   4917      DEF_ASM_OP0(cmc, 0xf5)
   4918      DEF_ASM_OP0(lahf, 0x9f)
   4919      DEF_ASM_OP0(sahf, 0x9e)
   4920      DEF_ASM_OP0(pushfl, 0x9c)
   4921      DEF_ASM_OP0(popfl, 0x9d)
   4922      DEF_ASM_OP0(pushf, 0x9c)
   4923      DEF_ASM_OP0(popf, 0x9d)
   4924      DEF_ASM_OP0(stc, 0xf9)
   4925      DEF_ASM_OP0(std, 0xfd)
   4926      DEF_ASM_OP0(sti, 0xfb)
   4927      DEF_ASM_OP0(aaa, 0x37)
   4928      DEF_ASM_OP0(aas, 0x3f)
   4929      DEF_ASM_OP0(daa, 0x27)
   4930      DEF_ASM_OP0(das, 0x2f)
   4931      DEF_ASM_OP0(aad, 0xd50a)
   4932      DEF_ASM_OP0(aam, 0xd40a)
   4933      DEF_ASM_OP0(cbw, 0x6698)
   4934      DEF_ASM_OP0(cwd, 0x6699)
   4935      DEF_ASM_OP0(cwde, 0x98)
   4936      DEF_ASM_OP0(cdq, 0x99)
   4937      DEF_ASM_OP0(cbtw, 0x6698)
   4938      DEF_ASM_OP0(cwtl, 0x98)
   4939      DEF_ASM_OP0(cwtd, 0x6699)
   4940      DEF_ASM_OP0(cltd, 0x99)
   4941      DEF_ASM_OP0(int3, 0xcc)
   4942      DEF_ASM_OP0(into, 0xce)
   4943      DEF_ASM_OP0(iret, 0xcf)
   4944      DEF_ASM_OP0(rsm, 0x0faa)
   4945      DEF_ASM_OP0(hlt, 0xf4)
   4946      DEF_ASM_OP0(wait, 0x9b)
   4947      DEF_ASM_OP0(nop, 0x90)
   4948      DEF_ASM_OP0(xlat, 0xd7)
   4949 
   4950      /* strings */
   4951 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
   4952 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
   4953 
   4954 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
   4955 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
   4956 
   4957 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
   4958 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
   4959 
   4960 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
   4961 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
   4962 
   4963 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
   4964 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
   4965 
   4966 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
   4967 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
   4968 
   4969      /* bits */
   4970 
   4971 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   4972 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   4973 
   4974 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4975 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4976 
   4977 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4978 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4979 
   4980 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4981 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4982 
   4983 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   4984 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   4985 
   4986      /* prefixes */
   4987      DEF_ASM_OP0(aword, 0x67)
   4988      DEF_ASM_OP0(addr16, 0x67)
   4989      DEF_ASM_OP0(word, 0x66)
   4990      DEF_ASM_OP0(data16, 0x66)
   4991      DEF_ASM_OP0(lock, 0xf0)
   4992      DEF_ASM_OP0(rep, 0xf3)
   4993      DEF_ASM_OP0(repe, 0xf3)
   4994      DEF_ASM_OP0(repz, 0xf3)
   4995      DEF_ASM_OP0(repne, 0xf2)
   4996      DEF_ASM_OP0(repnz, 0xf2)
   4997 
   4998      DEF_ASM_OP0(invd, 0x0f08)
   4999      DEF_ASM_OP0(wbinvd, 0x0f09)
   5000      DEF_ASM_OP0(cpuid, 0x0fa2)
   5001      DEF_ASM_OP0(wrmsr, 0x0f30)
   5002      DEF_ASM_OP0(rdtsc, 0x0f31)
   5003      DEF_ASM_OP0(rdmsr, 0x0f32)
   5004      DEF_ASM_OP0(rdpmc, 0x0f33)
   5005      DEF_ASM_OP0(ud2, 0x0f0b)
   5006 
   5007      /* NOTE: we took the same order as gas opcode definition order */
   5008 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
   5009 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
   5010 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   5011 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   5012 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
   5013 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
   5014 
   5015 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
   5016 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
   5017 
   5018 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
   5019 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
   5020 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
   5021 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
   5022 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
   5023 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
   5024 
   5025 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
   5026 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
   5027 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   5028 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
   5029 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   5030 
   5031 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
   5032 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   5033 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
   5034 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
   5035 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
   5036 
   5037 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
   5038 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   5039 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
   5040 
   5041 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
   5042 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
   5043 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   5044 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   5045 
   5046 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
   5047 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
   5048 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
   5049 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
   5050 
   5051 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
   5052 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
   5053 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
   5054 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
   5055 
   5056 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
   5057 
   5058 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   5059 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   5060 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   5061 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   5062 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   5063 
   5064      /* arith */
   5065 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
   5066 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   5067 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
   5068 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   5069 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
   5070 
   5071 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   5072 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   5073 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
   5074 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   5075 
   5076 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
   5077 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5078 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
   5079 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5080 
   5081 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5082 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5083 
   5084 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5085 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5086 
   5087 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
   5088 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
   5089 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
   5090 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
   5091 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
   5092 
   5093 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5094 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   5095 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   5096 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   5097 
   5098      /* shifts */
   5099 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
   5100 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
   5101 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
   5102 
   5103 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   5104 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   5105 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   5106 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   5107 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   5108 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   5109 
   5110 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
   5111 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
   5112 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
   5113 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
   5114 
   5115 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
   5116 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
   5117 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
   5118 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
   5119 
   5120 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
   5121 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
   5122     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
   5123     DEF_ASM_OP0(leave, 0xc9)
   5124     DEF_ASM_OP0(ret, 0xc3)
   5125 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
   5126     DEF_ASM_OP0(lret, 0xcb)
   5127 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
   5128 
   5129 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
   5130     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   5131     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   5132     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   5133     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   5134     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
   5135     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
   5136 
   5137      /* float */
   5138      /* specific fcomp handling */
   5139 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
   5140 
   5141 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   5142 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   5143 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
   5144 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   5145 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   5146 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
   5147 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
   5148 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   5149 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   5150 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   5151 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   5152 
   5153      DEF_ASM_OP0(fucompp, 0xdae9)
   5154      DEF_ASM_OP0(ftst, 0xd9e4)
   5155      DEF_ASM_OP0(fxam, 0xd9e5)
   5156      DEF_ASM_OP0(fld1, 0xd9e8)
   5157      DEF_ASM_OP0(fldl2t, 0xd9e9)
   5158      DEF_ASM_OP0(fldl2e, 0xd9ea)
   5159      DEF_ASM_OP0(fldpi, 0xd9eb)
   5160      DEF_ASM_OP0(fldlg2, 0xd9ec)
   5161      DEF_ASM_OP0(fldln2, 0xd9ed)
   5162      DEF_ASM_OP0(fldz, 0xd9ee)
   5163 
   5164      DEF_ASM_OP0(f2xm1, 0xd9f0)
   5165      DEF_ASM_OP0(fyl2x, 0xd9f1)
   5166      DEF_ASM_OP0(fptan, 0xd9f2)
   5167      DEF_ASM_OP0(fpatan, 0xd9f3)
   5168      DEF_ASM_OP0(fxtract, 0xd9f4)
   5169      DEF_ASM_OP0(fprem1, 0xd9f5)
   5170      DEF_ASM_OP0(fdecstp, 0xd9f6)
   5171      DEF_ASM_OP0(fincstp, 0xd9f7)
   5172      DEF_ASM_OP0(fprem, 0xd9f8)
   5173      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
   5174      DEF_ASM_OP0(fsqrt, 0xd9fa)
   5175      DEF_ASM_OP0(fsincos, 0xd9fb)
   5176      DEF_ASM_OP0(frndint, 0xd9fc)
   5177      DEF_ASM_OP0(fscale, 0xd9fd)
   5178      DEF_ASM_OP0(fsin, 0xd9fe)
   5179      DEF_ASM_OP0(fcos, 0xd9ff)
   5180      DEF_ASM_OP0(fchs, 0xd9e0)
   5181      DEF_ASM_OP0(fabs, 0xd9e1)
   5182      DEF_ASM_OP0(fninit, 0xdbe3)
   5183      DEF_ASM_OP0(fnclex, 0xdbe2)
   5184      DEF_ASM_OP0(fnop, 0xd9d0)
   5185      DEF_ASM_OP0(fwait, 0x9b)
   5186 
   5187     /* fp load */
   5188     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
   5189     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
   5190     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
   5191 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
   5192     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
   5193     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
   5194     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
   5195     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
   5196     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
   5197 
   5198     /* fp store */
   5199     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
   5200     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
   5201     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
   5202     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
   5203 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
   5204     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
   5205     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
   5206     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
   5207     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
   5208     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
   5209 
   5210     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
   5211     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
   5212     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
   5213     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
   5214     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
   5215 
   5216     /* exchange */
   5217     DEF_ASM_OP0(fxch, 0xd9c9)
   5218 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
   5219 
   5220     /* misc FPU */
   5221     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
   5222     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
   5223 
   5224     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
   5225     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
   5226     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
   5227     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
   5228     DEF_ASM_OP0(fnstsw, 0xdfe0)
   5229 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
   5230 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
   5231     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
   5232 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
   5233 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
   5234     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
   5235     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
   5236     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   5237     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
   5238     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
   5239     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   5240     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
   5241     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
   5242     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
   5243     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
   5244     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
   5245 
   5246     /* segments */
   5247     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
   5248     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
   5249     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
   5250     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
   5251     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
   5252     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
   5253 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
   5254     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
   5255     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
   5256     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
   5257     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
   5258     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
   5259     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
   5260     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
   5261     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
   5262 
   5263     /* 486 */
   5264     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
   5265 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   5266 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   5267     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
   5268 
   5269     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
   5270     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
   5271 
   5272     /* pentium */
   5273     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
   5274 
   5275     /* pentium pro */
   5276     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
   5277 
   5278     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5279     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5280     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5281     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5282     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5283     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5284     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5285     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5286 
   5287     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5288     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5289     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5290     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   5291 
   5292     /* mmx */
   5293     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
   5294     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
   5295 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
   5296     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5297 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
   5298     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5299     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5300     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5301     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5302     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5303     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5304     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5305     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5306     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5307     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5308     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5309     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5310     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5311     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5312     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5313     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5314     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5315     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5316     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5317     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5318     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5319     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5320     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5321 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5322     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5323 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5324     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5325 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5326     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5327 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5328     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5329 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5330     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5331 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5332     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5333 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5334     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5335 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   5336     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5337     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5338     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5339     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5340     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5341     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5342     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5343     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5344     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5345     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5346     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5347     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5348     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5349     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   5350 
   5351 #undef ALT
   5352 #undef DEF_ASM_OP0
   5353 #undef DEF_ASM_OP0L
   5354 #undef DEF_ASM_OP1
   5355 #undef DEF_ASM_OP2
   5356 #undef DEF_ASM_OP3
   5357 //---------------------------------------------------------------------------
   5358 
   5359 #endif
   5360 //---------------------------------------------------------------------------
   5361 #undef DEF
   5362 ;
   5363 
   5364 #define TOK_UIDENT TOK_DEFINE
   5365 
   5366 #ifdef WIN32
   5367 int __stdcall GetModuleFileNameA(void *, char *, int);
   5368 void *__stdcall GetProcAddress(void *, const char *);
   5369 void *__stdcall GetModuleHandleA(const char *);
   5370 void *__stdcall LoadLibraryA(const char *);
   5371 int __stdcall FreeConsole(void);
   5372 
   5373 #define snprintf _snprintf
   5374 #define vsnprintf _vsnprintf
   5375 #ifndef __GNUC__
   5376   #define strtold (long double)strtod
   5377   #define strtof (float)strtod
   5378   #define strtoll (long long)strtol
   5379 #endif
   5380 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
   5381 /* currently incorrect */
   5382 long double strtold(const char *nptr, char **endptr)
   5383 {
   5384     return (long double)strtod(nptr, endptr);
   5385 }
   5386 float strtof(const char *nptr, char **endptr)
   5387 {
   5388     return (float)strtod(nptr, endptr);
   5389 }
   5390 #else
   5391 /* XXX: need to define this to use them in non ISOC99 context */
   5392 extern float strtof (const char *__nptr, char **__endptr);
   5393 extern long double strtold (const char *__nptr, char **__endptr);
   5394 #endif
   5395 
   5396 static char *pstrcpy(char *buf, int buf_size, const char *s);
   5397 static char *pstrcat(char *buf, int buf_size, const char *s);
   5398 static const char *tcc_basename(const char *name);
   5399 
   5400 static void next(void);
   5401 static void next_nomacro(void);
   5402 static void parse_expr_type(CType *type);
   5403 static void expr_type(CType *type);
   5404 static void unary_type(CType *type);
   5405 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
   5406                   int case_reg, int is_expr);
   5407 static int expr_const(void);
   5408 static void expr_eq(void);
   5409 static void gexpr(void);
   5410 static void gen_inline_functions(void);
   5411 static void decl(int l);
   5412 static void decl_initializer(CType *type, Section *sec, unsigned long c,
   5413                              int first, int size_only);
   5414 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
   5415                                    int has_init, int v, int scope);
   5416 int gv(int rc);
   5417 void gv2(int rc1, int rc2);
   5418 void move_reg(int r, int s);
   5419 void save_regs(int n);
   5420 void save_reg(int r);
   5421 void vpop(void);
   5422 void vswap(void);
   5423 void vdup(void);
   5424 int get_reg(int rc);
   5425 int get_reg_ex(int rc,int rc2);
   5426 
   5427 struct macro_level {
   5428     struct macro_level *prev;
   5429     int *p;
   5430 };
   5431 
   5432 static void macro_subst(TokenString *tok_str, Sym **nested_list,
   5433                         const int *macro_str, struct macro_level **can_read_stream);
   5434 void gen_op(int op);
   5435 void force_charshort_cast(int t);
   5436 static void gen_cast(CType *type);
   5437 void vstore(void);
   5438 static Sym *sym_find(int v);
   5439 static Sym *sym_push(int v, CType *type, int r, int c);
   5440 
   5441 /* type handling */
   5442 static int type_size(CType *type, int *a);
   5443 static inline CType *pointed_type(CType *type);
   5444 static int pointed_size(CType *type);
   5445 static int lvalue_type(int t);
   5446 static int parse_btype(CType *type, AttributeDef *ad);
   5447 static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
   5448 static int is_compatible_types(CType *type1, CType *type2);
   5449 
   5450 int ieee_finite(double d);
   5451 void error(const char *fmt, ...);
   5452 void vpushi(int v);
   5453 void vrott(int n);
   5454 void vnrott(int n);
   5455 void lexpand_nr(void);
   5456 static void vpush_global_sym(CType *type, int v);
   5457 void vset(CType *type, int r, int v);
   5458 void type_to_str(char *buf, int buf_size,
   5459                  CType *type, const char *varstr);
   5460 char *get_tok_str(int v, CValue *cv);
   5461 static Sym *get_sym_ref(CType *type, Section *sec,
   5462                         unsigned long offset, unsigned long size);
   5463 static Sym *external_global_sym(int v, CType *type, int r);
   5464 
   5465 /* section generation */
   5466 static void section_realloc(Section *sec, unsigned long new_size);
   5467 static void *section_ptr_add(Section *sec, unsigned long size);
   5468 static void put_extern_sym(Sym *sym, Section *section,
   5469                            unsigned long value, unsigned long size);
   5470 static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
   5471 static int put_elf_str(Section *s, const char *sym);
   5472 static int put_elf_sym(Section *s,
   5473                        unsigned long value, unsigned long size,
   5474                        int info, int other, int shndx, const char *name);
   5475 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
   5476                        int info, int other, int sh_num, const char *name);
   5477 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
   5478                           int type, int symbol);
   5479 static void put_stabs(const char *str, int type, int other, int desc,
   5480                       unsigned long value);
   5481 static void put_stabs_r(const char *str, int type, int other, int desc,
   5482                         unsigned long value, Section *sec, int sym_index);
   5483 static void put_stabn(int type, int other, int desc, int value);
   5484 static void put_stabd(int type, int other, int desc);
   5485 static int tcc_add_dll(TCCState *s, const char *filename, int flags);
   5486 
   5487 #define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
   5488 #define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
   5489 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
   5490 
   5491 /* tcccoff.c */
   5492 int tcc_output_coff(TCCState *s1, FILE *f);
   5493 
   5494 /* tccpe.c */
   5495 void *resolve_sym(TCCState *s1, const char *sym, int type);
   5496 int pe_load_def_file(struct TCCState *s1, FILE *fp);
   5497 void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
   5498 unsigned long pe_add_runtime(struct TCCState *s1);
   5499 int tcc_output_pe(struct TCCState *s1, const char *filename);
   5500 
   5501 /* tccasm.c */
   5502 
   5503 #ifdef CONFIG_TCC_ASM
   5504 
   5505 typedef struct ExprValue {
   5506     uint32_t v;
   5507     Sym *sym;
   5508 } ExprValue;
   5509 
   5510 #define MAX_ASM_OPERANDS 30
   5511 
   5512 typedef struct ASMOperand {
   5513     int id; /* GCC 3 optional identifier (0 if number only supported */
   5514     char *constraint;
   5515     char asm_str[16]; /* computed asm string for operand */
   5516     SValue *vt; /* C value of the expression */
   5517     int ref_index; /* if >= 0, gives reference to a output constraint */
   5518     int input_index; /* if >= 0, gives reference to an input constraint */
   5519     int priority; /* priority, used to assign registers */
   5520     int reg; /* if >= 0, register number used for this operand */
   5521     int is_llong; /* true if double register value */
   5522     int is_memory; /* true if memory operand */
   5523     int is_rw;     /* for '+' modifier */
   5524 } ASMOperand;
   5525 
   5526 static void asm_expr(TCCState *s1, ExprValue *pe);
   5527 static int asm_int_expr(TCCState *s1);
   5528 static int find_constraint(ASMOperand *operands, int nb_operands,
   5529                            const char *name, const char **pp);
   5530 
   5531 static int tcc_assemble(TCCState *s1, int do_preprocess);
   5532 
   5533 #endif
   5534 
   5535 static void asm_instr(void);
   5536 static void asm_global_instr(void);
   5537 
   5538 /* true if float/double/long double type */
   5539 static inline int is_float(int t)
   5540 {
   5541     int bt;
   5542     bt = t & VT_BTYPE;
   5543     return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
   5544 }
   5545 
   5546 #ifdef TCC_TARGET_I386
   5547 // njn: inlined i386-gen.c
   5548 //#include "i386-gen.c"
   5549 //---------------------------------------------------------------------------
   5550 /*
   5551  *  X86 code generator for TCC
   5552  *
   5553  *  Copyright (c) 2001-2004 Fabrice Bellard
   5554  *
   5555  * This library is free software; you can redistribute it and/or
   5556  * modify it under the terms of the GNU Lesser General Public
   5557  * License as published by the Free Software Foundation; either
   5558  * version 2 of the License, or (at your option) any later version.
   5559  *
   5560  * This library is distributed in the hope that it will be useful,
   5561  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   5562  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   5563  * Lesser General Public License for more details.
   5564  *
   5565  * You should have received a copy of the GNU Lesser General Public
   5566  * License along with this library; if not, write to the Free Software
   5567  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   5568  */
   5569 
   5570 /* number of available registers */
   5571 #define NB_REGS             4
   5572 
   5573 /* a register can belong to several classes. The classes must be
   5574    sorted from more general to more precise (see gv2() code which does
   5575    assumptions on it). */
   5576 #define RC_INT     0x0001 /* generic integer register */
   5577 #define RC_FLOAT   0x0002 /* generic float register */
   5578 #define RC_EAX     0x0004
   5579 #define RC_ST0     0x0008
   5580 #define RC_ECX     0x0010
   5581 #define RC_EDX     0x0020
   5582 #define RC_IRET    RC_EAX /* function return: integer register */
   5583 #define RC_LRET    RC_EDX /* function return: second integer register */
   5584 #define RC_FRET    RC_ST0 /* function return: float register */
   5585 
   5586 /* pretty names for the registers */
   5587 enum {
   5588     TREG_EAX = 0,
   5589     TREG_ECX,
   5590     TREG_EDX,
   5591     TREG_ST0,
   5592 };
   5593 
   5594 int reg_classes[NB_REGS] = {
   5595     /* eax */ RC_INT | RC_EAX,
   5596     /* ecx */ RC_INT | RC_ECX,
   5597     /* edx */ RC_INT | RC_EDX,
   5598     /* st0 */ RC_FLOAT | RC_ST0,
   5599 };
   5600 
   5601 /* return registers for function */
   5602 #define REG_IRET TREG_EAX /* single word int return register */
   5603 #define REG_LRET TREG_EDX /* second word return register (for long long) */
   5604 #define REG_FRET TREG_ST0 /* float return register */
   5605 
   5606 /* defined if function parameters must be evaluated in reverse order */
   5607 #define INVERT_FUNC_PARAMS
   5608 
   5609 /* defined if structures are passed as pointers. Otherwise structures
   5610    are directly pushed on stack. */
   5611 //#define FUNC_STRUCT_PARAM_AS_PTR
   5612 
   5613 /* pointer size, in bytes */
   5614 #define PTR_SIZE 4
   5615 
   5616 /* long double size and alignment, in bytes */
   5617 #define LDOUBLE_SIZE  12
   5618 #define LDOUBLE_ALIGN 4
   5619 /* maximum alignment (for aligned attribute support) */
   5620 #define MAX_ALIGN     8
   5621 
   5622 /******************************************************/
   5623 /* ELF defines */
   5624 
   5625 #define EM_TCC_TARGET EM_386
   5626 
   5627 /* relocation type for 32 bit data relocation */
   5628 #define R_DATA_32   R_386_32
   5629 #define R_JMP_SLOT  R_386_JMP_SLOT
   5630 #define R_COPY      R_386_COPY
   5631 
   5632 #define ELF_START_ADDR 0x08048000
   5633 #define ELF_PAGE_SIZE  0x1000
   5634 
   5635 /******************************************************/
   5636 
   5637 static unsigned long func_sub_sp_offset;
   5638 static unsigned long func_bound_offset;
   5639 static int func_ret_sub;
   5640 
   5641 /* XXX: make it faster ? */
   5642 void g(int c)
   5643 {
   5644     int ind1;
   5645     ind1 = ind + 1;
   5646     if (ind1 > cur_text_section->data_allocated)
   5647         section_realloc(cur_text_section, ind1);
   5648     cur_text_section->data[ind] = c;
   5649     ind = ind1;
   5650 }
   5651 
   5652 void o(unsigned int c)
   5653 {
   5654     while (c) {
   5655         g(c);
   5656         c = c >> 8;
   5657     }
   5658 }
   5659 
   5660 void gen_le32(int c)
   5661 {
   5662     g(c);
   5663     g(c >> 8);
   5664     g(c >> 16);
   5665     g(c >> 24);
   5666 }
   5667 
   5668 /* output a symbol and patch all calls to it */
   5669 void gsym_addr(int t, int a)
   5670 {
   5671     int n, *ptr;
   5672     while (t) {
   5673         ptr = (int *)(cur_text_section->data + t);
   5674         n = *ptr; /* next value */
   5675         *ptr = a - t - 4;
   5676         t = n;
   5677     }
   5678 }
   5679 
   5680 void gsym(int t)
   5681 {
   5682     gsym_addr(t, ind);
   5683 }
   5684 
   5685 /* psym is used to put an instruction with a data field which is a
   5686    reference to a symbol. It is in fact the same as oad ! */
   5687 #define psym oad
   5688 
   5689 /* instruction + 4 bytes data. Return the address of the data */
   5690 static int oad(int c, int s)
   5691 {
   5692     int ind1;
   5693 
   5694     o(c);
   5695     ind1 = ind + 4;
   5696     if (ind1 > cur_text_section->data_allocated)
   5697         section_realloc(cur_text_section, ind1);
   5698     *(int *)(cur_text_section->data + ind) = s;
   5699     s = ind;
   5700     ind = ind1;
   5701     return s;
   5702 }
   5703 
   5704 /* output constant with relocation if 'r & VT_SYM' is true */
   5705 static void gen_addr32(int r, Sym *sym, int c)
   5706 {
   5707     if (r & VT_SYM)
   5708         greloc(cur_text_section, sym, ind, R_386_32);
   5709     gen_le32(c);
   5710 }
   5711 
   5712 /* generate a modrm reference. 'op_reg' contains the addtionnal 3
   5713    opcode bits */
   5714 static void gen_modrm(int op_reg, int r, Sym *sym, int c)
   5715 {
   5716     op_reg = op_reg << 3;
   5717     if ((r & VT_VALMASK) == VT_CONST) {
   5718         /* constant memory reference */
   5719         o(0x05 | op_reg);
   5720         gen_addr32(r, sym, c);
   5721     } else if ((r & VT_VALMASK) == VT_LOCAL) {
   5722         /* currently, we use only ebp as base */
   5723         if (c == (char)c) {
   5724             /* short reference */
   5725             o(0x45 | op_reg);
   5726             g(c);
   5727         } else {
   5728             oad(0x85 | op_reg, c);
   5729         }
   5730     } else {
   5731         g(0x00 | op_reg | (r & VT_VALMASK));
   5732     }
   5733 }
   5734 
   5735 
   5736 /* load 'r' from value 'sv' */
   5737 void load(int r, SValue *sv)
   5738 {
   5739     int v, t, ft, fc, fr;
   5740     SValue v1;
   5741 
   5742     fr = sv->r;
   5743     ft = sv->type.t;
   5744     fc = sv->c.ul;
   5745 
   5746     v = fr & VT_VALMASK;
   5747     if (fr & VT_LVAL) {
   5748         if (v == VT_LLOCAL) {
   5749             v1.type.t = VT_INT;
   5750             v1.r = VT_LOCAL | VT_LVAL;
   5751             v1.c.ul = fc;
   5752             load(r, &v1);
   5753             fr = r;
   5754         }
   5755         if ((ft & VT_BTYPE) == VT_FLOAT) {
   5756             o(0xd9); /* flds */
   5757             r = 0;
   5758         } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
   5759             o(0xdd); /* fldl */
   5760             r = 0;
   5761         } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
   5762             o(0xdb); /* fldt */
   5763             r = 5;
   5764         } else if ((ft & VT_TYPE) == VT_BYTE) {
   5765             o(0xbe0f);   /* movsbl */
   5766         } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
   5767             o(0xb60f);   /* movzbl */
   5768         } else if ((ft & VT_TYPE) == VT_SHORT) {
   5769             o(0xbf0f);   /* movswl */
   5770         } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
   5771             o(0xb70f);   /* movzwl */
   5772         } else {
   5773             o(0x8b);     /* movl */
   5774         }
   5775         gen_modrm(r, fr, sv->sym, fc);
   5776     } else {
   5777         if (v == VT_CONST) {
   5778             o(0xb8 + r); /* mov $xx, r */
   5779             gen_addr32(fr, sv->sym, fc);
   5780         } else if (v == VT_LOCAL) {
   5781             o(0x8d); /* lea xxx(%ebp), r */
   5782             gen_modrm(r, VT_LOCAL, sv->sym, fc);
   5783         } else if (v == VT_CMP) {
   5784             oad(0xb8 + r, 0); /* mov $0, r */
   5785             o(0x0f); /* setxx %br */
   5786             o(fc);
   5787             o(0xc0 + r);
   5788         } else if (v == VT_JMP || v == VT_JMPI) {
   5789             t = v & 1;
   5790             oad(0xb8 + r, t); /* mov $1, r */
   5791             o(0x05eb); /* jmp after */
   5792             gsym(fc);
   5793             oad(0xb8 + r, t ^ 1); /* mov $0, r */
   5794         } else if (v != r) {
   5795             o(0x89);
   5796             o(0xc0 + r + v * 8); /* mov v, r */
   5797         }
   5798     }
   5799 }
   5800 
   5801 /* store register 'r' in lvalue 'v' */
   5802 void store(int r, SValue *v)
   5803 {
   5804     int fr, bt, ft, fc;
   5805 
   5806     ft = v->type.t;
   5807     fc = v->c.ul;
   5808     fr = v->r & VT_VALMASK;
   5809     bt = ft & VT_BTYPE;
   5810     /* XXX: incorrect if float reg to reg */
   5811     if (bt == VT_FLOAT) {
   5812         o(0xd9); /* fsts */
   5813         r = 2;
   5814     } else if (bt == VT_DOUBLE) {
   5815         o(0xdd); /* fstpl */
   5816         r = 2;
   5817     } else if (bt == VT_LDOUBLE) {
   5818         o(0xc0d9); /* fld %st(0) */
   5819         o(0xdb); /* fstpt */
   5820         r = 7;
   5821     } else {
   5822         if (bt == VT_SHORT)
   5823             o(0x66);
   5824         if (bt == VT_BYTE || bt == VT_BOOL)
   5825             o(0x88);
   5826         else
   5827             o(0x89);
   5828     }
   5829     if (fr == VT_CONST ||
   5830         fr == VT_LOCAL ||
   5831         (v->r & VT_LVAL)) {
   5832         gen_modrm(r, v->r, v->sym, fc);
   5833     } else if (fr != r) {
   5834         o(0xc0 + fr + r * 8); /* mov r, fr */
   5835     }
   5836 }
   5837 
   5838 static void gadd_sp(int val)
   5839 {
   5840     if (val == (char)val) {
   5841         o(0xc483);
   5842         g(val);
   5843     } else {
   5844         oad(0xc481, val); /* add $xxx, %esp */
   5845     }
   5846 }
   5847 
   5848 /* 'is_jmp' is '1' if it is a jump */
   5849 static void gcall_or_jmp(int is_jmp)
   5850 {
   5851     int r;
   5852     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
   5853         /* constant case */
   5854         if (vtop->r & VT_SYM) {
   5855             /* relocation case */
   5856             greloc(cur_text_section, vtop->sym,
   5857                    ind + 1, R_386_PC32);
   5858         } else {
   5859             /* put an empty PC32 relocation */
   5860             put_elf_reloc(symtab_section, cur_text_section,
   5861                           ind + 1, R_386_PC32, 0);
   5862         }
   5863         oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
   5864     } else {
   5865         /* otherwise, indirect call */
   5866         r = gv(RC_INT);
   5867         o(0xff); /* call/jmp *r */
   5868         o(0xd0 + r + (is_jmp << 4));
   5869     }
   5870 }
   5871 
   5872 static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
   5873 
   5874 /* Generate function call. The function address is pushed first, then
   5875    all the parameters in call order. This functions pops all the
   5876    parameters and the function address. */
   5877 void gfunc_call(int nb_args)
   5878 {
   5879     int size, align, r, args_size, i, func_call;
   5880     Sym *func_sym;
   5881 
   5882     args_size = 0;
   5883     for(i = 0;i < nb_args; i++) {
   5884         if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
   5885             size = type_size(&vtop->type, &align);
   5886             /* align to stack align size */
   5887             size = (size + 3) & ~3;
   5888             /* allocate the necessary size on stack */
   5889             oad(0xec81, size); /* sub $xxx, %esp */
   5890             /* generate structure store */
   5891             r = get_reg(RC_INT);
   5892             o(0x89); /* mov %esp, r */
   5893             o(0xe0 + r);
   5894             vset(&vtop->type, r | VT_LVAL, 0);
   5895             vswap();
   5896             vstore();
   5897             args_size += size;
   5898         } else if (is_float(vtop->type.t)) {
   5899             gv(RC_FLOAT); /* only one float register */
   5900             if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
   5901                 size = 4;
   5902             else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
   5903                 size = 8;
   5904             else
   5905                 size = 12;
   5906             oad(0xec81, size); /* sub $xxx, %esp */
   5907             if (size == 12)
   5908                 o(0x7cdb);
   5909             else
   5910                 o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
   5911             g(0x24);
   5912             g(0x00);
   5913             args_size += size;
   5914         } else {
   5915             /* simple type (currently always same size) */
   5916             /* XXX: implicit cast ? */
   5917             r = gv(RC_INT);
   5918             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
   5919                 size = 8;
   5920                 o(0x50 + vtop->r2); /* push r */
   5921             } else {
   5922                 size = 4;
   5923             }
   5924             o(0x50 + r); /* push r */
   5925             args_size += size;
   5926         }
   5927         vtop--;
   5928     }
   5929     save_regs(0); /* save used temporary registers */
   5930     func_sym = vtop->type.ref;
   5931     func_call = func_sym->r;
   5932     /* fast call case */
   5933     if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
   5934         int fastcall_nb_regs;
   5935         fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
   5936         for(i = 0;i < fastcall_nb_regs; i++) {
   5937             if (args_size <= 0)
   5938                 break;
   5939             o(0x58 + fastcall_regs[i]); /* pop r */
   5940             /* XXX: incorrect for struct/floats */
   5941             args_size -= 4;
   5942         }
   5943     }
   5944     gcall_or_jmp(0);
   5945     if (args_size && func_sym->r != FUNC_STDCALL)
   5946         gadd_sp(args_size);
   5947     vtop--;
   5948 }
   5949 
   5950 #ifdef TCC_TARGET_PE
   5951 #define FUNC_PROLOG_SIZE 10
   5952 #else
   5953 #define FUNC_PROLOG_SIZE 9
   5954 #endif
   5955 
   5956 /* generate function prolog of type 't' */
   5957 void gfunc_prolog(CType *func_type)
   5958 {
   5959     int addr, align, size, func_call, fastcall_nb_regs;
   5960     int param_index, param_addr;
   5961     Sym *sym;
   5962     CType *type;
   5963 
   5964     sym = func_type->ref;
   5965     func_call = sym->r;
   5966     addr = 8;
   5967     loc = 0;
   5968     if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
   5969         fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
   5970     } else {
   5971         fastcall_nb_regs = 0;
   5972     }
   5973     param_index = 0;
   5974 
   5975     ind += FUNC_PROLOG_SIZE;
   5976     func_sub_sp_offset = ind;
   5977     /* if the function returns a structure, then add an
   5978        implicit pointer parameter */
   5979     func_vt = sym->type;
   5980     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
   5981         /* XXX: fastcall case ? */
   5982         func_vc = addr;
   5983         addr += 4;
   5984         param_index++;
   5985     }
   5986     /* define parameters */
   5987     while ((sym = sym->next) != NULL) {
   5988         type = &sym->type;
   5989         size = type_size(type, &align);
   5990         size = (size + 3) & ~3;
   5991 #ifdef FUNC_STRUCT_PARAM_AS_PTR
   5992         /* structs are passed as pointer */
   5993         if ((type->t & VT_BTYPE) == VT_STRUCT) {
   5994             size = 4;
   5995         }
   5996 #endif
   5997         if (param_index < fastcall_nb_regs) {
   5998             /* save FASTCALL register */
   5999             loc -= 4;
   6000             o(0x89);     /* movl */
   6001             gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc);
   6002             param_addr = loc;
   6003         } else {
   6004             param_addr = addr;
   6005             addr += size;
   6006         }
   6007         sym_push(sym->v & ~SYM_FIELD, type,
   6008                  VT_LOCAL | VT_LVAL, param_addr);
   6009         param_index++;
   6010     }
   6011     func_ret_sub = 0;
   6012     /* pascal type call ? */
   6013     if (func_call == FUNC_STDCALL)
   6014         func_ret_sub = addr - 8;
   6015 
   6016     /* leave some room for bound checking code */
   6017     if (do_bounds_check) {
   6018         oad(0xb8, 0); /* lbound section pointer */
   6019         oad(0xb8, 0); /* call to function */
   6020         func_bound_offset = lbounds_section->data_offset;
   6021     }
   6022 }
   6023 
   6024 /* generate function epilog */
   6025 void gfunc_epilog(void)
   6026 {
   6027     int v, saved_ind;
   6028 
   6029 #ifdef CONFIG_TCC_BCHECK
   6030     if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
   6031         int saved_ind;
   6032         int *bounds_ptr;
   6033         Sym *sym, *sym_data;
   6034         /* add end of table info */
   6035         bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
   6036         *bounds_ptr = 0;
   6037         /* generate bound local allocation */
   6038         saved_ind = ind;
   6039         ind = func_sub_sp_offset;
   6040         sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
   6041                                func_bound_offset, lbounds_section->data_offset);
   6042         greloc(cur_text_section, sym_data,
   6043                ind + 1, R_386_32);
   6044         oad(0xb8, 0); /* mov %eax, xxx */
   6045         sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
   6046         greloc(cur_text_section, sym,
   6047                ind + 1, R_386_PC32);
   6048         oad(0xe8, -4);
   6049         ind = saved_ind;
   6050         /* generate bound check local freeing */
   6051         o(0x5250); /* save returned value, if any */
   6052         greloc(cur_text_section, sym_data,
   6053                ind + 1, R_386_32);
   6054         oad(0xb8, 0); /* mov %eax, xxx */
   6055         sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
   6056         greloc(cur_text_section, sym,
   6057                ind + 1, R_386_PC32);
   6058         oad(0xe8, -4);
   6059         o(0x585a); /* restore returned value, if any */
   6060     }
   6061 #endif
   6062     o(0xc9); /* leave */
   6063     if (func_ret_sub == 0) {
   6064         o(0xc3); /* ret */
   6065     } else {
   6066         o(0xc2); /* ret n */
   6067         g(func_ret_sub);
   6068         g(func_ret_sub >> 8);
   6069     }
   6070     /* align local size to word & save local variables */
   6071 
   6072     v = (-loc + 3) & -4;
   6073     saved_ind = ind;
   6074     ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
   6075 #ifdef TCC_TARGET_PE
   6076     if (v >= 4096) {
   6077         Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
   6078         oad(0xb8, v); /* mov stacksize, %eax */
   6079         oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
   6080         greloc(cur_text_section, sym, ind-4, R_386_PC32);
   6081     } else
   6082 #endif
   6083     {
   6084         o(0xe58955);  /* push %ebp, mov %esp, %ebp */
   6085         o(0xec81);  /* sub esp, stacksize */
   6086         gen_le32(v);
   6087 #if FUNC_PROLOG_SIZE == 10
   6088         o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
   6089 #endif
   6090     }
   6091     ind = saved_ind;
   6092 }
   6093 
   6094 /* generate a jump to a label */
   6095 long gjmp(int t)
   6096 {
   6097     return psym(0xe9, t);
   6098 }
   6099 
   6100 /* generate a jump to a fixed address */
   6101 void gjmp_addr(int a)
   6102 {
   6103     int r;
   6104     r = a - ind - 2;
   6105     if (r == (char)r) {
   6106         g(0xeb);
   6107         g(r);
   6108     } else {
   6109         oad(0xe9, a - ind - 5);
   6110     }
   6111 }
   6112 
   6113 /* generate a test. set 'inv' to invert test. Stack entry is popped */
   6114 int gtst(int inv, int t)
   6115 {
   6116     int v, *p;
   6117 
   6118     v = vtop->r & VT_VALMASK;
   6119     if (v == VT_CMP) {
   6120         /* fast case : can jump directly since flags are set */
   6121         g(0x0f);
   6122         t = psym((vtop->c.i - 16) ^ inv, t);
   6123     } else if (v == VT_JMP || v == VT_JMPI) {
   6124         /* && or || optimization */
   6125         if ((v & 1) == inv) {
   6126             /* insert vtop->c jump list in t */
   6127             p = &vtop->c.i;
   6128             while (*p != 0)
   6129                 p = (int *)(cur_text_section->data + *p);
   6130             *p = t;
   6131             t = vtop->c.i;
   6132         } else {
   6133             t = gjmp(t);
   6134             gsym(vtop->c.i);
   6135         }
   6136     } else {
   6137         if (is_float(vtop->type.t)) {
   6138             vpushi(0);
   6139             gen_op(TOK_NE);
   6140         }
   6141         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
   6142             /* constant jmp optimization */
   6143             if ((vtop->c.i != 0) != inv)
   6144                 t = gjmp(t);
   6145         } else {
   6146             v = gv(RC_INT);
   6147             o(0x85);
   6148             o(0xc0 + v * 9);
   6149             g(0x0f);
   6150             t = psym(0x85 ^ inv, t);
   6151         }
   6152     }
   6153     vtop--;
   6154     return t;
   6155 }
   6156 
   6157 /* generate an integer binary operation */
   6158 void gen_opi(int op)
   6159 {
   6160     int r, fr, opc, c;
   6161 
   6162     switch(op) {
   6163     case '+':
   6164     case TOK_ADDC1: /* add with carry generation */
   6165         opc = 0;
   6166     gen_op8:
   6167         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
   6168             /* constant case */
   6169             vswap();
   6170             r = gv(RC_INT);
   6171             vswap();
   6172             c = vtop->c.i;
   6173             if (c == (char)c) {
   6174                 /* XXX: generate inc and dec for smaller code ? */
   6175                 o(0x83);
   6176                 o(0xc0 | (opc << 3) | r);
   6177                 g(c);
   6178             } else {
   6179                 o(0x81);
   6180                 oad(0xc0 | (opc << 3) | r, c);
   6181             }
   6182         } else {
   6183             gv2(RC_INT, RC_INT);
   6184             r = vtop[-1].r;
   6185             fr = vtop[0].r;
   6186             o((opc << 3) | 0x01);
   6187             o(0xc0 + r + fr * 8);
   6188         }
   6189         vtop--;
   6190         if (op >= TOK_ULT && op <= TOK_GT) {
   6191             vtop->r = VT_CMP;
   6192             vtop->c.i = op;
   6193         }
   6194         break;
   6195     case '-':
   6196     case TOK_SUBC1: /* sub with carry generation */
   6197         opc = 5;
   6198         goto gen_op8;
   6199     case TOK_ADDC2: /* add with carry use */
   6200         opc = 2;
   6201         goto gen_op8;
   6202     case TOK_SUBC2: /* sub with carry use */
   6203         opc = 3;
   6204         goto gen_op8;
   6205     case '&':
   6206         opc = 4;
   6207         goto gen_op8;
   6208     case '^':
   6209         opc = 6;
   6210         goto gen_op8;
   6211     case '|':
   6212         opc = 1;
   6213         goto gen_op8;
   6214     case '*':
   6215         gv2(RC_INT, RC_INT);
   6216         r = vtop[-1].r;
   6217         fr = vtop[0].r;
   6218         vtop--;
   6219         o(0xaf0f); /* imul fr, r */
   6220         o(0xc0 + fr + r * 8);
   6221         break;
   6222     case TOK_SHL:
   6223         opc = 4;
   6224         goto gen_shift;
   6225     case TOK_SHR:
   6226         opc = 5;
   6227         goto gen_shift;
   6228     case TOK_SAR:
   6229         opc = 7;
   6230     gen_shift:
   6231         opc = 0xc0 | (opc << 3);
   6232         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
   6233             /* constant case */
   6234             vswap();
   6235             r = gv(RC_INT);
   6236             vswap();
   6237             c = vtop->c.i & 0x1f;
   6238             o(0xc1); /* shl/shr/sar $xxx, r */
   6239             o(opc | r);
   6240             g(c);
   6241         } else {
   6242             /* we generate the shift in ecx */
   6243             gv2(RC_INT, RC_ECX);
   6244             r = vtop[-1].r;
   6245             o(0xd3); /* shl/shr/sar %cl, r */
   6246             o(opc | r);
   6247         }
   6248         vtop--;
   6249         break;
   6250     case '/':
   6251     case TOK_UDIV:
   6252     case TOK_PDIV:
   6253     case '%':
   6254     case TOK_UMOD:
   6255     case TOK_UMULL:
   6256         /* first operand must be in eax */
   6257         /* XXX: need better constraint for second operand */
   6258         gv2(RC_EAX, RC_ECX);
   6259         r = vtop[-1].r;
   6260         fr = vtop[0].r;
   6261         vtop--;
   6262         save_reg(TREG_EDX);
   6263         if (op == TOK_UMULL) {
   6264             o(0xf7); /* mul fr */
   6265             o(0xe0 + fr);
   6266             vtop->r2 = TREG_EDX;
   6267             r = TREG_EAX;
   6268         } else {
   6269             if (op == TOK_UDIV || op == TOK_UMOD) {
   6270                 o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
   6271                 o(0xf0 + fr);
   6272             } else {
   6273                 o(0xf799); /* cltd, idiv fr, %eax */
   6274                 o(0xf8 + fr);
   6275             }
   6276             if (op == '%' || op == TOK_UMOD)
   6277                 r = TREG_EDX;
   6278             else
   6279                 r = TREG_EAX;
   6280         }
   6281         vtop->r = r;
   6282         break;
   6283     default:
   6284         opc = 7;
   6285         goto gen_op8;
   6286     }
   6287 }
   6288 
   6289 /* generate a floating point operation 'v = t1 op t2' instruction. The
   6290    two operands are guaranted to have the same floating point type */
   6291 /* XXX: need to use ST1 too */
   6292 void gen_opf(int op)
   6293 {
   6294     int a, ft, fc, swapped, r;
   6295 
   6296     /* convert constants to memory references */
   6297     if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
   6298         vswap();
   6299         gv(RC_FLOAT);
   6300         vswap();
   6301     }
   6302     if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
   6303         gv(RC_FLOAT);
   6304 
   6305     /* must put at least one value in the floating point register */
   6306     if ((vtop[-1].r & VT_LVAL) &&
   6307         (vtop[0].r & VT_LVAL)) {
   6308         vswap();
   6309         gv(RC_FLOAT);
   6310         vswap();
   6311     }
   6312     swapped = 0;
   6313     /* swap the stack if needed so that t1 is the register and t2 is
   6314        the memory reference */
   6315     if (vtop[-1].r & VT_LVAL) {
   6316         vswap();
   6317         swapped = 1;
   6318     }
   6319     if (op >= TOK_ULT && op <= TOK_GT) {
   6320         /* load on stack second operand */
   6321         load(TREG_ST0, vtop);
   6322         save_reg(TREG_EAX); /* eax is used by FP comparison code */
   6323         if (op == TOK_GE || op == TOK_GT)
   6324             swapped = !swapped;
   6325         else if (op == TOK_EQ || op == TOK_NE)
   6326             swapped = 0;
   6327         if (swapped)
   6328             o(0xc9d9); /* fxch %st(1) */
   6329         o(0xe9da); /* fucompp */
   6330         o(0xe0df); /* fnstsw %ax */
   6331         if (op == TOK_EQ) {
   6332             o(0x45e480); /* and $0x45, %ah */
   6333             o(0x40fC80); /* cmp $0x40, %ah */
   6334         } else if (op == TOK_NE) {
   6335             o(0x45e480); /* and $0x45, %ah */
   6336             o(0x40f480); /* xor $0x40, %ah */
   6337             op = TOK_NE;
   6338         } else if (op == TOK_GE || op == TOK_LE) {
   6339             o(0x05c4f6); /* test $0x05, %ah */
   6340             op = TOK_EQ;
   6341         } else {
   6342             o(0x45c4f6); /* test $0x45, %ah */
   6343             op = TOK_EQ;
   6344         }
   6345         vtop--;
   6346         vtop->r = VT_CMP;
   6347         vtop->c.i = op;
   6348     } else {
   6349         /* no memory reference possible for long double operations */
   6350         if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
   6351             load(TREG_ST0, vtop);
   6352             swapped = !swapped;
   6353         }
   6354 
   6355         switch(op) {
   6356         default:
   6357         case '+':
   6358             a = 0;
   6359             break;
   6360         case '-':
   6361             a = 4;
   6362             if (swapped)
   6363                 a++;
   6364             break;
   6365         case '*':
   6366             a = 1;
   6367             break;
   6368         case '/':
   6369             a = 6;
   6370             if (swapped)
   6371                 a++;
   6372             break;
   6373         }
   6374         ft = vtop->type.t;
   6375         fc = vtop->c.ul;
   6376         if ((ft & VT_BTYPE) == VT_LDOUBLE) {
   6377             o(0xde); /* fxxxp %st, %st(1) */
   6378             o(0xc1 + (a << 3));
   6379         } else {
   6380             /* if saved lvalue, then we must reload it */
   6381             r = vtop->r;
   6382             if ((r & VT_VALMASK) == VT_LLOCAL) {
   6383                 SValue v1;
   6384                 r = get_reg(RC_INT);
   6385                 v1.type.t = VT_INT;
   6386                 v1.r = VT_LOCAL | VT_LVAL;
   6387                 v1.c.ul = fc;
   6388                 load(r, &v1);
   6389                 fc = 0;
   6390             }
   6391 
   6392             if ((ft & VT_BTYPE) == VT_DOUBLE)
   6393                 o(0xdc);
   6394             else
   6395                 o(0xd8);
   6396             gen_modrm(a, r, vtop->sym, fc);
   6397         }
   6398         vtop--;
   6399     }
   6400 }
   6401 
   6402 /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
   6403    and 'long long' cases. */
   6404 void gen_cvt_itof(int t)
   6405 {
   6406     save_reg(TREG_ST0);
   6407     gv(RC_INT);
   6408     if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
   6409         /* signed long long to float/double/long double (unsigned case
   6410            is handled generically) */
   6411         o(0x50 + vtop->r2); /* push r2 */
   6412         o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
   6413         o(0x242cdf); /* fildll (%esp) */
   6414         o(0x08c483); /* add $8, %esp */
   6415     } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
   6416                (VT_INT | VT_UNSIGNED)) {
   6417         /* unsigned int to float/double/long double */
   6418         o(0x6a); /* push $0 */
   6419         g(0x00);
   6420         o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
   6421         o(0x242cdf); /* fildll (%esp) */
   6422         o(0x08c483); /* add $8, %esp */
   6423     } else {
   6424         /* int to float/double/long double */
   6425         o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
   6426         o(0x2404db); /* fildl (%esp) */
   6427         o(0x04c483); /* add $4, %esp */
   6428     }
   6429     vtop->r = TREG_ST0;
   6430 }
   6431 
   6432 /* convert fp to int 't' type */
   6433 /* XXX: handle long long case */
   6434 void gen_cvt_ftoi(int t)
   6435 {
   6436     int r, r2, size;
   6437     Sym *sym;
   6438     CType ushort_type;
   6439 
   6440     ushort_type.t = VT_SHORT | VT_UNSIGNED;
   6441 
   6442     gv(RC_FLOAT);
   6443     if (t != VT_INT)
   6444         size = 8;
   6445     else
   6446         size = 4;
   6447 
   6448     o(0x2dd9); /* ldcw xxx */
   6449     sym = external_global_sym(TOK___tcc_int_fpu_control,
   6450                               &ushort_type, VT_LVAL);
   6451     greloc(cur_text_section, sym,
   6452            ind, R_386_32);
   6453     gen_le32(0);
   6454 
   6455     oad(0xec81, size); /* sub $xxx, %esp */
   6456     if (size == 4)
   6457         o(0x1cdb); /* fistpl */
   6458     else
   6459         o(0x3cdf); /* fistpll */
   6460     o(0x24);
   6461     o(0x2dd9); /* ldcw xxx */
   6462     sym = external_global_sym(TOK___tcc_fpu_control,
   6463                               &ushort_type, VT_LVAL);
   6464     greloc(cur_text_section, sym,
   6465            ind, R_386_32);
   6466     gen_le32(0);
   6467 
   6468     r = get_reg(RC_INT);
   6469     o(0x58 + r); /* pop r */
   6470     if (size == 8) {
   6471         if (t == VT_LLONG) {
   6472             vtop->r = r; /* mark reg as used */
   6473             r2 = get_reg(RC_INT);
   6474             o(0x58 + r2); /* pop r2 */
   6475             vtop->r2 = r2;
   6476         } else {
   6477             o(0x04c483); /* add $4, %esp */
   6478         }
   6479     }
   6480     vtop->r = r;
   6481 }
   6482 
   6483 /* convert from one floating point type to another */
   6484 void gen_cvt_ftof(int t)
   6485 {
   6486     /* all we have to do on i386 is to put the float in a register */
   6487     gv(RC_FLOAT);
   6488 }
   6489 
   6490 /* computed goto support */
   6491 void ggoto(void)
   6492 {
   6493     gcall_or_jmp(1);
   6494     vtop--;
   6495 }
   6496 
   6497 /* bound check support functions */
   6498 #ifdef CONFIG_TCC_BCHECK
   6499 
   6500 /* generate a bounded pointer addition */
   6501 void gen_bounded_ptr_add(void)
   6502 {
   6503     Sym *sym;
   6504 
   6505     /* prepare fast i386 function call (args in eax and edx) */
   6506     gv2(RC_EAX, RC_EDX);
   6507     /* save all temporary registers */
   6508     vtop -= 2;
   6509     save_regs(0);
   6510     /* do a fast function call */
   6511     sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
   6512     greloc(cur_text_section, sym,
   6513            ind + 1, R_386_PC32);
   6514     oad(0xe8, -4);
   6515     /* returned pointer is in eax */
   6516     vtop++;
   6517     vtop->r = TREG_EAX | VT_BOUNDED;
   6518     /* address of bounding function call point */
   6519     vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
   6520 }
   6521 
   6522 /* patch pointer addition in vtop so that pointer dereferencing is
   6523    also tested */
   6524 void gen_bounded_ptr_deref(void)
   6525 {
   6526     int func;
   6527     int size, align;
   6528     Elf32_Rel *rel;
   6529     Sym *sym;
   6530 
   6531     size = 0;
   6532     /* XXX: put that code in generic part of tcc */
   6533     if (!is_float(vtop->type.t)) {
   6534         if (vtop->r & VT_LVAL_BYTE)
   6535             size = 1;
   6536         else if (vtop->r & VT_LVAL_SHORT)
   6537             size = 2;
   6538     }
   6539     if (!size)
   6540         size = type_size(&vtop->type, &align);
   6541     switch(size) {
   6542     case  1: func = TOK___bound_ptr_indir1; break;
   6543     case  2: func = TOK___bound_ptr_indir2; break;
   6544     case  4: func = TOK___bound_ptr_indir4; break;
   6545     case  8: func = TOK___bound_ptr_indir8; break;
   6546     case 12: func = TOK___bound_ptr_indir12; break;
   6547     case 16: func = TOK___bound_ptr_indir16; break;
   6548     default:
   6549         error("unhandled size when derefencing bounded pointer");
   6550         func = 0;
   6551         break;
   6552     }
   6553 
   6554     /* patch relocation */
   6555     /* XXX: find a better solution ? */
   6556     rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
   6557     sym = external_global_sym(func, &func_old_type, 0);
   6558     if (!sym->c)
   6559         put_extern_sym(sym, NULL, 0, 0);
   6560     rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
   6561 }
   6562 #endif
   6563 
   6564 /* end of X86 code generator */
   6565 /*************************************************************/
   6566 
   6567 //---------------------------------------------------------------------------
   6568 #endif
   6569 
   6570 // njn: commented these out
   6571 //#ifdef TCC_TARGET_ARM
   6572 //#include "arm-gen.c"
   6573 //#endif
   6574 //
   6575 //#ifdef TCC_TARGET_C67
   6576 //#include "c67-gen.c"
   6577 //#endif
   6578 
   6579 #ifdef CONFIG_TCC_STATIC
   6580 
   6581 #define RTLD_LAZY       0x001
   6582 #define RTLD_NOW        0x002
   6583 #define RTLD_GLOBAL     0x100
   6584 #define RTLD_DEFAULT    NULL
   6585 
   6586 /* dummy function for profiling */
   6587 void *dlopen(const char *filename, int flag)
   6588 {
   6589     return NULL;
   6590 }
   6591 
   6592 const char *dlerror(void)
   6593 {
   6594     return "error";
   6595 }
   6596 
   6597 typedef struct TCCSyms {
   6598     char *str;
   6599     void *ptr;
   6600 } TCCSyms;
   6601 
   6602 #define TCCSYM(a) { #a, &a, },
   6603 
   6604 /* add the symbol you want here if no dynamic linking is done */
   6605 static TCCSyms tcc_syms[] = {
   6606 #if !defined(CONFIG_TCCBOOT)
   6607     TCCSYM(printf)
   6608     TCCSYM(fprintf)
   6609     TCCSYM(fopen)
   6610     TCCSYM(fclose)
   6611 #endif
   6612     { NULL, NULL },
   6613 };
   6614 
   6615 void *resolve_sym(TCCState *s1, const char *symbol, int type)
   6616 {
   6617     TCCSyms *p;
   6618     p = tcc_syms;
   6619     while (p->str != NULL) {
   6620         if (!strcmp(p->str, symbol))
   6621             return p->ptr;
   6622         p++;
   6623     }
   6624     return NULL;
   6625 }
   6626 
   6627 #elif !defined(WIN32)
   6628 
   6629 #include <dlfcn.h>
   6630 
   6631 void *resolve_sym(TCCState *s1, const char *sym, int type)
   6632 {
   6633   assert(0);
   6634   return 0; //dlsym(RTLD_DEFAULT, sym);
   6635   // jrs: remove need for dlsym
   6636 }
   6637 
   6638 #endif
   6639 
   6640 /********************************************************/
   6641 
   6642 /* we use our own 'finite' function to avoid potential problems with
   6643    non standard math libs */
   6644 /* XXX: endianness dependent */
   6645 int ieee_finite(double d)
   6646 {
   6647     int *p = (int *)&d;
   6648     return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
   6649 }
   6650 
   6651 /* copy a string and truncate it. */
   6652 static char *pstrcpy(char *buf, int buf_size, const char *s)
   6653 {
   6654     char *q, *q_end;
   6655     int c;
   6656 
   6657     if (buf_size > 0) {
   6658         q = buf;
   6659         q_end = buf + buf_size - 1;
   6660         while (q < q_end) {
   6661             c = *s++;
   6662             if (c == '\0')
   6663                 break;
   6664             *q++ = c;
   6665         }
   6666         *q = '\0';
   6667     }
   6668     return buf;
   6669 }
   6670 
   6671 /* strcat and truncate. */
   6672 static char *pstrcat(char *buf, int buf_size, const char *s)
   6673 {
   6674     int len;
   6675     len = strlen(buf);
   6676     if (len < buf_size)
   6677         pstrcpy(buf + len, buf_size - len, s);
   6678     return buf;
   6679 }
   6680 
   6681 static int strstart(const char *str, const char *val, const char **ptr)
   6682 {
   6683     const char *p, *q;
   6684     p = str;
   6685     q = val;
   6686     while (*q != '\0') {
   6687         if (*p != *q)
   6688             return 0;
   6689         p++;
   6690         q++;
   6691     }
   6692     if (ptr)
   6693         *ptr = p;
   6694     return 1;
   6695 }
   6696 
   6697 /* memory management */
   6698 #ifdef MEM_DEBUG
   6699 int mem_cur_size;
   6700 int mem_max_size;
   6701 #endif
   6702 
   6703 static inline void tcc_free(void *ptr)
   6704 {
   6705 #ifdef MEM_DEBUG
   6706     mem_cur_size -= malloc_usable_size(ptr);
   6707 #endif
   6708     free(ptr);
   6709 }
   6710 
   6711 static void *tcc_malloc(unsigned long size)
   6712 {
   6713     void *ptr;
   6714     ptr = malloc(size);
   6715     if (!ptr && size)
   6716         error("memory full");
   6717 #ifdef MEM_DEBUG
   6718     mem_cur_size += malloc_usable_size(ptr);
   6719     if (mem_cur_size > mem_max_size)
   6720         mem_max_size = mem_cur_size;
   6721 #endif
   6722     return ptr;
   6723 }
   6724 
   6725 static void *tcc_mallocz(unsigned long size)
   6726 {
   6727     void *ptr;
   6728     ptr = tcc_malloc(size);
   6729     memset(ptr, 0, size);
   6730     return ptr;
   6731 }
   6732 
   6733 static inline void *tcc_realloc(void *ptr, unsigned long size)
   6734 {
   6735     void *ptr1;
   6736 #ifdef MEM_DEBUG
   6737     mem_cur_size -= malloc_usable_size(ptr);
   6738 #endif
   6739     ptr1 = realloc(ptr, size);
   6740 #ifdef MEM_DEBUG
   6741     /* NOTE: count not correct if alloc error, but not critical */
   6742     mem_cur_size += malloc_usable_size(ptr1);
   6743     if (mem_cur_size > mem_max_size)
   6744         mem_max_size = mem_cur_size;
   6745 #endif
   6746     return ptr1;
   6747 }
   6748 
   6749 static char *tcc_strdup(const char *str)
   6750 {
   6751     char *ptr;
   6752     ptr = tcc_malloc(strlen(str) + 1);
   6753     strcpy(ptr, str);
   6754     return ptr;
   6755 }
   6756 
   6757 #define free(p) use_tcc_free(p)
   6758 #define malloc(s) use_tcc_malloc(s)
   6759 #define realloc(p, s) use_tcc_realloc(p, s)
   6760 
   6761 static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
   6762 {
   6763     int nb, nb_alloc;
   6764     void **pp;
   6765 
   6766     nb = *nb_ptr;
   6767     pp = *ptab;
   6768     /* every power of two we double array size */
   6769     if ((nb & (nb - 1)) == 0) {
   6770         if (!nb)
   6771             nb_alloc = 1;
   6772         else
   6773             nb_alloc = nb * 2;
   6774         pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
   6775         if (!pp)
   6776             error("memory full");
   6777         *ptab = pp;
   6778     }
   6779     pp[nb++] = data;
   6780     *nb_ptr = nb;
   6781 }
   6782 
   6783 /* symbol allocator */
   6784 static Sym *__sym_malloc(void)
   6785 {
   6786     Sym *sym_pool, *sym, *last_sym;
   6787     int i;
   6788 
   6789     sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
   6790 
   6791     last_sym = sym_free_first;
   6792     sym = sym_pool;
   6793     for(i = 0; i < SYM_POOL_NB; i++) {
   6794         sym->next = last_sym;
   6795         last_sym = sym;
   6796         sym++;
   6797     }
   6798     sym_free_first = last_sym;
   6799     return last_sym;
   6800 }
   6801 
   6802 static inline Sym *sym_malloc(void)
   6803 {
   6804     Sym *sym;
   6805     sym = sym_free_first;
   6806     if (!sym)
   6807         sym = __sym_malloc();
   6808     sym_free_first = sym->next;
   6809     return sym;
   6810 }
   6811 
   6812 static inline void sym_free(Sym *sym)
   6813 {
   6814     sym->next = sym_free_first;
   6815     sym_free_first = sym;
   6816 }
   6817 
   6818 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
   6819 {
   6820     Section *sec;
   6821 
   6822     sec = tcc_mallocz(sizeof(Section) + strlen(name));
   6823     strcpy(sec->name, name);
   6824     sec->sh_type = sh_type;
   6825     sec->sh_flags = sh_flags;
   6826     switch(sh_type) {
   6827     case SHT_HASH:
   6828     case SHT_REL:
   6829     case SHT_DYNSYM:
   6830     case SHT_SYMTAB:
   6831     case SHT_DYNAMIC:
   6832         sec->sh_addralign = 4;
   6833         break;
   6834     case SHT_STRTAB:
   6835         sec->sh_addralign = 1;
   6836         break;
   6837     default:
   6838         sec->sh_addralign = 32; /* default conservative alignment */
   6839         break;
   6840     }
   6841 
   6842     /* only add section if not private */
   6843     if (!(sh_flags & SHF_PRIVATE)) {
   6844         sec->sh_num = s1->nb_sections;
   6845         dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
   6846     }
   6847     return sec;
   6848 }
   6849 
   6850 static void free_section(Section *s)
   6851 {
   6852     tcc_free(s->data);
   6853     tcc_free(s);
   6854 }
   6855 
   6856 /* realloc section and set its content to zero */
   6857 static void section_realloc(Section *sec, unsigned long new_size)
   6858 {
   6859     unsigned long size;
   6860     unsigned char *data;
   6861 
   6862     size = sec->data_allocated;
   6863     if (size == 0)
   6864         size = 1;
   6865     while (size < new_size)
   6866         size = size * 2;
   6867     data = tcc_realloc(sec->data, size);
   6868     if (!data)
   6869         error("memory full");
   6870     memset(data + sec->data_allocated, 0, size - sec->data_allocated);
   6871     sec->data = data;
   6872     sec->data_allocated = size;
   6873 }
   6874 
   6875 /* reserve at least 'size' bytes in section 'sec' from
   6876    sec->data_offset. */
   6877 static void *section_ptr_add(Section *sec, unsigned long size)
   6878 {
   6879     unsigned long offset, offset1;
   6880 
   6881     offset = sec->data_offset;
   6882     offset1 = offset + size;
   6883     if (offset1 > sec->data_allocated)
   6884         section_realloc(sec, offset1);
   6885     sec->data_offset = offset1;
   6886     return sec->data + offset;
   6887 }
   6888 
   6889 /* return a reference to a section, and create it if it does not
   6890    exists */
   6891 Section *find_section(TCCState *s1, const char *name)
   6892 {
   6893     Section *sec;
   6894     int i;
   6895     for(i = 1; i < s1->nb_sections; i++) {
   6896         sec = s1->sections[i];
   6897         if (!strcmp(name, sec->name))
   6898             return sec;
   6899     }
   6900     /* sections are created as PROGBITS */
   6901     return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
   6902 }
   6903 
   6904 #define SECTION_ABS ((void *)1)
   6905 
   6906 /* update sym->c so that it points to an external symbol in section
   6907    'section' with value 'value' */
   6908 static void put_extern_sym2(Sym *sym, Section *section,
   6909                             unsigned long value, unsigned long size,
   6910                             int can_add_underscore)
   6911 {
   6912     int sym_type, sym_bind, sh_num, info;
   6913     Elf32_Sym *esym;
   6914     const char *name;
   6915     char buf1[256];
   6916 
   6917     if (section == NULL)
   6918         sh_num = SHN_UNDEF;
   6919     else if (section == SECTION_ABS)
   6920         sh_num = SHN_ABS;
   6921     else
   6922         sh_num = section->sh_num;
   6923     if (!sym->c) {
   6924         if ((sym->type.t & VT_BTYPE) == VT_FUNC)
   6925             sym_type = STT_FUNC;
   6926         else
   6927             sym_type = STT_OBJECT;
   6928         if (sym->type.t & VT_STATIC)
   6929             sym_bind = STB_LOCAL;
   6930         else
   6931             sym_bind = STB_GLOBAL;
   6932 
   6933         name = get_tok_str(sym->v, NULL);
   6934 #ifdef CONFIG_TCC_BCHECK
   6935         if (do_bounds_check) {
   6936             char buf[32];
   6937 
   6938             /* XXX: avoid doing that for statics ? */
   6939             /* if bound checking is activated, we change some function
   6940                names by adding the "__bound" prefix */
   6941             switch(sym->v) {
   6942 #if 0
   6943             /* XXX: we rely only on malloc hooks */
   6944             case TOK_malloc:
   6945             case TOK_free:
   6946             case TOK_realloc:
   6947             case TOK_memalign:
   6948             case TOK_calloc:
   6949 #endif
   6950             case TOK_memcpy:
   6951             case TOK_memmove:
   6952             case TOK_memset:
   6953             case TOK_strlen:
   6954             case TOK_strcpy:
   6955                 strcpy(buf, "__bound_");
   6956                 strcat(buf, name);
   6957                 name = buf;
   6958                 break;
   6959             }
   6960         }
   6961 #endif
   6962         if (tcc_state->leading_underscore && can_add_underscore) {
   6963             buf1[0] = '_';
   6964             pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
   6965             name = buf1;
   6966         }
   6967         info = ELF32_ST_INFO(sym_bind, sym_type);
   6968         sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
   6969     } else {
   6970         esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
   6971         esym->st_value = value;
   6972         esym->st_size = size;
   6973         esym->st_shndx = sh_num;
   6974     }
   6975 }
   6976 
   6977 static void put_extern_sym(Sym *sym, Section *section,
   6978                            unsigned long value, unsigned long size)
   6979 {
   6980     put_extern_sym2(sym, section, value, size, 1);
   6981 }
   6982 
   6983 /* add a new relocation entry to symbol 'sym' in section 's' */
   6984 static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
   6985 {
   6986     if (!sym->c)
   6987         put_extern_sym(sym, NULL, 0, 0);
   6988     /* now we can add ELF relocation info */
   6989     put_elf_reloc(symtab_section, s, offset, type, sym->c);
   6990 }
   6991 
   6992 static inline int isid(int c)
   6993 {
   6994     return (c >= 'a' && c <= 'z') ||
   6995         (c >= 'A' && c <= 'Z') ||
   6996         c == '_';
   6997 }
   6998 
   6999 static inline int isnum(int c)
   7000 {
   7001     return c >= '0' && c <= '9';
   7002 }
   7003 
   7004 static inline int isoct(int c)
   7005 {
   7006     return c >= '0' && c <= '7';
   7007 }
   7008 
   7009 static inline int toup(int c)
   7010 {
   7011     if (c >= 'a' && c <= 'z')
   7012         return c - 'a' + 'A';
   7013     else
   7014         return c;
   7015 }
   7016 
   7017 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
   7018 {
   7019     int len;
   7020     len = strlen(buf);
   7021     vsnprintf(buf + len, buf_size - len, fmt, ap);
   7022 }
   7023 
   7024 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
   7025 {
   7026     va_list ap;
   7027     va_start(ap, fmt);
   7028     strcat_vprintf(buf, buf_size, fmt, ap);
   7029     va_end(ap);
   7030 }
   7031 
   7032 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
   7033 {
   7034     char buf[2048];
   7035     BufferedFile **f;
   7036 
   7037     buf[0] = '\0';
   7038     if (file) {
   7039         for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
   7040             strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
   7041                           (*f)->filename, (*f)->line_num);
   7042         if (file->line_num > 0) {
   7043             strcat_printf(buf, sizeof(buf),
   7044                           "%s:%d: ", file->filename, file->line_num);
   7045         } else {
   7046             strcat_printf(buf, sizeof(buf),
   7047                           "%s: ", file->filename);
   7048         }
   7049     } else {
   7050         strcat_printf(buf, sizeof(buf),
   7051                       "tcc: ");
   7052     }
   7053     if (is_warning)
   7054         strcat_printf(buf, sizeof(buf), "warning: ");
   7055     strcat_vprintf(buf, sizeof(buf), fmt, ap);
   7056 
   7057     if (!s1->error_func) {
   7058         /* default case: stderr */
   7059         fprintf(stderr, "%s\n", buf);
   7060     } else {
   7061         s1->error_func(s1->error_opaque, buf);
   7062     }
   7063     if (!is_warning || s1->warn_error)
   7064         s1->nb_errors++;
   7065 }
   7066 
   7067 #ifdef LIBTCC
   7068 void tcc_set_error_func(TCCState *s, void *error_opaque,
   7069                         void (*error_func)(void *opaque, const char *msg))
   7070 {
   7071     s->error_opaque = error_opaque;
   7072     s->error_func = error_func;
   7073 }
   7074 #endif
   7075 
   7076 /* error without aborting current compilation */
   7077 void error_noabort(const char *fmt, ...)
   7078 {
   7079     TCCState *s1 = tcc_state;
   7080     va_list ap;
   7081 
   7082     va_start(ap, fmt);
   7083     error1(s1, 0, fmt, ap);
   7084     va_end(ap);
   7085 }
   7086 
   7087 void error(const char *fmt, ...)
   7088 {
   7089     TCCState *s1 = tcc_state;
   7090     va_list ap;
   7091 
   7092     va_start(ap, fmt);
   7093     error1(s1, 0, fmt, ap);
   7094     va_end(ap);
   7095     /* better than nothing: in some cases, we accept to handle errors */
   7096     if (s1->error_set_jmp_enabled) {
   7097         longjmp(s1->error_jmp_buf, 1);
   7098     } else {
   7099         /* XXX: eliminate this someday */
   7100         exit(1);
   7101     }
   7102 }
   7103 
   7104 void expect(const char *msg)
   7105 {
   7106     error("%s expected", msg);
   7107 }
   7108 
   7109 void warning(const char *fmt, ...)
   7110 {
   7111     TCCState *s1 = tcc_state;
   7112     va_list ap;
   7113 
   7114     if (s1->warn_none)
   7115         return;
   7116 
   7117     va_start(ap, fmt);
   7118     error1(s1, 1, fmt, ap);
   7119     va_end(ap);
   7120 }
   7121 
   7122 void skip(int c)
   7123 {
   7124     if (tok != c)
   7125         error("'%c' expected", c);
   7126     next();
   7127 }
   7128 
   7129 static void test_lvalue(void)
   7130 {
   7131     if (!(vtop->r & VT_LVAL))
   7132         expect("lvalue");
   7133 }
   7134 
   7135 /* allocate a new token */
   7136 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
   7137 {
   7138     TokenSym *ts, **ptable;
   7139     int i;
   7140 
   7141     if (tok_ident >= SYM_FIRST_ANOM)
   7142         error("memory full");
   7143 
   7144     /* expand token table if needed */
   7145     i = tok_ident - TOK_IDENT;
   7146     if ((i % TOK_ALLOC_INCR) == 0) {
   7147         ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
   7148         if (!ptable)
   7149             error("memory full");
   7150         table_ident = ptable;
   7151     }
   7152 
   7153     ts = tcc_malloc(sizeof(TokenSym) + len);
   7154     table_ident[i] = ts;
   7155     ts->tok = tok_ident++;
   7156     ts->sym_define = NULL;
   7157     ts->sym_label = NULL;
   7158     ts->sym_struct = NULL;
   7159     ts->sym_identifier = NULL;
   7160     ts->len = len;
   7161     ts->hash_next = NULL;
   7162     memcpy(ts->str, str, len);
   7163     ts->str[len] = '\0';
   7164     *pts = ts;
   7165     return ts;
   7166 }
   7167 
   7168 #define TOK_HASH_INIT 1
   7169 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
   7170 
   7171 /* find a token and add it if not found */
   7172 static TokenSym *tok_alloc(const char *str, int len)
   7173 {
   7174     TokenSym *ts, **pts;
   7175     int i;
   7176     unsigned int h;
   7177 
   7178     h = TOK_HASH_INIT;
   7179     for(i=0;i<len;i++)
   7180         h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
   7181     h &= (TOK_HASH_SIZE - 1);
   7182 
   7183     pts = &hash_ident[h];
   7184     for(;;) {
   7185         ts = *pts;
   7186         if (!ts)
   7187             break;
   7188         if (ts->len == len && !memcmp(ts->str, str, len))
   7189             return ts;
   7190         pts = &(ts->hash_next);
   7191     }
   7192     return tok_alloc_new(pts, str, len);
   7193 }
   7194 
   7195 /* CString handling */
   7196 
   7197 static void cstr_realloc(CString *cstr, int new_size)
   7198 {
   7199     int size;
   7200     void *data;
   7201 
   7202     size = cstr->size_allocated;
   7203     if (size == 0)
   7204         size = 8; /* no need to allocate a too small first string */
   7205     while (size < new_size)
   7206         size = size * 2;
   7207     data = tcc_realloc(cstr->data_allocated, size);
   7208     if (!data)
   7209         error("memory full");
   7210     cstr->data_allocated = data;
   7211     cstr->size_allocated = size;
   7212     cstr->data = data;
   7213 }
   7214 
   7215 /* add a byte */
   7216 static inline void cstr_ccat(CString *cstr, int ch)
   7217 {
   7218     int size;
   7219     size = cstr->size + 1;
   7220     if (size > cstr->size_allocated)
   7221         cstr_realloc(cstr, size);
   7222     ((unsigned char *)cstr->data)[size - 1] = ch;
   7223     cstr->size = size;
   7224 }
   7225 
   7226 static void cstr_cat(CString *cstr, const char *str)
   7227 {
   7228     int c;
   7229     for(;;) {
   7230         c = *str;
   7231         if (c == '\0')
   7232             break;
   7233         cstr_ccat(cstr, c);
   7234         str++;
   7235     }
   7236 }
   7237 
   7238 /* add a wide char */
   7239 static void cstr_wccat(CString *cstr, int ch)
   7240 {
   7241     int size;
   7242     size = cstr->size + sizeof(int);
   7243     if (size > cstr->size_allocated)
   7244         cstr_realloc(cstr, size);
   7245     *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
   7246     cstr->size = size;
   7247 }
   7248 
   7249 static void cstr_new(CString *cstr)
   7250 {
   7251     memset(cstr, 0, sizeof(CString));
   7252 }
   7253 
   7254 /* free string and reset it to NULL */
   7255 static void cstr_free(CString *cstr)
   7256 {
   7257     tcc_free(cstr->data_allocated);
   7258     cstr_new(cstr);
   7259 }
   7260 
   7261 #define cstr_reset(cstr) cstr_free(cstr)
   7262 
   7263 /* XXX: unicode ? */
   7264 static void add_char(CString *cstr, int c)
   7265 {
   7266     if (c == '\'' || c == '\"' || c == '\\') {
   7267         /* XXX: could be more precise if char or string */
   7268         cstr_ccat(cstr, '\\');
   7269     }
   7270     if (c >= 32 && c <= 126) {
   7271         cstr_ccat(cstr, c);
   7272     } else {
   7273         cstr_ccat(cstr, '\\');
   7274         if (c == '\n') {
   7275             cstr_ccat(cstr, 'n');
   7276         } else {
   7277             cstr_ccat(cstr, '0' + ((c >> 6) & 7));
   7278             cstr_ccat(cstr, '0' + ((c >> 3) & 7));
   7279             cstr_ccat(cstr, '0' + (c & 7));
   7280         }
   7281     }
   7282 }
   7283 
   7284 /* XXX: buffer overflow */
   7285 /* XXX: float tokens */
   7286 char *get_tok_str(int v, CValue *cv)
   7287 {
   7288     static char buf[STRING_MAX_SIZE + 1];
   7289     static CString cstr_buf;
   7290     CString *cstr;
   7291     unsigned char *q;
   7292     char *p;
   7293     int i, len;
   7294 
   7295     /* NOTE: to go faster, we give a fixed buffer for small strings */
   7296     cstr_reset(&cstr_buf);
   7297     cstr_buf.data = buf;
   7298     cstr_buf.size_allocated = sizeof(buf);
   7299     p = buf;
   7300 
   7301     switch(v) {
   7302     case TOK_CINT:
   7303     case TOK_CUINT:
   7304         /* XXX: not quite exact, but only useful for testing */
   7305         sprintf(p, "%u", cv->ui);
   7306         break;
   7307     case TOK_CLLONG:
   7308     case TOK_CULLONG:
   7309         /* XXX: not quite exact, but only useful for testing  */
   7310         sprintf(p, "%llu", cv->ull);
   7311         break;
   7312     case TOK_CCHAR:
   7313     case TOK_LCHAR:
   7314         cstr_ccat(&cstr_buf, '\'');
   7315         add_char(&cstr_buf, cv->i);
   7316         cstr_ccat(&cstr_buf, '\'');
   7317         cstr_ccat(&cstr_buf, '\0');
   7318         break;
   7319     case TOK_PPNUM:
   7320         cstr = cv->cstr;
   7321         len = cstr->size - 1;
   7322         for(i=0;i<len;i++)
   7323             add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
   7324         cstr_ccat(&cstr_buf, '\0');
   7325         break;
   7326     case TOK_STR:
   7327     case TOK_LSTR:
   7328         cstr = cv->cstr;
   7329         cstr_ccat(&cstr_buf, '\"');
   7330         if (v == TOK_STR) {
   7331             len = cstr->size - 1;
   7332             for(i=0;i<len;i++)
   7333                 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
   7334         } else {
   7335             len = (cstr->size / sizeof(int)) - 1;
   7336             for(i=0;i<len;i++)
   7337                 add_char(&cstr_buf, ((int *)cstr->data)[i]);
   7338         }
   7339         cstr_ccat(&cstr_buf, '\"');
   7340         cstr_ccat(&cstr_buf, '\0');
   7341         break;
   7342     case TOK_LT:
   7343         v = '<';
   7344         goto addv;
   7345     case TOK_GT:
   7346         v = '>';
   7347         goto addv;
   7348     case TOK_A_SHL:
   7349         return strcpy(p, "<<=");
   7350     case TOK_A_SAR:
   7351         return strcpy(p, ">>=");
   7352     default:
   7353         if (v < TOK_IDENT) {
   7354             /* search in two bytes table */
   7355             q = tok_two_chars;
   7356             while (*q) {
   7357                 if (q[2] == v) {
   7358                     *p++ = q[0];
   7359                     *p++ = q[1];
   7360                     *p = '\0';
   7361                     return buf;
   7362                 }
   7363                 q += 3;
   7364             }
   7365         addv:
   7366             *p++ = v;
   7367             *p = '\0';
   7368         } else if (v < tok_ident) {
   7369             return table_ident[v - TOK_IDENT]->str;
   7370         } else if (v >= SYM_FIRST_ANOM) {
   7371             /* special name for anonymous symbol */
   7372             sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
   7373         } else {
   7374             /* should never happen */
   7375             return NULL;
   7376         }
   7377         break;
   7378     }
   7379     return cstr_buf.data;
   7380 }
   7381 
   7382 /* push, without hashing */
   7383 static Sym *sym_push2(Sym **ps, long v, long t, long c)
   7384 {
   7385     Sym *s;
   7386     s = sym_malloc();
   7387     s->v = v;
   7388     s->type.t = t;
   7389     s->c = c;
   7390     s->next = NULL;
   7391     /* add in stack */
   7392     s->prev = *ps;
   7393     *ps = s;
   7394     return s;
   7395 }
   7396 
   7397 /* find a symbol and return its associated structure. 's' is the top
   7398    of the symbol stack */
   7399 static Sym *sym_find2(Sym *s, int v)
   7400 {
   7401     while (s) {
   7402         if (s->v == v)
   7403             return s;
   7404         s = s->prev;
   7405     }
   7406     return NULL;
   7407 }
   7408 
   7409 /* structure lookup */
   7410 static inline Sym *struct_find(int v)
   7411 {
   7412     v -= TOK_IDENT;
   7413     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
   7414         return NULL;
   7415     return table_ident[v]->sym_struct;
   7416 }
   7417 
   7418 /* find an identifier */
   7419 static inline Sym *sym_find(int v)
   7420 {
   7421     v -= TOK_IDENT;
   7422     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
   7423         return NULL;
   7424     return table_ident[v]->sym_identifier;
   7425 }
   7426 
   7427 /* push a given symbol on the symbol stack */
   7428 static Sym *sym_push(int v, CType *type, int r, int c)
   7429 {
   7430     Sym *s, **ps;
   7431     TokenSym *ts;
   7432 
   7433     if (local_stack)
   7434         ps = &local_stack;
   7435     else
   7436         ps = &global_stack;
   7437     s = sym_push2(ps, v, type->t, c);
   7438     s->type.ref = type->ref;
   7439     s->r = r;
   7440     /* don't record fields or anonymous symbols */
   7441     /* XXX: simplify */
   7442     if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
   7443         /* record symbol in token array */
   7444         ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
   7445         if (v & SYM_STRUCT)
   7446             ps = &ts->sym_struct;
   7447         else
   7448             ps = &ts->sym_identifier;
   7449         s->prev_tok = *ps;
   7450         *ps = s;
   7451     }
   7452     return s;
   7453 }
   7454 
   7455 /* push a global identifier */
   7456 static Sym *global_identifier_push(int v, int t, int c)
   7457 {
   7458     Sym *s, **ps;
   7459     s = sym_push2(&global_stack, v, t, c);
   7460     /* don't record anonymous symbol */
   7461     if (v < SYM_FIRST_ANOM) {
   7462         ps = &table_ident[v - TOK_IDENT]->sym_identifier;
   7463         /* modify the top most local identifier, so that
   7464            sym_identifier will point to 's' when popped */
   7465         while (*ps != NULL)
   7466             ps = &(*ps)->prev_tok;
   7467         s->prev_tok = NULL;
   7468         *ps = s;
   7469     }
   7470     return s;
   7471 }
   7472 
   7473 /* pop symbols until top reaches 'b' */
   7474 static void sym_pop(Sym **ptop, Sym *b)
   7475 {
   7476     Sym *s, *ss, **ps;
   7477     TokenSym *ts;
   7478     int v;
   7479 
   7480     s = *ptop;
   7481     while(s != b) {
   7482         ss = s->prev;
   7483         v = s->v;
   7484         /* remove symbol in token array */
   7485         /* XXX: simplify */
   7486         if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
   7487             ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
   7488             if (v & SYM_STRUCT)
   7489                 ps = &ts->sym_struct;
   7490             else
   7491                 ps = &ts->sym_identifier;
   7492             *ps = s->prev_tok;
   7493         }
   7494         sym_free(s);
   7495         s = ss;
   7496     }
   7497     *ptop = b;
   7498 }
   7499 
   7500 /* I/O layer */
   7501 
   7502 BufferedFile *tcc_open(TCCState *s1, const char *filename)
   7503 {
   7504     int fd;
   7505     BufferedFile *bf;
   7506 
   7507     fd = open(filename, O_RDONLY | O_BINARY);
   7508     if (fd < 0)
   7509         return NULL;
   7510     bf = tcc_malloc(sizeof(BufferedFile));
   7511     if (!bf) {
   7512         close(fd);
   7513         return NULL;
   7514     }
   7515     bf->fd = fd;
   7516     bf->buf_ptr = bf->buffer;
   7517     bf->buf_end = bf->buffer;
   7518     bf->buffer[0] = CH_EOB; /* put eob symbol */
   7519     pstrcpy(bf->filename, sizeof(bf->filename), filename);
   7520     bf->line_num = 1;
   7521     bf->ifndef_macro = 0;
   7522     bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
   7523     //    printf("opening '%s'\n", filename);
   7524     return bf;
   7525 }
   7526 
   7527 void tcc_close(BufferedFile *bf)
   7528 {
   7529     total_lines += bf->line_num;
   7530     close(bf->fd);
   7531     tcc_free(bf);
   7532 }
   7533 
   7534 /* fill input buffer and peek next char */
   7535 static int tcc_peekc_slow(BufferedFile *bf)
   7536 {
   7537     int len;
   7538     /* only tries to read if really end of buffer */
   7539     if (bf->buf_ptr >= bf->buf_end) {
   7540         if (bf->fd != -1) {
   7541 #if defined(PARSE_DEBUG)
   7542             len = 8;
   7543 #else
   7544             len = IO_BUF_SIZE;
   7545 #endif
   7546             len = read(bf->fd, bf->buffer, len);
   7547             if (len < 0)
   7548                 len = 0;
   7549         } else {
   7550             len = 0;
   7551         }
   7552         total_bytes += len;
   7553         bf->buf_ptr = bf->buffer;
   7554         bf->buf_end = bf->buffer + len;
   7555         *bf->buf_end = CH_EOB;
   7556     }
   7557     if (bf->buf_ptr < bf->buf_end) {
   7558         return bf->buf_ptr[0];
   7559     } else {
   7560         bf->buf_ptr = bf->buf_end;
   7561         return CH_EOF;
   7562     }
   7563 }
   7564 
   7565 /* return the current character, handling end of block if necessary
   7566    (but not stray) */
   7567 static int handle_eob(void)
   7568 {
   7569     return tcc_peekc_slow(file);
   7570 }
   7571 
   7572 /* read next char from current input file and handle end of input buffer */
   7573 static inline void inp(void)
   7574 {
   7575     ch = *(++(file->buf_ptr));
   7576     /* end of buffer/file handling */
   7577     if (ch == CH_EOB)
   7578         ch = handle_eob();
   7579 }
   7580 
   7581 /* handle '\[\r]\n' */
   7582 static void handle_stray(void)
   7583 {
   7584     while (ch == '\\') {
   7585         inp();
   7586         if (ch == '\n') {
   7587             file->line_num++;
   7588             inp();
   7589         } else if (ch == '\r') {
   7590             inp();
   7591             if (ch != '\n')
   7592                 goto fail;
   7593             file->line_num++;
   7594             inp();
   7595         } else {
   7596         fail:
   7597             error("stray '\\' in program");
   7598         }
   7599     }
   7600 }
   7601 
   7602 /* skip the stray and handle the \\n case. Output an error if
   7603    incorrect char after the stray */
   7604 static int handle_stray1(uint8_t *p)
   7605 {
   7606     int c;
   7607 
   7608     if (p >= file->buf_end) {
   7609         file->buf_ptr = p;
   7610         c = handle_eob();
   7611         p = file->buf_ptr;
   7612         if (c == '\\')
   7613             goto parse_stray;
   7614     } else {
   7615     parse_stray:
   7616         file->buf_ptr = p;
   7617         ch = *p;
   7618         handle_stray();
   7619         p = file->buf_ptr;
   7620         c = *p;
   7621     }
   7622     return c;
   7623 }
   7624 
   7625 /* handle just the EOB case, but not stray */
   7626 #define PEEKC_EOB(c, p)\
   7627 {\
   7628     p++;\
   7629     c = *p;\
   7630     if (c == '\\') {\
   7631         file->buf_ptr = p;\
   7632         c = handle_eob();\
   7633         p = file->buf_ptr;\
   7634     }\
   7635 }
   7636 
   7637 /* handle the complicated stray case */
   7638 #define PEEKC(c, p)\
   7639 {\
   7640     p++;\
   7641     c = *p;\
   7642     if (c == '\\') {\
   7643         c = handle_stray1(p);\
   7644         p = file->buf_ptr;\
   7645     }\
   7646 }
   7647 
   7648 /* input with '\[\r]\n' handling. Note that this function cannot
   7649    handle other characters after '\', so you cannot call it inside
   7650    strings or comments */
   7651 static void minp(void)
   7652 {
   7653     inp();
   7654     if (ch == '\\')
   7655         handle_stray();
   7656 }
   7657 
   7658 
   7659 /* single line C++ comments */
   7660 static uint8_t *parse_line_comment(uint8_t *p)
   7661 {
   7662     int c;
   7663 
   7664     p++;
   7665     for(;;) {
   7666         c = *p;
   7667     redo:
   7668         if (c == '\n' || c == CH_EOF) {
   7669             break;
   7670         } else if (c == '\\') {
   7671             file->buf_ptr = p;
   7672             c = handle_eob();
   7673             p = file->buf_ptr;
   7674             if (c == '\\') {
   7675                 PEEKC_EOB(c, p);
   7676                 if (c == '\n') {
   7677                     file->line_num++;
   7678                     PEEKC_EOB(c, p);
   7679                 } else if (c == '\r') {
   7680                     PEEKC_EOB(c, p);
   7681                     if (c == '\n') {
   7682                         file->line_num++;
   7683                         PEEKC_EOB(c, p);
   7684                     }
   7685                 }
   7686             } else {
   7687                 goto redo;
   7688             }
   7689         } else {
   7690             p++;
   7691         }
   7692     }
   7693     return p;
   7694 }
   7695 
   7696 /* C comments */
   7697 static uint8_t *parse_comment(uint8_t *p)
   7698 {
   7699     int c;
   7700 
   7701     p++;
   7702     for(;;) {
   7703         /* fast skip loop */
   7704         for(;;) {
   7705             c = *p;
   7706             if (c == '\n' || c == '*' || c == '\\')
   7707                 break;
   7708             p++;
   7709             c = *p;
   7710             if (c == '\n' || c == '*' || c == '\\')
   7711                 break;
   7712             p++;
   7713         }
   7714         /* now we can handle all the cases */
   7715         if (c == '\n') {
   7716             file->line_num++;
   7717             p++;
   7718         } else if (c == '*') {
   7719             p++;
   7720             for(;;) {
   7721                 c = *p;
   7722                 if (c == '*') {
   7723                     p++;
   7724                 } else if (c == '/') {
   7725                     goto end_of_comment;
   7726                 } else if (c == '\\') {
   7727                     file->buf_ptr = p;
   7728                     c = handle_eob();
   7729                     p = file->buf_ptr;
   7730                     if (c == '\\') {
   7731                         /* skip '\[\r]\n', otherwise just skip the stray */
   7732                         while (c == '\\') {
   7733                             PEEKC_EOB(c, p);
   7734                             if (c == '\n') {
   7735                                 file->line_num++;
   7736                                 PEEKC_EOB(c, p);
   7737                             } else if (c == '\r') {
   7738                                 PEEKC_EOB(c, p);
   7739                                 if (c == '\n') {
   7740                                     file->line_num++;
   7741                                     PEEKC_EOB(c, p);
   7742                                 }
   7743                             } else {
   7744                                 goto after_star;
   7745                             }
   7746                         }
   7747                     }
   7748                 } else {
   7749                     break;
   7750                 }
   7751             }
   7752         after_star: ;
   7753         } else {
   7754             /* stray, eob or eof */
   7755             file->buf_ptr = p;
   7756             c = handle_eob();
   7757             p = file->buf_ptr;
   7758             if (c == CH_EOF) {
   7759                 error("unexpected end of file in comment");
   7760             } else if (c == '\\') {
   7761                 p++;
   7762             }
   7763         }
   7764     }
   7765  end_of_comment:
   7766     p++;
   7767     return p;
   7768 }
   7769 
   7770 #define cinp minp
   7771 
   7772 /* space exlcuding newline */
   7773 static inline int is_space(int ch)
   7774 {
   7775     return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
   7776 }
   7777 
   7778 static inline void skip_spaces(void)
   7779 {
   7780     while (is_space(ch))
   7781         cinp();
   7782 }
   7783 
   7784 /* parse a string without interpreting escapes */
   7785 static uint8_t *parse_pp_string(uint8_t *p,
   7786                                 int sep, CString *str)
   7787 {
   7788     int c;
   7789     p++;
   7790     for(;;) {
   7791         c = *p;
   7792         if (c == sep) {
   7793             break;
   7794         } else if (c == '\\') {
   7795             file->buf_ptr = p;
   7796             c = handle_eob();
   7797             p = file->buf_ptr;
   7798             if (c == CH_EOF) {
   7799             unterminated_string:
   7800                 /* XXX: indicate line number of start of string */
   7801                 error("missing terminating %c character", sep);
   7802             } else if (c == '\\') {
   7803                 /* escape : just skip \[\r]\n */
   7804                 PEEKC_EOB(c, p);
   7805                 if (c == '\n') {
   7806                     file->line_num++;
   7807                     p++;
   7808                 } else if (c == '\r') {
   7809                     PEEKC_EOB(c, p);
   7810                     if (c != '\n')
   7811                         expect("'\n' after '\r'");
   7812                     file->line_num++;
   7813                     p++;
   7814                 } else if (c == CH_EOF) {
   7815                     goto unterminated_string;
   7816                 } else {
   7817                     if (str) {
   7818                         cstr_ccat(str, '\\');
   7819                         cstr_ccat(str, c);
   7820                     }
   7821                     p++;
   7822                 }
   7823             }
   7824         } else if (c == '\n') {
   7825             file->line_num++;
   7826             goto add_char;
   7827         } else if (c == '\r') {
   7828             PEEKC_EOB(c, p);
   7829             if (c != '\n') {
   7830                 if (str)
   7831                     cstr_ccat(str, '\r');
   7832             } else {
   7833                 file->line_num++;
   7834                 goto add_char;
   7835             }
   7836         } else {
   7837         add_char:
   7838             if (str)
   7839                 cstr_ccat(str, c);
   7840             p++;
   7841         }
   7842     }
   7843     p++;
   7844     return p;
   7845 }
   7846 
   7847 /* skip block of text until #else, #elif or #endif. skip also pairs of
   7848    #if/#endif */
   7849 void preprocess_skip(void)
   7850 {
   7851     int a, start_of_line, c;
   7852     uint8_t *p;
   7853 
   7854     p = file->buf_ptr;
   7855     start_of_line = 1;
   7856     a = 0;
   7857     for(;;) {
   7858     redo_no_start:
   7859         c = *p;
   7860         switch(c) {
   7861         case ' ':
   7862         case '\t':
   7863         case '\f':
   7864         case '\v':
   7865         case '\r':
   7866             p++;
   7867             goto redo_no_start;
   7868         case '\n':
   7869             start_of_line = 1;
   7870             file->line_num++;
   7871             p++;
   7872             goto redo_no_start;
   7873         case '\\':
   7874             file->buf_ptr = p;
   7875             c = handle_eob();
   7876             if (c == CH_EOF) {
   7877                 expect("#endif");
   7878             } else if (c == '\\') {
   7879                 /* XXX: incorrect: should not give an error */
   7880                 ch = file->buf_ptr[0];
   7881                 handle_stray();
   7882             }
   7883             p = file->buf_ptr;
   7884             goto redo_no_start;
   7885             /* skip strings */
   7886         case '\"':
   7887         case '\'':
   7888             p = parse_pp_string(p, c, NULL);
   7889             break;
   7890             /* skip comments */
   7891         case '/':
   7892             file->buf_ptr = p;
   7893             ch = *p;
   7894             minp();
   7895             p = file->buf_ptr;
   7896             if (ch == '*') {
   7897                 p = parse_comment(p);
   7898             } else if (ch == '/') {
   7899                 p = parse_line_comment(p);
   7900             }
   7901             break;
   7902 
   7903         case '#':
   7904             p++;
   7905             if (start_of_line) {
   7906                 file->buf_ptr = p;
   7907                 next_nomacro();
   7908                 p = file->buf_ptr;
   7909                 if (a == 0 &&
   7910                     (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
   7911                     goto the_end;
   7912                 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
   7913                     a++;
   7914                 else if (tok == TOK_ENDIF)
   7915                     a--;
   7916             }
   7917             break;
   7918         default:
   7919             p++;
   7920             break;
   7921         }
   7922         start_of_line = 0;
   7923     }
   7924  the_end: ;
   7925     file->buf_ptr = p;
   7926 }
   7927 
   7928 /* ParseState handling */
   7929 
   7930 /* XXX: currently, no include file info is stored. Thus, we cannot display
   7931    accurate messages if the function or data definition spans multiple
   7932    files */
   7933 
   7934 /* save current parse state in 's' */
   7935 void save_parse_state(ParseState *s)
   7936 {
   7937     s->line_num = file->line_num;
   7938     s->macro_ptr = macro_ptr;
   7939     s->tok = tok;
   7940     s->tokc = tokc;
   7941 }
   7942 
   7943 /* restore parse state from 's' */
   7944 void restore_parse_state(ParseState *s)
   7945 {
   7946     file->line_num = s->line_num;
   7947     macro_ptr = s->macro_ptr;
   7948     tok = s->tok;
   7949     tokc = s->tokc;
   7950 }
   7951 
   7952 /* return the number of additional 'ints' necessary to store the
   7953    token */
   7954 static inline int tok_ext_size(int t)
   7955 {
   7956     switch(t) {
   7957         /* 4 bytes */
   7958     case TOK_CINT:
   7959     case TOK_CUINT:
   7960     case TOK_CCHAR:
   7961     case TOK_LCHAR:
   7962     case TOK_CFLOAT:
   7963     case TOK_LINENUM:
   7964         return 1;
   7965     case TOK_STR:
   7966     case TOK_LSTR:
   7967     case TOK_PPNUM:
   7968         error("unsupported token");
   7969         return 1;
   7970     case TOK_CDOUBLE:
   7971     case TOK_CLLONG:
   7972     case TOK_CULLONG:
   7973         return 2;
   7974     case TOK_CLDOUBLE:
   7975         return LDOUBLE_SIZE / 4;
   7976     default:
   7977         return 0;
   7978     }
   7979 }
   7980 
   7981 /* token string handling */
   7982 
   7983 static inline void tok_str_new(TokenString *s)
   7984 {
   7985     s->str = NULL;
   7986     s->len = 0;
   7987     s->allocated_len = 0;
   7988     s->last_line_num = -1;
   7989 }
   7990 
   7991 static void tok_str_free(int *str)
   7992 {
   7993     tcc_free(str);
   7994 }
   7995 
   7996 static int *tok_str_realloc(TokenString *s)
   7997 {
   7998     int *str, len;
   7999 
   8000     if (s->allocated_len == 0) {
   8001         len = 8;
   8002     } else {
   8003         len = s->allocated_len * 2;
   8004     }
   8005     str = tcc_realloc(s->str, len * sizeof(int));
   8006     if (!str)
   8007         error("memory full");
   8008     s->allocated_len = len;
   8009     s->str = str;
   8010     return str;
   8011 }
   8012 
   8013 static void tok_str_add(TokenString *s, int t)
   8014 {
   8015     int len, *str;
   8016 
   8017     len = s->len;
   8018     str = s->str;
   8019     if (len >= s->allocated_len)
   8020         str = tok_str_realloc(s);
   8021     str[len++] = t;
   8022     s->len = len;
   8023 }
   8024 
   8025 static void tok_str_add2(TokenString *s, int t, CValue *cv)
   8026 {
   8027     int len, *str;
   8028 
   8029     len = s->len;
   8030     str = s->str;
   8031 
   8032     /* allocate space for worst case */
   8033     if (len + TOK_MAX_SIZE > s->allocated_len)
   8034         str = tok_str_realloc(s);
   8035     str[len++] = t;
   8036     switch(t) {
   8037     case TOK_CINT:
   8038     case TOK_CUINT:
   8039     case TOK_CCHAR:
   8040     case TOK_LCHAR:
   8041     case TOK_CFLOAT:
   8042     case TOK_LINENUM:
   8043         str[len++] = cv->tab[0];
   8044         break;
   8045     case TOK_PPNUM:
   8046     case TOK_STR:
   8047     case TOK_LSTR:
   8048         {
   8049             int nb_words;
   8050             CString *cstr;
   8051 
   8052             nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
   8053             while ((len + nb_words) > s->allocated_len)
   8054                 str = tok_str_realloc(s);
   8055             cstr = (CString *)(str + len);
   8056             cstr->data = NULL;
   8057             cstr->size = cv->cstr->size;
   8058             cstr->data_allocated = NULL;
   8059             cstr->size_allocated = cstr->size;
   8060             memcpy((char *)cstr + sizeof(CString),
   8061                    cv->cstr->data, cstr->size);
   8062             len += nb_words;
   8063         }
   8064         break;
   8065     case TOK_CDOUBLE:
   8066     case TOK_CLLONG:
   8067     case TOK_CULLONG:
   8068 #if LDOUBLE_SIZE == 8
   8069     case TOK_CLDOUBLE:
   8070 #endif
   8071         str[len++] = cv->tab[0];
   8072         str[len++] = cv->tab[1];
   8073         break;
   8074 #if LDOUBLE_SIZE == 12
   8075     case TOK_CLDOUBLE:
   8076         str[len++] = cv->tab[0];
   8077         str[len++] = cv->tab[1];
   8078         str[len++] = cv->tab[2];
   8079 #elif LDOUBLE_SIZE != 8
   8080 #error add long double size support
   8081 #endif
   8082         break;
   8083     default:
   8084         break;
   8085     }
   8086     s->len = len;
   8087 }
   8088 
   8089 /* add the current parse token in token string 's' */
   8090 static void tok_str_add_tok(TokenString *s)
   8091 {
   8092     CValue cval;
   8093 
   8094     /* save line number info */
   8095     if (file->line_num != s->last_line_num) {
   8096         s->last_line_num = file->line_num;
   8097         cval.i = s->last_line_num;
   8098         tok_str_add2(s, TOK_LINENUM, &cval);
   8099     }
   8100     tok_str_add2(s, tok, &tokc);
   8101 }
   8102 
   8103 #if LDOUBLE_SIZE == 12
   8104 #define LDOUBLE_GET(p, cv)                      \
   8105         cv.tab[0] = p[0];                       \
   8106         cv.tab[1] = p[1];                       \
   8107         cv.tab[2] = p[2];
   8108 #elif LDOUBLE_SIZE == 8
   8109 #define LDOUBLE_GET(p, cv)                      \
   8110         cv.tab[0] = p[0];                       \
   8111         cv.tab[1] = p[1];
   8112 #else
   8113 #error add long double size support
   8114 #endif
   8115 
   8116 
   8117 /* get a token from an integer array and increment pointer
   8118    accordingly. we code it as a macro to avoid pointer aliasing. */
   8119 #define TOK_GET(t, p, cv)                       \
   8120 {                                               \
   8121     t = *p++;                                   \
   8122     switch(t) {                                 \
   8123     case TOK_CINT:                              \
   8124     case TOK_CUINT:                             \
   8125     case TOK_CCHAR:                             \
   8126     case TOK_LCHAR:                             \
   8127     case TOK_CFLOAT:                            \
   8128     case TOK_LINENUM:                           \
   8129         cv.tab[0] = *p++;                       \
   8130         break;                                  \
   8131     case TOK_STR:                               \
   8132     case TOK_LSTR:                              \
   8133     case TOK_PPNUM:                             \
   8134         cv.cstr = (CString *)p;                 \
   8135         cv.cstr->data = (char *)p + sizeof(CString);\
   8136         p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
   8137         break;                                  \
   8138     case TOK_CDOUBLE:                           \
   8139     case TOK_CLLONG:                            \
   8140     case TOK_CULLONG:                           \
   8141         cv.tab[0] = p[0];                       \
   8142         cv.tab[1] = p[1];                       \
   8143         p += 2;                                 \
   8144         break;                                  \
   8145     case TOK_CLDOUBLE:                          \
   8146         LDOUBLE_GET(p, cv);                     \
   8147         p += LDOUBLE_SIZE / 4;                  \
   8148         break;                                  \
   8149     default:                                    \
   8150         break;                                  \
   8151     }                                           \
   8152 }
   8153 
   8154 /* defines handling */
   8155 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
   8156 {
   8157     Sym *s;
   8158 
   8159     s = sym_push2(&define_stack, v, macro_type, (long)str);
   8160     s->next = first_arg;
   8161     table_ident[v - TOK_IDENT]->sym_define = s;
   8162 }
   8163 
   8164 /* undefined a define symbol. Its name is just set to zero */
   8165 static void define_undef(Sym *s)
   8166 {
   8167     int v;
   8168     v = s->v;
   8169     if (v >= TOK_IDENT && v < tok_ident)
   8170         table_ident[v - TOK_IDENT]->sym_define = NULL;
   8171     s->v = 0;
   8172 }
   8173 
   8174 static inline Sym *define_find(int v)
   8175 {
   8176     v -= TOK_IDENT;
   8177     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
   8178         return NULL;
   8179     return table_ident[v]->sym_define;
   8180 }
   8181 
   8182 /* free define stack until top reaches 'b' */
   8183 static void free_defines(Sym *b)
   8184 {
   8185     Sym *top, *top1;
   8186     int v;
   8187 
   8188     top = define_stack;
   8189     while (top != b) {
   8190         top1 = top->prev;
   8191         /* do not free args or predefined defines */
   8192         if (top->c)
   8193             tok_str_free((int *)top->c);
   8194         v = top->v;
   8195         if (v >= TOK_IDENT && v < tok_ident)
   8196             table_ident[v - TOK_IDENT]->sym_define = NULL;
   8197         sym_free(top);
   8198         top = top1;
   8199     }
   8200     define_stack = b;
   8201 }
   8202 
   8203 /* label lookup */
   8204 static Sym *label_find(int v)
   8205 {
   8206     v -= TOK_IDENT;
   8207     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
   8208         return NULL;
   8209     return table_ident[v]->sym_label;
   8210 }
   8211 
   8212 static Sym *label_push(Sym **ptop, int v, int flags)
   8213 {
   8214     Sym *s, **ps;
   8215     s = sym_push2(ptop, v, 0, 0);
   8216     s->r = flags;
   8217     ps = &table_ident[v - TOK_IDENT]->sym_label;
   8218     if (ptop == &global_label_stack) {
   8219         /* modify the top most local identifier, so that
   8220            sym_identifier will point to 's' when popped */
   8221         while (*ps != NULL)
   8222             ps = &(*ps)->prev_tok;
   8223     }
   8224     s->prev_tok = *ps;
   8225     *ps = s;
   8226     return s;
   8227 }
   8228 
   8229 /* pop labels until element last is reached. Look if any labels are
   8230    undefined. Define symbols if '&&label' was used. */
   8231 static void label_pop(Sym **ptop, Sym *slast)
   8232 {
   8233     Sym *s, *s1;
   8234     for(s = *ptop; s != slast; s = s1) {
   8235         s1 = s->prev;
   8236         if (s->r == LABEL_DECLARED) {
   8237             warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
   8238         } else if (s->r == LABEL_FORWARD) {
   8239                 error("label '%s' used but not defined",
   8240                       get_tok_str(s->v, NULL));
   8241         } else {
   8242             if (s->c) {
   8243                 /* define corresponding symbol. A size of
   8244                    1 is put. */
   8245                 put_extern_sym(s, cur_text_section, (long)s->next, 1);
   8246             }
   8247         }
   8248         /* remove label */
   8249         table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
   8250         sym_free(s);
   8251     }
   8252     *ptop = slast;
   8253 }
   8254 
   8255 /* eval an expression for #if/#elif */
   8256 static int expr_preprocess(void)
   8257 {
   8258     int c, t;
   8259     TokenString str;
   8260 
   8261     tok_str_new(&str);
   8262     while (tok != TOK_LINEFEED && tok != TOK_EOF) {
   8263         next(); /* do macro subst */
   8264         if (tok == TOK_DEFINED) {
   8265             next_nomacro();
   8266             t = tok;
   8267             if (t == '(')
   8268                 next_nomacro();
   8269             c = define_find(tok) != 0;
   8270             if (t == '(')
   8271                 next_nomacro();
   8272             tok = TOK_CINT;
   8273             tokc.i = c;
   8274         } else if (tok >= TOK_IDENT) {
   8275             /* if undefined macro */
   8276             tok = TOK_CINT;
   8277             tokc.i = 0;
   8278         }
   8279         tok_str_add_tok(&str);
   8280     }
   8281     tok_str_add(&str, -1); /* simulate end of file */
   8282     tok_str_add(&str, 0);
   8283     /* now evaluate C constant expression */
   8284     macro_ptr = str.str;
   8285     next();
   8286     c = expr_const();
   8287     macro_ptr = NULL;
   8288     tok_str_free(str.str);
   8289     return c != 0;
   8290 }
   8291 
   8292 #if defined(PARSE_DEBUG) || defined(PP_DEBUG)
   8293 static void tok_print(int *str)
   8294 {
   8295     int t;
   8296     CValue cval;
   8297 
   8298     while (1) {
   8299         TOK_GET(t, str, cval);
   8300         if (!t)
   8301             break;
   8302         printf(" %s", get_tok_str(t, &cval));
   8303     }
   8304     printf("\n");
   8305 }
   8306 #endif
   8307 
   8308 /* parse after #define */
   8309 static void parse_define(void)
   8310 {
   8311     Sym *s, *first, **ps;
   8312     int v, t, varg, is_vaargs, c;
   8313     TokenString str;
   8314 
   8315     v = tok;
   8316     if (v < TOK_IDENT)
   8317         error("invalid macro name '%s'", get_tok_str(tok, &tokc));
   8318     /* XXX: should check if same macro (ANSI) */
   8319     first = NULL;
   8320     t = MACRO_OBJ;
   8321     /* '(' must be just after macro definition for MACRO_FUNC */
   8322     c = file->buf_ptr[0];
   8323     if (c == '\\')
   8324         c = handle_stray1(file->buf_ptr);
   8325     if (c == '(') {
   8326         next_nomacro();
   8327         next_nomacro();
   8328         ps = &first;
   8329         while (tok != ')') {
   8330             varg = tok;
   8331             next_nomacro();
   8332             is_vaargs = 0;
   8333             if (varg == TOK_DOTS) {
   8334                 varg = TOK___VA_ARGS__;
   8335                 is_vaargs = 1;
   8336             } else if (tok == TOK_DOTS && gnu_ext) {
   8337                 is_vaargs = 1;
   8338                 next_nomacro();
   8339             }
   8340             if (varg < TOK_IDENT)
   8341                 error("badly punctuated parameter list");
   8342             s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
   8343             *ps = s;
   8344             ps = &s->next;
   8345             if (tok != ',')
   8346                 break;
   8347             next_nomacro();
   8348         }
   8349         t = MACRO_FUNC;
   8350     }
   8351     tok_str_new(&str);
   8352     next_nomacro();
   8353     /* EOF testing necessary for '-D' handling */
   8354     while (tok != TOK_LINEFEED && tok != TOK_EOF) {
   8355         tok_str_add2(&str, tok, &tokc);
   8356         next_nomacro();
   8357     }
   8358     tok_str_add(&str, 0);
   8359 #ifdef PP_DEBUG
   8360     printf("define %s %d: ", get_tok_str(v, NULL), t);
   8361     tok_print(str.str);
   8362 #endif
   8363     define_push(v, t, str.str, first);
   8364 }
   8365 
   8366 static inline int hash_cached_include(int type, const char *filename)
   8367 {
   8368     const unsigned char *s;
   8369     unsigned int h;
   8370 
   8371     h = TOK_HASH_INIT;
   8372     h = TOK_HASH_FUNC(h, type);
   8373     s = filename;
   8374     while (*s) {
   8375         h = TOK_HASH_FUNC(h, *s);
   8376         s++;
   8377     }
   8378     h &= (CACHED_INCLUDES_HASH_SIZE - 1);
   8379     return h;
   8380 }
   8381 
   8382 /* XXX: use a token or a hash table to accelerate matching ? */
   8383 static CachedInclude *search_cached_include(TCCState *s1,
   8384                                             int type, const char *filename)
   8385 {
   8386     CachedInclude *e;
   8387     int i, h;
   8388     h = hash_cached_include(type, filename);
   8389     i = s1->cached_includes_hash[h];
   8390     for(;;) {
   8391         if (i == 0)
   8392             break;
   8393         e = s1->cached_includes[i - 1];
   8394         if (e->type == type && !strcmp(e->filename, filename))
   8395             return e;
   8396         i = e->hash_next;
   8397     }
   8398     return NULL;
   8399 }
   8400 
   8401 static inline void add_cached_include(TCCState *s1, int type,
   8402                                       const char *filename, int ifndef_macro)
   8403 {
   8404     CachedInclude *e;
   8405     int h;
   8406 
   8407     if (search_cached_include(s1, type, filename))
   8408         return;
   8409 #ifdef INC_DEBUG
   8410     printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
   8411 #endif
   8412     e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
   8413     if (!e)
   8414         return;
   8415     e->type = type;
   8416     strcpy(e->filename, filename);
   8417     e->ifndef_macro = ifndef_macro;
   8418     dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
   8419     /* add in hash table */
   8420     h = hash_cached_include(type, filename);
   8421     e->hash_next = s1->cached_includes_hash[h];
   8422     s1->cached_includes_hash[h] = s1->nb_cached_includes;
   8423 }
   8424 
   8425 static void pragma_parse(TCCState *s1)
   8426 {
   8427     int val;
   8428 
   8429     next();
   8430     if (tok == TOK_pack) {
   8431         /*
   8432           This may be:
   8433           #pragma pack(1) // set
   8434           #pragma pack() // reset to default
   8435           #pragma pack(push,1) // push & set
   8436           #pragma pack(pop) // restore previous
   8437         */
   8438         next();
   8439         skip('(');
   8440         if (tok == TOK_ASM_pop) {
   8441             next();
   8442             if (s1->pack_stack_ptr <= s1->pack_stack) {
   8443             stk_error:
   8444                 error("out of pack stack");
   8445             }
   8446             s1->pack_stack_ptr--;
   8447         } else {
   8448             val = 0;
   8449             if (tok != ')') {
   8450                 if (tok == TOK_ASM_push) {
   8451                     next();
   8452                     if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
   8453                         goto stk_error;
   8454                     s1->pack_stack_ptr++;
   8455                     skip(',');
   8456                 }
   8457                 if (tok != TOK_CINT) {
   8458                 pack_error:
   8459                     error("invalid pack pragma");
   8460                 }
   8461                 val = tokc.i;
   8462                 if (val < 1 || val > 16 || (val & (val - 1)) != 0)
   8463                     goto pack_error;
   8464                 next();
   8465             }
   8466             *s1->pack_stack_ptr = val;
   8467             skip(')');
   8468         }
   8469     }
   8470 }
   8471 
   8472 /* is_bof is true if first non space token at beginning of file */
   8473 static void preprocess(int is_bof)
   8474 {
   8475     TCCState *s1 = tcc_state;
   8476     int size, i, c, n, saved_parse_flags;
   8477     char buf[1024], *q, *p;
   8478     char buf1[1024];
   8479     BufferedFile *f;
   8480     Sym *s;
   8481     CachedInclude *e;
   8482 
   8483     saved_parse_flags = parse_flags;
   8484     parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
   8485         PARSE_FLAG_LINEFEED;
   8486     next_nomacro();
   8487  redo:
   8488     switch(tok) {
   8489     case TOK_DEFINE:
   8490         next_nomacro();
   8491         parse_define();
   8492         break;
   8493     case TOK_UNDEF:
   8494         next_nomacro();
   8495         s = define_find(tok);
   8496         /* undefine symbol by putting an invalid name */
   8497         if (s)
   8498             define_undef(s);
   8499         break;
   8500     case TOK_INCLUDE:
   8501     case TOK_INCLUDE_NEXT:
   8502         ch = file->buf_ptr[0];
   8503         /* XXX: incorrect if comments : use next_nomacro with a special mode */
   8504         skip_spaces();
   8505         if (ch == '<') {
   8506             c = '>';
   8507             goto read_name;
   8508         } else if (ch == '\"') {
   8509             c = ch;
   8510         read_name:
   8511             /* XXX: better stray handling */
   8512             minp();
   8513             q = buf;
   8514             while (ch != c && ch != '\n' && ch != CH_EOF) {
   8515                 if ((q - buf) < sizeof(buf) - 1)
   8516                     *q++ = ch;
   8517                 minp();
   8518             }
   8519             *q = '\0';
   8520             minp();
   8521 #if 0
   8522             /* eat all spaces and comments after include */
   8523             /* XXX: slightly incorrect */
   8524             while (ch1 != '\n' && ch1 != CH_EOF)
   8525                 inp();
   8526 #endif
   8527         } else {
   8528             /* computed #include : either we have only strings or
   8529                we have anything enclosed in '<>' */
   8530             next();
   8531             buf[0] = '\0';
   8532             if (tok == TOK_STR) {
   8533                 while (tok != TOK_LINEFEED) {
   8534                     if (tok != TOK_STR) {
   8535                     include_syntax:
   8536                         error("'#include' expects \"FILENAME\" or <FILENAME>");
   8537                     }
   8538                     pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
   8539                     next();
   8540                 }
   8541                 c = '\"';
   8542             } else {
   8543                 int len;
   8544                 while (tok != TOK_LINEFEED) {
   8545                     pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
   8546                     next();
   8547                 }
   8548                 len = strlen(buf);
   8549                 /* check syntax and remove '<>' */
   8550                 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
   8551                     goto include_syntax;
   8552                 memmove(buf, buf + 1, len - 2);
   8553                 buf[len - 2] = '\0';
   8554                 c = '>';
   8555             }
   8556         }
   8557 
   8558         e = search_cached_include(s1, c, buf);
   8559         if (e && define_find(e->ifndef_macro)) {
   8560             /* no need to parse the include because the 'ifndef macro'
   8561                is defined */
   8562 #ifdef INC_DEBUG
   8563             printf("%s: skipping %s\n", file->filename, buf);
   8564 #endif
   8565         } else {
   8566             if (c == '\"') {
   8567                 /* first search in current dir if "header.h" */
   8568                 size = 0;
   8569                 p = strrchr(file->filename, '/');
   8570                 if (p)
   8571                     size = p + 1 - file->filename;
   8572                 if (size > sizeof(buf1) - 1)
   8573                     size = sizeof(buf1) - 1;
   8574                 memcpy(buf1, file->filename, size);
   8575                 buf1[size] = '\0';
   8576                 pstrcat(buf1, sizeof(buf1), buf);
   8577                 f = tcc_open(s1, buf1);
   8578                 if (f) {
   8579                     if (tok == TOK_INCLUDE_NEXT)
   8580                         tok = TOK_INCLUDE;
   8581                     else
   8582                         goto found;
   8583                 }
   8584             }
   8585             if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
   8586                 error("#include recursion too deep");
   8587             /* now search in all the include paths */
   8588             n = s1->nb_include_paths + s1->nb_sysinclude_paths;
   8589             for(i = 0; i < n; i++) {
   8590                 const char *path;
   8591                 if (i < s1->nb_include_paths)
   8592                     path = s1->include_paths[i];
   8593                 else
   8594                     path = s1->sysinclude_paths[i - s1->nb_include_paths];
   8595                 pstrcpy(buf1, sizeof(buf1), path);
   8596                 pstrcat(buf1, sizeof(buf1), "/");
   8597                 pstrcat(buf1, sizeof(buf1), buf);
   8598                 f = tcc_open(s1, buf1);
   8599                 if (f) {
   8600                     if (tok == TOK_INCLUDE_NEXT)
   8601                         tok = TOK_INCLUDE;
   8602                     else
   8603                         goto found;
   8604                 }
   8605             }
   8606             error("include file '%s' not found", buf);
   8607             f = NULL;
   8608         found:
   8609 #ifdef INC_DEBUG
   8610             printf("%s: including %s\n", file->filename, buf1);
   8611 #endif
   8612             f->inc_type = c;
   8613             pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
   8614             /* push current file in stack */
   8615             /* XXX: fix current line init */
   8616             *s1->include_stack_ptr++ = file;
   8617             file = f;
   8618             /* add include file debug info */
   8619             if (do_debug) {
   8620                 put_stabs(file->filename, N_BINCL, 0, 0, 0);
   8621             }
   8622             tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
   8623             ch = file->buf_ptr[0];
   8624             goto the_end;
   8625         }
   8626         break;
   8627     case TOK_IFNDEF:
   8628         c = 1;
   8629         goto do_ifdef;
   8630     case TOK_IF:
   8631         c = expr_preprocess();
   8632         goto do_if;
   8633     case TOK_IFDEF:
   8634         c = 0;
   8635     do_ifdef:
   8636         next_nomacro();
   8637         if (tok < TOK_IDENT)
   8638             error("invalid argument for '#if%sdef'", c ? "n" : "");
   8639         if (is_bof) {
   8640             if (c) {
   8641 #ifdef INC_DEBUG
   8642                 printf("#ifndef %s\n", get_tok_str(tok, NULL));
   8643 #endif
   8644                 file->ifndef_macro = tok;
   8645             }
   8646         }
   8647         c = (define_find(tok) != 0) ^ c;
   8648     do_if:
   8649         if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
   8650             error("memory full");
   8651         *s1->ifdef_stack_ptr++ = c;
   8652         goto test_skip;
   8653     case TOK_ELSE:
   8654         if (s1->ifdef_stack_ptr == s1->ifdef_stack)
   8655             error("#else without matching #if");
   8656         if (s1->ifdef_stack_ptr[-1] & 2)
   8657             error("#else after #else");
   8658         c = (s1->ifdef_stack_ptr[-1] ^= 3);
   8659         goto test_skip;
   8660     case TOK_ELIF:
   8661         if (s1->ifdef_stack_ptr == s1->ifdef_stack)
   8662             error("#elif without matching #if");
   8663         c = s1->ifdef_stack_ptr[-1];
   8664         if (c > 1)
   8665             error("#elif after #else");
   8666         /* last #if/#elif expression was true: we skip */
   8667         if (c == 1)
   8668             goto skip;
   8669         c = expr_preprocess();
   8670         s1->ifdef_stack_ptr[-1] = c;
   8671     test_skip:
   8672         if (!(c & 1)) {
   8673         skip:
   8674             preprocess_skip();
   8675             is_bof = 0;
   8676             goto redo;
   8677         }
   8678         break;
   8679     case TOK_ENDIF:
   8680         if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
   8681             error("#endif without matching #if");
   8682         s1->ifdef_stack_ptr--;
   8683         /* '#ifndef macro' was at the start of file. Now we check if
   8684            an '#endif' is exactly at the end of file */
   8685         if (file->ifndef_macro &&
   8686             s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
   8687             file->ifndef_macro_saved = file->ifndef_macro;
   8688             /* need to set to zero to avoid false matches if another
   8689                #ifndef at middle of file */
   8690             file->ifndef_macro = 0;
   8691             while (tok != TOK_LINEFEED)
   8692                 next_nomacro();
   8693             tok_flags |= TOK_FLAG_ENDIF;
   8694             goto the_end;
   8695         }
   8696         break;
   8697     case TOK_LINE:
   8698         next();
   8699         if (tok != TOK_CINT)
   8700             error("#line");
   8701         file->line_num = tokc.i - 1; /* the line number will be incremented after */
   8702         next();
   8703         if (tok != TOK_LINEFEED) {
   8704             if (tok != TOK_STR)
   8705                 error("#line");
   8706             pstrcpy(file->filename, sizeof(file->filename),
   8707                     (char *)tokc.cstr->data);
   8708         }
   8709         break;
   8710     case TOK_ERROR:
   8711     case TOK_WARNING:
   8712         c = tok;
   8713         ch = file->buf_ptr[0];
   8714         skip_spaces();
   8715         q = buf;
   8716         while (ch != '\n' && ch != CH_EOF) {
   8717             if ((q - buf) < sizeof(buf) - 1)
   8718                 *q++ = ch;
   8719             minp();
   8720         }
   8721         *q = '\0';
   8722         if (c == TOK_ERROR)
   8723             error("#error %s", buf);
   8724         else
   8725             warning("#warning %s", buf);
   8726         break;
   8727     case TOK_PRAGMA:
   8728         pragma_parse(s1);
   8729         break;
   8730     default:
   8731         if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
   8732             /* '!' is ignored to allow C scripts. numbers are ignored
   8733                to emulate cpp behaviour */
   8734         } else {
   8735             if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
   8736                 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
   8737         }
   8738         break;
   8739     }
   8740     /* ignore other preprocess commands or #! for C scripts */
   8741     while (tok != TOK_LINEFEED)
   8742         next_nomacro();
   8743  the_end:
   8744     parse_flags = saved_parse_flags;
   8745 }
   8746 
   8747 /* evaluate escape codes in a string. */
   8748 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
   8749 {
   8750     int c, n;
   8751     const uint8_t *p;
   8752 
   8753     p = buf;
   8754     for(;;) {
   8755         c = *p;
   8756         if (c == '\0')
   8757             break;
   8758         if (c == '\\') {
   8759             p++;
   8760             /* escape */
   8761             c = *p;
   8762             switch(c) {
   8763             case '0': case '1': case '2': case '3':
   8764             case '4': case '5': case '6': case '7':
   8765                 /* at most three octal digits */
   8766                 n = c - '0';
   8767                 p++;
   8768                 c = *p;
   8769                 if (isoct(c)) {
   8770                     n = n * 8 + c - '0';
   8771                     p++;
   8772                     c = *p;
   8773                     if (isoct(c)) {
   8774                         n = n * 8 + c - '0';
   8775                         p++;
   8776                     }
   8777                 }
   8778                 c = n;
   8779                 goto add_char_nonext;
   8780             case 'x':
   8781                 p++;
   8782                 n = 0;
   8783                 for(;;) {
   8784                     c = *p;
   8785                     if (c >= 'a' && c <= 'f')
   8786                         c = c - 'a' + 10;
   8787                     else if (c >= 'A' && c <= 'F')
   8788                         c = c - 'A' + 10;
   8789                     else if (isnum(c))
   8790                         c = c - '0';
   8791                     else
   8792                         break;
   8793                     n = n * 16 + c;
   8794                     p++;
   8795                 }
   8796                 c = n;
   8797                 goto add_char_nonext;
   8798             case 'a':
   8799                 c = '\a';
   8800                 break;
   8801             case 'b':
   8802                 c = '\b';
   8803                 break;
   8804             case 'f':
   8805                 c = '\f';
   8806                 break;
   8807             case 'n':
   8808                 c = '\n';
   8809                 break;
   8810             case 'r':
   8811                 c = '\r';
   8812                 break;
   8813             case 't':
   8814                 c = '\t';
   8815                 break;
   8816             case 'v':
   8817                 c = '\v';
   8818                 break;
   8819             case 'e':
   8820                 if (!gnu_ext)
   8821                     goto invalid_escape;
   8822                 c = 27;
   8823                 break;
   8824             case '\'':
   8825             case '\"':
   8826             case '\\':
   8827             case '?':
   8828                 break;
   8829             default:
   8830             invalid_escape:
   8831                 if (c >= '!' && c <= '~')
   8832                     warning("unknown escape sequence: \'\\%c\'", c);
   8833                 else
   8834                     warning("unknown escape sequence: \'\\x%x\'", c);
   8835                 break;
   8836             }
   8837         }
   8838         p++;
   8839     add_char_nonext:
   8840         if (!is_long)
   8841             cstr_ccat(outstr, c);
   8842         else
   8843             cstr_wccat(outstr, c);
   8844     }
   8845     /* add a trailing '\0' */
   8846     if (!is_long)
   8847         cstr_ccat(outstr, '\0');
   8848     else
   8849         cstr_wccat(outstr, '\0');
   8850 }
   8851 
   8852 /* we use 64 bit numbers */
   8853 #define BN_SIZE 2
   8854 
   8855 /* bn = (bn << shift) | or_val */
   8856 void bn_lshift(unsigned int *bn, int shift, int or_val)
   8857 {
   8858     int i;
   8859     unsigned int v;
   8860     for(i=0;i<BN_SIZE;i++) {
   8861         v = bn[i];
   8862         bn[i] = (v << shift) | or_val;
   8863         or_val = v >> (32 - shift);
   8864     }
   8865 }
   8866 
   8867 void bn_zero(unsigned int *bn)
   8868 {
   8869     int i;
   8870     for(i=0;i<BN_SIZE;i++) {
   8871         bn[i] = 0;
   8872     }
   8873 }
   8874 
   8875 /* parse number in null terminated string 'p' and return it in the
   8876    current token */
   8877 void parse_number(const char *p)
   8878 {
   8879     int b, t, shift, frac_bits, s, exp_val, ch;
   8880     char *q;
   8881     unsigned int bn[BN_SIZE];
   8882     double d;
   8883 
   8884     /* number */
   8885     q = token_buf;
   8886     ch = *p++;
   8887     t = ch;
   8888     ch = *p++;
   8889     *q++ = t;
   8890     b = 10;
   8891     if (t == '.') {
   8892         goto float_frac_parse;
   8893     } else if (t == '0') {
   8894         if (ch == 'x' || ch == 'X') {
   8895             q--;
   8896             ch = *p++;
   8897             b = 16;
   8898         } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
   8899             q--;
   8900             ch = *p++;
   8901             b = 2;
   8902         }
   8903     }
   8904     /* parse all digits. cannot check octal numbers at this stage
   8905        because of floating point constants */
   8906     while (1) {
   8907         if (ch >= 'a' && ch <= 'f')
   8908             t = ch - 'a' + 10;
   8909         else if (ch >= 'A' && ch <= 'F')
   8910             t = ch - 'A' + 10;
   8911         else if (isnum(ch))
   8912             t = ch - '0';
   8913         else
   8914             break;
   8915         if (t >= b)
   8916             break;
   8917         if (q >= token_buf + STRING_MAX_SIZE) {
   8918         num_too_long:
   8919             error("number too long");
   8920         }
   8921         *q++ = ch;
   8922         ch = *p++;
   8923     }
   8924     if (ch == '.' ||
   8925         ((ch == 'e' || ch == 'E') && b == 10) ||
   8926         ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
   8927         if (b != 10) {
   8928             /* NOTE: strtox should support that for hexa numbers, but
   8929                non ISOC99 libcs do not support it, so we prefer to do
   8930                it by hand */
   8931             /* hexadecimal or binary floats */
   8932             /* XXX: handle overflows */
   8933             *q = '\0';
   8934             if (b == 16)
   8935                 shift = 4;
   8936             else
   8937                 shift = 2;
   8938             bn_zero(bn);
   8939             q = token_buf;
   8940             while (1) {
   8941                 t = *q++;
   8942                 if (t == '\0') {
   8943                     break;
   8944                 } else if (t >= 'a') {
   8945                     t = t - 'a' + 10;
   8946                 } else if (t >= 'A') {
   8947                     t = t - 'A' + 10;
   8948                 } else {
   8949                     t = t - '0';
   8950                 }
   8951                 bn_lshift(bn, shift, t);
   8952             }
   8953             frac_bits = 0;
   8954             if (ch == '.') {
   8955                 ch = *p++;
   8956                 while (1) {
   8957                     t = ch;
   8958                     if (t >= 'a' && t <= 'f') {
   8959                         t = t - 'a' + 10;
   8960                     } else if (t >= 'A' && t <= 'F') {
   8961                         t = t - 'A' + 10;
   8962                     } else if (t >= '0' && t <= '9') {
   8963                         t = t - '0';
   8964                     } else {
   8965                         break;
   8966                     }
   8967                     if (t >= b)
   8968                         error("invalid digit");
   8969                     bn_lshift(bn, shift, t);
   8970                     frac_bits += shift;
   8971                     ch = *p++;
   8972                 }
   8973             }
   8974             if (ch != 'p' && ch != 'P')
   8975                 expect("exponent");
   8976             ch = *p++;
   8977             s = 1;
   8978             exp_val = 0;
   8979             if (ch == '+') {
   8980                 ch = *p++;
   8981             } else if (ch == '-') {
   8982                 s = -1;
   8983                 ch = *p++;
   8984             }
   8985             if (ch < '0' || ch > '9')
   8986                 expect("exponent digits");
   8987             while (ch >= '0' && ch <= '9') {
   8988                 exp_val = exp_val * 10 + ch - '0';
   8989                 ch = *p++;
   8990             }
   8991             exp_val = exp_val * s;
   8992 
   8993             /* now we can generate the number */
   8994             /* XXX: should patch directly float number */
   8995             d = (double)bn[1] * 4294967296.0 + (double)bn[0];
   8996             d = ldexp(d, exp_val - frac_bits);
   8997             t = toup(ch);
   8998             if (t == 'F') {
   8999                 ch = *p++;
   9000                 tok = TOK_CFLOAT;
   9001                 /* float : should handle overflow */
   9002                 tokc.f = (float)d;
   9003             } else if (t == 'L') {
   9004                 ch = *p++;
   9005                 tok = TOK_CLDOUBLE;
   9006                 /* XXX: not large enough */
   9007                 tokc.ld = (long double)d;
   9008             } else {
   9009                 tok = TOK_CDOUBLE;
   9010                 tokc.d = d;
   9011             }
   9012         } else {
   9013             /* decimal floats */
   9014             if (ch == '.') {
   9015                 if (q >= token_buf + STRING_MAX_SIZE)
   9016                     goto num_too_long;
   9017                 *q++ = ch;
   9018                 ch = *p++;
   9019             float_frac_parse:
   9020                 while (ch >= '0' && ch <= '9') {
   9021                     if (q >= token_buf + STRING_MAX_SIZE)
   9022                         goto num_too_long;
   9023                     *q++ = ch;
   9024                     ch = *p++;
   9025                 }
   9026             }
   9027             if (ch == 'e' || ch == 'E') {
   9028                 if (q >= token_buf + STRING_MAX_SIZE)
   9029                     goto num_too_long;
   9030                 *q++ = ch;
   9031                 ch = *p++;
   9032                 if (ch == '-' || ch == '+') {
   9033                     if (q >= token_buf + STRING_MAX_SIZE)
   9034                         goto num_too_long;
   9035                     *q++ = ch;
   9036                     ch = *p++;
   9037                 }
   9038                 if (ch < '0' || ch > '9')
   9039                     expect("exponent digits");
   9040                 while (ch >= '0' && ch <= '9') {
   9041                     if (q >= token_buf + STRING_MAX_SIZE)
   9042                         goto num_too_long;
   9043                     *q++ = ch;
   9044                     ch = *p++;
   9045                 }
   9046             }
   9047             *q = '\0';
   9048             t = toup(ch);
   9049             errno = 0;
   9050             if (t == 'F') {
   9051                 ch = *p++;
   9052                 tok = TOK_CFLOAT;
   9053                 tokc.f = strtof(token_buf, NULL);
   9054             } else if (t == 'L') {
   9055                 ch = *p++;
   9056                 tok = TOK_CLDOUBLE;
   9057                 tokc.ld = strtold(token_buf, NULL);
   9058             } else {
   9059                 tok = TOK_CDOUBLE;
   9060                 tokc.d = strtod(token_buf, NULL);
   9061             }
   9062         }
   9063     } else {
   9064         unsigned long long n, n1;
   9065         int lcount, ucount;
   9066 
   9067         /* integer number */
   9068         *q = '\0';
   9069         q = token_buf;
   9070         if (b == 10 && *q == '0') {
   9071             b = 8;
   9072             q++;
   9073         }
   9074         n = 0;
   9075         while(1) {
   9076             t = *q++;
   9077             /* no need for checks except for base 10 / 8 errors */
   9078             if (t == '\0') {
   9079                 break;
   9080             } else if (t >= 'a') {
   9081                 t = t - 'a' + 10;
   9082             } else if (t >= 'A') {
   9083                 t = t - 'A' + 10;
   9084             } else {
   9085                 t = t - '0';
   9086                 if (t >= b)
   9087                     error("invalid digit");
   9088             }
   9089             n1 = n;
   9090             n = n * b + t;
   9091             /* detect overflow */
   9092             /* XXX: this test is not reliable */
   9093             if (n < n1)
   9094                 error("integer constant overflow");
   9095         }
   9096 
   9097         /* XXX: not exactly ANSI compliant */
   9098         if ((n & 0xffffffff00000000LL) != 0) {
   9099             if ((n >> 63) != 0)
   9100                 tok = TOK_CULLONG;
   9101             else
   9102                 tok = TOK_CLLONG;
   9103         } else if (n > 0x7fffffff) {
   9104             tok = TOK_CUINT;
   9105         } else {
   9106             tok = TOK_CINT;
   9107         }
   9108         lcount = 0;
   9109         ucount = 0;
   9110         for(;;) {
   9111             t = toup(ch);
   9112             if (t == 'L') {
   9113                 if (lcount >= 2)
   9114                     error("three 'l's in integer constant");
   9115                 lcount++;
   9116                 if (lcount == 2) {
   9117                     if (tok == TOK_CINT)
   9118                         tok = TOK_CLLONG;
   9119                     else if (tok == TOK_CUINT)
   9120                         tok = TOK_CULLONG;
   9121                 }
   9122                 ch = *p++;
   9123             } else if (t == 'U') {
   9124                 if (ucount >= 1)
   9125                     error("two 'u's in integer constant");
   9126                 ucount++;
   9127                 if (tok == TOK_CINT)
   9128                     tok = TOK_CUINT;
   9129                 else if (tok == TOK_CLLONG)
   9130                     tok = TOK_CULLONG;
   9131                 ch = *p++;
   9132             } else {
   9133                 break;
   9134             }
   9135         }
   9136         if (tok == TOK_CINT || tok == TOK_CUINT)
   9137             tokc.ui = n;
   9138         else
   9139             tokc.ull = n;
   9140     }
   9141 }
   9142 
   9143 
   9144 #define PARSE2(c1, tok1, c2, tok2)              \
   9145     case c1:                                    \
   9146         PEEKC(c, p);                            \
   9147         if (c == c2) {                          \
   9148             p++;                                \
   9149             tok = tok2;                         \
   9150         } else {                                \
   9151             tok = tok1;                         \
   9152         }                                       \
   9153         break;
   9154 
   9155 /* return next token without macro substitution */
   9156 static /*inline*/ void next_nomacro1(void)
   9157 {
   9158     int t, c, is_long;
   9159     TokenSym *ts;
   9160     uint8_t *p, *p1;
   9161     unsigned int h;
   9162 
   9163     p = file->buf_ptr;
   9164  redo_no_start:
   9165     c = *p;
   9166     switch(c) {
   9167     case ' ':
   9168     case '\t':
   9169     case '\f':
   9170     case '\v':
   9171     case '\r':
   9172         p++;
   9173         goto redo_no_start;
   9174 
   9175     case '\\':
   9176         /* first look if it is in fact an end of buffer */
   9177         if (p >= file->buf_end) {
   9178             file->buf_ptr = p;
   9179             handle_eob();
   9180             p = file->buf_ptr;
   9181             if (p >= file->buf_end)
   9182                 goto parse_eof;
   9183             else
   9184                 goto redo_no_start;
   9185         } else {
   9186             file->buf_ptr = p;
   9187             ch = *p;
   9188             handle_stray();
   9189             p = file->buf_ptr;
   9190             goto redo_no_start;
   9191         }
   9192     parse_eof:
   9193         {
   9194             TCCState *s1 = tcc_state;
   9195             if (parse_flags & PARSE_FLAG_LINEFEED) {
   9196                 tok = TOK_LINEFEED;
   9197             } else if (s1->include_stack_ptr == s1->include_stack ||
   9198                        !(parse_flags & PARSE_FLAG_PREPROCESS)) {
   9199                 /* no include left : end of file. */
   9200                 tok = TOK_EOF;
   9201             } else {
   9202                 /* pop include file */
   9203 
   9204                 /* test if previous '#endif' was after a #ifdef at
   9205                    start of file */
   9206                 if (tok_flags & TOK_FLAG_ENDIF) {
   9207 #ifdef INC_DEBUG
   9208                     printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
   9209 #endif
   9210                     add_cached_include(s1, file->inc_type, file->inc_filename,
   9211                                        file->ifndef_macro_saved);
   9212                 }
   9213 
   9214                 /* add end of include file debug info */
   9215                 if (do_debug) {
   9216                     put_stabd(N_EINCL, 0, 0);
   9217                 }
   9218                 /* pop include stack */
   9219                 tcc_close(file);
   9220                 s1->include_stack_ptr--;
   9221                 file = *s1->include_stack_ptr;
   9222                 p = file->buf_ptr;
   9223                 goto redo_no_start;
   9224             }
   9225         }
   9226         break;
   9227 
   9228     case '\n':
   9229         if (parse_flags & PARSE_FLAG_LINEFEED) {
   9230             tok = TOK_LINEFEED;
   9231         } else {
   9232             file->line_num++;
   9233             tok_flags |= TOK_FLAG_BOL;
   9234             p++;
   9235             goto redo_no_start;
   9236         }
   9237         break;
   9238 
   9239     case '#':
   9240         /* XXX: simplify */
   9241         PEEKC(c, p);
   9242         if ((tok_flags & TOK_FLAG_BOL) &&
   9243             (parse_flags & PARSE_FLAG_PREPROCESS)) {
   9244             file->buf_ptr = p;
   9245             preprocess(tok_flags & TOK_FLAG_BOF);
   9246             p = file->buf_ptr;
   9247             goto redo_no_start;
   9248         } else {
   9249             if (c == '#') {
   9250                 p++;
   9251                 tok = TOK_TWOSHARPS;
   9252             } else {
   9253                 if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
   9254                     p = parse_line_comment(p - 1);
   9255                     goto redo_no_start;
   9256                 } else {
   9257                     tok = '#';
   9258                 }
   9259             }
   9260         }
   9261         break;
   9262 
   9263     case 'a': case 'b': case 'c': case 'd':
   9264     case 'e': case 'f': case 'g': case 'h':
   9265     case 'i': case 'j': case 'k': case 'l':
   9266     case 'm': case 'n': case 'o': case 'p':
   9267     case 'q': case 'r': case 's': case 't':
   9268     case 'u': case 'v': case 'w': case 'x':
   9269     case 'y': case 'z':
   9270     case 'A': case 'B': case 'C': case 'D':
   9271     case 'E': case 'F': case 'G': case 'H':
   9272     case 'I': case 'J': case 'K':
   9273     case 'M': case 'N': case 'O': case 'P':
   9274     case 'Q': case 'R': case 'S': case 'T':
   9275     case 'U': case 'V': case 'W': case 'X':
   9276     case 'Y': case 'Z':
   9277     case '_':
   9278     parse_ident_fast:
   9279         p1 = p;
   9280         h = TOK_HASH_INIT;
   9281         h = TOK_HASH_FUNC(h, c);
   9282         p++;
   9283         for(;;) {
   9284             c = *p;
   9285             if (!isidnum_table[c])
   9286                 break;
   9287             h = TOK_HASH_FUNC(h, c);
   9288             p++;
   9289         }
   9290         if (c != '\\') {
   9291             TokenSym **pts;
   9292             int len;
   9293 
   9294             /* fast case : no stray found, so we have the full token
   9295                and we have already hashed it */
   9296             len = p - p1;
   9297             h &= (TOK_HASH_SIZE - 1);
   9298             pts = &hash_ident[h];
   9299             for(;;) {
   9300                 ts = *pts;
   9301                 if (!ts)
   9302                     break;
   9303                 if (ts->len == len && !memcmp(ts->str, p1, len))
   9304                     goto token_found;
   9305                 pts = &(ts->hash_next);
   9306             }
   9307             ts = tok_alloc_new(pts, p1, len);
   9308         token_found: ;
   9309         } else {
   9310             /* slower case */
   9311             cstr_reset(&tokcstr);
   9312 
   9313             while (p1 < p) {
   9314                 cstr_ccat(&tokcstr, *p1);
   9315                 p1++;
   9316             }
   9317             p--;
   9318             PEEKC(c, p);
   9319         parse_ident_slow:
   9320             while (isidnum_table[c]) {
   9321                 cstr_ccat(&tokcstr, c);
   9322                 PEEKC(c, p);
   9323             }
   9324             ts = tok_alloc(tokcstr.data, tokcstr.size);
   9325         }
   9326         tok = ts->tok;
   9327         break;
   9328     case 'L':
   9329         t = p[1];
   9330         if (t != '\\' && t != '\'' && t != '\"') {
   9331             /* fast case */
   9332             goto parse_ident_fast;
   9333         } else {
   9334             PEEKC(c, p);
   9335             if (c == '\'' || c == '\"') {
   9336                 is_long = 1;
   9337                 goto str_const;
   9338             } else {
   9339                 cstr_reset(&tokcstr);
   9340                 cstr_ccat(&tokcstr, 'L');
   9341                 goto parse_ident_slow;
   9342             }
   9343         }
   9344         break;
   9345     case '0': case '1': case '2': case '3':
   9346     case '4': case '5': case '6': case '7':
   9347     case '8': case '9':
   9348 
   9349         cstr_reset(&tokcstr);
   9350         /* after the first digit, accept digits, alpha, '.' or sign if
   9351            prefixed by 'eEpP' */
   9352     parse_num:
   9353         for(;;) {
   9354             t = c;
   9355             cstr_ccat(&tokcstr, c);
   9356             PEEKC(c, p);
   9357             if (!(isnum(c) || isid(c) || c == '.' ||
   9358                   ((c == '+' || c == '-') &&
   9359                    (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
   9360                 break;
   9361         }
   9362         /* We add a trailing '\0' to ease parsing */
   9363         cstr_ccat(&tokcstr, '\0');
   9364         tokc.cstr = &tokcstr;
   9365         tok = TOK_PPNUM;
   9366         break;
   9367     case '.':
   9368         /* special dot handling because it can also start a number */
   9369         PEEKC(c, p);
   9370         if (isnum(c)) {
   9371             cstr_reset(&tokcstr);
   9372             cstr_ccat(&tokcstr, '.');
   9373             goto parse_num;
   9374         } else if (c == '.') {
   9375             PEEKC(c, p);
   9376             if (c != '.')
   9377                 expect("'.'");
   9378             PEEKC(c, p);
   9379             tok = TOK_DOTS;
   9380         } else {
   9381             tok = '.';
   9382         }
   9383         break;
   9384     case '\'':
   9385     case '\"':
   9386         is_long = 0;
   9387     str_const:
   9388         {
   9389             CString str;
   9390             int sep;
   9391 
   9392             sep = c;
   9393 
   9394             /* parse the string */
   9395             cstr_new(&str);
   9396             p = parse_pp_string(p, sep, &str);
   9397             cstr_ccat(&str, '\0');
   9398 
   9399             /* eval the escape (should be done as TOK_PPNUM) */
   9400             cstr_reset(&tokcstr);
   9401             parse_escape_string(&tokcstr, str.data, is_long);
   9402             cstr_free(&str);
   9403 
   9404             if (sep == '\'') {
   9405                 int char_size;
   9406                 /* XXX: make it portable */
   9407                 if (!is_long)
   9408                     char_size = 1;
   9409                 else
   9410                     char_size = sizeof(int);
   9411                 if (tokcstr.size <= char_size)
   9412                     error("empty character constant");
   9413                 if (tokcstr.size > 2 * char_size)
   9414                     warning("multi-character character constant");
   9415                 if (!is_long) {
   9416                     tokc.i = *(int8_t *)tokcstr.data;
   9417                     tok = TOK_CCHAR;
   9418                 } else {
   9419                     tokc.i = *(int *)tokcstr.data;
   9420                     tok = TOK_LCHAR;
   9421                 }
   9422             } else {
   9423                 tokc.cstr = &tokcstr;
   9424                 if (!is_long)
   9425                     tok = TOK_STR;
   9426                 else
   9427                     tok = TOK_LSTR;
   9428             }
   9429         }
   9430         break;
   9431 
   9432     case '<':
   9433         PEEKC(c, p);
   9434         if (c == '=') {
   9435             p++;
   9436             tok = TOK_LE;
   9437         } else if (c == '<') {
   9438             PEEKC(c, p);
   9439             if (c == '=') {
   9440                 p++;
   9441                 tok = TOK_A_SHL;
   9442             } else {
   9443                 tok = TOK_SHL;
   9444             }
   9445         } else {
   9446             tok = TOK_LT;
   9447         }
   9448         break;
   9449 
   9450     case '>':
   9451         PEEKC(c, p);
   9452         if (c == '=') {
   9453             p++;
   9454             tok = TOK_GE;
   9455         } else if (c == '>') {
   9456             PEEKC(c, p);
   9457             if (c == '=') {
   9458                 p++;
   9459                 tok = TOK_A_SAR;
   9460             } else {
   9461                 tok = TOK_SAR;
   9462             }
   9463         } else {
   9464             tok = TOK_GT;
   9465         }
   9466         break;
   9467 
   9468     case '&':
   9469         PEEKC(c, p);
   9470         if (c == '&') {
   9471             p++;
   9472             tok = TOK_LAND;
   9473         } else if (c == '=') {
   9474             p++;
   9475             tok = TOK_A_AND;
   9476         } else {
   9477             tok = '&';
   9478         }
   9479         break;
   9480 
   9481     case '|':
   9482         PEEKC(c, p);
   9483         if (c == '|') {
   9484             p++;
   9485             tok = TOK_LOR;
   9486         } else if (c == '=') {
   9487             p++;
   9488             tok = TOK_A_OR;
   9489         } else {
   9490             tok = '|';
   9491         }
   9492         break;
   9493 
   9494     case '+':
   9495         PEEKC(c, p);
   9496         if (c == '+') {
   9497             p++;
   9498             tok = TOK_INC;
   9499         } else if (c == '=') {
   9500             p++;
   9501             tok = TOK_A_ADD;
   9502         } else {
   9503             tok = '+';
   9504         }
   9505         break;
   9506 
   9507     case '-':
   9508         PEEKC(c, p);
   9509         if (c == '-') {
   9510             p++;
   9511             tok = TOK_DEC;
   9512         } else if (c == '=') {
   9513             p++;
   9514             tok = TOK_A_SUB;
   9515         } else if (c == '>') {
   9516             p++;
   9517             tok = TOK_ARROW;
   9518         } else {
   9519             tok = '-';
   9520         }
   9521         break;
   9522 
   9523     PARSE2('!', '!', '=', TOK_NE)
   9524     PARSE2('=', '=', '=', TOK_EQ)
   9525     PARSE2('*', '*', '=', TOK_A_MUL)
   9526     PARSE2('%', '%', '=', TOK_A_MOD)
   9527     PARSE2('^', '^', '=', TOK_A_XOR)
   9528 
   9529         /* comments or operator */
   9530     case '/':
   9531         PEEKC(c, p);
   9532         if (c == '*') {
   9533             p = parse_comment(p);
   9534             goto redo_no_start;
   9535         } else if (c == '/') {
   9536             p = parse_line_comment(p);
   9537             goto redo_no_start;
   9538         } else if (c == '=') {
   9539             p++;
   9540             tok = TOK_A_DIV;
   9541         } else {
   9542             tok = '/';
   9543         }
   9544         break;
   9545 
   9546         /* simple tokens */
   9547     case '(':
   9548     case ')':
   9549     case '[':
   9550     case ']':
   9551     case '{':
   9552     case '}':
   9553     case ',':
   9554     case ';':
   9555     case ':':
   9556     case '?':
   9557     case '~':
   9558     case '$': /* only used in assembler */
   9559     case '@': /* dito */
   9560         tok = c;
   9561         p++;
   9562         break;
   9563     default:
   9564         error("unrecognized character \\x%02x", c);
   9565         break;
   9566     }
   9567     file->buf_ptr = p;
   9568     tok_flags = 0;
   9569 #if defined(PARSE_DEBUG)
   9570     printf("token = %s\n", get_tok_str(tok, &tokc));
   9571 #endif
   9572 }
   9573 
   9574 /* return next token without macro substitution. Can read input from
   9575    macro_ptr buffer */
   9576 static void next_nomacro(void)
   9577 {
   9578     if (macro_ptr) {
   9579     redo:
   9580         tok = *macro_ptr;
   9581         if (tok) {
   9582             TOK_GET(tok, macro_ptr, tokc);
   9583             if (tok == TOK_LINENUM) {
   9584                 file->line_num = tokc.i;
   9585                 goto redo;
   9586             }
   9587         }
   9588     } else {
   9589         next_nomacro1();
   9590     }
   9591 }
   9592 
   9593 /* substitute args in macro_str and return allocated string */
   9594 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
   9595 {
   9596     int *st, last_tok, t, notfirst;
   9597     Sym *s;
   9598     CValue cval;
   9599     TokenString str;
   9600     CString cstr;
   9601 
   9602     tok_str_new(&str);
   9603     last_tok = 0;
   9604     while(1) {
   9605         TOK_GET(t, macro_str, cval);
   9606         if (!t)
   9607             break;
   9608         if (t == '#') {
   9609             /* stringize */
   9610             TOK_GET(t, macro_str, cval);
   9611             if (!t)
   9612                 break;
   9613             s = sym_find2(args, t);
   9614             if (s) {
   9615                 cstr_new(&cstr);
   9616                 st = (int *)s->c;
   9617                 notfirst = 0;
   9618                 while (*st) {
   9619                     if (notfirst)
   9620                         cstr_ccat(&cstr, ' ');
   9621                     TOK_GET(t, st, cval);
   9622                     cstr_cat(&cstr, get_tok_str(t, &cval));
   9623                     notfirst = 1;
   9624                 }
   9625                 cstr_ccat(&cstr, '\0');
   9626 #ifdef PP_DEBUG
   9627                 printf("stringize: %s\n", (char *)cstr.data);
   9628 #endif
   9629                 /* add string */
   9630                 cval.cstr = &cstr;
   9631                 tok_str_add2(&str, TOK_STR, &cval);
   9632                 cstr_free(&cstr);
   9633             } else {
   9634                 tok_str_add2(&str, t, &cval);
   9635             }
   9636         } else if (t >= TOK_IDENT) {
   9637             s = sym_find2(args, t);
   9638             if (s) {
   9639                 st = (int *)s->c;
   9640                 /* if '##' is present before or after, no arg substitution */
   9641                 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
   9642                     /* special case for var arg macros : ## eats the
   9643                        ',' if empty VA_ARGS variable. */
   9644                     /* XXX: test of the ',' is not 100%
   9645                        reliable. should fix it to avoid security
   9646                        problems */
   9647                     if (gnu_ext && s->type.t &&
   9648                         last_tok == TOK_TWOSHARPS &&
   9649                         str.len >= 2 && str.str[str.len - 2] == ',') {
   9650                         if (*st == 0) {
   9651                             /* suppress ',' '##' */
   9652                             str.len -= 2;
   9653                         } else {
   9654                             /* suppress '##' and add variable */
   9655                             str.len--;
   9656                             goto add_var;
   9657                         }
   9658                     } else {
   9659                         int t1;
   9660                     add_var:
   9661                         for(;;) {
   9662                             TOK_GET(t1, st, cval);
   9663                             if (!t1)
   9664                                 break;
   9665                             tok_str_add2(&str, t1, &cval);
   9666                         }
   9667                     }
   9668                 } else {
   9669                     /* NOTE: the stream cannot be read when macro
   9670                        substituing an argument */
   9671                     macro_subst(&str, nested_list, st, NULL);
   9672                 }
   9673             } else {
   9674                 tok_str_add(&str, t);
   9675             }
   9676         } else {
   9677             tok_str_add2(&str, t, &cval);
   9678         }
   9679         last_tok = t;
   9680     }
   9681     tok_str_add(&str, 0);
   9682     return str.str;
   9683 }
   9684 
   9685 static char const ab_month_name[12][4] =
   9686 {
   9687     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
   9688     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
   9689 };
   9690 
   9691 /* do macro substitution of current token with macro 's' and add
   9692    result to (tok_str,tok_len). 'nested_list' is the list of all
   9693    macros we got inside to avoid recursing. Return non zero if no
   9694    substitution needs to be done */
   9695 static int macro_subst_tok(TokenString *tok_str,
   9696                            Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
   9697 {
   9698     Sym *args, *sa, *sa1;
   9699     int mstr_allocated, parlevel, *mstr, t, t1;
   9700     TokenString str;
   9701     char *cstrval;
   9702     CValue cval;
   9703     CString cstr;
   9704     char buf[32];
   9705 
   9706     /* if symbol is a macro, prepare substitution */
   9707     /* special macros */
   9708     if (tok == TOK___LINE__) {
   9709         snprintf(buf, sizeof(buf), "%d", file->line_num);
   9710         cstrval = buf;
   9711         t1 = TOK_PPNUM;
   9712         goto add_cstr1;
   9713     } else if (tok == TOK___FILE__) {
   9714         cstrval = file->filename;
   9715         goto add_cstr;
   9716     } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
   9717         time_t ti;
   9718         struct tm *tm;
   9719 
   9720         time(&ti);
   9721         tm = localtime(&ti);
   9722         if (tok == TOK___DATE__) {
   9723             snprintf(buf, sizeof(buf), "%s %2d %d",
   9724                      ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
   9725         } else {
   9726             snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
   9727                      tm->tm_hour, tm->tm_min, tm->tm_sec);
   9728         }
   9729         cstrval = buf;
   9730     add_cstr:
   9731         t1 = TOK_STR;
   9732     add_cstr1:
   9733         cstr_new(&cstr);
   9734         cstr_cat(&cstr, cstrval);
   9735         cstr_ccat(&cstr, '\0');
   9736         cval.cstr = &cstr;
   9737         tok_str_add2(tok_str, t1, &cval);
   9738         cstr_free(&cstr);
   9739     } else {
   9740         mstr = (int *)s->c;
   9741         mstr_allocated = 0;
   9742         if (s->type.t == MACRO_FUNC) {
   9743             /* NOTE: we do not use next_nomacro to avoid eating the
   9744                next token. XXX: find better solution */
   9745         redo:
   9746             if (macro_ptr) {
   9747                 t = *macro_ptr;
   9748                 if (t == 0 && can_read_stream) {
   9749                     /* end of macro stream: we must look at the token
   9750                        after in the file */
   9751                     struct macro_level *ml = *can_read_stream;
   9752                     macro_ptr = NULL;
   9753                     if (ml)
   9754                     {
   9755                         macro_ptr = ml->p;
   9756                         ml->p = NULL;
   9757                         *can_read_stream = ml -> prev;
   9758                     }
   9759                     goto redo;
   9760                 }
   9761             } else {
   9762                 /* XXX: incorrect with comments */
   9763                 ch = file->buf_ptr[0];
   9764                 while (is_space(ch) || ch == '\n')
   9765                     cinp();
   9766                 t = ch;
   9767             }
   9768             if (t != '(') /* no macro subst */
   9769                 return -1;
   9770 
   9771             /* argument macro */
   9772             next_nomacro();
   9773             next_nomacro();
   9774             args = NULL;
   9775             sa = s->next;
   9776             /* NOTE: empty args are allowed, except if no args */
   9777             for(;;) {
   9778                 /* handle '()' case */
   9779                 if (!args && !sa && tok == ')')
   9780                     break;
   9781                 if (!sa)
   9782                     error("macro '%s' used with too many args",
   9783                           get_tok_str(s->v, 0));
   9784                 tok_str_new(&str);
   9785                 parlevel = 0;
   9786                 /* NOTE: non zero sa->t indicates VA_ARGS */
   9787                 while ((parlevel > 0 ||
   9788                         (tok != ')' &&
   9789                          (tok != ',' || sa->type.t))) &&
   9790                        tok != -1) {
   9791                     if (tok == '(')
   9792                         parlevel++;
   9793                     else if (tok == ')')
   9794                         parlevel--;
   9795                     tok_str_add2(&str, tok, &tokc);
   9796                     next_nomacro();
   9797                 }
   9798                 tok_str_add(&str, 0);
   9799                 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
   9800                 sa = sa->next;
   9801                 if (tok == ')') {
   9802                     /* special case for gcc var args: add an empty
   9803                        var arg argument if it is omitted */
   9804                     if (sa && sa->type.t && gnu_ext)
   9805                         continue;
   9806                     else
   9807                         break;
   9808                 }
   9809                 if (tok != ',')
   9810                     expect(",");
   9811                 next_nomacro();
   9812             }
   9813             if (sa) {
   9814                 error("macro '%s' used with too few args",
   9815                       get_tok_str(s->v, 0));
   9816             }
   9817 
   9818             /* now subst each arg */
   9819             mstr = macro_arg_subst(nested_list, mstr, args);
   9820             /* free memory */
   9821             sa = args;
   9822             while (sa) {
   9823                 sa1 = sa->prev;
   9824                 tok_str_free((int *)sa->c);
   9825                 sym_free(sa);
   9826                 sa = sa1;
   9827             }
   9828             mstr_allocated = 1;
   9829         }
   9830         sym_push2(nested_list, s->v, 0, 0);
   9831         macro_subst(tok_str, nested_list, mstr, can_read_stream);
   9832         /* pop nested defined symbol */
   9833         sa1 = *nested_list;
   9834         *nested_list = sa1->prev;
   9835         sym_free(sa1);
   9836         if (mstr_allocated)
   9837             tok_str_free(mstr);
   9838     }
   9839     return 0;
   9840 }
   9841 
   9842 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise
   9843    return the resulting string (which must be freed). */
   9844 static /*inline*/ int *macro_twosharps(const int *macro_str)
   9845 {
   9846     TokenSym *ts;
   9847     const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
   9848     int t;
   9849     const char *p1, *p2;
   9850     CValue cval;
   9851     TokenString macro_str1;
   9852     CString cstr;
   9853     memset(&cval, 0, sizeof(cval));
   9854     start_macro_ptr = macro_str;
   9855     /* we search the first '##' */
   9856     for(;;) {
   9857         macro_ptr1 = macro_str;
   9858         TOK_GET(t, macro_str, cval);
   9859         /* nothing more to do if end of string */
   9860         if (t == 0)
   9861             return NULL;
   9862         if (*macro_str == TOK_TWOSHARPS)
   9863             break;
   9864     }
   9865 
   9866     /* we saw '##', so we need more processing to handle it */
   9867     cstr_new(&cstr);
   9868     tok_str_new(&macro_str1);
   9869     tok = t;
   9870     tokc = cval;
   9871 
   9872     /* add all tokens seen so far */
   9873     for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
   9874         TOK_GET(t, ptr, cval);
   9875         tok_str_add2(&macro_str1, t, &cval);
   9876     }
   9877     saved_macro_ptr = macro_ptr;
   9878     /* XXX: get rid of the use of macro_ptr here */
   9879     macro_ptr = (int *)macro_str;
   9880     for(;;) {
   9881         while (*macro_ptr == TOK_TWOSHARPS) {
   9882             macro_ptr++;
   9883             macro_ptr1 = macro_ptr;
   9884             t = *macro_ptr;
   9885             if (t) {
   9886                 TOK_GET(t, macro_ptr, cval);
   9887                 /* We concatenate the two tokens if we have an
   9888                    identifier or a preprocessing number */
   9889                 cstr_reset(&cstr);
   9890                 p1 = get_tok_str(tok, &tokc);
   9891                 cstr_cat(&cstr, p1);
   9892                 p2 = get_tok_str(t, &cval);
   9893                 cstr_cat(&cstr, p2);
   9894                 cstr_ccat(&cstr, '\0');
   9895 
   9896                 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
   9897                     (t >= TOK_IDENT || t == TOK_PPNUM)) {
   9898                     if (tok == TOK_PPNUM) {
   9899                         /* if number, then create a number token */
   9900                         /* NOTE: no need to allocate because
   9901                            tok_str_add2() does it */
   9902                         tokc.cstr = &cstr;
   9903                     } else {
   9904                         /* if identifier, we must do a test to
   9905                            validate we have a correct identifier */
   9906                         if (t == TOK_PPNUM) {
   9907                             const char *p;
   9908                             int c;
   9909 
   9910                             p = p2;
   9911                             for(;;) {
   9912                                 c = *p;
   9913                                 if (c == '\0')
   9914                                     break;
   9915                                 p++;
   9916                                 if (!isnum(c) && !isid(c))
   9917                                     goto error_pasting;
   9918                             }
   9919                         }
   9920                         ts = tok_alloc(cstr.data, strlen(cstr.data));
   9921                         tok = ts->tok; /* modify current token */
   9922                     }
   9923                 } else {
   9924                     const char *str = cstr.data;
   9925                     const unsigned char *q;
   9926 
   9927                     /* we look for a valid token */
   9928                     /* XXX: do more extensive checks */
   9929                     if (!strcmp(str, ">>=")) {
   9930                         tok = TOK_A_SAR;
   9931                     } else if (!strcmp(str, "<<=")) {
   9932                         tok = TOK_A_SHL;
   9933                     } else if (strlen(str) == 2) {
   9934                         /* search in two bytes table */
   9935                         q = tok_two_chars;
   9936                         for(;;) {
   9937                             if (!*q)
   9938                                 goto error_pasting;
   9939                             if (q[0] == str[0] && q[1] == str[1])
   9940                                 break;
   9941                             q += 3;
   9942                         }
   9943                         tok = q[2];
   9944                     } else {
   9945                     error_pasting:
   9946                         /* NOTE: because get_tok_str use a static buffer,
   9947                            we must save it */
   9948                         cstr_reset(&cstr);
   9949                         p1 = get_tok_str(tok, &tokc);
   9950                         cstr_cat(&cstr, p1);
   9951                         cstr_ccat(&cstr, '\0');
   9952                         p2 = get_tok_str(t, &cval);
   9953                         warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
   9954                         /* cannot merge tokens: just add them separately */
   9955                         tok_str_add2(&macro_str1, tok, &tokc);
   9956                         /* XXX: free associated memory ? */
   9957                         tok = t;
   9958                         tokc = cval;
   9959                     }
   9960                 }
   9961             }
   9962         }
   9963         tok_str_add2(&macro_str1, tok, &tokc);
   9964         next_nomacro();
   9965         if (tok == 0)
   9966             break;
   9967     }
   9968     macro_ptr = (int *)saved_macro_ptr;
   9969     cstr_free(&cstr);
   9970     tok_str_add(&macro_str1, 0);
   9971     return macro_str1.str;
   9972 }
   9973 
   9974 
   9975 /* do macro substitution of macro_str and add result to
   9976    (tok_str,tok_len). 'nested_list' is the list of all macros we got
   9977    inside to avoid recursing. */
   9978 static void macro_subst(TokenString *tok_str, Sym **nested_list,
   9979                         const int *macro_str, struct macro_level ** can_read_stream)
   9980 {
   9981     Sym *s;
   9982     int *macro_str1;
   9983     const int *ptr;
   9984     int t, ret;
   9985     CValue cval;
   9986     struct macro_level ml;
   9987 
   9988     /* first scan for '##' operator handling */
   9989     ptr = macro_str;
   9990     macro_str1 = macro_twosharps(ptr);
   9991     if (macro_str1)
   9992         ptr = macro_str1;
   9993     while (1) {
   9994         /* NOTE: ptr == NULL can only happen if tokens are read from
   9995            file stream due to a macro function call */
   9996         if (ptr == NULL)
   9997             break;
   9998         TOK_GET(t, ptr, cval);
   9999         if (t == 0)
   10000             break;
   10001         s = define_find(t);
   10002         if (s != NULL) {
   10003             /* if nested substitution, do nothing */
   10004             if (sym_find2(*nested_list, t))
   10005                 goto no_subst;
   10006             ml.p = macro_ptr;
   10007             if (can_read_stream)
   10008                 ml.prev = *can_read_stream, *can_read_stream = &ml;
   10009             macro_ptr = (int *)ptr;
   10010             tok = t;
   10011             ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
   10012             ptr = (int *)macro_ptr;
   10013             macro_ptr = ml.p;
   10014             if (can_read_stream && *can_read_stream == &ml)
   10015                     *can_read_stream = ml.prev;
   10016             if (ret != 0)
   10017                 goto no_subst;
   10018         } else {
   10019         no_subst:
   10020             tok_str_add2(tok_str, t, &cval);
   10021         }
   10022     }
   10023     if (macro_str1)
   10024         tok_str_free(macro_str1);
   10025 }
   10026 
   10027 /* return next token with macro substitution */
   10028 static void next(void)
   10029 {
   10030     Sym *nested_list, *s;
   10031     TokenString str;
   10032     struct macro_level *ml;
   10033 
   10034  redo:
   10035     next_nomacro();
   10036     if (!macro_ptr) {
   10037         /* if not reading from macro substituted string, then try
   10038            to substitute macros */
   10039         if (tok >= TOK_IDENT &&
   10040             (parse_flags & PARSE_FLAG_PREPROCESS)) {
   10041             s = define_find(tok);
   10042             if (s) {
   10043                 /* we have a macro: we try to substitute */
   10044                 tok_str_new(&str);
   10045                 nested_list = NULL;
   10046                 ml = NULL;
   10047                 if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
   10048                     /* substitution done, NOTE: maybe empty */
   10049                     tok_str_add(&str, 0);
   10050                     macro_ptr = str.str;
   10051                     macro_ptr_allocated = str.str;
   10052                     goto redo;
   10053                 }
   10054             }
   10055         }
   10056     } else {
   10057         if (tok == 0) {
   10058             /* end of macro or end of unget buffer */
   10059             if (unget_buffer_enabled) {
   10060                 macro_ptr = unget_saved_macro_ptr;
   10061                 unget_buffer_enabled = 0;
   10062             } else {
   10063                 /* end of macro string: free it */
   10064                 tok_str_free(macro_ptr_allocated);
   10065                 macro_ptr = NULL;
   10066             }
   10067             goto redo;
   10068         }
   10069     }
   10070 
   10071     /* convert preprocessor tokens into C tokens */
   10072     if (tok == TOK_PPNUM &&
   10073         (parse_flags & PARSE_FLAG_TOK_NUM)) {
   10074         parse_number((char *)tokc.cstr->data);
   10075     }
   10076 }
   10077 
   10078 /* push back current token and set current token to 'last_tok'. Only
   10079    identifier case handled for labels. */
   10080 static inline void unget_tok(int last_tok)
   10081 {
   10082     int i, n;
   10083     int *q;
   10084     unget_saved_macro_ptr = macro_ptr;
   10085     unget_buffer_enabled = 1;
   10086     q = unget_saved_buffer;
   10087     macro_ptr = q;
   10088     *q++ = tok;
   10089     n = tok_ext_size(tok) - 1;
   10090     for(i=0;i<n;i++)
   10091         *q++ = tokc.tab[i];
   10092     *q = 0; /* end of token string */
   10093     tok = last_tok;
   10094 }
   10095 
   10096 
   10097 void swap(int *p, int *q)
   10098 {
   10099     int t;
   10100     t = *p;
   10101     *p = *q;
   10102     *q = t;
   10103 }
   10104 
   10105 void vsetc(CType *type, int r, CValue *vc)
   10106 {
   10107     int v;
   10108 
   10109     if (vtop >= vstack + (VSTACK_SIZE - 1))
   10110         error("memory full");
   10111     /* cannot let cpu flags if other instruction are generated. Also
   10112        avoid leaving VT_JMP anywhere except on the top of the stack
   10113        because it would complicate the code generator. */
   10114     if (vtop >= vstack) {
   10115         v = vtop->r & VT_VALMASK;
   10116         if (v == VT_CMP || (v & ~1) == VT_JMP)
   10117             gv(RC_INT);
   10118     }
   10119     vtop++;
   10120     vtop->type = *type;
   10121     vtop->r = r;
   10122     vtop->r2 = VT_CONST;
   10123     vtop->c = *vc;
   10124 }
   10125 
   10126 /* push integer constant */
   10127 void vpushi(int v)
   10128 {
   10129     CValue cval;
   10130     cval.i = v;
   10131     vsetc(&int_type, VT_CONST, &cval);
   10132 }
   10133 
   10134 /* Return a static symbol pointing to a section */
   10135 static Sym *get_sym_ref(CType *type, Section *sec,
   10136                         unsigned long offset, unsigned long size)
   10137 {
   10138     int v;
   10139     Sym *sym;
   10140 
   10141     v = anon_sym++;
   10142     sym = global_identifier_push(v, type->t | VT_STATIC, 0);
   10143     sym->type.ref = type->ref;
   10144     sym->r = VT_CONST | VT_SYM;
   10145     put_extern_sym(sym, sec, offset, size);
   10146     return sym;
   10147 }
   10148 
   10149 /* push a reference to a section offset by adding a dummy symbol */
   10150 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
   10151 {
   10152     CValue cval;
   10153 
   10154     cval.ul = 0;
   10155     vsetc(type, VT_CONST | VT_SYM, &cval);
   10156     vtop->sym = get_sym_ref(type, sec, offset, size);
   10157 }
   10158 
   10159 /* define a new external reference to a symbol 'v' of type 'u' */
   10160 static Sym *external_global_sym(int v, CType *type, int r)
   10161 {
   10162     Sym *s;
   10163 
   10164     s = sym_find(v);
   10165     if (!s) {
   10166         /* push forward reference */
   10167         s = global_identifier_push(v, type->t | VT_EXTERN, 0);
   10168         s->type.ref = type->ref;
   10169         s->r = r | VT_CONST | VT_SYM;
   10170     }
   10171     return s;
   10172 }
   10173 
   10174 /* define a new external reference to a symbol 'v' of type 'u' */
   10175 static Sym *external_sym(int v, CType *type, int r)
   10176 {
   10177     Sym *s;
   10178 
   10179     s = sym_find(v);
   10180     if (!s) {
   10181         /* push forward reference */
   10182         s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
   10183         s->type.t |= VT_EXTERN;
   10184     } else {
   10185         if (!is_compatible_types(&s->type, type))
   10186             error("incompatible types for redefinition of '%s'",
   10187                   get_tok_str(v, NULL));
   10188     }
   10189     return s;
   10190 }
   10191 
   10192 /* push a reference to global symbol v */
   10193 static void vpush_global_sym(CType *type, int v)
   10194 {
   10195     Sym *sym;
   10196     CValue cval;
   10197 
   10198     sym = external_global_sym(v, type, 0);
   10199     cval.ul = 0;
   10200     vsetc(type, VT_CONST | VT_SYM, &cval);
   10201     vtop->sym = sym;
   10202 }
   10203 
   10204 void vset(CType *type, int r, int v)
   10205 {
   10206     CValue cval;
   10207 
   10208     cval.i = v;
   10209     vsetc(type, r, &cval);
   10210 }
   10211 
   10212 void vseti(int r, int v)
   10213 {
   10214     CType type;
   10215     type.t = VT_INT;
   10216     vset(&type, r, v);
   10217 }
   10218 
   10219 void vswap(void)
   10220 {
   10221     SValue tmp;
   10222 
   10223     tmp = vtop[0];
   10224     vtop[0] = vtop[-1];
   10225     vtop[-1] = tmp;
   10226 }
   10227 
   10228 void vpushv(SValue *v)
   10229 {
   10230     if (vtop >= vstack + (VSTACK_SIZE - 1))
   10231         error("memory full");
   10232     vtop++;
   10233     *vtop = *v;
   10234 }
   10235 
   10236 void vdup(void)
   10237 {
   10238     vpushv(vtop);
   10239 }
   10240 
   10241 /* save r to the memory stack, and mark it as being free */
   10242 void save_reg(int r)
   10243 {
   10244     int l, saved, size, align;
   10245     SValue *p, sv;
   10246     CType *type;
   10247 
   10248     /* modify all stack values */
   10249     saved = 0;
   10250     l = 0;
   10251     for(p=vstack;p<=vtop;p++) {
   10252         if ((p->r & VT_VALMASK) == r ||
   10253             (p->r2 & VT_VALMASK) == r) {
   10254             /* must save value on stack if not already done */
   10255             if (!saved) {
   10256                 /* NOTE: must reload 'r' because r might be equal to r2 */
   10257                 r = p->r & VT_VALMASK;
   10258                 /* store register in the stack */
   10259                 type = &p->type;
   10260                 if ((p->r & VT_LVAL) ||
   10261                     (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
   10262                     type = &int_type;
   10263                 size = type_size(type, &align);
   10264                 loc = (loc - size) & -align;
   10265                 sv.type.t = type->t;
   10266                 sv.r = VT_LOCAL | VT_LVAL;
   10267                 sv.c.ul = loc;
   10268                 store(r, &sv);
   10269 #ifdef TCC_TARGET_I386
   10270                 /* x86 specific: need to pop fp register ST0 if saved */
   10271                 if (r == TREG_ST0) {
   10272                     o(0xd9dd); /* fstp %st(1) */
   10273                 }
   10274 #endif
   10275                 /* special long long case */
   10276                 if ((type->t & VT_BTYPE) == VT_LLONG) {
   10277                     sv.c.ul += 4;
   10278                     store(p->r2, &sv);
   10279                 }
   10280                 l = loc;
   10281                 saved = 1;
   10282             }
   10283             /* mark that stack entry as being saved on the stack */
   10284             if (p->r & VT_LVAL) {
   10285                 /* also clear the bounded flag because the
   10286                    relocation address of the function was stored in
   10287                    p->c.ul */
   10288                 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
   10289             } else {
   10290                 p->r = lvalue_type(p->type.t) | VT_LOCAL;
   10291             }
   10292             p->r2 = VT_CONST;
   10293             p->c.ul = l;
   10294         }
   10295     }
   10296 }
   10297 
   10298 /* find a register of class 'rc2' with at most one reference on stack.
   10299  * If none, call get_reg(rc) */
   10300 int get_reg_ex(int rc, int rc2)
   10301 {
   10302     int r;
   10303     SValue *p;
   10304 
   10305     for(r=0;r<NB_REGS;r++) {
   10306         if (reg_classes[r] & rc2) {
   10307             int n;
   10308             n=0;
   10309             for(p = vstack; p <= vtop; p++) {
   10310                 if ((p->r & VT_VALMASK) == r ||
   10311                     (p->r2 & VT_VALMASK) == r)
   10312                     n++;
   10313             }
   10314             if (n <= 1)
   10315                 return r;
   10316         }
   10317     }
   10318     return get_reg(rc);
   10319 }
   10320 
   10321 /* find a free register of class 'rc'. If none, save one register */
   10322 int get_reg(int rc)
   10323 {
   10324     int r;
   10325     SValue *p;
   10326 
   10327     /* find a free register */
   10328     for(r=0;r<NB_REGS;r++) {
   10329         if (reg_classes[r] & rc) {
   10330             for(p=vstack;p<=vtop;p++) {
   10331                 if ((p->r & VT_VALMASK) == r ||
   10332                     (p->r2 & VT_VALMASK) == r)
   10333                     goto notfound;
   10334             }
   10335             return r;
   10336         }
   10337     notfound: ;
   10338     }
   10339 
   10340     /* no register left : free the first one on the stack (VERY
   10341        IMPORTANT to start from the bottom to ensure that we don't
   10342        spill registers used in gen_opi()) */
   10343     for(p=vstack;p<=vtop;p++) {
   10344         r = p->r & VT_VALMASK;
   10345         if (r < VT_CONST && (reg_classes[r] & rc))
   10346             goto save_found;
   10347         /* also look at second register (if long long) */
   10348         r = p->r2 & VT_VALMASK;
   10349         if (r < VT_CONST && (reg_classes[r] & rc)) {
   10350         save_found:
   10351             save_reg(r);
   10352             return r;
   10353         }
   10354     }
   10355     /* Should never comes here */
   10356     return -1;
   10357 }
   10358 
   10359 /* save registers up to (vtop - n) stack entry */
   10360 void save_regs(int n)
   10361 {
   10362     int r;
   10363     SValue *p, *p1;
   10364     p1 = vtop - n;
   10365     for(p = vstack;p <= p1; p++) {
   10366         r = p->r & VT_VALMASK;
   10367         if (r < VT_CONST) {
   10368             save_reg(r);
   10369         }
   10370     }
   10371 }
   10372 
   10373 /* move register 's' to 'r', and flush previous value of r to memory
   10374    if needed */
   10375 void move_reg(int r, int s)
   10376 {
   10377     SValue sv;
   10378 
   10379     if (r != s) {
   10380         save_reg(r);
   10381         sv.type.t = VT_INT;
   10382         sv.r = s;
   10383         sv.c.ul = 0;
   10384         load(r, &sv);
   10385     }
   10386 }
   10387 
   10388 /* get address of vtop (vtop MUST BE an lvalue) */
   10389 void gaddrof(void)
   10390 {
   10391     vtop->r &= ~VT_LVAL;
   10392     /* tricky: if saved lvalue, then we can go back to lvalue */
   10393     if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
   10394         vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
   10395 }
   10396 
   10397 #ifdef CONFIG_TCC_BCHECK
   10398 /* generate lvalue bound code */
   10399 void gbound(void)
   10400 {
   10401     int lval_type;
   10402     CType type1;
   10403 
   10404     vtop->r &= ~VT_MUSTBOUND;
   10405     /* if lvalue, then use checking code before dereferencing */
   10406     if (vtop->r & VT_LVAL) {
   10407         /* if not VT_BOUNDED value, then make one */
   10408         if (!(vtop->r & VT_BOUNDED)) {
   10409             lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
   10410             /* must save type because we must set it to int to get pointer */
   10411             type1 = vtop->type;
   10412             vtop->type.t = VT_INT;
   10413             gaddrof();
   10414             vpushi(0);
   10415             gen_bounded_ptr_add();
   10416             vtop->r |= lval_type;
   10417             vtop->type = type1;
   10418         }
   10419         /* then check for dereferencing */
   10420         gen_bounded_ptr_deref();
   10421     }
   10422 }
   10423 #endif
   10424 
   10425 /* store vtop a register belonging to class 'rc'. lvalues are
   10426    converted to values. Cannot be used if cannot be converted to
   10427    register value (such as structures). */
   10428 int gv(int rc)
   10429 {
   10430     int r, r2, rc2, bit_pos, bit_size, size, align, i;
   10431     unsigned long long ll;
   10432 
   10433     /* NOTE: get_reg can modify vstack[] */
   10434     if (vtop->type.t & VT_BITFIELD) {
   10435         bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
   10436         bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
   10437         /* remove bit field info to avoid loops */
   10438         vtop->type.t &= ~(VT_BITFIELD | (~0U << VT_STRUCT_SHIFT));
   10439         /* generate shifts */
   10440         vpushi(32 - (bit_pos + bit_size));
   10441         gen_op(TOK_SHL);
   10442         vpushi(32 - bit_size);
   10443         /* NOTE: transformed to SHR if unsigned */
   10444         gen_op(TOK_SAR);
   10445         r = gv(rc);
   10446     } else {
   10447         if (is_float(vtop->type.t) &&
   10448             (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
   10449             Sym *sym;
   10450             int *ptr;
   10451             unsigned long offset;
   10452 
   10453             /* XXX: unify with initializers handling ? */
   10454             /* CPUs usually cannot use float constants, so we store them
   10455                generically in data segment */
   10456             size = type_size(&vtop->type, &align);
   10457             offset = (data_section->data_offset + align - 1) & -align;
   10458             data_section->data_offset = offset;
   10459             /* XXX: not portable yet */
   10460             ptr = section_ptr_add(data_section, size);
   10461             size = size >> 2;
   10462             for(i=0;i<size;i++)
   10463                 ptr[i] = vtop->c.tab[i];
   10464             sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
   10465             vtop->r |= VT_LVAL | VT_SYM;
   10466             vtop->sym = sym;
   10467             vtop->c.ul = 0;
   10468         }
   10469 #ifdef CONFIG_TCC_BCHECK
   10470         if (vtop->r & VT_MUSTBOUND)
   10471             gbound();
   10472 #endif
   10473 
   10474         r = vtop->r & VT_VALMASK;
   10475         /* need to reload if:
   10476            - constant
   10477            - lvalue (need to dereference pointer)
   10478            - already a register, but not in the right class */
   10479         if (r >= VT_CONST ||
   10480             (vtop->r & VT_LVAL) ||
   10481             !(reg_classes[r] & rc) ||
   10482             ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
   10483              !(reg_classes[vtop->r2] & rc))) {
   10484             r = get_reg(rc);
   10485             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
   10486                 /* two register type load : expand to two words
   10487                    temporarily */
   10488                 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
   10489                     /* load constant */
   10490                     ll = vtop->c.ull;
   10491                     vtop->c.ui = ll; /* first word */
   10492                     load(r, vtop);
   10493                     vtop->r = r; /* save register value */
   10494                     vpushi(ll >> 32); /* second word */
   10495                 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
   10496                            (vtop->r & VT_LVAL)) {
   10497                     /* We do not want to modifier the long long
   10498                        pointer here, so the safest (and less
   10499                        efficient) is to save all the other registers
   10500                        in the stack. XXX: totally inefficient. */
   10501                     save_regs(1);
   10502                     /* load from memory */
   10503                     load(r, vtop);
   10504                     vdup();
   10505                     vtop[-1].r = r; /* save register value */
   10506                     /* increment pointer to get second word */
   10507                     vtop->type.t = VT_INT;
   10508                     gaddrof();
   10509                     vpushi(4);
   10510                     gen_op('+');
   10511                     vtop->r |= VT_LVAL;
   10512                 } else {
   10513                     /* move registers */
   10514                     load(r, vtop);
   10515                     vdup();
   10516                     vtop[-1].r = r; /* save register value */
   10517                     vtop->r = vtop[-1].r2;
   10518                 }
   10519                 /* allocate second register */
   10520                 rc2 = RC_INT;
   10521                 if (rc == RC_IRET)
   10522                     rc2 = RC_LRET;
   10523                 r2 = get_reg(rc2);
   10524                 load(r2, vtop);
   10525                 vpop();
   10526                 /* write second register */
   10527                 vtop->r2 = r2;
   10528             } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
   10529                 int t1, t;
   10530                 /* lvalue of scalar type : need to use lvalue type
   10531                    because of possible cast */
   10532                 t = vtop->type.t;
   10533                 t1 = t;
   10534                 /* compute memory access type */
   10535                 if (vtop->r & VT_LVAL_BYTE)
   10536                     t = VT_BYTE;
   10537                 else if (vtop->r & VT_LVAL_SHORT)
   10538                     t = VT_SHORT;
   10539                 if (vtop->r & VT_LVAL_UNSIGNED)
   10540                     t |= VT_UNSIGNED;
   10541                 vtop->type.t = t;
   10542                 load(r, vtop);
   10543                 /* restore wanted type */
   10544                 vtop->type.t = t1;
   10545             } else {
   10546                 /* one register type load */
   10547                 load(r, vtop);
   10548             }
   10549         }
   10550         vtop->r = r;
   10551 #ifdef TCC_TARGET_C67
   10552         /* uses register pairs for doubles */
   10553         if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
   10554             vtop->r2 = r+1;
   10555 #endif
   10556     }
   10557     return r;
   10558 }
   10559 
   10560 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
   10561 void gv2(int rc1, int rc2)
   10562 {
   10563     int v;
   10564 
   10565     /* generate more generic register first. But VT_JMP or VT_CMP
   10566        values must be generated first in all cases to avoid possible
   10567        reload errors */
   10568     v = vtop[0].r & VT_VALMASK;
   10569     if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
   10570         vswap();
   10571         gv(rc1);
   10572         vswap();
   10573         gv(rc2);
   10574         /* test if reload is needed for first register */
   10575         if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
   10576             vswap();
   10577             gv(rc1);
   10578             vswap();
   10579         }
   10580     } else {
   10581         gv(rc2);
   10582         vswap();
   10583         gv(rc1);
   10584         vswap();
   10585         /* test if reload is needed for first register */
   10586         if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
   10587             gv(rc2);
   10588         }
   10589     }
   10590 }
   10591 
   10592 /* expand long long on stack in two int registers */
   10593 void lexpand(void)
   10594 {
   10595     int u;
   10596 
   10597     u = vtop->type.t & VT_UNSIGNED;
   10598     gv(RC_INT);
   10599     vdup();
   10600     vtop[0].r = vtop[-1].r2;
   10601     vtop[0].r2 = VT_CONST;
   10602     vtop[-1].r2 = VT_CONST;
   10603     vtop[0].type.t = VT_INT | u;
   10604     vtop[-1].type.t = VT_INT | u;
   10605 }
   10606 
   10607 #ifdef TCC_TARGET_ARM
   10608 /* expand long long on stack */
   10609 void lexpand_nr(void)
   10610 {
   10611     int u,v;
   10612 
   10613     u = vtop->type.t & VT_UNSIGNED;
   10614     vdup();
   10615     vtop->r2 = VT_CONST;
   10616     vtop->type.t = VT_INT | u;
   10617     v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
   10618     if (v == VT_CONST) {
   10619       vtop[-1].c.ui = vtop->c.ull;
   10620       vtop->c.ui = vtop->c.ull >> 32;
   10621       vtop->r = VT_CONST;
   10622     } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
   10623       vtop->c.ui += 4;
   10624       vtop->r = vtop[-1].r;
   10625     } else if (v > VT_CONST) {
   10626       vtop--;
   10627       lexpand();
   10628     } else
   10629       vtop->r = vtop[-1].r2;
   10630     vtop[-1].r2 = VT_CONST;
   10631     vtop[-1].type.t = VT_INT | u;
   10632 }
   10633 #endif
   10634 
   10635 /* build a long long from two ints */
   10636 void lbuild(int t)
   10637 {
   10638     gv2(RC_INT, RC_INT);
   10639     vtop[-1].r2 = vtop[0].r;
   10640     vtop[-1].type.t = t;
   10641     vpop();
   10642 }
   10643 
   10644 /* rotate n first stack elements to the bottom
   10645    I1 ... In -> I2 ... In I1 [top is right]
   10646 */
   10647 void vrotb(int n)
   10648 {
   10649     int i;
   10650     SValue tmp;
   10651 
   10652     tmp = vtop[-n + 1];
   10653     for(i=-n+1;i!=0;i++)
   10654         vtop[i] = vtop[i+1];
   10655     vtop[0] = tmp;
   10656 }
   10657 
   10658 /* rotate n first stack elements to the top
   10659    I1 ... In -> In I1 ... I(n-1)  [top is right]
   10660  */
   10661 void vrott(int n)
   10662 {
   10663     int i;
   10664     SValue tmp;
   10665 
   10666     tmp = vtop[0];
   10667     for(i = 0;i < n - 1; i++)
   10668         vtop[-i] = vtop[-i - 1];
   10669     vtop[-n + 1] = tmp;
   10670 }
   10671 
   10672 #ifdef TCC_TARGET_ARM
   10673 /* like vrott but in other direction
   10674    In ... I1 -> I(n-1) ... I1 In  [top is right]
   10675  */
   10676 void vnrott(int n)
   10677 {
   10678     int i;
   10679     SValue tmp;
   10680 
   10681     tmp = vtop[-n + 1];
   10682     for(i = n - 1; i > 0; i--)
   10683         vtop[-i] = vtop[-i + 1];
   10684     vtop[0] = tmp;
   10685 }
   10686 #endif
   10687 
   10688 /* pop stack value */
   10689 void vpop(void)
   10690 {
   10691     int v;
   10692     v = vtop->r & VT_VALMASK;
   10693 #ifdef TCC_TARGET_I386
   10694     /* for x86, we need to pop the FP stack */
   10695     if (v == TREG_ST0 && !nocode_wanted) {
   10696         o(0xd9dd); /* fstp %st(1) */
   10697     } else
   10698 #endif
   10699     if (v == VT_JMP || v == VT_JMPI) {
   10700         /* need to put correct jump if && or || without test */
   10701         gsym(vtop->c.ul);
   10702     }
   10703     vtop--;
   10704 }
   10705 
   10706 /* convert stack entry to register and duplicate its value in another
   10707    register */
   10708 void gv_dup(void)
   10709 {
   10710     int rc, t, r, r1;
   10711     SValue sv;
   10712 
   10713     t = vtop->type.t;
   10714     if ((t & VT_BTYPE) == VT_LLONG) {
   10715         lexpand();
   10716         gv_dup();
   10717         vswap();
   10718         vrotb(3);
   10719         gv_dup();
   10720         vrotb(4);
   10721         /* stack: H L L1 H1 */
   10722         lbuild(t);
   10723         vrotb(3);
   10724         vrotb(3);
   10725         vswap();
   10726         lbuild(t);
   10727         vswap();
   10728     } else {
   10729         /* duplicate value */
   10730         rc = RC_INT;
   10731         sv.type.t = VT_INT;
   10732         if (is_float(t)) {
   10733             rc = RC_FLOAT;
   10734             sv.type.t = t;
   10735         }
   10736         r = gv(rc);
   10737         r1 = get_reg(rc);
   10738         sv.r = r;
   10739         sv.c.ul = 0;
   10740         load(r1, &sv); /* move r to r1 */
   10741         vdup();
   10742         /* duplicates value */
   10743         vtop->r = r1;
   10744     }
   10745 }
   10746 
   10747 /* generate CPU independent (unsigned) long long operations */
   10748 void gen_opl(int op)
   10749 {
   10750     int t, a, b, op1, c, i;
   10751     int func;
   10752     SValue tmp;
   10753 
   10754     switch(op) {
   10755     case '/':
   10756     case TOK_PDIV:
   10757         func = TOK___divdi3;
   10758         goto gen_func;
   10759     case TOK_UDIV:
   10760         func = TOK___udivdi3;
   10761         goto gen_func;
   10762     case '%':
   10763         func = TOK___moddi3;
   10764         goto gen_func;
   10765     case TOK_UMOD:
   10766         func = TOK___umoddi3;
   10767     gen_func:
   10768         /* call generic long long function */
   10769         vpush_global_sym(&func_old_type, func);
   10770         vrott(3);
   10771         gfunc_call(2);
   10772         vpushi(0);
   10773         vtop->r = REG_IRET;
   10774         vtop->r2 = REG_LRET;
   10775         break;
   10776     case '^':
   10777     case '&':
   10778     case '|':
   10779     case '*':
   10780     case '+':
   10781     case '-':
   10782         t = vtop->type.t;
   10783         vswap();
   10784         lexpand();
   10785         vrotb(3);
   10786         lexpand();
   10787         /* stack: L1 H1 L2 H2 */
   10788         tmp = vtop[0];
   10789         vtop[0] = vtop[-3];
   10790         vtop[-3] = tmp;
   10791         tmp = vtop[-2];
   10792         vtop[-2] = vtop[-3];
   10793         vtop[-3] = tmp;
   10794         vswap();
   10795         /* stack: H1 H2 L1 L2 */
   10796         if (op == '*') {
   10797             vpushv(vtop - 1);
   10798             vpushv(vtop - 1);
   10799             gen_op(TOK_UMULL);
   10800             lexpand();
   10801             /* stack: H1 H2 L1 L2 ML MH */
   10802             for(i=0;i<4;i++)
   10803                 vrotb(6);
   10804             /* stack: ML MH H1 H2 L1 L2 */
   10805             tmp = vtop[0];
   10806             vtop[0] = vtop[-2];
   10807             vtop[-2] = tmp;
   10808             /* stack: ML MH H1 L2 H2 L1 */
   10809             gen_op('*');
   10810             vrotb(3);
   10811             vrotb(3);
   10812             gen_op('*');
   10813             /* stack: ML MH M1 M2 */
   10814             gen_op('+');
   10815             gen_op('+');
   10816         } else if (op == '+' || op == '-') {
   10817             /* XXX: add non carry method too (for MIPS or alpha) */
   10818             if (op == '+')
   10819                 op1 = TOK_ADDC1;
   10820             else
   10821                 op1 = TOK_SUBC1;
   10822             gen_op(op1);
   10823             /* stack: H1 H2 (L1 op L2) */
   10824             vrotb(3);
   10825             vrotb(3);
   10826             gen_op(op1 + 1); /* TOK_xxxC2 */
   10827         } else {
   10828             gen_op(op);
   10829             /* stack: H1 H2 (L1 op L2) */
   10830             vrotb(3);
   10831             vrotb(3);
   10832             /* stack: (L1 op L2) H1 H2 */
   10833             gen_op(op);
   10834             /* stack: (L1 op L2) (H1 op H2) */
   10835         }
   10836         /* stack: L H */
   10837         lbuild(t);
   10838         break;
   10839     case TOK_SAR:
   10840     case TOK_SHR:
   10841     case TOK_SHL:
   10842         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
   10843             t = vtop[-1].type.t;
   10844             vswap();
   10845             lexpand();
   10846             vrotb(3);
   10847             /* stack: L H shift */
   10848             c = (int)vtop->c.i;
   10849             /* constant: simpler */
   10850             /* NOTE: all comments are for SHL. the other cases are
   10851                done by swapping words */
   10852             vpop();
   10853             if (op != TOK_SHL)
   10854                 vswap();
   10855             if (c >= 32) {
   10856                 /* stack: L H */
   10857                 vpop();
   10858                 if (c > 32) {
   10859                     vpushi(c - 32);
   10860                     gen_op(op);
   10861                 }
   10862                 if (op != TOK_SAR) {
   10863                     vpushi(0);
   10864                 } else {
   10865                     gv_dup();
   10866                     vpushi(31);
   10867                     gen_op(TOK_SAR);
   10868                 }
   10869                 vswap();
   10870             } else {
   10871                 vswap();
   10872                 gv_dup();
   10873                 /* stack: H L L */
   10874                 vpushi(c);
   10875                 gen_op(op);
   10876                 vswap();
   10877                 vpushi(32 - c);
   10878                 if (op == TOK_SHL)
   10879                     gen_op(TOK_SHR);
   10880                 else
   10881                     gen_op(TOK_SHL);
   10882                 vrotb(3);
   10883                 /* stack: L L H */
   10884                 vpushi(c);
   10885                 if (op == TOK_SHL)
   10886                     gen_op(TOK_SHL);
   10887                 else
   10888                     gen_op(TOK_SHR);
   10889                 gen_op('|');
   10890             }
   10891             if (op != TOK_SHL)
   10892                 vswap();
   10893             lbuild(t);
   10894         } else {
   10895             /* XXX: should provide a faster fallback on x86 ? */
   10896             switch(op) {
   10897             case TOK_SAR:
   10898                 func = TOK___sardi3;
   10899                 goto gen_func;
   10900             case TOK_SHR:
   10901                 func = TOK___shrdi3;
   10902                 goto gen_func;
   10903             case TOK_SHL:
   10904                 func = TOK___shldi3;
   10905                 goto gen_func;
   10906             }
   10907         }
   10908         break;
   10909     default:
   10910         /* compare operations */
   10911         t = vtop->type.t;
   10912         vswap();
   10913         lexpand();
   10914         vrotb(3);
   10915         lexpand();
   10916         /* stack: L1 H1 L2 H2 */
   10917         tmp = vtop[-1];
   10918         vtop[-1] = vtop[-2];
   10919         vtop[-2] = tmp;
   10920         /* stack: L1 L2 H1 H2 */
   10921         /* compare high */
   10922         op1 = op;
   10923         /* when values are equal, we need to compare low words. since
   10924            the jump is inverted, we invert the test too. */
   10925         if (op1 == TOK_LT)
   10926             op1 = TOK_LE;
   10927         else if (op1 == TOK_GT)
   10928             op1 = TOK_GE;
   10929         else if (op1 == TOK_ULT)
   10930             op1 = TOK_ULE;
   10931         else if (op1 == TOK_UGT)
   10932             op1 = TOK_UGE;
   10933         a = 0;
   10934         b = 0;
   10935         gen_op(op1);
   10936         if (op1 != TOK_NE) {
   10937             a = gtst(1, 0);
   10938         }
   10939         if (op != TOK_EQ) {
   10940             /* generate non equal test */
   10941             /* XXX: NOT PORTABLE yet */
   10942             if (a == 0) {
   10943                 b = gtst(0, 0);
   10944             } else {
   10945 #if defined(TCC_TARGET_I386)
   10946                 b = psym(0x850f, 0);
   10947 #elif defined(TCC_TARGET_ARM)
   10948 		b = ind;
   10949 		o(0x1A000000 | encbranch(ind, 0, 1));
   10950 #elif defined(TCC_TARGET_C67)
   10951                 error("not implemented");
   10952 #else
   10953 #error not supported
   10954 #endif
   10955             }
   10956         }
   10957         /* compare low. Always unsigned */
   10958         op1 = op;
   10959         if (op1 == TOK_LT)
   10960             op1 = TOK_ULT;
   10961         else if (op1 == TOK_LE)
   10962             op1 = TOK_ULE;
   10963         else if (op1 == TOK_GT)
   10964             op1 = TOK_UGT;
   10965         else if (op1 == TOK_GE)
   10966             op1 = TOK_UGE;
   10967         gen_op(op1);
   10968         a = gtst(1, a);
   10969         gsym(b);
   10970         vseti(VT_JMPI, a);
   10971         break;
   10972     }
   10973 }
   10974 
   10975 /* handle integer constant optimizations and various machine
   10976    independent opt */
   10977 void gen_opic(int op)
   10978 {
   10979     int fc, c1, c2, n;
   10980     SValue *v1, *v2;
   10981 
   10982     v1 = vtop - 1;
   10983     v2 = vtop;
   10984     /* currently, we cannot do computations with forward symbols */
   10985     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
   10986     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
   10987     if (c1 && c2) {
   10988         fc = v2->c.i;
   10989         switch(op) {
   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         case '|': v1->c.i |= fc; break;
   10995         case '*': v1->c.i *= fc; break;
   10996 
   10997         case TOK_PDIV:
   10998         case '/':
   10999         case '%':
   11000         case TOK_UDIV:
   11001         case TOK_UMOD:
   11002             /* if division by zero, generate explicit division */
   11003             if (fc == 0) {
   11004                 if (const_wanted)
   11005                     error("division by zero in constant");
   11006                 goto general_case;
   11007             }
   11008             switch(op) {
   11009             default: v1->c.i /= fc; break;
   11010             case '%': v1->c.i %= fc; break;
   11011             case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
   11012             case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
   11013             }
   11014             break;
   11015         case TOK_SHL: v1->c.i <<= fc; break;
   11016         case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
   11017         case TOK_SAR: v1->c.i >>= fc; break;
   11018             /* tests */
   11019         case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
   11020         case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
   11021         case TOK_EQ: v1->c.i = v1->c.i == fc; break;
   11022         case TOK_NE: v1->c.i = v1->c.i != fc; break;
   11023         case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
   11024         case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
   11025         case TOK_LT: v1->c.i = v1->c.i < fc; break;
   11026         case TOK_GE: v1->c.i = v1->c.i >= fc; break;
   11027         case TOK_LE: v1->c.i = v1->c.i <= fc; break;
   11028         case TOK_GT: v1->c.i = v1->c.i > fc; break;
   11029             /* logical */
   11030         case TOK_LAND: v1->c.i = v1->c.i && fc; break;
   11031         case TOK_LOR: v1->c.i = v1->c.i || fc; break;
   11032         default:
   11033             goto general_case;
   11034         }
   11035         vtop--;
   11036     } else {
   11037         /* if commutative ops, put c2 as constant */
   11038         if (c1 && (op == '+' || op == '&' || op == '^' ||
   11039                    op == '|' || op == '*')) {
   11040             vswap();
   11041             swap(&c1, &c2);
   11042         }
   11043         fc = vtop->c.i;
   11044         if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
   11045                      op == TOK_PDIV) &&
   11046                     fc == 1) ||
   11047                    ((op == '+' || op == '-' || op == '|' || op == '^' ||
   11048                      op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
   11049                     fc == 0) ||
   11050                    (op == '&' &&
   11051                     fc == -1))) {
   11052             /* nothing to do */
   11053             vtop--;
   11054         } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
   11055             /* try to use shifts instead of muls or divs */
   11056             if (fc > 0 && (fc & (fc - 1)) == 0) {
   11057                 n = -1;
   11058                 while (fc) {
   11059                     fc >>= 1;
   11060                     n++;
   11061                 }
   11062                 vtop->c.i = n;
   11063                 if (op == '*')
   11064                     op = TOK_SHL;
   11065                 else if (op == TOK_PDIV)
   11066                     op = TOK_SAR;
   11067                 else
   11068                     op = TOK_SHR;
   11069             }
   11070             goto general_case;
   11071         } else if (c2 && (op == '+' || op == '-') &&
   11072                    (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
   11073                    (VT_CONST | VT_SYM)) {
   11074             /* symbol + constant case */
   11075             if (op == '-')
   11076                 fc = -fc;
   11077             vtop--;
   11078             vtop->c.i += fc;
   11079         } else {
   11080         general_case:
   11081             if (!nocode_wanted) {
   11082                 /* call low level op generator */
   11083                 gen_opi(op);
   11084             } else {
   11085                 vtop--;
   11086             }
   11087         }
   11088     }
   11089 }
   11090 
   11091 /* generate a floating point operation with constant propagation */
   11092 void gen_opif(int op)
   11093 {
   11094     int c1, c2;
   11095     SValue *v1, *v2;
   11096     long double f1, f2;
   11097 
   11098     v1 = vtop - 1;
   11099     v2 = vtop;
   11100     /* currently, we cannot do computations with forward symbols */
   11101     c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
   11102     c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
   11103     if (c1 && c2) {
   11104         if (v1->type.t == VT_FLOAT) {
   11105             f1 = v1->c.f;
   11106             f2 = v2->c.f;
   11107         } else if (v1->type.t == VT_DOUBLE) {
   11108             f1 = v1->c.d;
   11109             f2 = v2->c.d;
   11110         } else {
   11111             f1 = v1->c.ld;
   11112             f2 = v2->c.ld;
   11113         }
   11114 
   11115         /* NOTE: we only do constant propagation if finite number (not
   11116            NaN or infinity) (ANSI spec) */
   11117         if (!ieee_finite(f1) || !ieee_finite(f2))
   11118             goto general_case;
   11119 
   11120         switch(op) {
   11121         case '+': f1 += f2; break;
   11122         case '-': f1 -= f2; break;
   11123         case '*': f1 *= f2; break;
   11124         case '/':
   11125             if (f2 == 0.0) {
   11126                 if (const_wanted)
   11127                     error("division by zero in constant");
   11128                 goto general_case;
   11129             }
   11130             f1 /= f2;
   11131             break;
   11132             /* XXX: also handles tests ? */
   11133         default:
   11134             goto general_case;
   11135         }
   11136         /* XXX: overflow test ? */
   11137         if (v1->type.t == VT_FLOAT) {
   11138             v1->c.f = f1;
   11139         } else if (v1->type.t == VT_DOUBLE) {
   11140             v1->c.d = f1;
   11141         } else {
   11142             v1->c.ld = f1;
   11143         }
   11144         vtop--;
   11145     } else {
   11146     general_case:
   11147         if (!nocode_wanted) {
   11148             gen_opf(op);
   11149         } else {
   11150             vtop--;
   11151         }
   11152     }
   11153 }
   11154 
   11155 /* return the pointed type of t */
   11156 static inline CType *pointed_type(CType *type)
   11157 {
   11158     return &type->ref->type;
   11159 }
   11160 
   11161 static int pointed_size(CType *type)
   11162 {
   11163     int align;
   11164     return type_size(pointed_type(type), &align);
   11165 }
   11166 
   11167 static inline int is_null_pointer(SValue *p)
   11168 {
   11169     if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
   11170         return 0;
   11171     return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
   11172         ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
   11173 }
   11174 
   11175 static inline int is_integer_btype(int bt)
   11176 {
   11177     return (bt == VT_BYTE || bt == VT_SHORT ||
   11178             bt == VT_INT || bt == VT_LLONG);
   11179 }
   11180 
   11181 /* check types for comparison or substraction of pointers */
   11182 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
   11183 {
   11184     CType *type1, *type2, tmp_type1, tmp_type2;
   11185     int bt1, bt2;
   11186 
   11187     /* null pointers are accepted for all comparisons as gcc */
   11188     if (is_null_pointer(p1) || is_null_pointer(p2))
   11189         return;
   11190     type1 = &p1->type;
   11191     type2 = &p2->type;
   11192     bt1 = type1->t & VT_BTYPE;
   11193     bt2 = type2->t & VT_BTYPE;
   11194     /* accept comparison between pointer and integer with a warning */
   11195     if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
   11196         warning("comparison between pointer and integer");
   11197         return;
   11198     }
   11199 
   11200     /* both must be pointers or implicit function pointers */
   11201     if (bt1 == VT_PTR) {
   11202         type1 = pointed_type(type1);
   11203     } else if (bt1 != VT_FUNC)
   11204         goto invalid_operands;
   11205 
   11206     if (bt2 == VT_PTR) {
   11207         type2 = pointed_type(type2);
   11208     } else if (bt2 != VT_FUNC) {
   11209     invalid_operands:
   11210         error("invalid operands to binary %s", get_tok_str(op, NULL));
   11211     }
   11212     if ((type1->t & VT_BTYPE) == VT_VOID ||
   11213         (type2->t & VT_BTYPE) == VT_VOID)
   11214         return;
   11215     tmp_type1 = *type1;
   11216     tmp_type2 = *type2;
   11217     tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
   11218     tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
   11219     if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
   11220         /* gcc-like error if '-' is used */
   11221         if (op == '-')
   11222             goto invalid_operands;
   11223         else
   11224             warning("comparison of distinct pointer types lacks a cast");
   11225     }
   11226 }
   11227 
   11228 /* generic gen_op: handles types problems */
   11229 void gen_op(int op)
   11230 {
   11231     int u, t1, t2, bt1, bt2, t;
   11232     CType type1;
   11233 
   11234     t1 = vtop[-1].type.t;
   11235     t2 = vtop[0].type.t;
   11236     bt1 = t1 & VT_BTYPE;
   11237     bt2 = t2 & VT_BTYPE;
   11238 
   11239     if (bt1 == VT_PTR || bt2 == VT_PTR) {
   11240         /* at least one operand is a pointer */
   11241         /* relationnal op: must be both pointers */
   11242         if (op >= TOK_ULT && op <= TOK_GT) {
   11243             check_comparison_pointer_types(vtop - 1, vtop, op);
   11244             /* pointers are handled are unsigned */
   11245             t = VT_INT | VT_UNSIGNED;
   11246             goto std_op;
   11247         }
   11248         /* if both pointers, then it must be the '-' op */
   11249         if (bt1 == VT_PTR && bt2 == VT_PTR) {
   11250             if (op != '-')
   11251                 error("cannot use pointers here");
   11252             check_comparison_pointer_types(vtop - 1, vtop, op);
   11253             /* XXX: check that types are compatible */
   11254             u = pointed_size(&vtop[-1].type);
   11255             gen_opic(op);
   11256             /* set to integer type */
   11257             vtop->type.t = VT_INT;
   11258             vpushi(u);
   11259             gen_op(TOK_PDIV);
   11260         } else {
   11261             /* exactly one pointer : must be '+' or '-'. */
   11262             if (op != '-' && op != '+')
   11263                 error("cannot use pointers here");
   11264             /* Put pointer as first operand */
   11265             if (bt2 == VT_PTR) {
   11266                 vswap();
   11267                 swap(&t1, &t2);
   11268             }
   11269             type1 = vtop[-1].type;
   11270             /* XXX: cast to int ? (long long case) */
   11271             vpushi(pointed_size(&vtop[-1].type));
   11272             gen_op('*');
   11273 #ifdef CONFIG_TCC_BCHECK
   11274             /* if evaluating constant expression, no code should be
   11275                generated, so no bound check */
   11276             if (do_bounds_check && !const_wanted) {
   11277                 /* if bounded pointers, we generate a special code to
   11278                    test bounds */
   11279                 if (op == '-') {
   11280                     vpushi(0);
   11281                     vswap();
   11282                     gen_op('-');
   11283                 }
   11284                 gen_bounded_ptr_add();
   11285             } else
   11286 #endif
   11287             {
   11288                 gen_opic(op);
   11289             }
   11290             /* put again type if gen_opic() swaped operands */
   11291             vtop->type = type1;
   11292         }
   11293     } else if (is_float(bt1) || is_float(bt2)) {
   11294         /* compute bigger type and do implicit casts */
   11295         if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
   11296             t = VT_LDOUBLE;
   11297         } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
   11298             t = VT_DOUBLE;
   11299         } else {
   11300             t = VT_FLOAT;
   11301         }
   11302         /* floats can only be used for a few operations */
   11303         if (op != '+' && op != '-' && op != '*' && op != '/' &&
   11304             (op < TOK_ULT || op > TOK_GT))
   11305             error("invalid operands for binary operation");
   11306         goto std_op;
   11307     } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
   11308         /* cast to biggest op */
   11309         t = VT_LLONG;
   11310         /* convert to unsigned if it does not fit in a long long */
   11311         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
   11312             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
   11313             t |= VT_UNSIGNED;
   11314         goto std_op;
   11315     } else {
   11316         /* integer operations */
   11317         t = VT_INT;
   11318         /* convert to unsigned if it does not fit in an integer */
   11319         if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
   11320             (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
   11321             t |= VT_UNSIGNED;
   11322     std_op:
   11323         /* XXX: currently, some unsigned operations are explicit, so
   11324            we modify them here */
   11325         if (t & VT_UNSIGNED) {
   11326             if (op == TOK_SAR)
   11327                 op = TOK_SHR;
   11328             else if (op == '/')
   11329                 op = TOK_UDIV;
   11330             else if (op == '%')
   11331                 op = TOK_UMOD;
   11332             else if (op == TOK_LT)
   11333                 op = TOK_ULT;
   11334             else if (op == TOK_GT)
   11335                 op = TOK_UGT;
   11336             else if (op == TOK_LE)
   11337                 op = TOK_ULE;
   11338             else if (op == TOK_GE)
   11339                 op = TOK_UGE;
   11340         }
   11341         vswap();
   11342         type1.t = t;
   11343         gen_cast(&type1);
   11344         vswap();
   11345         /* special case for shifts and long long: we keep the shift as
   11346            an integer */
   11347         if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
   11348             type1.t = VT_INT;
   11349         gen_cast(&type1);
   11350         if (is_float(t))
   11351             gen_opif(op);
   11352         else if ((t & VT_BTYPE) == VT_LLONG)
   11353             gen_opl(op);
   11354         else
   11355             gen_opic(op);
   11356         if (op >= TOK_ULT && op <= TOK_GT) {
   11357             /* relationnal op: the result is an int */
   11358             vtop->type.t = VT_INT;
   11359         } else {
   11360             vtop->type.t = t;
   11361         }
   11362     }
   11363 }
   11364 
   11365 /* generic itof for unsigned long long case */
   11366 void gen_cvt_itof1(int t)
   11367 {
   11368     if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
   11369         (VT_LLONG | VT_UNSIGNED)) {
   11370 
   11371         if (t == VT_FLOAT)
   11372             vpush_global_sym(&func_old_type, TOK___ulltof);
   11373         else if (t == VT_DOUBLE)
   11374             vpush_global_sym(&func_old_type, TOK___ulltod);
   11375         else
   11376             vpush_global_sym(&func_old_type, TOK___ulltold);
   11377         vrott(2);
   11378         gfunc_call(1);
   11379         vpushi(0);
   11380         vtop->r = REG_FRET;
   11381     } else {
   11382         gen_cvt_itof(t);
   11383     }
   11384 }
   11385 
   11386 /* generic ftoi for unsigned long long case */
   11387 void gen_cvt_ftoi1(int t)
   11388 {
   11389     int st;
   11390 
   11391     if (t == (VT_LLONG | VT_UNSIGNED)) {
   11392         /* not handled natively */
   11393         st = vtop->type.t & VT_BTYPE;
   11394         if (st == VT_FLOAT)
   11395             vpush_global_sym(&func_old_type, TOK___fixunssfdi);
   11396         else if (st == VT_DOUBLE)
   11397             vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
   11398         else
   11399             vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
   11400         vrott(2);
   11401         gfunc_call(1);
   11402         vpushi(0);
   11403         vtop->r = REG_IRET;
   11404         vtop->r2 = REG_LRET;
   11405     } else {
   11406         gen_cvt_ftoi(t);
   11407     }
   11408 }
   11409 
   11410 /* force char or short cast */
   11411 void force_charshort_cast(int t)
   11412 {
   11413     int bits, dbt;
   11414     dbt = t & VT_BTYPE;
   11415     /* XXX: add optimization if lvalue : just change type and offset */
   11416     if (dbt == VT_BYTE)
   11417         bits = 8;
   11418     else
   11419         bits = 16;
   11420     if (t & VT_UNSIGNED) {
   11421         vpushi((1 << bits) - 1);
   11422         gen_op('&');
   11423     } else {
   11424         bits = 32 - bits;
   11425         vpushi(bits);
   11426         gen_op(TOK_SHL);
   11427         vpushi(bits);
   11428         gen_op(TOK_SAR);
   11429     }
   11430 }
   11431 
   11432 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
   11433 static void gen_cast(CType *type)
   11434 {
   11435     int sbt, dbt, sf, df, c;
   11436 
   11437     /* special delayed cast for char/short */
   11438     /* XXX: in some cases (multiple cascaded casts), it may still
   11439        be incorrect */
   11440     if (vtop->r & VT_MUSTCAST) {
   11441         vtop->r &= ~VT_MUSTCAST;
   11442         force_charshort_cast(vtop->type.t);
   11443     }
   11444 
   11445     /* bitfields first get cast to ints */
   11446     if (vtop->type.t & VT_BITFIELD) {
   11447         gv(RC_INT);
   11448     }
   11449 
   11450     dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
   11451     sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
   11452 
   11453     if (sbt != dbt && !nocode_wanted) {
   11454         sf = is_float(sbt);
   11455         df = is_float(dbt);
   11456         c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
   11457         if (sf && df) {
   11458             /* convert from fp to fp */
   11459             if (c) {
   11460                 /* constant case: we can do it now */
   11461                 /* XXX: in ISOC, cannot do it if error in convert */
   11462                 if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
   11463                     vtop->c.f = (float)vtop->c.d;
   11464                 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
   11465                     vtop->c.f = (float)vtop->c.ld;
   11466                 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
   11467                     vtop->c.d = (double)vtop->c.f;
   11468                 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
   11469                     vtop->c.d = (double)vtop->c.ld;
   11470                 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
   11471                     vtop->c.ld = (long double)vtop->c.f;
   11472                 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
   11473                     vtop->c.ld = (long double)vtop->c.d;
   11474             } else {
   11475                 /* non constant case: generate code */
   11476                 gen_cvt_ftof(dbt);
   11477             }
   11478         } else if (df) {
   11479             /* convert int to fp */
   11480             if (c) {
   11481                 switch(sbt) {
   11482                 case VT_LLONG | VT_UNSIGNED:
   11483                 case VT_LLONG:
   11484                     /* XXX: add const cases for long long */
   11485                     goto do_itof;
   11486                 case VT_INT | VT_UNSIGNED:
   11487                     switch(dbt) {
   11488                     case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
   11489                     case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
   11490                     case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
   11491                     }
   11492                     break;
   11493                 default:
   11494                     switch(dbt) {
   11495                     case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
   11496                     case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
   11497                     case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
   11498                     }
   11499                     break;
   11500                 }
   11501             } else {
   11502             do_itof:
   11503 #if !defined(TCC_TARGET_ARM)
   11504                 gen_cvt_itof1(dbt);
   11505 #else
   11506                 gen_cvt_itof(dbt);
   11507 #endif
   11508             }
   11509         } else if (sf) {
   11510             /* convert fp to int */
   11511             /* we handle char/short/etc... with generic code */
   11512             if (dbt != (VT_INT | VT_UNSIGNED) &&
   11513                 dbt != (VT_LLONG | VT_UNSIGNED) &&
   11514                 dbt != VT_LLONG)
   11515                 dbt = VT_INT;
   11516             if (c) {
   11517                 switch(dbt) {
   11518                 case VT_LLONG | VT_UNSIGNED:
   11519                 case VT_LLONG:
   11520                     /* XXX: add const cases for long long */
   11521                     goto do_ftoi;
   11522                 case VT_INT | VT_UNSIGNED:
   11523                     switch(sbt) {
   11524                     case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
   11525                     case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
   11526                     case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
   11527                     }
   11528                     break;
   11529                 default:
   11530                     /* int case */
   11531                     switch(sbt) {
   11532                     case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
   11533                     case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
   11534                     case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
   11535                     }
   11536                     break;
   11537                 }
   11538             } else {
   11539             do_ftoi:
   11540                 gen_cvt_ftoi1(dbt);
   11541             }
   11542             if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
   11543                 /* additional cast for char/short/bool... */
   11544                 vtop->type.t = dbt;
   11545                 gen_cast(type);
   11546             }
   11547         } else if ((dbt & VT_BTYPE) == VT_LLONG) {
   11548             if ((sbt & VT_BTYPE) != VT_LLONG) {
   11549                 /* scalar to long long */
   11550                 if (c) {
   11551                     if (sbt == (VT_INT | VT_UNSIGNED))
   11552                         vtop->c.ll = vtop->c.ui;
   11553                     else
   11554                         vtop->c.ll = vtop->c.i;
   11555                 } else {
   11556                     /* machine independent conversion */
   11557                     gv(RC_INT);
   11558                     /* generate high word */
   11559                     if (sbt == (VT_INT | VT_UNSIGNED)) {
   11560                         vpushi(0);
   11561                         gv(RC_INT);
   11562                     } else {
   11563                         gv_dup();
   11564                         vpushi(31);
   11565                         gen_op(TOK_SAR);
   11566                     }
   11567                     /* patch second register */
   11568                     vtop[-1].r2 = vtop->r;
   11569                     vpop();
   11570                 }
   11571             }
   11572         } else if (dbt == VT_BOOL) {
   11573             /* scalar to bool */
   11574             vpushi(0);
   11575             gen_op(TOK_NE);
   11576         } else if ((dbt & VT_BTYPE) == VT_BYTE ||
   11577                    (dbt & VT_BTYPE) == VT_SHORT) {
   11578             force_charshort_cast(dbt);
   11579         } else if ((dbt & VT_BTYPE) == VT_INT) {
   11580             /* scalar to int */
   11581             if (sbt == VT_LLONG) {
   11582                 /* from long long: just take low order word */
   11583                 lexpand();
   11584                 vpop();
   11585             }
   11586             /* if lvalue and single word type, nothing to do because
   11587                the lvalue already contains the real type size (see
   11588                VT_LVAL_xxx constants) */
   11589         }
   11590     }
   11591     vtop->type = *type;
   11592 }
   11593 
   11594 /* return type size. Put alignment at 'a' */
   11595 static int type_size(CType *type, int *a)
   11596 {
   11597     Sym *s;
   11598     int bt;
   11599 
   11600     bt = type->t & VT_BTYPE;
   11601     if (bt == VT_STRUCT) {
   11602         /* struct/union */
   11603         s = type->ref;
   11604         *a = s->r;
   11605         return s->c;
   11606     } else if (bt == VT_PTR) {
   11607         if (type->t & VT_ARRAY) {
   11608             s = type->ref;
   11609             return type_size(&s->type, a) * s->c;
   11610         } else {
   11611             *a = PTR_SIZE;
   11612             return PTR_SIZE;
   11613         }
   11614     } else if (bt == VT_LDOUBLE) {
   11615         *a = LDOUBLE_ALIGN;
   11616         return LDOUBLE_SIZE;
   11617     } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
   11618 #ifdef TCC_TARGET_I386
   11619         *a = 4;
   11620 #else
   11621         *a = 8;
   11622 #endif
   11623         return 8;
   11624     } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
   11625         *a = 4;
   11626         return 4;
   11627     } else if (bt == VT_SHORT) {
   11628         *a = 2;
   11629         return 2;
   11630     } else {
   11631         /* char, void, function, _Bool */
   11632         *a = 1;
   11633         return 1;
   11634     }
   11635 }
   11636 
   11637 /* modify type so that its it is a pointer to type. */
   11638 static void mk_pointer(CType *type)
   11639 {
   11640     Sym *s;
   11641     s = sym_push(SYM_FIELD, type, 0, -1);
   11642     type->t = VT_PTR | (type->t & ~VT_TYPE);
   11643     type->ref = s;
   11644 }
   11645 
   11646 /* compare function types. OLD functions match any new functions */
   11647 static int is_compatible_func(CType *type1, CType *type2)
   11648 {
   11649     Sym *s1, *s2;
   11650 
   11651     s1 = type1->ref;
   11652     s2 = type2->ref;
   11653     if (!is_compatible_types(&s1->type, &s2->type))
   11654         return 0;
   11655     /* check func_call */
   11656     if (s1->r != s2->r)
   11657         return 0;
   11658     /* XXX: not complete */
   11659     if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
   11660         return 1;
   11661     if (s1->c != s2->c)
   11662         return 0;
   11663     while (s1 != NULL) {
   11664         if (s2 == NULL)
   11665             return 0;
   11666         if (!is_compatible_types(&s1->type, &s2->type))
   11667             return 0;
   11668         s1 = s1->next;
   11669         s2 = s2->next;
   11670     }
   11671     if (s2)
   11672         return 0;
   11673     return 1;
   11674 }
   11675 
   11676 /* return true if type1 and type2 are exactly the same (including
   11677    qualifiers).
   11678 
   11679    - enums are not checked as gcc __builtin_types_compatible_p ()
   11680  */
   11681 static int is_compatible_types(CType *type1, CType *type2)
   11682 {
   11683     int bt1, t1, t2;
   11684 
   11685     t1 = type1->t & VT_TYPE;
   11686     t2 = type2->t & VT_TYPE;
   11687     /* XXX: bitfields ? */
   11688     if (t1 != t2)
   11689         return 0;
   11690     /* test more complicated cases */
   11691     bt1 = t1 & VT_BTYPE;
   11692     if (bt1 == VT_PTR) {
   11693         type1 = pointed_type(type1);
   11694         type2 = pointed_type(type2);
   11695         return is_compatible_types(type1, type2);
   11696     } else if (bt1 == VT_STRUCT) {
   11697         return (type1->ref == type2->ref);
   11698     } else if (bt1 == VT_FUNC) {
   11699         return is_compatible_func(type1, type2);
   11700     } else {
   11701         return 1;
   11702     }
   11703 }
   11704 
   11705 /* print a type. If 'varstr' is not NULL, then the variable is also
   11706    printed in the type */
   11707 /* XXX: union */
   11708 /* XXX: add array and function pointers */
   11709 void type_to_str(char *buf, int buf_size,
   11710                  CType *type, const char *varstr)
   11711 {
   11712     int bt, v, t;
   11713     Sym *s, *sa;
   11714     char buf1[256];
   11715     const char *tstr;
   11716 
   11717     t = type->t & VT_TYPE;
   11718     bt = t & VT_BTYPE;
   11719     buf[0] = '\0';
   11720     if (t & VT_CONSTANT)
   11721         pstrcat(buf, buf_size, "const ");
   11722     if (t & VT_VOLATILE)
   11723         pstrcat(buf, buf_size, "volatile ");
   11724     if (t & VT_UNSIGNED)
   11725         pstrcat(buf, buf_size, "unsigned ");
   11726     switch(bt) {
   11727     case VT_VOID:
   11728         tstr = "void";
   11729         goto add_tstr;
   11730     case VT_BOOL:
   11731         tstr = "_Bool";
   11732         goto add_tstr;
   11733     case VT_BYTE:
   11734         tstr = "char";
   11735         goto add_tstr;
   11736     case VT_SHORT:
   11737         tstr = "short";
   11738         goto add_tstr;
   11739     case VT_INT:
   11740         tstr = "int";
   11741         goto add_tstr;
   11742     case VT_LONG:
   11743         tstr = "long";
   11744         goto add_tstr;
   11745     case VT_LLONG:
   11746         tstr = "long long";
   11747         goto add_tstr;
   11748     case VT_FLOAT:
   11749         tstr = "float";
   11750         goto add_tstr;
   11751     case VT_DOUBLE:
   11752         tstr = "double";
   11753         goto add_tstr;
   11754     case VT_LDOUBLE:
   11755         tstr = "long double";
   11756     add_tstr:
   11757         pstrcat(buf, buf_size, tstr);
   11758         break;
   11759     case VT_ENUM:
   11760     case VT_STRUCT:
   11761         if (bt == VT_STRUCT)
   11762             tstr = "struct ";
   11763         else
   11764             tstr = "enum ";
   11765         pstrcat(buf, buf_size, tstr);
   11766         v = type->ref->v & ~SYM_STRUCT;
   11767         if (v >= SYM_FIRST_ANOM)
   11768             pstrcat(buf, buf_size, "<anonymous>");
   11769         else
   11770             pstrcat(buf, buf_size, get_tok_str(v, NULL));
   11771         break;
   11772     case VT_FUNC:
   11773         s = type->ref;
   11774         type_to_str(buf, buf_size, &s->type, varstr);
   11775         pstrcat(buf, buf_size, "(");
   11776         sa = s->next;
   11777         while (sa != NULL) {
   11778             type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
   11779             pstrcat(buf, buf_size, buf1);
   11780             sa = sa->next;
   11781             if (sa)
   11782                 pstrcat(buf, buf_size, ", ");
   11783         }
   11784         pstrcat(buf, buf_size, ")");
   11785         goto no_var;
   11786     case VT_PTR:
   11787         s = type->ref;
   11788         pstrcpy(buf1, sizeof(buf1), "*");
   11789         if (varstr)
   11790             pstrcat(buf1, sizeof(buf1), varstr);
   11791         type_to_str(buf, buf_size, &s->type, buf1);
   11792         goto no_var;
   11793     }
   11794     if (varstr) {
   11795         pstrcat(buf, buf_size, " ");
   11796         pstrcat(buf, buf_size, varstr);
   11797     }
   11798  no_var: ;
   11799 }
   11800 
   11801 /* verify type compatibility to store vtop in 'dt' type, and generate
   11802    casts if needed. */
   11803 static void gen_assign_cast(CType *dt)
   11804 {
   11805     CType *st, *type1, *type2, tmp_type1, tmp_type2;
   11806     char buf1[256], buf2[256];
   11807     int dbt, sbt;
   11808 
   11809     st = &vtop->type; /* source type */
   11810     dbt = dt->t & VT_BTYPE;
   11811     sbt = st->t & VT_BTYPE;
   11812     if (dt->t & VT_CONSTANT)
   11813         warning("assignment of read-only location");
   11814     switch(dbt) {
   11815     case VT_PTR:
   11816         /* special cases for pointers */
   11817         /* '0' can also be a pointer */
   11818         if (is_null_pointer(vtop))
   11819             goto type_ok;
   11820         /* accept implicit pointer to integer cast with warning */
   11821         if (is_integer_btype(sbt)) {
   11822             warning("assignment makes pointer from integer without a cast");
   11823             goto type_ok;
   11824         }
   11825         type1 = pointed_type(dt);
   11826         /* a function is implicitly a function pointer */
   11827         if (sbt == VT_FUNC) {
   11828             if ((type1->t & VT_BTYPE) != VT_VOID &&
   11829                 !is_compatible_types(pointed_type(dt), st))
   11830                 goto error;
   11831             else
   11832                 goto type_ok;
   11833         }
   11834         if (sbt != VT_PTR)
   11835             goto error;
   11836         type2 = pointed_type(st);
   11837         if ((type1->t & VT_BTYPE) == VT_VOID ||
   11838             (type2->t & VT_BTYPE) == VT_VOID) {
   11839             /* void * can match anything */
   11840         } else {
   11841             /* exact type match, except for unsigned */
   11842             tmp_type1 = *type1;
   11843             tmp_type2 = *type2;
   11844             tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
   11845             tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
   11846             if (!is_compatible_types(&tmp_type1, &tmp_type2))
   11847                 goto error;
   11848         }
   11849         /* check const and volatile */
   11850         if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
   11851             (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
   11852             warning("assignment discards qualifiers from pointer target type");
   11853         break;
   11854     case VT_BYTE:
   11855     case VT_SHORT:
   11856     case VT_INT:
   11857     case VT_LLONG:
   11858         if (sbt == VT_PTR || sbt == VT_FUNC) {
   11859             warning("assignment makes integer from pointer without a cast");
   11860         }
   11861         /* XXX: more tests */
   11862         break;
   11863     case VT_STRUCT:
   11864         tmp_type1 = *dt;
   11865         tmp_type2 = *st;
   11866         tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
   11867         tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
   11868         if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
   11869         error:
   11870             type_to_str(buf1, sizeof(buf1), st, NULL);
   11871             type_to_str(buf2, sizeof(buf2), dt, NULL);
   11872             error("cannot cast '%s' to '%s'", buf1, buf2);
   11873         }
   11874         break;
   11875     }
   11876  type_ok:
   11877     gen_cast(dt);
   11878 }
   11879 
   11880 /* store vtop in lvalue pushed on stack */
   11881 void vstore(void)
   11882 {
   11883     int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
   11884 
   11885     ft = vtop[-1].type.t;
   11886     sbt = vtop->type.t & VT_BTYPE;
   11887     dbt = ft & VT_BTYPE;
   11888     if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
   11889         (sbt == VT_INT && dbt == VT_SHORT)) {
   11890         /* optimize char/short casts */
   11891         delayed_cast = VT_MUSTCAST;
   11892         vtop->type.t = ft & VT_TYPE;
   11893         /* XXX: factorize */
   11894         if (ft & VT_CONSTANT)
   11895             warning("assignment of read-only location");
   11896     } else {
   11897         delayed_cast = 0;
   11898         if (!(ft & VT_BITFIELD))
   11899             gen_assign_cast(&vtop[-1].type);
   11900     }
   11901 
   11902     if (sbt == VT_STRUCT) {
   11903         /* if structure, only generate pointer */
   11904         /* structure assignment : generate memcpy */
   11905         /* XXX: optimize if small size */
   11906         if (!nocode_wanted) {
   11907             size = type_size(&vtop->type, &align);
   11908 
   11909             vpush_global_sym(&func_old_type, TOK_memcpy);
   11910 
   11911             /* destination */
   11912             vpushv(vtop - 2);
   11913             vtop->type.t = VT_INT;
   11914             gaddrof();
   11915             /* source */
   11916             vpushv(vtop - 2);
   11917             vtop->type.t = VT_INT;
   11918             gaddrof();
   11919             /* type size */
   11920             vpushi(size);
   11921             gfunc_call(3);
   11922 
   11923             vswap();
   11924             vpop();
   11925         } else {
   11926             vswap();
   11927             vpop();
   11928         }
   11929         /* leave source on stack */
   11930     } else if (ft & VT_BITFIELD) {
   11931         /* bitfield store handling */
   11932         bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
   11933         bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
   11934         /* remove bit field info to avoid loops */
   11935         vtop[-1].type.t = ft & ~(VT_BITFIELD | (~0U << VT_STRUCT_SHIFT));
   11936 
   11937         /* duplicate destination */
   11938         vdup();
   11939         vtop[-1] = vtop[-2];
   11940 
   11941         /* mask and shift source */
   11942         vpushi((1 << bit_size) - 1);
   11943         gen_op('&');
   11944         vpushi(bit_pos);
   11945         gen_op(TOK_SHL);
   11946         /* load destination, mask and or with source */
   11947         vswap();
   11948         vpushi(~(((1 << bit_size) - 1) << bit_pos));
   11949         gen_op('&');
   11950         gen_op('|');
   11951         /* store result */
   11952         vstore();
   11953     } else {
   11954 #ifdef CONFIG_TCC_BCHECK
   11955         /* bound check case */
   11956         if (vtop[-1].r & VT_MUSTBOUND) {
   11957             vswap();
   11958             gbound();
   11959             vswap();
   11960         }
   11961 #endif
   11962         if (!nocode_wanted) {
   11963             rc = RC_INT;
   11964             if (is_float(ft))
   11965                 rc = RC_FLOAT;
   11966             r = gv(rc);  /* generate value */
   11967             /* if lvalue was saved on stack, must read it */
   11968             if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
   11969                 SValue sv;
   11970                 t = get_reg(RC_INT);
   11971                 sv.type.t = VT_INT;
   11972                 sv.r = VT_LOCAL | VT_LVAL;
   11973                 sv.c.ul = vtop[-1].c.ul;
   11974                 load(t, &sv);
   11975                 vtop[-1].r = t | VT_LVAL;
   11976             }
   11977             store(r, vtop - 1);
   11978             /* two word case handling : store second register at word + 4 */
   11979             if ((ft & VT_BTYPE) == VT_LLONG) {
   11980                 vswap();
   11981                 /* convert to int to increment easily */
   11982                 vtop->type.t = VT_INT;
   11983                 gaddrof();
   11984                 vpushi(4);
   11985                 gen_op('+');
   11986                 vtop->r |= VT_LVAL;
   11987                 vswap();
   11988                 /* XXX: it works because r2 is spilled last ! */
   11989                 store(vtop->r2, vtop - 1);
   11990             }
   11991         }
   11992         vswap();
   11993         vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
   11994         vtop->r |= delayed_cast;
   11995     }
   11996 }
   11997 
   11998 /* post defines POST/PRE add. c is the token ++ or -- */
   11999 void inc(int post, int c)
   12000 {
   12001     test_lvalue();
   12002     vdup(); /* save lvalue */
   12003     if (post) {
   12004         gv_dup(); /* duplicate value */
   12005         vrotb(3);
   12006         vrotb(3);
   12007     }
   12008     /* add constant */
   12009     vpushi(c - TOK_MID);
   12010     gen_op('+');
   12011     vstore(); /* store value */
   12012     if (post)
   12013         vpop(); /* if post op, return saved value */
   12014 }
   12015 
   12016 /* Parse GNUC __attribute__ extension. Currently, the following
   12017    extensions are recognized:
   12018    - aligned(n) : set data/function alignment.
   12019    - packed : force data alignment to 1
   12020    - section(x) : generate data/code in this section.
   12021    - unused : currently ignored, but may be used someday.
   12022    - regparm(n) : pass function parameters in registers (i386 only)
   12023  */
   12024 static void parse_attribute(AttributeDef *ad)
   12025 {
   12026     int t, n;
   12027 
   12028     while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
   12029     next();
   12030     skip('(');
   12031     skip('(');
   12032     while (tok != ')') {
   12033         if (tok < TOK_IDENT)
   12034             expect("attribute name");
   12035         t = tok;
   12036         next();
   12037         switch(t) {
   12038         case TOK_SECTION1:
   12039         case TOK_SECTION2:
   12040             skip('(');
   12041             if (tok != TOK_STR)
   12042                 expect("section name");
   12043             ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
   12044             next();
   12045             skip(')');
   12046             break;
   12047         case TOK_ALIGNED1:
   12048         case TOK_ALIGNED2:
   12049             if (tok == '(') {
   12050                 next();
   12051                 n = expr_const();
   12052                 if (n <= 0 || (n & (n - 1)) != 0)
   12053                     error("alignment must be a positive power of two");
   12054                 skip(')');
   12055             } else {
   12056                 n = MAX_ALIGN;
   12057             }
   12058             ad->aligned = n;
   12059             break;
   12060         case TOK_PACKED1:
   12061         case TOK_PACKED2:
   12062             ad->packed = 1;
   12063             break;
   12064         case TOK_UNUSED1:
   12065         case TOK_UNUSED2:
   12066             /* currently, no need to handle it because tcc does not
   12067                track unused objects */
   12068             break;
   12069         case TOK_NORETURN1:
   12070         case TOK_NORETURN2:
   12071             /* currently, no need to handle it because tcc does not
   12072                track unused objects */
   12073             break;
   12074         case TOK_CDECL1:
   12075         case TOK_CDECL2:
   12076         case TOK_CDECL3:
   12077             ad->func_call = FUNC_CDECL;
   12078             break;
   12079         case TOK_STDCALL1:
   12080         case TOK_STDCALL2:
   12081         case TOK_STDCALL3:
   12082             ad->func_call = FUNC_STDCALL;
   12083             break;
   12084 #ifdef TCC_TARGET_I386
   12085         case TOK_REGPARM1:
   12086         case TOK_REGPARM2:
   12087             skip('(');
   12088             n = expr_const();
   12089             if (n > 3)
   12090                 n = 3;
   12091             else if (n < 0)
   12092                 n = 0;
   12093             if (n > 0)
   12094                 ad->func_call = FUNC_FASTCALL1 + n - 1;
   12095             skip(')');
   12096             break;
   12097 #endif
   12098         case TOK_DLLEXPORT:
   12099             ad->dllexport = 1;
   12100             break;
   12101         default:
   12102             if (tcc_state->warn_unsupported)
   12103                 warning("'%s' attribute ignored", get_tok_str(t, NULL));
   12104             /* skip parameters */
   12105             /* XXX: skip parenthesis too */
   12106             if (tok == '(') {
   12107                 next();
   12108                 while (tok != ')' && tok != -1)
   12109                     next();
   12110                 next();
   12111             }
   12112             break;
   12113         }
   12114         if (tok != ',')
   12115             break;
   12116         next();
   12117     }
   12118     skip(')');
   12119     skip(')');
   12120     }
   12121 }
   12122 
   12123 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
   12124 static void struct_decl(CType *type, int u)
   12125 {
   12126     int a, v, size, align, maxalign, c, offset;
   12127     int bit_size, bit_pos, bsize, bt, lbit_pos;
   12128     Sym *s, *ss, **ps;
   12129     AttributeDef ad;
   12130     CType type1, btype;
   12131 
   12132     a = tok; /* save decl type */
   12133     next();
   12134     if (tok != '{') {
   12135         v = tok;
   12136         next();
   12137         /* struct already defined ? return it */
   12138         if (v < TOK_IDENT)
   12139             expect("struct/union/enum name");
   12140         s = struct_find(v);
   12141         if (s) {
   12142             if (s->type.t != a)
   12143                 error("invalid type");
   12144             goto do_decl;
   12145         }
   12146     } else {
   12147         v = anon_sym++;
   12148     }
   12149     type1.t = a;
   12150     /* we put an undefined size for struct/union */
   12151     s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
   12152     s->r = 0; /* default alignment is zero as gcc */
   12153     /* put struct/union/enum name in type */
   12154  do_decl:
   12155     type->t = u;
   12156     type->ref = s;
   12157 
   12158     if (tok == '{') {
   12159         next();
   12160         if (s->c != -1)
   12161             error("struct/union/enum already defined");
   12162         /* cannot be empty */
   12163         c = 0;
   12164         /* non empty enums are not allowed */
   12165         if (a == TOK_ENUM) {
   12166             for(;;) {
   12167                 v = tok;
   12168                 if (v < TOK_UIDENT)
   12169                     expect("identifier");
   12170                 next();
   12171                 if (tok == '=') {
   12172                     next();
   12173                     c = expr_const();
   12174                 }
   12175                 /* enum symbols have static storage */
   12176                 ss = sym_push(v, &int_type, VT_CONST, c);
   12177                 ss->type.t |= VT_STATIC;
   12178                 if (tok != ',')
   12179                     break;
   12180                 next();
   12181                 c++;
   12182                 /* NOTE: we accept a trailing comma */
   12183                 if (tok == '}')
   12184                     break;
   12185             }
   12186             skip('}');
   12187         } else {
   12188             maxalign = 1;
   12189             ps = &s->next;
   12190             bit_pos = 0;
   12191             offset = 0;
   12192             while (tok != '}') {
   12193                 parse_btype(&btype, &ad);
   12194                 while (1) {
   12195                     bit_size = -1;
   12196                     v = 0;
   12197                     type1 = btype;
   12198                     if (tok != ':') {
   12199                         type_decl(&type1, &ad, &v, TYPE_DIRECT);
   12200                         if ((type1.t & VT_BTYPE) == VT_FUNC ||
   12201                             (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
   12202                             error("invalid type for '%s'",
   12203                                   get_tok_str(v, NULL));
   12204                     }
   12205                     if (tok == ':') {
   12206                         next();
   12207                         bit_size = expr_const();
   12208                         /* XXX: handle v = 0 case for messages */
   12209                         if (bit_size < 0)
   12210                             error("negative width in bit-field '%s'",
   12211                                   get_tok_str(v, NULL));
   12212                         if (v && bit_size == 0)
   12213                             error("zero width for bit-field '%s'",
   12214                                   get_tok_str(v, NULL));
   12215                     }
   12216                     size = type_size(&type1, &align);
   12217                     if (ad.aligned) {
   12218                         if (align < ad.aligned)
   12219                             align = ad.aligned;
   12220                     } else if (ad.packed) {
   12221                         align = 1;
   12222                     } else if (*tcc_state->pack_stack_ptr) {
   12223                         if (align > *tcc_state->pack_stack_ptr)
   12224                             align = *tcc_state->pack_stack_ptr;
   12225                     }
   12226                     lbit_pos = 0;
   12227                     if (bit_size >= 0) {
   12228                         bt = type1.t & VT_BTYPE;
   12229                         if (bt != VT_INT &&
   12230                             bt != VT_BYTE &&
   12231                             bt != VT_SHORT &&
   12232                             bt != VT_BOOL &&
   12233                             bt != VT_ENUM)
   12234                             error("bitfields must have scalar type");
   12235                         bsize = size * 8;
   12236                         if (bit_size > bsize) {
   12237                             error("width of '%s' exceeds its type",
   12238                                   get_tok_str(v, NULL));
   12239                         } else if (bit_size == bsize) {
   12240                             /* no need for bit fields */
   12241                             bit_pos = 0;
   12242                         } else if (bit_size == 0) {
   12243                             /* XXX: what to do if only padding in a
   12244                                structure ? */
   12245                             /* zero size: means to pad */
   12246                             if (bit_pos > 0)
   12247                                 bit_pos = bsize;
   12248                         } else {
   12249                             /* we do not have enough room ? */
   12250                             if ((bit_pos + bit_size) > bsize)
   12251                                 bit_pos = 0;
   12252                             lbit_pos = bit_pos;
   12253                             /* XXX: handle LSB first */
   12254                             type1.t |= VT_BITFIELD |
   12255                                 (bit_pos << VT_STRUCT_SHIFT) |
   12256                                 (bit_size << (VT_STRUCT_SHIFT + 6));
   12257                             bit_pos += bit_size;
   12258                         }
   12259                     } else {
   12260                         bit_pos = 0;
   12261                     }
   12262                     if (v) {
   12263                         /* add new memory data only if starting
   12264                            bit field */
   12265                         if (lbit_pos == 0) {
   12266                             if (a == TOK_STRUCT) {
   12267                                 c = (c + align - 1) & -align;
   12268                                 offset = c;
   12269                                 c += size;
   12270                             } else {
   12271                                 offset = 0;
   12272                                 if (size > c)
   12273                                     c = size;
   12274                             }
   12275                             if (align > maxalign)
   12276                                 maxalign = align;
   12277                         }
   12278 #if 0
   12279                         printf("add field %s offset=%d",
   12280                                get_tok_str(v, NULL), offset);
   12281                         if (type1.t & VT_BITFIELD) {
   12282                             printf(" pos=%d size=%d",
   12283                                    (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
   12284                                    (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
   12285                         }
   12286                         printf("\n");
   12287 #endif
   12288                         ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
   12289                         *ps = ss;
   12290                         ps = &ss->next;
   12291                     }
   12292                     if (tok == ';' || tok == TOK_EOF)
   12293                         break;
   12294                     skip(',');
   12295                 }
   12296                 skip(';');
   12297             }
   12298             skip('}');
   12299             /* store size and alignment */
   12300             s->c = (c + maxalign - 1) & -maxalign;
   12301             s->r = maxalign;
   12302         }
   12303     }
   12304 }
   12305 
   12306 /* return 0 if no type declaration. otherwise, return the basic type
   12307    and skip it.
   12308  */
   12309 static int parse_btype(CType *type, AttributeDef *ad)
   12310 {
   12311     int t, u, type_found, typespec_found;
   12312     Sym *s;
   12313     CType type1;
   12314 
   12315     memset(ad, 0, sizeof(AttributeDef));
   12316     type_found = 0;
   12317     typespec_found = 0;
   12318     t = 0;
   12319     while(1) {
   12320         switch(tok) {
   12321         case TOK_EXTENSION:
   12322             /* currently, we really ignore extension */
   12323             next();
   12324             continue;
   12325 
   12326             /* basic types */
   12327         case TOK_CHAR:
   12328             u = VT_BYTE;
   12329         basic_type:
   12330             next();
   12331         basic_type1:
   12332             if ((t & VT_BTYPE) != 0)
   12333                 error("too many basic types");
   12334             t |= u;
   12335             typespec_found = 1;
   12336             break;
   12337         case TOK_VOID:
   12338             u = VT_VOID;
   12339             goto basic_type;
   12340         case TOK_SHORT:
   12341             u = VT_SHORT;
   12342             goto basic_type;
   12343         case TOK_INT:
   12344             next();
   12345             typespec_found = 1;
   12346             break;
   12347         case TOK_LONG:
   12348             next();
   12349             if ((t & VT_BTYPE) == VT_DOUBLE) {
   12350                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
   12351             } else if ((t & VT_BTYPE) == VT_LONG) {
   12352                 t = (t & ~VT_BTYPE) | VT_LLONG;
   12353             } else {
   12354                 u = VT_LONG;
   12355                 goto basic_type1;
   12356             }
   12357             break;
   12358         case TOK_BOOL:
   12359             u = VT_BOOL;
   12360             goto basic_type;
   12361         case TOK_FLOAT:
   12362             u = VT_FLOAT;
   12363             goto basic_type;
   12364         case TOK_DOUBLE:
   12365             next();
   12366             if ((t & VT_BTYPE) == VT_LONG) {
   12367                 t = (t & ~VT_BTYPE) | VT_LDOUBLE;
   12368             } else {
   12369                 u = VT_DOUBLE;
   12370                 goto basic_type1;
   12371             }
   12372             break;
   12373         case TOK_ENUM:
   12374             struct_decl(&type1, VT_ENUM);
   12375         basic_type2:
   12376             u = type1.t;
   12377             type->ref = type1.ref;
   12378             goto basic_type1;
   12379         case TOK_STRUCT:
   12380         case TOK_UNION:
   12381             struct_decl(&type1, VT_STRUCT);
   12382             goto basic_type2;
   12383 
   12384             /* type modifiers */
   12385         case TOK_CONST1:
   12386         case TOK_CONST2:
   12387         case TOK_CONST3:
   12388             t |= VT_CONSTANT;
   12389             next();
   12390             break;
   12391         case TOK_VOLATILE1:
   12392         case TOK_VOLATILE2:
   12393         case TOK_VOLATILE3:
   12394             t |= VT_VOLATILE;
   12395             next();
   12396             break;
   12397         case TOK_SIGNED1:
   12398         case TOK_SIGNED2:
   12399         case TOK_SIGNED3:
   12400             typespec_found = 1;
   12401 	    t |= VT_SIGNED;
   12402 	    next();
   12403 	    break;
   12404         case TOK_REGISTER:
   12405         case TOK_AUTO:
   12406         case TOK_RESTRICT1:
   12407         case TOK_RESTRICT2:
   12408         case TOK_RESTRICT3:
   12409             next();
   12410             break;
   12411         case TOK_UNSIGNED:
   12412             t |= VT_UNSIGNED;
   12413             next();
   12414             typespec_found = 1;
   12415             break;
   12416 
   12417             /* storage */
   12418         case TOK_EXTERN:
   12419             t |= VT_EXTERN;
   12420             next();
   12421             break;
   12422         case TOK_STATIC:
   12423             t |= VT_STATIC;
   12424             next();
   12425             break;
   12426         case TOK_TYPEDEF:
   12427             t |= VT_TYPEDEF;
   12428             next();
   12429             break;
   12430         case TOK_INLINE1:
   12431         case TOK_INLINE2:
   12432         case TOK_INLINE3:
   12433             t |= VT_INLINE;
   12434             next();
   12435             break;
   12436 
   12437             /* GNUC attribute */
   12438         case TOK_ATTRIBUTE1:
   12439         case TOK_ATTRIBUTE2:
   12440             parse_attribute(ad);
   12441             break;
   12442             /* GNUC typeof */
   12443         case TOK_TYPEOF1:
   12444         case TOK_TYPEOF2:
   12445         case TOK_TYPEOF3:
   12446             next();
   12447             parse_expr_type(&type1);
   12448             goto basic_type2;
   12449         default:
   12450             if (typespec_found)
   12451                 goto the_end;
   12452             s = sym_find(tok);
   12453             if (!s || !(s->type.t & VT_TYPEDEF))
   12454                 goto the_end;
   12455             t |= (s->type.t & ~VT_TYPEDEF);
   12456             type->ref = s->type.ref;
   12457             next();
   12458             break;
   12459         }
   12460         type_found = 1;
   12461     }
   12462 the_end:
   12463     if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
   12464       error("signed and unsigned modifier");
   12465     if (tcc_state->char_is_unsigned) {
   12466         if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
   12467             t |= VT_UNSIGNED;
   12468     }
   12469     t &= ~VT_SIGNED;
   12470 
   12471     /* long is never used as type */
   12472     if ((t & VT_BTYPE) == VT_LONG)
   12473         t = (t & ~VT_BTYPE) | VT_INT;
   12474     type->t = t;
   12475     return type_found;
   12476 }
   12477 
   12478 /* convert a function parameter type (array to pointer and function to
   12479    function pointer) */
   12480 static inline void convert_parameter_type(CType *pt)
   12481 {
   12482     /* remove const and volatile qualifiers (XXX: const could be used
   12483        to indicate a const function parameter */
   12484     pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
   12485     /* array must be transformed to pointer according to ANSI C */
   12486     pt->t &= ~VT_ARRAY;
   12487     if ((pt->t & VT_BTYPE) == VT_FUNC) {
   12488         mk_pointer(pt);
   12489     }
   12490 }
   12491 
   12492 static void post_type(CType *type, AttributeDef *ad)
   12493 {
   12494     int n, l, t1;
   12495     Sym **plast, *s, *first;
   12496     AttributeDef ad1;
   12497     CType pt;
   12498 
   12499     if (tok == '(') {
   12500         /* function declaration */
   12501         next();
   12502         l = 0;
   12503         first = NULL;
   12504         plast = &first;
   12505         while (tok != ')') {
   12506             /* read param name and compute offset */
   12507             if (l != FUNC_OLD) {
   12508                 if (!parse_btype(&pt, &ad1)) {
   12509                     if (l) {
   12510                         error("invalid type");
   12511                     } else {
   12512                         l = FUNC_OLD;
   12513                         goto old_proto;
   12514                     }
   12515                 }
   12516                 l = FUNC_NEW;
   12517                 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
   12518                     break;
   12519                 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
   12520                 if ((pt.t & VT_BTYPE) == VT_VOID)
   12521                     error("parameter declared as void");
   12522             } else {
   12523             old_proto:
   12524                 n = tok;
   12525                 pt.t = VT_INT;
   12526                 next();
   12527             }
   12528             convert_parameter_type(&pt);
   12529             s = sym_push(n | SYM_FIELD, &pt, 0, 0);
   12530             *plast = s;
   12531             plast = &s->next;
   12532             if (tok == ',') {
   12533                 next();
   12534                 if (l == FUNC_NEW && tok == TOK_DOTS) {
   12535                     l = FUNC_ELLIPSIS;
   12536                     next();
   12537                     break;
   12538                 }
   12539             }
   12540         }
   12541         /* if no parameters, then old type prototype */
   12542         if (l == 0)
   12543             l = FUNC_OLD;
   12544         skip(')');
   12545         t1 = type->t & VT_STORAGE;
   12546         /* NOTE: const is ignored in returned type as it has a special
   12547            meaning in gcc / C++ */
   12548         type->t &= ~(VT_STORAGE | VT_CONSTANT);
   12549         post_type(type, ad);
   12550         /* we push a anonymous symbol which will contain the function prototype */
   12551         s = sym_push(SYM_FIELD, type, ad->func_call, l);
   12552         s->next = first;
   12553         type->t = t1 | VT_FUNC;
   12554         type->ref = s;
   12555     } else if (tok == '[') {
   12556         /* array definition */
   12557         next();
   12558         n = -1;
   12559         if (tok != ']') {
   12560             n = expr_const();
   12561             if (n < 0)
   12562                 error("invalid array size");
   12563         }
   12564         skip(']');
   12565         /* parse next post type */
   12566         t1 = type->t & VT_STORAGE;
   12567         type->t &= ~VT_STORAGE;
   12568         post_type(type, ad);
   12569 
   12570         /* we push a anonymous symbol which will contain the array
   12571            element type */
   12572         s = sym_push(SYM_FIELD, type, 0, n);
   12573         type->t = t1 | VT_ARRAY | VT_PTR;
   12574         type->ref = s;
   12575     }
   12576 }
   12577 
   12578 /* Parse a type declaration (except basic type), and return the type
   12579    in 'type'. 'td' is a bitmask indicating which kind of type decl is
   12580    expected. 'type' should contain the basic type. 'ad' is the
   12581    attribute definition of the basic type. It can be modified by
   12582    type_decl().
   12583  */
   12584 static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
   12585 {
   12586     Sym *s;
   12587     CType type1, *type2;
   12588     int qualifiers;
   12589 
   12590     while (tok == '*') {
   12591         qualifiers = 0;
   12592     redo:
   12593         next();
   12594         switch(tok) {
   12595         case TOK_CONST1:
   12596         case TOK_CONST2:
   12597         case TOK_CONST3:
   12598             qualifiers |= VT_CONSTANT;
   12599             goto redo;
   12600         case TOK_VOLATILE1:
   12601         case TOK_VOLATILE2:
   12602         case TOK_VOLATILE3:
   12603             qualifiers |= VT_VOLATILE;
   12604             goto redo;
   12605         case TOK_RESTRICT1:
   12606         case TOK_RESTRICT2:
   12607         case TOK_RESTRICT3:
   12608             goto redo;
   12609         }
   12610         mk_pointer(type);
   12611         type->t |= qualifiers;
   12612     }
   12613 
   12614     /* XXX: clarify attribute handling */
   12615     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
   12616         parse_attribute(ad);
   12617 
   12618     /* recursive type */
   12619     /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
   12620     type1.t = 0; /* XXX: same as int */
   12621     if (tok == '(') {
   12622         next();
   12623         /* XXX: this is not correct to modify 'ad' at this point, but
   12624            the syntax is not clear */
   12625         if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
   12626             parse_attribute(ad);
   12627         type_decl(&type1, ad, v, td);
   12628         skip(')');
   12629     } else {
   12630         /* type identifier */
   12631         if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
   12632             *v = tok;
   12633             next();
   12634         } else {
   12635             if (!(td & TYPE_ABSTRACT))
   12636                 expect("identifier");
   12637             *v = 0;
   12638         }
   12639     }
   12640     post_type(type, ad);
   12641     if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
   12642         parse_attribute(ad);
   12643     if (!type1.t)
   12644         return;
   12645     /* append type at the end of type1 */
   12646     type2 = &type1;
   12647     for(;;) {
   12648         s = type2->ref;
   12649         type2 = &s->type;
   12650         if (!type2->t) {
   12651             *type2 = *type;
   12652             break;
   12653         }
   12654     }
   12655     *type = type1;
   12656 }
   12657 
   12658 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
   12659 static int lvalue_type(int t)
   12660 {
   12661     int bt, r;
   12662     r = VT_LVAL;
   12663     bt = t & VT_BTYPE;
   12664     if (bt == VT_BYTE || bt == VT_BOOL)
   12665         r |= VT_LVAL_BYTE;
   12666     else if (bt == VT_SHORT)
   12667         r |= VT_LVAL_SHORT;
   12668     else
   12669         return r;
   12670     if (t & VT_UNSIGNED)
   12671         r |= VT_LVAL_UNSIGNED;
   12672     return r;
   12673 }
   12674 
   12675 /* indirection with full error checking and bound check */
   12676 static void indir(void)
   12677 {
   12678     if ((vtop->type.t & VT_BTYPE) != VT_PTR)
   12679         expect("pointer");
   12680     if ((vtop->r & VT_LVAL) && !nocode_wanted)
   12681         gv(RC_INT);
   12682     vtop->type = *pointed_type(&vtop->type);
   12683     /* an array is never an lvalue */
   12684     if (!(vtop->type.t & VT_ARRAY)) {
   12685         vtop->r |= lvalue_type(vtop->type.t);
   12686         /* if bound checking, the referenced pointer must be checked */
   12687         if (do_bounds_check)
   12688             vtop->r |= VT_MUSTBOUND;
   12689     }
   12690 }
   12691 
   12692 /* pass a parameter to a function and do type checking and casting */
   12693 static void gfunc_param_typed(Sym *func, Sym *arg)
   12694 {
   12695     int func_type;
   12696     CType type;
   12697 
   12698     func_type = func->c;
   12699     if (func_type == FUNC_OLD ||
   12700         (func_type == FUNC_ELLIPSIS && arg == NULL)) {
   12701         /* default casting : only need to convert float to double */
   12702         if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
   12703             type.t = VT_DOUBLE;
   12704             gen_cast(&type);
   12705         }
   12706     } else if (arg == NULL) {
   12707         error("too many arguments to function");
   12708     } else {
   12709         type = arg->type;
   12710         type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
   12711         gen_assign_cast(&type);
   12712     }
   12713 }
   12714 
   12715 /* parse an expression of the form '(type)' or '(expr)' and return its
   12716    type */
   12717 static void parse_expr_type(CType *type)
   12718 {
   12719     int n;
   12720     AttributeDef ad;
   12721 
   12722     skip('(');
   12723     if (parse_btype(type, &ad)) {
   12724         type_decl(type, &ad, &n, TYPE_ABSTRACT);
   12725     } else {
   12726         expr_type(type);
   12727     }
   12728     skip(')');
   12729 }
   12730 
   12731 static void parse_type(CType *type)
   12732 {
   12733     AttributeDef ad;
   12734     int n;
   12735 
   12736     if (!parse_btype(type, &ad)) {
   12737         expect("type");
   12738     }
   12739     type_decl(type, &ad, &n, TYPE_ABSTRACT);
   12740 }
   12741 
   12742 static void vpush_tokc(int t)
   12743 {
   12744     CType type;
   12745     type.t = t;
   12746     vsetc(&type, VT_CONST, &tokc);
   12747 }
   12748 
   12749 static void unary(void)
   12750 {
   12751     int n, t, align, size, r;
   12752     CType type;
   12753     Sym *s;
   12754     AttributeDef ad;
   12755 
   12756     /* XXX: GCC 2.95.3 does not generate a table although it should be
   12757        better here */
   12758  tok_next:
   12759     switch(tok) {
   12760     case TOK_EXTENSION:
   12761         next();
   12762         goto tok_next;
   12763     case TOK_CINT:
   12764     case TOK_CCHAR:
   12765     case TOK_LCHAR:
   12766         vpushi(tokc.i);
   12767         next();
   12768         break;
   12769     case TOK_CUINT:
   12770         vpush_tokc(VT_INT | VT_UNSIGNED);
   12771         next();
   12772         break;
   12773     case TOK_CLLONG:
   12774         vpush_tokc(VT_LLONG);
   12775         next();
   12776         break;
   12777     case TOK_CULLONG:
   12778         vpush_tokc(VT_LLONG | VT_UNSIGNED);
   12779         next();
   12780         break;
   12781     case TOK_CFLOAT:
   12782         vpush_tokc(VT_FLOAT);
   12783         next();
   12784         break;
   12785     case TOK_CDOUBLE:
   12786         vpush_tokc(VT_DOUBLE);
   12787         next();
   12788         break;
   12789     case TOK_CLDOUBLE:
   12790         vpush_tokc(VT_LDOUBLE);
   12791         next();
   12792         break;
   12793     case TOK___FUNCTION__:
   12794         if (!gnu_ext)
   12795             goto tok_identifier;
   12796         /* fall thru */
   12797     case TOK___FUNC__:
   12798         {
   12799             void *ptr;
   12800             int len;
   12801             /* special function name identifier */
   12802             len = strlen(funcname) + 1;
   12803             /* generate char[len] type */
   12804             type.t = VT_BYTE;
   12805             mk_pointer(&type);
   12806             type.t |= VT_ARRAY;
   12807             type.ref->c = len;
   12808             vpush_ref(&type, data_section, data_section->data_offset, len);
   12809             ptr = section_ptr_add(data_section, len);
   12810             memcpy(ptr, funcname, len);
   12811             next();
   12812         }
   12813         break;
   12814     case TOK_LSTR:
   12815         t = VT_INT;
   12816         goto str_init;
   12817     case TOK_STR:
   12818         /* string parsing */
   12819         t = VT_BYTE;
   12820     str_init:
   12821         if (tcc_state->warn_write_strings)
   12822             t |= VT_CONSTANT;
   12823         type.t = t;
   12824         mk_pointer(&type);
   12825         type.t |= VT_ARRAY;
   12826         memset(&ad, 0, sizeof(AttributeDef));
   12827         decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
   12828         break;
   12829     case '(':
   12830         next();
   12831         /* cast ? */
   12832         if (parse_btype(&type, &ad)) {
   12833             type_decl(&type, &ad, &n, TYPE_ABSTRACT);
   12834             skip(')');
   12835             /* check ISOC99 compound literal */
   12836             if (tok == '{') {
   12837                     /* data is allocated locally by default */
   12838                 if (global_expr)
   12839                     r = VT_CONST;
   12840                 else
   12841                     r = VT_LOCAL;
   12842                 /* all except arrays are lvalues */
   12843                 if (!(type.t & VT_ARRAY))
   12844                     r |= lvalue_type(type.t);
   12845                 memset(&ad, 0, sizeof(AttributeDef));
   12846                 decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
   12847             } else {
   12848                 unary();
   12849                 gen_cast(&type);
   12850             }
   12851         } else if (tok == '{') {
   12852             /* save all registers */
   12853             save_regs(0);
   12854             /* statement expression : we do not accept break/continue
   12855                inside as GCC does */
   12856             block(NULL, NULL, NULL, NULL, 0, 1);
   12857             skip(')');
   12858         } else {
   12859             gexpr();
   12860             skip(')');
   12861         }
   12862         break;
   12863     case '*':
   12864         next();
   12865         unary();
   12866         indir();
   12867         break;
   12868     case '&':
   12869         next();
   12870         unary();
   12871         /* functions names must be treated as function pointers,
   12872            except for unary '&' and sizeof. Since we consider that
   12873            functions are not lvalues, we only have to handle it
   12874            there and in function calls. */
   12875         /* arrays can also be used although they are not lvalues */
   12876         if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
   12877             !(vtop->type.t & VT_ARRAY))
   12878             test_lvalue();
   12879         mk_pointer(&vtop->type);
   12880         gaddrof();
   12881         break;
   12882     case '!':
   12883         next();
   12884         unary();
   12885         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
   12886             vtop->c.i = !vtop->c.i;
   12887         else if ((vtop->r & VT_VALMASK) == VT_CMP)
   12888             vtop->c.i = vtop->c.i ^ 1;
   12889         else
   12890             vseti(VT_JMP, gtst(1, 0));
   12891         break;
   12892     case '~':
   12893         next();
   12894         unary();
   12895         vpushi(-1);
   12896         gen_op('^');
   12897         break;
   12898     case '+':
   12899         next();
   12900         /* in order to force cast, we add zero */
   12901         unary();
   12902         if ((vtop->type.t & VT_BTYPE) == VT_PTR)
   12903             error("pointer not accepted for unary plus");
   12904         vpushi(0);
   12905         gen_op('+');
   12906         break;
   12907     case TOK_SIZEOF:
   12908     case TOK_ALIGNOF1:
   12909     case TOK_ALIGNOF2:
   12910         t = tok;
   12911         next();
   12912         if (tok == '(') {
   12913             parse_expr_type(&type);
   12914         } else {
   12915             unary_type(&type);
   12916         }
   12917         size = type_size(&type, &align);
   12918         if (t == TOK_SIZEOF) {
   12919             if (size < 0)
   12920                 error("sizeof applied to an incomplete type");
   12921             vpushi(size);
   12922         } else {
   12923             vpushi(align);
   12924         }
   12925         break;
   12926 
   12927     case TOK_builtin_types_compatible_p:
   12928         {
   12929             CType type1, type2;
   12930             next();
   12931             skip('(');
   12932             parse_type(&type1);
   12933             skip(',');
   12934             parse_type(&type2);
   12935             skip(')');
   12936             type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
   12937             type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
   12938             vpushi(is_compatible_types(&type1, &type2));
   12939         }
   12940         break;
   12941     case TOK_builtin_constant_p:
   12942         {
   12943             int saved_nocode_wanted, res;
   12944             next();
   12945             skip('(');
   12946             saved_nocode_wanted = nocode_wanted;
   12947             nocode_wanted = 1;
   12948             gexpr();
   12949             res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
   12950             vpop();
   12951             nocode_wanted = saved_nocode_wanted;
   12952             skip(')');
   12953             vpushi(res);
   12954         }
   12955         break;
   12956     case TOK_INC:
   12957     case TOK_DEC:
   12958         t = tok;
   12959         next();
   12960         unary();
   12961         inc(0, t);
   12962         break;
   12963     case '-':
   12964         next();
   12965         vpushi(0);
   12966         unary();
   12967         gen_op('-');
   12968         break;
   12969     case TOK_LAND:
   12970         if (!gnu_ext)
   12971             goto tok_identifier;
   12972         next();
   12973         /* allow to take the address of a label */
   12974         if (tok < TOK_UIDENT)
   12975             expect("label identifier");
   12976         s = label_find(tok);
   12977         if (!s) {
   12978             s = label_push(&global_label_stack, tok, LABEL_FORWARD);
   12979         } else {
   12980             if (s->r == LABEL_DECLARED)
   12981                 s->r = LABEL_FORWARD;
   12982         }
   12983         if (!s->type.t) {
   12984             s->type.t = VT_VOID;
   12985             mk_pointer(&s->type);
   12986             s->type.t |= VT_STATIC;
   12987         }
   12988         vset(&s->type, VT_CONST | VT_SYM, 0);
   12989         vtop->sym = s;
   12990         next();
   12991         break;
   12992     default:
   12993     tok_identifier:
   12994         t = tok;
   12995         next();
   12996         if (t < TOK_UIDENT)
   12997             expect("identifier");
   12998         s = sym_find(t);
   12999         if (!s) {
   13000             if (tok != '(')
   13001                 error("'%s' undeclared", get_tok_str(t, NULL));
   13002             /* for simple function calls, we tolerate undeclared
   13003                external reference to int() function */
   13004             if (tcc_state->warn_implicit_function_declaration)
   13005                 warning("implicit declaration of function '%s'",
   13006                         get_tok_str(t, NULL));
   13007             s = external_global_sym(t, &func_old_type, 0);
   13008         }
   13009         if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
   13010             (VT_STATIC | VT_INLINE | VT_FUNC)) {
   13011             /* if referencing an inline function, then we generate a
   13012                symbol to it if not already done. It will have the
   13013                effect to generate code for it at the end of the
   13014                compilation unit. Inline function as always
   13015                generated in the text section. */
   13016             if (!s->c)
   13017                 put_extern_sym(s, text_section, 0, 0);
   13018             r = VT_SYM | VT_CONST;
   13019         } else {
   13020             r = s->r;
   13021         }
   13022         vset(&s->type, r, s->c);
   13023         /* if forward reference, we must point to s */
   13024         if (vtop->r & VT_SYM) {
   13025             vtop->sym = s;
   13026             vtop->c.ul = 0;
   13027         }
   13028         break;
   13029     }
   13030 
   13031     /* post operations */
   13032     while (1) {
   13033         if (tok == TOK_INC || tok == TOK_DEC) {
   13034             inc(1, tok);
   13035             next();
   13036         } else if (tok == '.' || tok == TOK_ARROW) {
   13037             /* field */
   13038             if (tok == TOK_ARROW)
   13039                 indir();
   13040             test_lvalue();
   13041             gaddrof();
   13042             next();
   13043             /* expect pointer on structure */
   13044             if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
   13045                 expect("struct or union");
   13046             s = vtop->type.ref;
   13047             /* find field */
   13048             tok |= SYM_FIELD;
   13049             while ((s = s->next) != NULL) {
   13050                 if (s->v == tok)
   13051                     break;
   13052             }
   13053             if (!s)
   13054                 error("field not found");
   13055             /* add field offset to pointer */
   13056             vtop->type = char_pointer_type; /* change type to 'char *' */
   13057             vpushi(s->c);
   13058             gen_op('+');
   13059             /* change type to field type, and set to lvalue */
   13060             vtop->type = s->type;
   13061             /* an array is never an lvalue */
   13062             if (!(vtop->type.t & VT_ARRAY)) {
   13063                 vtop->r |= lvalue_type(vtop->type.t);
   13064                 /* if bound checking, the referenced pointer must be checked */
   13065                 if (do_bounds_check)
   13066                     vtop->r |= VT_MUSTBOUND;
   13067             }
   13068             next();
   13069         } else if (tok == '[') {
   13070             next();
   13071             gexpr();
   13072             gen_op('+');
   13073             indir();
   13074             skip(']');
   13075         } else if (tok == '(') {
   13076             SValue ret;
   13077             Sym *sa;
   13078             int nb_args;
   13079 
   13080             /* function call  */
   13081             if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
   13082                 /* pointer test (no array accepted) */
   13083                 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
   13084                     vtop->type = *pointed_type(&vtop->type);
   13085                     if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
   13086                         goto error_func;
   13087                 } else {
   13088                 error_func:
   13089                     expect("function pointer");
   13090                 }
   13091             } else {
   13092                 vtop->r &= ~VT_LVAL; /* no lvalue */
   13093             }
   13094             /* get return type */
   13095             s = vtop->type.ref;
   13096             next();
   13097             sa = s->next; /* first parameter */
   13098             nb_args = 0;
   13099             /* compute first implicit argument if a structure is returned */
   13100             if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
   13101                 /* get some space for the returned structure */
   13102                 size = type_size(&s->type, &align);
   13103                 loc = (loc - size) & -align;
   13104                 ret.type = s->type;
   13105                 ret.r = VT_LOCAL | VT_LVAL;
   13106                 /* pass it as 'int' to avoid structure arg passing
   13107                    problems */
   13108                 vseti(VT_LOCAL, loc);
   13109                 ret.c = vtop->c;
   13110                 nb_args++;
   13111             } else {
   13112                 ret.type = s->type;
   13113                 ret.r2 = VT_CONST;
   13114                 /* return in register */
   13115                 if (is_float(ret.type.t)) {
   13116                     ret.r = REG_FRET;
   13117                 } else {
   13118                     if ((ret.type.t & VT_BTYPE) == VT_LLONG)
   13119                         ret.r2 = REG_LRET;
   13120                     ret.r = REG_IRET;
   13121                 }
   13122                 ret.c.i = 0;
   13123             }
   13124             if (tok != ')') {
   13125                 for(;;) {
   13126                     expr_eq();
   13127                     gfunc_param_typed(s, sa);
   13128                     nb_args++;
   13129                     if (sa)
   13130                         sa = sa->next;
   13131                     if (tok == ')')
   13132                         break;
   13133                     skip(',');
   13134                 }
   13135             }
   13136             if (sa)
   13137                 error("too few arguments to function");
   13138             skip(')');
   13139             if (!nocode_wanted) {
   13140                 gfunc_call(nb_args);
   13141             } else {
   13142                 vtop -= (nb_args + 1);
   13143             }
   13144             /* return value */
   13145             vsetc(&ret.type, ret.r, &ret.c);
   13146             vtop->r2 = ret.r2;
   13147         } else {
   13148             break;
   13149         }
   13150     }
   13151 }
   13152 
   13153 static void uneq(void)
   13154 {
   13155     int t;
   13156 
   13157     unary();
   13158     if (tok == '=' ||
   13159         (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
   13160         tok == TOK_A_XOR || tok == TOK_A_OR ||
   13161         tok == TOK_A_SHL || tok == TOK_A_SAR) {
   13162         test_lvalue();
   13163         t = tok;
   13164         next();
   13165         if (t == '=') {
   13166             expr_eq();
   13167         } else {
   13168             vdup();
   13169             expr_eq();
   13170             gen_op(t & 0x7f);
   13171         }
   13172         vstore();
   13173     }
   13174 }
   13175 
   13176 static void expr_prod(void)
   13177 {
   13178     int t;
   13179 
   13180     uneq();
   13181     while (tok == '*' || tok == '/' || tok == '%') {
   13182         t = tok;
   13183         next();
   13184         uneq();
   13185         gen_op(t);
   13186     }
   13187 }
   13188 
   13189 static void expr_sum(void)
   13190 {
   13191     int t;
   13192 
   13193     expr_prod();
   13194     while (tok == '+' || tok == '-') {
   13195         t = tok;
   13196         next();
   13197         expr_prod();
   13198         gen_op(t);
   13199     }
   13200 }
   13201 
   13202 static void expr_shift(void)
   13203 {
   13204     int t;
   13205 
   13206     expr_sum();
   13207     while (tok == TOK_SHL || tok == TOK_SAR) {
   13208         t = tok;
   13209         next();
   13210         expr_sum();
   13211         gen_op(t);
   13212     }
   13213 }
   13214 
   13215 static void expr_cmp(void)
   13216 {
   13217     int t;
   13218 
   13219     expr_shift();
   13220     while ((tok >= TOK_ULE && tok <= TOK_GT) ||
   13221            tok == TOK_ULT || tok == TOK_UGE) {
   13222         t = tok;
   13223         next();
   13224         expr_shift();
   13225         gen_op(t);
   13226     }
   13227 }
   13228 
   13229 static void expr_cmpeq(void)
   13230 {
   13231     int t;
   13232 
   13233     expr_cmp();
   13234     while (tok == TOK_EQ || tok == TOK_NE) {
   13235         t = tok;
   13236         next();
   13237         expr_cmp();
   13238         gen_op(t);
   13239     }
   13240 }
   13241 
   13242 static void expr_and(void)
   13243 {
   13244     expr_cmpeq();
   13245     while (tok == '&') {
   13246         next();
   13247         expr_cmpeq();
   13248         gen_op('&');
   13249     }
   13250 }
   13251 
   13252 static void expr_xor(void)
   13253 {
   13254     expr_and();
   13255     while (tok == '^') {
   13256         next();
   13257         expr_and();
   13258         gen_op('^');
   13259     }
   13260 }
   13261 
   13262 static void expr_or(void)
   13263 {
   13264     expr_xor();
   13265     while (tok == '|') {
   13266         next();
   13267         expr_xor();
   13268         gen_op('|');
   13269     }
   13270 }
   13271 
   13272 /* XXX: fix this mess */
   13273 static void expr_land_const(void)
   13274 {
   13275     expr_or();
   13276     while (tok == TOK_LAND) {
   13277         next();
   13278         expr_or();
   13279         gen_op(TOK_LAND);
   13280     }
   13281 }
   13282 
   13283 /* XXX: fix this mess */
   13284 static void expr_lor_const(void)
   13285 {
   13286     expr_land_const();
   13287     while (tok == TOK_LOR) {
   13288         next();
   13289         expr_land_const();
   13290         gen_op(TOK_LOR);
   13291     }
   13292 }
   13293 
   13294 /* only used if non constant */
   13295 static void expr_land(void)
   13296 {
   13297     int t;
   13298 
   13299     expr_or();
   13300     if (tok == TOK_LAND) {
   13301         t = 0;
   13302         for(;;) {
   13303             t = gtst(1, t);
   13304             if (tok != TOK_LAND) {
   13305                 vseti(VT_JMPI, t);
   13306                 break;
   13307             }
   13308             next();
   13309             expr_or();
   13310         }
   13311     }
   13312 }
   13313 
   13314 static void expr_lor(void)
   13315 {
   13316     int t;
   13317 
   13318     expr_land();
   13319     if (tok == TOK_LOR) {
   13320         t = 0;
   13321         for(;;) {
   13322             t = gtst(0, t);
   13323             if (tok != TOK_LOR) {
   13324                 vseti(VT_JMP, t);
   13325                 break;
   13326             }
   13327             next();
   13328             expr_land();
   13329         }
   13330     }
   13331 }
   13332 
   13333 /* XXX: better constant handling */
   13334 static void expr_eq(void)
   13335 {
   13336     int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
   13337     SValue sv;
   13338     CType type, type1, type2;
   13339 
   13340     if (const_wanted) {
   13341         int c1, c;
   13342         expr_lor_const();
   13343         if (tok == '?') {
   13344             c = vtop->c.i;
   13345             vpop();
   13346             next();
   13347             if (tok == ':' && gnu_ext) {
   13348                 c1 = c;
   13349             } else {
   13350                 gexpr();
   13351                 c1 = vtop->c.i;
   13352                 vpop();
   13353             }
   13354             skip(':');
   13355             expr_eq();
   13356             if (c)
   13357                 vtop->c.i = c1;
   13358         }
   13359     } else {
   13360         expr_lor();
   13361         if (tok == '?') {
   13362             next();
   13363             if (vtop != vstack) {
   13364                 /* needed to avoid having different registers saved in
   13365                    each branch */
   13366                 if (is_float(vtop->type.t))
   13367                     rc = RC_FLOAT;
   13368                 else
   13369                     rc = RC_INT;
   13370                 gv(rc);
   13371                 save_regs(1);
   13372             }
   13373             if (tok == ':' && gnu_ext) {
   13374                 gv_dup();
   13375                 tt = gtst(1, 0);
   13376             } else {
   13377                 tt = gtst(1, 0);
   13378                 gexpr();
   13379             }
   13380             type1 = vtop->type;
   13381             sv = *vtop; /* save value to handle it later */
   13382             vtop--; /* no vpop so that FP stack is not flushed */
   13383             skip(':');
   13384             u = gjmp(0);
   13385             gsym(tt);
   13386             expr_eq();
   13387             type2 = vtop->type;
   13388 
   13389             t1 = type1.t;
   13390             bt1 = t1 & VT_BTYPE;
   13391             t2 = type2.t;
   13392             bt2 = t2 & VT_BTYPE;
   13393             /* cast operands to correct type according to ISOC rules */
   13394             if (is_float(bt1) || is_float(bt2)) {
   13395                 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
   13396                     type.t = VT_LDOUBLE;
   13397                 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
   13398                     type.t = VT_DOUBLE;
   13399                 } else {
   13400                     type.t = VT_FLOAT;
   13401                 }
   13402             } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
   13403                 /* cast to biggest op */
   13404                 type.t = VT_LLONG;
   13405                 /* convert to unsigned if it does not fit in a long long */
   13406                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
   13407                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
   13408                     type.t |= VT_UNSIGNED;
   13409             } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
   13410                 /* XXX: test pointer compatibility */
   13411                 type = type1;
   13412             } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
   13413                 /* XXX: test structure compatibility */
   13414                 type = type1;
   13415             } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
   13416                 /* NOTE: as an extension, we accept void on only one side */
   13417                 type.t = VT_VOID;
   13418             } else {
   13419                 /* integer operations */
   13420                 type.t = VT_INT;
   13421                 /* convert to unsigned if it does not fit in an integer */
   13422                 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
   13423                     (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
   13424                     type.t |= VT_UNSIGNED;
   13425             }
   13426 
   13427             /* now we convert second operand */
   13428             gen_cast(&type);
   13429             rc = RC_INT;
   13430             if (is_float(type.t)) {
   13431                 rc = RC_FLOAT;
   13432             } else if ((type.t & VT_BTYPE) == VT_LLONG) {
   13433                 /* for long longs, we use fixed registers to avoid having
   13434                    to handle a complicated move */
   13435                 rc = RC_IRET;
   13436             }
   13437 
   13438             r2 = gv(rc);
   13439             /* this is horrible, but we must also convert first
   13440                operand */
   13441             tt = gjmp(0);
   13442             gsym(u);
   13443             /* put again first value and cast it */
   13444             *vtop = sv;
   13445             gen_cast(&type);
   13446             r1 = gv(rc);
   13447             move_reg(r2, r1);
   13448             vtop->r = r2;
   13449             gsym(tt);
   13450         }
   13451     }
   13452 }
   13453 
   13454 static void gexpr(void)
   13455 {
   13456     while (1) {
   13457         expr_eq();
   13458         if (tok != ',')
   13459             break;
   13460         vpop();
   13461         next();
   13462     }
   13463 }
   13464 
   13465 /* parse an expression and return its type without any side effect. */
   13466 static void expr_type(CType *type)
   13467 {
   13468     int saved_nocode_wanted;
   13469 
   13470     saved_nocode_wanted = nocode_wanted;
   13471     nocode_wanted = 1;
   13472     gexpr();
   13473     *type = vtop->type;
   13474     vpop();
   13475     nocode_wanted = saved_nocode_wanted;
   13476 }
   13477 
   13478 /* parse a unary expression and return its type without any side
   13479    effect. */
   13480 static void unary_type(CType *type)
   13481 {
   13482     int a;
   13483 
   13484     a = nocode_wanted;
   13485     nocode_wanted = 1;
   13486     unary();
   13487     *type = vtop->type;
   13488     vpop();
   13489     nocode_wanted = a;
   13490 }
   13491 
   13492 /* parse a constant expression and return value in vtop.  */
   13493 static void expr_const1(void)
   13494 {
   13495     int a;
   13496     a = const_wanted;
   13497     const_wanted = 1;
   13498     expr_eq();
   13499     const_wanted = a;
   13500 }
   13501 
   13502 /* parse an integer constant and return its value. */
   13503 static int expr_const(void)
   13504 {
   13505     int c;
   13506     expr_const1();
   13507     if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
   13508         expect("constant expression");
   13509     c = vtop->c.i;
   13510     vpop();
   13511     return c;
   13512 }
   13513 
   13514 /* return the label token if current token is a label, otherwise
   13515    return zero */
   13516 static int is_label(void)
   13517 {
   13518     int last_tok;
   13519 
   13520     /* fast test first */
   13521     if (tok < TOK_UIDENT)
   13522         return 0;
   13523     /* no need to save tokc because tok is an identifier */
   13524     last_tok = tok;
   13525     next();
   13526     if (tok == ':') {
   13527         next();
   13528         return last_tok;
   13529     } else {
   13530         unget_tok(last_tok);
   13531         return 0;
   13532     }
   13533 }
   13534 
   13535 static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
   13536                   int case_reg, int is_expr)
   13537 {
   13538     int a, b, c, d;
   13539     Sym *s;
   13540 
   13541     /* generate line number info */
   13542     if (do_debug &&
   13543         (last_line_num != file->line_num || last_ind != ind)) {
   13544         put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
   13545         last_ind = ind;
   13546         last_line_num = file->line_num;
   13547     }
   13548 
   13549     if (is_expr) {
   13550         /* default return value is (void) */
   13551         vpushi(0);
   13552         vtop->type.t = VT_VOID;
   13553     }
   13554 
   13555     if (tok == TOK_IF) {
   13556         /* if test */
   13557         next();
   13558         skip('(');
   13559         gexpr();
   13560         skip(')');
   13561         a = gtst(1, 0);
   13562         block(bsym, csym, case_sym, def_sym, case_reg, 0);
   13563         c = tok;
   13564         if (c == TOK_ELSE) {
   13565             next();
   13566             d = gjmp(0);
   13567             gsym(a);
   13568             block(bsym, csym, case_sym, def_sym, case_reg, 0);
   13569             gsym(d); /* patch else jmp */
   13570         } else
   13571             gsym(a);
   13572     } else if (tok == TOK_WHILE) {
   13573         next();
   13574         d = ind;
   13575         skip('(');
   13576         gexpr();
   13577         skip(')');
   13578         a = gtst(1, 0);
   13579         b = 0;
   13580         block(&a, &b, case_sym, def_sym, case_reg, 0);
   13581         gjmp_addr(d);
   13582         gsym(a);
   13583         gsym_addr(b, d);
   13584     } else if (tok == '{') {
   13585         Sym *llabel;
   13586 
   13587         next();
   13588         /* record local declaration stack position */
   13589         s = local_stack;
   13590         llabel = local_label_stack;
   13591         /* handle local labels declarations */
   13592         if (tok == TOK_LABEL) {
   13593             next();
   13594             for(;;) {
   13595                 if (tok < TOK_UIDENT)
   13596                     expect("label identifier");
   13597                 label_push(&local_label_stack, tok, LABEL_DECLARED);
   13598                 next();
   13599                 if (tok == ',') {
   13600                     next();
   13601                 } else {
   13602                     skip(';');
   13603                     break;
   13604                 }
   13605             }
   13606         }
   13607         while (tok != '}') {
   13608             decl(VT_LOCAL);
   13609             if (tok != '}') {
   13610                 if (is_expr)
   13611                     vpop();
   13612                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
   13613             }
   13614         }
   13615         /* pop locally defined labels */
   13616         label_pop(&local_label_stack, llabel);
   13617         /* pop locally defined symbols */
   13618         sym_pop(&local_stack, s);
   13619         next();
   13620     } else if (tok == TOK_RETURN) {
   13621         next();
   13622         if (tok != ';') {
   13623             gexpr();
   13624             gen_assign_cast(&func_vt);
   13625             if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
   13626                 CType type;
   13627                 /* if returning structure, must copy it to implicit
   13628                    first pointer arg location */
   13629                 type = func_vt;
   13630                 mk_pointer(&type);
   13631                 vset(&type, VT_LOCAL | VT_LVAL, func_vc);
   13632                 indir();
   13633                 vswap();
   13634                 /* copy structure value to pointer */
   13635                 vstore();
   13636             } else if (is_float(func_vt.t)) {
   13637                 gv(RC_FRET);
   13638             } else {
   13639                 gv(RC_IRET);
   13640             }
   13641             vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
   13642         }
   13643         skip(';');
   13644         rsym = gjmp(rsym); /* jmp */
   13645     } else if (tok == TOK_BREAK) {
   13646         /* compute jump */
   13647         if (!bsym)
   13648             error("cannot break");
   13649         *bsym = gjmp(*bsym);
   13650         next();
   13651         skip(';');
   13652     } else if (tok == TOK_CONTINUE) {
   13653         /* compute jump */
   13654         if (!csym)
   13655             error("cannot continue");
   13656         *csym = gjmp(*csym);
   13657         next();
   13658         skip(';');
   13659     } else if (tok == TOK_FOR) {
   13660         int e;
   13661         next();
   13662         skip('(');
   13663         if (tok != ';') {
   13664             gexpr();
   13665             vpop();
   13666         }
   13667         skip(';');
   13668         d = ind;
   13669         c = ind;
   13670         a = 0;
   13671         b = 0;
   13672         if (tok != ';') {
   13673             gexpr();
   13674             a = gtst(1, 0);
   13675         }
   13676         skip(';');
   13677         if (tok != ')') {
   13678             e = gjmp(0);
   13679             c = ind;
   13680             gexpr();
   13681             vpop();
   13682             gjmp_addr(d);
   13683             gsym(e);
   13684         }
   13685         skip(')');
   13686         block(&a, &b, case_sym, def_sym, case_reg, 0);
   13687         gjmp_addr(c);
   13688         gsym(a);
   13689         gsym_addr(b, c);
   13690     } else
   13691     if (tok == TOK_DO) {
   13692         next();
   13693         a = 0;
   13694         b = 0;
   13695         d = ind;
   13696         block(&a, &b, case_sym, def_sym, case_reg, 0);
   13697         skip(TOK_WHILE);
   13698         skip('(');
   13699         gsym(b);
   13700         gexpr();
   13701         c = gtst(0, 0);
   13702         gsym_addr(c, d);
   13703         skip(')');
   13704         gsym(a);
   13705         skip(';');
   13706     } else
   13707     if (tok == TOK_SWITCH) {
   13708         next();
   13709         skip('(');
   13710         gexpr();
   13711         /* XXX: other types than integer */
   13712         case_reg = gv(RC_INT);
   13713         vpop();
   13714         skip(')');
   13715         a = 0;
   13716         b = gjmp(0); /* jump to first case */
   13717         c = 0;
   13718         block(&a, csym, &b, &c, case_reg, 0);
   13719         /* if no default, jmp after switch */
   13720         if (c == 0)
   13721             c = ind;
   13722         /* default label */
   13723         gsym_addr(b, c);
   13724         /* break label */
   13725         gsym(a);
   13726     } else
   13727     if (tok == TOK_CASE) {
   13728         int v1, v2;
   13729         if (!case_sym)
   13730             expect("switch");
   13731         next();
   13732         v1 = expr_const();
   13733         v2 = v1;
   13734         if (gnu_ext && tok == TOK_DOTS) {
   13735             next();
   13736             v2 = expr_const();
   13737             if (v2 < v1)
   13738                 warning("empty case range");
   13739         }
   13740         /* since a case is like a label, we must skip it with a jmp */
   13741         b = gjmp(0);
   13742         gsym(*case_sym);
   13743         vseti(case_reg, 0);
   13744         vpushi(v1);
   13745         if (v1 == v2) {
   13746             gen_op(TOK_EQ);
   13747             *case_sym = gtst(1, 0);
   13748         } else {
   13749             gen_op(TOK_GE);
   13750             *case_sym = gtst(1, 0);
   13751             vseti(case_reg, 0);
   13752             vpushi(v2);
   13753             gen_op(TOK_LE);
   13754             *case_sym = gtst(1, *case_sym);
   13755         }
   13756         gsym(b);
   13757         skip(':');
   13758         is_expr = 0;
   13759         goto block_after_label;
   13760     } else
   13761     if (tok == TOK_DEFAULT) {
   13762         next();
   13763         skip(':');
   13764         if (!def_sym)
   13765             expect("switch");
   13766         if (*def_sym)
   13767             error("too many 'default'");
   13768         *def_sym = ind;
   13769         is_expr = 0;
   13770         goto block_after_label;
   13771     } else
   13772     if (tok == TOK_GOTO) {
   13773         next();
   13774         if (tok == '*' && gnu_ext) {
   13775             /* computed goto */
   13776             next();
   13777             gexpr();
   13778             if ((vtop->type.t & VT_BTYPE) != VT_PTR)
   13779                 expect("pointer");
   13780             ggoto();
   13781         } else if (tok >= TOK_UIDENT) {
   13782             s = label_find(tok);
   13783             /* put forward definition if needed */
   13784             if (!s) {
   13785                 s = label_push(&global_label_stack, tok, LABEL_FORWARD);
   13786             } else {
   13787                 if (s->r == LABEL_DECLARED)
   13788                     s->r = LABEL_FORWARD;
   13789             }
   13790             /* label already defined */
   13791             if (s->r & LABEL_FORWARD)
   13792                 s->next = (void *)gjmp((long)s->next);
   13793             else
   13794                 gjmp_addr((long)s->next);
   13795             next();
   13796         } else {
   13797             expect("label identifier");
   13798         }
   13799         skip(';');
   13800     } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
   13801         asm_instr();
   13802     } else {
   13803         b = is_label();
   13804         if (b) {
   13805             /* label case */
   13806             s = label_find(b);
   13807             if (s) {
   13808                 if (s->r == LABEL_DEFINED)
   13809                     error("duplicate label '%s'", get_tok_str(s->v, NULL));
   13810                 gsym((long)s->next);
   13811                 s->r = LABEL_DEFINED;
   13812             } else {
   13813                 s = label_push(&global_label_stack, b, LABEL_DEFINED);
   13814             }
   13815             s->next = (void *)ind;
   13816             /* we accept this, but it is a mistake */
   13817         block_after_label:
   13818             if (tok == '}') {
   13819                 warning("deprecated use of label at end of compound statement");
   13820             } else {
   13821                 if (is_expr)
   13822                     vpop();
   13823                 block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
   13824             }
   13825         } else {
   13826             /* expression case */
   13827             if (tok != ';') {
   13828                 if (is_expr) {
   13829                     vpop();
   13830                     gexpr();
   13831                 } else {
   13832                     gexpr();
   13833                     vpop();
   13834                 }
   13835             }
   13836             skip(';');
   13837         }
   13838     }
   13839 }
   13840 
   13841 /* t is the array or struct type. c is the array or struct
   13842    address. cur_index/cur_field is the pointer to the current
   13843    value. 'size_only' is true if only size info is needed (only used
   13844    in arrays) */
   13845 static void decl_designator(CType *type, Section *sec, unsigned long c,
   13846                             int *cur_index, Sym **cur_field,
   13847                             int size_only)
   13848 {
   13849     Sym *s, *f;
   13850     int notfirst, index, index_last, align, l, nb_elems, elem_size;
   13851     CType type1;
   13852 
   13853     notfirst = 0;
   13854     elem_size = 0;
   13855     nb_elems = 1;
   13856     if (gnu_ext && (l = is_label()) != 0)
   13857         goto struct_field;
   13858     while (tok == '[' || tok == '.') {
   13859         if (tok == '[') {
   13860             if (!(type->t & VT_ARRAY))
   13861                 expect("array type");
   13862             s = type->ref;
   13863             next();
   13864             index = expr_const();
   13865             if (index < 0 || (s->c >= 0 && index >= s->c))
   13866                 expect("invalid index");
   13867             if (tok == TOK_DOTS && gnu_ext) {
   13868                 next();
   13869                 index_last = expr_const();
   13870                 if (index_last < 0 ||
   13871                     (s->c >= 0 && index_last >= s->c) ||
   13872                     index_last < index)
   13873                     expect("invalid index");
   13874             } else {
   13875                 index_last = index;
   13876             }
   13877             skip(']');
   13878             if (!notfirst)
   13879                 *cur_index = index_last;
   13880             type = pointed_type(type);
   13881             elem_size = type_size(type, &align);
   13882             c += index * elem_size;
   13883             /* NOTE: we only support ranges for last designator */
   13884             nb_elems = index_last - index + 1;
   13885             if (nb_elems != 1) {
   13886                 notfirst = 1;
   13887                 break;
   13888             }
   13889         } else {
   13890             next();
   13891             l = tok;
   13892             next();
   13893         struct_field:
   13894             if ((type->t & VT_BTYPE) != VT_STRUCT)
   13895                 expect("struct/union type");
   13896             s = type->ref;
   13897             l |= SYM_FIELD;
   13898             f = s->next;
   13899             while (f) {
   13900                 if (f->v == l)
   13901                     break;
   13902                 f = f->next;
   13903             }
   13904             if (!f)
   13905                 expect("field");
   13906             if (!notfirst)
   13907                 *cur_field = f;
   13908             /* XXX: fix this mess by using explicit storage field */
   13909             type1 = f->type;
   13910             type1.t |= (type->t & ~VT_TYPE);
   13911             type = &type1;
   13912             c += f->c;
   13913         }
   13914         notfirst = 1;
   13915     }
   13916     if (notfirst) {
   13917         if (tok == '=') {
   13918             next();
   13919         } else {
   13920             if (!gnu_ext)
   13921                 expect("=");
   13922         }
   13923     } else {
   13924         if (type->t & VT_ARRAY) {
   13925             index = *cur_index;
   13926             type = pointed_type(type);
   13927             c += index * type_size(type, &align);
   13928         } else {
   13929             f = *cur_field;
   13930             if (!f)
   13931                 error("too many field init");
   13932             /* XXX: fix this mess by using explicit storage field */
   13933             type1 = f->type;
   13934             type1.t |= (type->t & ~VT_TYPE);
   13935             type = &type1;
   13936             c += f->c;
   13937         }
   13938     }
   13939     decl_initializer(type, sec, c, 0, size_only);
   13940 
   13941     /* XXX: make it more general */
   13942     if (!size_only && nb_elems > 1) {
   13943         unsigned long c_end;
   13944         uint8_t *src, *dst;
   13945         int i;
   13946 
   13947         if (!sec)
   13948             error("range init not supported yet for dynamic storage");
   13949         c_end = c + nb_elems * elem_size;
   13950         if (c_end > sec->data_allocated)
   13951             section_realloc(sec, c_end);
   13952         src = sec->data + c;
   13953         dst = src;
   13954         for(i = 1; i < nb_elems; i++) {
   13955             dst += elem_size;
   13956             memcpy(dst, src, elem_size);
   13957         }
   13958     }
   13959 }
   13960 
   13961 #define EXPR_VAL   0
   13962 #define EXPR_CONST 1
   13963 #define EXPR_ANY   2
   13964 
   13965 /* store a value or an expression directly in global data or in local array */
   13966 static void init_putv(CType *type, Section *sec, unsigned long c,
   13967                       int v, int expr_type)
   13968 {
   13969     int saved_global_expr, bt, bit_pos, bit_size;
   13970     void *ptr;
   13971     unsigned long long bit_mask;
   13972     CType dtype;
   13973 
   13974     switch(expr_type) {
   13975     case EXPR_VAL:
   13976         vpushi(v);
   13977         break;
   13978     case EXPR_CONST:
   13979         /* compound literals must be allocated globally in this case */
   13980         saved_global_expr = global_expr;
   13981         global_expr = 1;
   13982         expr_const1();
   13983         global_expr = saved_global_expr;
   13984         /* NOTE: symbols are accepted */
   13985         if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
   13986             error("initializer element is not constant");
   13987         break;
   13988     case EXPR_ANY:
   13989         expr_eq();
   13990         break;
   13991     }
   13992 
   13993     dtype = *type;
   13994     dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
   13995 
   13996     if (sec) {
   13997         /* XXX: not portable */
   13998         /* XXX: generate error if incorrect relocation */
   13999         gen_assign_cast(&dtype);
   14000         bt = type->t & VT_BTYPE;
   14001         ptr = sec->data + c;
   14002         /* XXX: make code faster ? */
   14003         if (!(type->t & VT_BITFIELD)) {
   14004             bit_pos = 0;
   14005             bit_size = 32;
   14006             bit_mask = -1LL;
   14007         } else {
   14008             bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
   14009             bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
   14010             bit_mask = (1LL << bit_size) - 1;
   14011         }
   14012         if ((vtop->r & VT_SYM) &&
   14013             (bt == VT_BYTE ||
   14014              bt == VT_SHORT ||
   14015              bt == VT_DOUBLE ||
   14016              bt == VT_LDOUBLE ||
   14017              bt == VT_LLONG ||
   14018              (bt == VT_INT && bit_size != 32)))
   14019             error("initializer element is not computable at load time");
   14020         switch(bt) {
   14021         case VT_BYTE:
   14022             *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
   14023             break;
   14024         case VT_SHORT:
   14025             *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
   14026             break;
   14027         case VT_DOUBLE:
   14028             *(double *)ptr = vtop->c.d;
   14029             break;
   14030         case VT_LDOUBLE:
   14031             *(long double *)ptr = vtop->c.ld;
   14032             break;
   14033         case VT_LLONG:
   14034             *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
   14035             break;
   14036         default:
   14037             if (vtop->r & VT_SYM) {
   14038                 greloc(sec, vtop->sym, c, R_DATA_32);
   14039             }
   14040             *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
   14041             break;
   14042         }
   14043         vtop--;
   14044     } else {
   14045         vset(&dtype, VT_LOCAL, c);
   14046         vswap();
   14047         vstore();
   14048         vpop();
   14049     }
   14050 }
   14051 
   14052 /* put zeros for variable based init */
   14053 static void init_putz(CType *t, Section *sec, unsigned long c, int size)
   14054 {
   14055     if (sec) {
   14056         /* nothing to do because globals are already set to zero */
   14057     } else {
   14058         vpush_global_sym(&func_old_type, TOK_memset);
   14059         vseti(VT_LOCAL, c);
   14060         vpushi(0);
   14061         vpushi(size);
   14062         gfunc_call(3);
   14063     }
   14064 }
   14065 
   14066 /* 't' contains the type and storage info. 'c' is the offset of the
   14067    object in section 'sec'. If 'sec' is NULL, it means stack based
   14068    allocation. 'first' is true if array '{' must be read (multi
   14069    dimension implicit array init handling). 'size_only' is true if
   14070    size only evaluation is wanted (only for arrays). */
   14071 static void decl_initializer(CType *type, Section *sec, unsigned long c,
   14072                              int first, int size_only)
   14073 {
   14074     int index, array_length, n, no_oblock, nb, parlevel, i;
   14075     int size1, align1, expr_type;
   14076     Sym *s, *f;
   14077     CType *t1;
   14078 
   14079     if (type->t & VT_ARRAY) {
   14080         s = type->ref;
   14081         n = s->c;
   14082         array_length = 0;
   14083         t1 = pointed_type(type);
   14084         size1 = type_size(t1, &align1);
   14085 
   14086         no_oblock = 1;
   14087         if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
   14088             tok == '{') {
   14089             skip('{');
   14090             no_oblock = 0;
   14091         }
   14092 
   14093         /* only parse strings here if correct type (otherwise: handle
   14094            them as ((w)char *) expressions */
   14095         if ((tok == TOK_LSTR &&
   14096              (t1->t & VT_BTYPE) == VT_INT) ||
   14097             (tok == TOK_STR &&
   14098              (t1->t & VT_BTYPE) == VT_BYTE)) {
   14099             while (tok == TOK_STR || tok == TOK_LSTR) {
   14100                 int cstr_len, ch;
   14101                 CString *cstr;
   14102 
   14103                 cstr = tokc.cstr;
   14104                 /* compute maximum number of chars wanted */
   14105                 if (tok == TOK_STR)
   14106                     cstr_len = cstr->size;
   14107                 else
   14108                     cstr_len = cstr->size / sizeof(int);
   14109                 cstr_len--;
   14110                 nb = cstr_len;
   14111                 if (n >= 0 && nb > (n - array_length))
   14112                     nb = n - array_length;
   14113                 if (!size_only) {
   14114                     if (cstr_len > nb)
   14115                         warning("initializer-string for array is too long");
   14116                     /* in order to go faster for common case (char
   14117                        string in global variable, we handle it
   14118                        specifically */
   14119                     if (sec && tok == TOK_STR && size1 == 1) {
   14120                         memcpy(sec->data + c + array_length, cstr->data, nb);
   14121                     } else {
   14122                         for(i=0;i<nb;i++) {
   14123                             if (tok == TOK_STR)
   14124                                 ch = ((unsigned char *)cstr->data)[i];
   14125                             else
   14126                                 ch = ((int *)cstr->data)[i];
   14127                             init_putv(t1, sec, c + (array_length + i) * size1,
   14128                                       ch, EXPR_VAL);
   14129                         }
   14130                     }
   14131                 }
   14132                 array_length += nb;
   14133                 next();
   14134             }
   14135             /* only add trailing zero if enough storage (no
   14136                warning in this case since it is standard) */
   14137             if (n < 0 || array_length < n) {
   14138                 if (!size_only) {
   14139                     init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
   14140                 }
   14141                 array_length++;
   14142             }
   14143         } else {
   14144             index = 0;
   14145             while (tok != '}') {
   14146                 decl_designator(type, sec, c, &index, NULL, size_only);
   14147                 if (n >= 0 && index >= n)
   14148                     error("index too large");
   14149                 /* must put zero in holes (note that doing it that way
   14150                    ensures that it even works with designators) */
   14151                 if (!size_only && array_length < index) {
   14152                     init_putz(t1, sec, c + array_length * size1,
   14153                               (index - array_length) * size1);
   14154                 }
   14155                 index++;
   14156                 if (index > array_length)
   14157                     array_length = index;
   14158                 /* special test for multi dimensional arrays (may not
   14159                    be strictly correct if designators are used at the
   14160                    same time) */
   14161                 if (index >= n && no_oblock)
   14162                     break;
   14163                 if (tok == '}')
   14164                     break;
   14165                 skip(',');
   14166             }
   14167         }
   14168         if (!no_oblock)
   14169             skip('}');
   14170         /* put zeros at the end */
   14171         if (!size_only && n >= 0 && array_length < n) {
   14172             init_putz(t1, sec, c + array_length * size1,
   14173                       (n - array_length) * size1);
   14174         }
   14175         /* patch type size if needed */
   14176         if (n < 0)
   14177             s->c = array_length;
   14178     } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
   14179                (sec || !first || tok == '{')) {
   14180         int par_count;
   14181 
   14182         /* NOTE: the previous test is a specific case for automatic
   14183            struct/union init */
   14184         /* XXX: union needs only one init */
   14185 
   14186         /* XXX: this test is incorrect for local initializers
   14187            beginning with ( without {. It would be much more difficult
   14188            to do it correctly (ideally, the expression parser should
   14189            be used in all cases) */
   14190         par_count = 0;
   14191         if (tok == '(') {
   14192             AttributeDef ad1;
   14193             CType type1;
   14194             next();
   14195             while (tok == '(') {
   14196                 par_count++;
   14197                 next();
   14198             }
   14199             if (!parse_btype(&type1, &ad1))
   14200                 expect("cast");
   14201             type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
   14202 #if 0
   14203             if (!is_assignable_types(type, &type1))
   14204                 error("invalid type for cast");
   14205 #endif
   14206             skip(')');
   14207         }
   14208         no_oblock = 1;
   14209         if (first || tok == '{') {
   14210             skip('{');
   14211             no_oblock = 0;
   14212         }
   14213         s = type->ref;
   14214         f = s->next;
   14215         array_length = 0;
   14216         index = 0;
   14217         n = s->c;
   14218         while (tok != '}') {
   14219             decl_designator(type, sec, c, NULL, &f, size_only);
   14220             index = f->c;
   14221             if (!size_only && array_length < index) {
   14222                 init_putz(type, sec, c + array_length,
   14223                           index - array_length);
   14224             }
   14225             index = index + type_size(&f->type, &align1);
   14226             if (index > array_length)
   14227                 array_length = index;
   14228             f = f->next;
   14229             if (no_oblock && f == NULL)
   14230                 break;
   14231             if (tok == '}')
   14232                 break;
   14233             skip(',');
   14234         }
   14235         /* put zeros at the end */
   14236         if (!size_only && array_length < n) {
   14237             init_putz(type, sec, c + array_length,
   14238                       n - array_length);
   14239         }
   14240         if (!no_oblock)
   14241             skip('}');
   14242         while (par_count) {
   14243             skip(')');
   14244             par_count--;
   14245         }
   14246     } else if (tok == '{') {
   14247         next();
   14248         decl_initializer(type, sec, c, first, size_only);
   14249         skip('}');
   14250     } else if (size_only) {
   14251         /* just skip expression */
   14252         parlevel = 0;
   14253         while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
   14254                tok != -1) {
   14255             if (tok == '(')
   14256                 parlevel++;
   14257             else if (tok == ')')
   14258                 parlevel--;
   14259             next();
   14260         }
   14261     } else {
   14262         /* currently, we always use constant expression for globals
   14263            (may change for scripting case) */
   14264         expr_type = EXPR_CONST;
   14265         if (!sec)
   14266             expr_type = EXPR_ANY;
   14267         init_putv(type, sec, c, 0, expr_type);
   14268     }
   14269 }
   14270 
   14271 /* parse an initializer for type 't' if 'has_init' is non zero, and
   14272    allocate space in local or global data space ('r' is either
   14273    VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
   14274    variable 'v' of scope 'scope' is declared before initializers are
   14275    parsed. If 'v' is zero, then a reference to the new object is put
   14276    in the value stack. If 'has_init' is 2, a special parsing is done
   14277    to handle string constants. */
   14278 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
   14279                                    int has_init, int v, int scope)
   14280 {
   14281     int size, align, addr, data_offset;
   14282     int level;
   14283     ParseState saved_parse_state;
   14284     TokenString init_str;
   14285     Section *sec;
   14286 
   14287     size = type_size(type, &align);
   14288     /* If unknown size, we must evaluate it before
   14289        evaluating initializers because
   14290        initializers can generate global data too
   14291        (e.g. string pointers or ISOC99 compound
   14292        literals). It also simplifies local
   14293        initializers handling */
   14294     tok_str_new(&init_str);
   14295     if (size < 0) {
   14296         if (!has_init)
   14297             error("unknown type size");
   14298         /* get all init string */
   14299         if (has_init == 2) {
   14300             /* only get strings */
   14301             while (tok == TOK_STR || tok == TOK_LSTR) {
   14302                 tok_str_add_tok(&init_str);
   14303                 next();
   14304             }
   14305         } else {
   14306             level = 0;
   14307             while (level > 0 || (tok != ',' && tok != ';')) {
   14308                 if (tok < 0)
   14309                     error("unexpected end of file in initializer");
   14310                 tok_str_add_tok(&init_str);
   14311                 if (tok == '{')
   14312                     level++;
   14313                 else if (tok == '}') {
   14314                     if (level == 0)
   14315                         break;
   14316                     level--;
   14317                 }
   14318                 next();
   14319             }
   14320         }
   14321         tok_str_add(&init_str, -1);
   14322         tok_str_add(&init_str, 0);
   14323 
   14324         /* compute size */
   14325         save_parse_state(&saved_parse_state);
   14326 
   14327         macro_ptr = init_str.str;
   14328         next();
   14329         decl_initializer(type, NULL, 0, 1, 1);
   14330         /* prepare second initializer parsing */
   14331         macro_ptr = init_str.str;
   14332         next();
   14333 
   14334         /* if still unknown size, error */
   14335         size = type_size(type, &align);
   14336         if (size < 0)
   14337             error("unknown type size");
   14338     }
   14339     /* take into account specified alignment if bigger */
   14340     if (ad->aligned) {
   14341         if (ad->aligned > align)
   14342             align = ad->aligned;
   14343     } else if (ad->packed) {
   14344         align = 1;
   14345     }
   14346     if ((r & VT_VALMASK) == VT_LOCAL) {
   14347         sec = NULL;
   14348         if (do_bounds_check && (type->t & VT_ARRAY))
   14349             loc--;
   14350         loc = (loc - size) & -align;
   14351         addr = loc;
   14352         /* handles bounds */
   14353         /* XXX: currently, since we do only one pass, we cannot track
   14354            '&' operators, so we add only arrays */
   14355         if (do_bounds_check && (type->t & VT_ARRAY)) {
   14356             unsigned long *bounds_ptr;
   14357             /* add padding between regions */
   14358             loc--;
   14359             /* then add local bound info */
   14360             bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
   14361             bounds_ptr[0] = addr;
   14362             bounds_ptr[1] = size;
   14363         }
   14364         if (v) {
   14365             /* local variable */
   14366             sym_push(v, type, r, addr);
   14367         } else {
   14368             /* push local reference */
   14369             vset(type, r, addr);
   14370         }
   14371     } else {
   14372         Sym *sym;
   14373 
   14374         sym = NULL;
   14375         if (v && scope == VT_CONST) {
   14376             /* see if the symbol was already defined */
   14377             sym = sym_find(v);
   14378             if (sym) {
   14379                 if (!is_compatible_types(&sym->type, type))
   14380                     error("incompatible types for redefinition of '%s'",
   14381                           get_tok_str(v, NULL));
   14382                 if (sym->type.t & VT_EXTERN) {
   14383                     /* if the variable is extern, it was not allocated */
   14384                     sym->type.t &= ~VT_EXTERN;
   14385                     /* set array size if it was ommited in extern
   14386                        declaration */
   14387                     if ((sym->type.t & VT_ARRAY) &&
   14388                         sym->type.ref->c < 0 &&
   14389                         type->ref->c >= 0)
   14390                         sym->type.ref->c = type->ref->c;
   14391                 } else {
   14392                     /* we accept several definitions of the same
   14393                        global variable. this is tricky, because we
   14394                        must play with the SHN_COMMON type of the symbol */
   14395                     /* XXX: should check if the variable was already
   14396                        initialized. It is incorrect to initialized it
   14397                        twice */
   14398                     /* no init data, we won't add more to the symbol */
   14399                     if (!has_init)
   14400                         goto no_alloc;
   14401                 }
   14402             }
   14403         }
   14404 
   14405         /* allocate symbol in corresponding section */
   14406         sec = ad->section;
   14407         if (!sec) {
   14408             if (has_init)
   14409                 sec = data_section;
   14410             else if (tcc_state->nocommon)
   14411                 sec = bss_section;
   14412         }
   14413         if (sec) {
   14414             data_offset = sec->data_offset;
   14415             data_offset = (data_offset + align - 1) & -align;
   14416             addr = data_offset;
   14417             /* very important to increment global pointer at this time
   14418                because initializers themselves can create new initializers */
   14419             data_offset += size;
   14420             /* add padding if bound check */
   14421             if (do_bounds_check)
   14422                 data_offset++;
   14423             sec->data_offset = data_offset;
   14424             /* allocate section space to put the data */
   14425             if (sec->sh_type != SHT_NOBITS &&
   14426                 data_offset > sec->data_allocated)
   14427                 section_realloc(sec, data_offset);
   14428             /* align section if needed */
   14429             if (align > sec->sh_addralign)
   14430                 sec->sh_addralign = align;
   14431         } else {
   14432             addr = 0; /* avoid warning */
   14433         }
   14434 
   14435         if (v) {
   14436             if (scope == VT_CONST) {
   14437                 if (!sym)
   14438                     goto do_def;
   14439             } else {
   14440             do_def:
   14441                 sym = sym_push(v, type, r | VT_SYM, 0);
   14442             }
   14443             /* update symbol definition */
   14444             if (sec) {
   14445                 put_extern_sym(sym, sec, addr, size);
   14446             } else {
   14447                 Elf32_Sym *esym;
   14448                 /* put a common area */
   14449                 put_extern_sym(sym, NULL, align, size);
   14450                 /* XXX: find a nicer way */
   14451                 esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
   14452                 esym->st_shndx = SHN_COMMON;
   14453             }
   14454         } else {
   14455             CValue cval;
   14456 
   14457             /* push global reference */
   14458             sym = get_sym_ref(type, sec, addr, size);
   14459             cval.ul = 0;
   14460             vsetc(type, VT_CONST | VT_SYM, &cval);
   14461             vtop->sym = sym;
   14462         }
   14463 
   14464         /* handles bounds now because the symbol must be defined
   14465            before for the relocation */
   14466         if (do_bounds_check) {
   14467             unsigned long *bounds_ptr;
   14468 
   14469             greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
   14470             /* then add global bound info */
   14471             bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
   14472             bounds_ptr[0] = 0; /* relocated */
   14473             bounds_ptr[1] = size;
   14474         }
   14475     }
   14476     if (has_init) {
   14477         decl_initializer(type, sec, addr, 1, 0);
   14478         /* restore parse state if needed */
   14479         if (init_str.str) {
   14480             tok_str_free(init_str.str);
   14481             restore_parse_state(&saved_parse_state);
   14482         }
   14483     }
   14484  no_alloc: ;
   14485 }
   14486 
   14487 void put_func_debug(Sym *sym)
   14488 {
   14489     char buf[512];
   14490 
   14491     /* stabs info */
   14492     /* XXX: we put here a dummy type */
   14493     snprintf(buf, sizeof(buf), "%s:%c1",
   14494              funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
   14495     put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
   14496                 cur_text_section, sym->c);
   14497     last_ind = 0;
   14498     last_line_num = 0;
   14499 }
   14500 
   14501 /* parse an old style function declaration list */
   14502 /* XXX: check multiple parameter */
   14503 static void func_decl_list(Sym *func_sym)
   14504 {
   14505     AttributeDef ad;
   14506     int v;
   14507     Sym *s;
   14508     CType btype, type;
   14509 
   14510     /* parse each declaration */
   14511     while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
   14512         if (!parse_btype(&btype, &ad))
   14513             expect("declaration list");
   14514         if (((btype.t & VT_BTYPE) == VT_ENUM ||
   14515              (btype.t & VT_BTYPE) == VT_STRUCT) &&
   14516             tok == ';') {
   14517             /* we accept no variable after */
   14518         } else {
   14519             for(;;) {
   14520                 type = btype;
   14521                 type_decl(&type, &ad, &v, TYPE_DIRECT);
   14522                 /* find parameter in function parameter list */
   14523                 s = func_sym->next;
   14524                 while (s != NULL) {
   14525                     if ((s->v & ~SYM_FIELD) == v)
   14526                         goto found;
   14527                     s = s->next;
   14528                 }
   14529                 error("declaration for parameter '%s' but no such parameter",
   14530                       get_tok_str(v, NULL));
   14531             found:
   14532                 /* check that no storage specifier except 'register' was given */
   14533                 if (type.t & VT_STORAGE)
   14534                     error("storage class specified for '%s'", get_tok_str(v, NULL));
   14535                 convert_parameter_type(&type);
   14536                 /* we can add the type (NOTE: it could be local to the function) */
   14537                 s->type = type;
   14538                 /* accept other parameters */
   14539                 if (tok == ',')
   14540                     next();
   14541                 else
   14542                     break;
   14543             }
   14544         }
   14545         skip(';');
   14546     }
   14547 }
   14548 
   14549 /* parse a function defined by symbol 'sym' and generate its code in
   14550    'cur_text_section' */
   14551 static void gen_function(Sym *sym)
   14552 {
   14553     ind = cur_text_section->data_offset;
   14554     /* NOTE: we patch the symbol size later */
   14555     put_extern_sym(sym, cur_text_section, ind, 0);
   14556     funcname = get_tok_str(sym->v, NULL);
   14557     func_ind = ind;
   14558     /* put debug symbol */
   14559     if (do_debug)
   14560         put_func_debug(sym);
   14561     /* push a dummy symbol to enable local sym storage */
   14562     sym_push2(&local_stack, SYM_FIELD, 0, 0);
   14563     gfunc_prolog(&sym->type);
   14564     rsym = 0;
   14565     block(NULL, NULL, NULL, NULL, 0, 0);
   14566     gsym(rsym);
   14567     gfunc_epilog();
   14568     cur_text_section->data_offset = ind;
   14569     label_pop(&global_label_stack, NULL);
   14570     sym_pop(&local_stack, NULL); /* reset local stack */
   14571     /* end of function */
   14572     /* patch symbol size */
   14573     ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
   14574         ind - func_ind;
   14575     if (do_debug) {
   14576         put_stabn(N_FUN, 0, 0, ind - func_ind);
   14577     }
   14578     funcname = ""; /* for safety */
   14579     func_vt.t = VT_VOID; /* for safety */
   14580     ind = 0; /* for safety */
   14581 }
   14582 
   14583 static void gen_inline_functions(void)
   14584 {
   14585     Sym *sym;
   14586     CType *type;
   14587     int *str, inline_generated;
   14588 
   14589     /* iterate while inline function are referenced */
   14590     for(;;) {
   14591         inline_generated = 0;
   14592         for(sym = global_stack; sym != NULL; sym = sym->prev) {
   14593             type = &sym->type;
   14594             if (((type->t & VT_BTYPE) == VT_FUNC) &&
   14595                 (type->t & (VT_STATIC | VT_INLINE)) ==
   14596                 (VT_STATIC | VT_INLINE) &&
   14597                 sym->c != 0) {
   14598                 /* the function was used: generate its code and
   14599                    convert it to a normal function */
   14600                 str = (int *)sym->r;
   14601                 sym->r = VT_SYM | VT_CONST;
   14602                 type->t &= ~VT_INLINE;
   14603 
   14604                 macro_ptr = str;
   14605                 next();
   14606                 cur_text_section = text_section;
   14607                 gen_function(sym);
   14608                 macro_ptr = NULL; /* fail safe */
   14609 
   14610                 tok_str_free(str);
   14611                 inline_generated = 1;
   14612             }
   14613         }
   14614         if (!inline_generated)
   14615             break;
   14616     }
   14617 
   14618     /* free all remaining inline function tokens */
   14619     for(sym = global_stack; sym != NULL; sym = sym->prev) {
   14620         type = &sym->type;
   14621         if (((type->t & VT_BTYPE) == VT_FUNC) &&
   14622             (type->t & (VT_STATIC | VT_INLINE)) ==
   14623             (VT_STATIC | VT_INLINE)) {
   14624             str = (int *)sym->r;
   14625             tok_str_free(str);
   14626             sym->r = 0; /* fail safe */
   14627         }
   14628     }
   14629 }
   14630 
   14631 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
   14632 static void decl(int l)
   14633 {
   14634     int v, has_init, r;
   14635     CType type, btype;
   14636     Sym *sym;
   14637     AttributeDef ad;
   14638 
   14639     while (1) {
   14640         if (!parse_btype(&btype, &ad)) {
   14641             /* skip redundant ';' */
   14642             /* XXX: find more elegant solution */
   14643             if (tok == ';') {
   14644                 next();
   14645                 continue;
   14646             }
   14647             if (l == VT_CONST &&
   14648                 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
   14649                 /* global asm block */
   14650                 asm_global_instr();
   14651                 continue;
   14652             }
   14653             /* special test for old K&R protos without explicit int
   14654                type. Only accepted when defining global data */
   14655             if (l == VT_LOCAL || tok < TOK_DEFINE)
   14656                 break;
   14657             btype.t = VT_INT;
   14658         }
   14659         if (((btype.t & VT_BTYPE) == VT_ENUM ||
   14660              (btype.t & VT_BTYPE) == VT_STRUCT) &&
   14661             tok == ';') {
   14662             /* we accept no variable after */
   14663             next();
   14664             continue;
   14665         }
   14666         while (1) { /* iterate thru each declaration */
   14667             type = btype;
   14668             type_decl(&type, &ad, &v, TYPE_DIRECT);
   14669 #if 0
   14670             {
   14671                 char buf[500];
   14672                 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
   14673                 printf("type = '%s'\n", buf);
   14674             }
   14675 #endif
   14676             if ((type.t & VT_BTYPE) == VT_FUNC) {
   14677                 /* if old style function prototype, we accept a
   14678                    declaration list */
   14679                 sym = type.ref;
   14680                 if (sym->c == FUNC_OLD)
   14681                     func_decl_list(sym);
   14682             }
   14683 
   14684             if (tok == '{') {
   14685                 if (l == VT_LOCAL)
   14686                     error("cannot use local functions");
   14687                 if (!(type.t & VT_FUNC))
   14688                     expect("function definition");
   14689 
   14690                 /* reject abstract declarators in function definition */
   14691                 sym = type.ref;
   14692                 while ((sym = sym->next) != NULL)
   14693                     if (!(sym->v & ~SYM_FIELD))
   14694                        expect("identifier");
   14695 
   14696                 /* XXX: cannot do better now: convert extern line to static inline */
   14697                 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
   14698                     type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
   14699 
   14700                 sym = sym_find(v);
   14701                 if (sym) {
   14702                     if ((sym->type.t & VT_BTYPE) != VT_FUNC)
   14703                         goto func_error1;
   14704                     /* specific case: if not func_call defined, we put
   14705                        the one of the prototype */
   14706                     /* XXX: should have default value */
   14707                     if (sym->type.ref->r != FUNC_CDECL &&
   14708                         type.ref->r == FUNC_CDECL)
   14709                         type.ref->r = sym->type.ref->r;
   14710                     if (!is_compatible_types(&sym->type, &type)) {
   14711                     func_error1:
   14712                         error("incompatible types for redefinition of '%s'",
   14713                               get_tok_str(v, NULL));
   14714                     }
   14715                     /* if symbol is already defined, then put complete type */
   14716                     sym->type = type;
   14717                 } else {
   14718                     /* put function symbol */
   14719                     sym = global_identifier_push(v, type.t, 0);
   14720                     sym->type.ref = type.ref;
   14721                 }
   14722 
   14723                 /* static inline functions are just recorded as a kind
   14724                    of macro. Their code will be emitted at the end of
   14725                    the compilation unit only if they are used */
   14726                 if ((type.t & (VT_INLINE | VT_STATIC)) ==
   14727                     (VT_INLINE | VT_STATIC)) {
   14728                     TokenString func_str;
   14729                     int block_level;
   14730 
   14731                     tok_str_new(&func_str);
   14732 
   14733                     block_level = 0;
   14734                     for(;;) {
   14735                         int t;
   14736                         if (tok == TOK_EOF)
   14737                             error("unexpected end of file");
   14738                         tok_str_add_tok(&func_str);
   14739                         t = tok;
   14740                         next();
   14741                         if (t == '{') {
   14742                             block_level++;
   14743                         } else if (t == '}') {
   14744                             block_level--;
   14745                             if (block_level == 0)
   14746                                 break;
   14747                         }
   14748                     }
   14749                     tok_str_add(&func_str, -1);
   14750                     tok_str_add(&func_str, 0);
   14751                     sym->r = (long)func_str.str;
   14752                 } else {
   14753                     /* compute text section */
   14754                     cur_text_section = ad.section;
   14755                     if (!cur_text_section)
   14756                         cur_text_section = text_section;
   14757                     sym->r = VT_SYM | VT_CONST;
   14758                     gen_function(sym);
   14759 #ifdef TCC_TARGET_PE
   14760                     if (ad.dllexport) {
   14761                         ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
   14762                     }
   14763 #endif
   14764                 }
   14765                 break;
   14766             } else {
   14767                 if (btype.t & VT_TYPEDEF) {
   14768                     /* save typedefed type  */
   14769                     /* XXX: test storage specifiers ? */
   14770                     sym = sym_push(v, &type, 0, 0);
   14771                     sym->type.t |= VT_TYPEDEF;
   14772                 } else if ((type.t & VT_BTYPE) == VT_FUNC) {
   14773                     /* external function definition */
   14774                     /* specific case for func_call attribute */
   14775                     if (ad.func_call)
   14776                         type.ref->r = ad.func_call;
   14777                     external_sym(v, &type, 0);
   14778                 } else {
   14779                     /* not lvalue if array */
   14780                     r = 0;
   14781                     if (!(type.t & VT_ARRAY))
   14782                         r |= lvalue_type(type.t);
   14783                     has_init = (tok == '=');
   14784                     if ((btype.t & VT_EXTERN) ||
   14785                         ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
   14786                          !has_init && l == VT_CONST && type.ref->c < 0)) {
   14787                         /* external variable */
   14788                         /* NOTE: as GCC, uninitialized global static
   14789                            arrays of null size are considered as
   14790                            extern */
   14791                         external_sym(v, &type, r);
   14792                     } else {
   14793                         if (type.t & VT_STATIC)
   14794                             r |= VT_CONST;
   14795                         else
   14796                             r |= l;
   14797                         if (has_init)
   14798                             next();
   14799                         decl_initializer_alloc(&type, &ad, r,
   14800                                                has_init, v, l);
   14801                     }
   14802                 }
   14803                 if (tok != ',') {
   14804                     skip(';');
   14805                     break;
   14806                 }
   14807                 next();
   14808             }
   14809         }
   14810     }
   14811 }
   14812 
   14813 /* better than nothing, but needs extension to handle '-E' option
   14814    correctly too */
   14815 static void preprocess_init(TCCState *s1)
   14816 {
   14817     s1->include_stack_ptr = s1->include_stack;
   14818     /* XXX: move that before to avoid having to initialize
   14819        file->ifdef_stack_ptr ? */
   14820     s1->ifdef_stack_ptr = s1->ifdef_stack;
   14821     file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
   14822 
   14823     /* XXX: not ANSI compliant: bound checking says error */
   14824     vtop = vstack - 1;
   14825     s1->pack_stack[0] = 0;
   14826     s1->pack_stack_ptr = s1->pack_stack;
   14827 }
   14828 
   14829 /* compile the C file opened in 'file'. Return non zero if errors. */
   14830 static int tcc_compile(TCCState *s1)
   14831 {
   14832     Sym *define_start;
   14833     char buf[512];
   14834     volatile int section_sym;
   14835 
   14836 #ifdef INC_DEBUG
   14837     printf("%s: **** new file\n", file->filename);
   14838 #endif
   14839     preprocess_init(s1);
   14840 
   14841     funcname = "";
   14842     anon_sym = SYM_FIRST_ANOM;
   14843 
   14844     /* file info: full path + filename */
   14845     section_sym = 0; /* avoid warning */
   14846     if (do_debug) {
   14847         section_sym = put_elf_sym(symtab_section, 0, 0,
   14848                                   ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
   14849                                   text_section->sh_num, NULL);
   14850         dummy_char_star = getcwd(buf, sizeof(buf));
   14851         pstrcat(buf, sizeof(buf), "/");
   14852         put_stabs_r(buf, N_SO, 0, 0,
   14853                     text_section->data_offset, text_section, section_sym);
   14854         put_stabs_r(file->filename, N_SO, 0, 0,
   14855                     text_section->data_offset, text_section, section_sym);
   14856     }
   14857     /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
   14858        symbols can be safely used */
   14859     put_elf_sym(symtab_section, 0, 0,
   14860                 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
   14861                 SHN_ABS, file->filename);
   14862 
   14863     /* define some often used types */
   14864     int_type.t = VT_INT;
   14865 
   14866     char_pointer_type.t = VT_BYTE;
   14867     mk_pointer(&char_pointer_type);
   14868 
   14869     func_old_type.t = VT_FUNC;
   14870     func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
   14871 
   14872 #if 0
   14873     /* define 'void *alloca(unsigned int)' builtin function */
   14874     {
   14875         Sym *s1;
   14876 
   14877         p = anon_sym++;
   14878         sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
   14879         s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
   14880         s1->next = NULL;
   14881         sym->next = s1;
   14882         sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
   14883     }
   14884 #endif
   14885 
   14886     define_start = define_stack;
   14887 
   14888     if (setjmp(s1->error_jmp_buf) == 0) {
   14889         s1->nb_errors = 0;
   14890         s1->error_set_jmp_enabled = 1;
   14891 
   14892         ch = file->buf_ptr[0];
   14893         tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
   14894         parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
   14895         next();
   14896         decl(VT_CONST);
   14897         if (tok != TOK_EOF)
   14898             expect("declaration");
   14899 
   14900         /* end of translation unit info */
   14901         if (do_debug) {
   14902             put_stabs_r(NULL, N_SO, 0, 0,
   14903                         text_section->data_offset, text_section, section_sym);
   14904         }
   14905     }
   14906     s1->error_set_jmp_enabled = 0;
   14907 
   14908     /* reset define stack, but leave -Dsymbols (may be incorrect if
   14909        they are undefined) */
   14910     free_defines(define_start);
   14911 
   14912     gen_inline_functions();
   14913 
   14914     sym_pop(&global_stack, NULL);
   14915 
   14916     return s1->nb_errors != 0 ? -1 : 0;
   14917 }
   14918 
   14919 #ifdef LIBTCC
   14920 int tcc_compile_string(TCCState *s, const char *str)
   14921 {
   14922     BufferedFile bf1, *bf = &bf1;
   14923     int ret, len;
   14924     char *buf;
   14925 
   14926     /* init file structure */
   14927     bf->fd = -1;
   14928     /* XXX: avoid copying */
   14929     len = strlen(str);
   14930     buf = tcc_malloc(len + 1);
   14931     if (!buf)
   14932         return -1;
   14933     memcpy(buf, str, len);
   14934     buf[len] = CH_EOB;
   14935     bf->buf_ptr = buf;
   14936     bf->buf_end = buf + len;
   14937     pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
   14938     bf->line_num = 1;
   14939     file = bf;
   14940 
   14941     ret = tcc_compile(s);
   14942 
   14943     tcc_free(buf);
   14944 
   14945     /* currently, no need to close */
   14946     return ret;
   14947 }
   14948 #endif
   14949 
   14950 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
   14951 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
   14952 {
   14953     BufferedFile bf1, *bf = &bf1;
   14954 
   14955     pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
   14956     pstrcat(bf->buffer, IO_BUF_SIZE, " ");
   14957     /* default value */
   14958     if (!value)
   14959         value = "1";
   14960     pstrcat(bf->buffer, IO_BUF_SIZE, value);
   14961 
   14962     /* init file structure */
   14963     bf->fd = -1;
   14964     bf->buf_ptr = bf->buffer;
   14965     bf->buf_end = bf->buffer + strlen(bf->buffer);
   14966     *bf->buf_end = CH_EOB;
   14967     bf->filename[0] = '\0';
   14968     bf->line_num = 1;
   14969     file = bf;
   14970 
   14971     s1->include_stack_ptr = s1->include_stack;
   14972 
   14973     /* parse with define parser */
   14974     ch = file->buf_ptr[0];
   14975     next_nomacro();
   14976     parse_define();
   14977     file = NULL;
   14978 }
   14979 
   14980 /* undefine a preprocessor symbol */
   14981 void tcc_undefine_symbol(TCCState *s1, const char *sym)
   14982 {
   14983     TokenSym *ts;
   14984     Sym *s;
   14985     ts = tok_alloc(sym, strlen(sym));
   14986     s = define_find(ts->tok);
   14987     /* undefine symbol by putting an invalid name */
   14988     if (s)
   14989         define_undef(s);
   14990 }
   14991 
   14992 #ifdef CONFIG_TCC_ASM
   14993 
   14994 #ifdef TCC_TARGET_I386
   14995 // njn: inlined i386-asm.c
   14996 //#include "i386-asm.c"
   14997 //---------------------------------------------------------------------------
   14998 /*
   14999  *  i386 specific functions for TCC assembler
   15000  *
   15001  *  Copyright (c) 2001, 2002 Fabrice Bellard
   15002  *
   15003  * This library is free software; you can redistribute it and/or
   15004  * modify it under the terms of the GNU Lesser General Public
   15005  * License as published by the Free Software Foundation; either
   15006  * version 2 of the License, or (at your option) any later version.
   15007  *
   15008  * This library is distributed in the hope that it will be useful,
   15009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15011  * Lesser General Public License for more details.
   15012  *
   15013  * You should have received a copy of the GNU Lesser General Public
   15014  * License along with this library; if not, write to the Free Software
   15015  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15016  */
   15017 
   15018 #define MAX_OPERANDS 3
   15019 
   15020 typedef struct ASMInstr {
   15021     uint16_t sym;
   15022     uint16_t opcode;
   15023     uint16_t instr_type;
   15024 #define OPC_JMP       0x01  /* jmp operand */
   15025 #define OPC_B         0x02  /* only used zith OPC_WL */
   15026 #define OPC_WL        0x04  /* accepts w, l or no suffix */
   15027 #define OPC_BWL       (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
   15028 #define OPC_REG       0x08 /* register is added to opcode */
   15029 #define OPC_MODRM     0x10 /* modrm encoding */
   15030 #define OPC_FWAIT     0x20 /* add fwait opcode */
   15031 #define OPC_TEST      0x40 /* test opcodes */
   15032 #define OPC_SHIFT     0x80 /* shift opcodes */
   15033 #define OPC_D16      0x0100 /* generate data16 prefix */
   15034 #define OPC_ARITH    0x0200 /* arithmetic opcodes */
   15035 #define OPC_SHORTJMP 0x0400 /* short jmp operand */
   15036 #define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
   15037 #define OPC_GROUP_SHIFT 13
   15038 
   15039 /* in order to compress the operand type, we use specific operands and
   15040    we or only with EA  */
   15041 #define OPT_REG8  0 /* warning: value is hardcoded from TOK_ASM_xxx */
   15042 #define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */
   15043 #define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */
   15044 #define OPT_MMX   3 /* warning: value is hardcoded from TOK_ASM_xxx */
   15045 #define OPT_SSE   4 /* warning: value is hardcoded from TOK_ASM_xxx */
   15046 #define OPT_CR    5 /* warning: value is hardcoded from TOK_ASM_xxx */
   15047 #define OPT_TR    6 /* warning: value is hardcoded from TOK_ASM_xxx */
   15048 #define OPT_DB    7 /* warning: value is hardcoded from TOK_ASM_xxx */
   15049 #define OPT_SEG   8
   15050 #define OPT_ST    9
   15051 #define OPT_IM8   10
   15052 #define OPT_IM8S  11
   15053 #define OPT_IM16  12
   15054 #define OPT_IM32  13
   15055 #define OPT_EAX   14 /* %al, %ax or %eax register */
   15056 #define OPT_ST0   15 /* %st(0) register */
   15057 #define OPT_CL    16 /* %cl register */
   15058 #define OPT_DX    17 /* %dx register */
   15059 #define OPT_ADDR  18 /* OP_EA with only offset */
   15060 #define OPT_INDIR 19 /* *(expr) */
   15061 
   15062 /* composite types */
   15063 #define OPT_COMPOSITE_FIRST   20
   15064 #define OPT_IM       20 /* IM8 | IM16 | IM32 */
   15065 #define OPT_REG      21 /* REG8 | REG16 | REG32 */
   15066 #define OPT_REGW     22 /* REG16 | REG32 */
   15067 #define OPT_IMW      23 /* IM16 | IM32 */
   15068 
   15069 /* can be ored with any OPT_xxx */
   15070 #define OPT_EA    0x80
   15071 
   15072     uint8_t nb_ops;
   15073     uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
   15074 } ASMInstr;
   15075 
   15076 typedef struct Operand {
   15077     uint32_t type;
   15078 #define OP_REG8   (1 << OPT_REG8)
   15079 #define OP_REG16  (1 << OPT_REG16)
   15080 #define OP_REG32  (1 << OPT_REG32)
   15081 #define OP_MMX    (1 << OPT_MMX)
   15082 #define OP_SSE    (1 << OPT_SSE)
   15083 #define OP_CR     (1 << OPT_CR)
   15084 #define OP_TR     (1 << OPT_TR)
   15085 #define OP_DB     (1 << OPT_DB)
   15086 #define OP_SEG    (1 << OPT_SEG)
   15087 #define OP_ST     (1 << OPT_ST)
   15088 #define OP_IM8    (1 << OPT_IM8)
   15089 #define OP_IM8S   (1 << OPT_IM8S)
   15090 #define OP_IM16   (1 << OPT_IM16)
   15091 #define OP_IM32   (1 << OPT_IM32)
   15092 #define OP_EAX    (1 << OPT_EAX)
   15093 #define OP_ST0    (1 << OPT_ST0)
   15094 #define OP_CL     (1 << OPT_CL)
   15095 #define OP_DX     (1 << OPT_DX)
   15096 #define OP_ADDR   (1 << OPT_ADDR)
   15097 #define OP_INDIR  (1 << OPT_INDIR)
   15098 
   15099 #define OP_EA     0x40000000
   15100 #define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32)
   15101 #define OP_IM     OP_IM32
   15102     int8_t  reg; /* register, -1 if none */
   15103     int8_t  reg2; /* second register, -1 if none */
   15104     uint8_t shift;
   15105     ExprValue e;
   15106 } Operand;
   15107 
   15108 static const uint8_t reg_to_size[5] = {
   15109     [OP_REG8] = 0,
   15110     [OP_REG16] = 1,
   15111     [OP_REG32] = 2,
   15112 };
   15113 
   15114 #define WORD_PREFIX_OPCODE 0x66
   15115 
   15116 #define NB_TEST_OPCODES 30
   15117 
   15118 static const uint8_t test_bits[NB_TEST_OPCODES] = {
   15119  0x00, /* o */
   15120  0x01, /* no */
   15121  0x02, /* b */
   15122  0x02, /* c */
   15123  0x02, /* nae */
   15124  0x03, /* nb */
   15125  0x03, /* nc */
   15126  0x03, /* ae */
   15127  0x04, /* e */
   15128  0x04, /* z */
   15129  0x05, /* ne */
   15130  0x05, /* nz */
   15131  0x06, /* be */
   15132  0x06, /* na */
   15133  0x07, /* nbe */
   15134  0x07, /* a */
   15135  0x08, /* s */
   15136  0x09, /* ns */
   15137  0x0a, /* p */
   15138  0x0a, /* pe */
   15139  0x0b, /* np */
   15140  0x0b, /* po */
   15141  0x0c, /* l */
   15142  0x0c, /* nge */
   15143  0x0d, /* nl */
   15144  0x0d, /* ge */
   15145  0x0e, /* le */
   15146  0x0e, /* ng */
   15147  0x0f, /* nle */
   15148  0x0f, /* g */
   15149 };
   15150 
   15151 static const ASMInstr asm_instrs[] = {
   15152 #define ALT(x) x
   15153 #define DEF_ASM_OP0(name, opcode)
   15154 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
   15155 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
   15156 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
   15157 #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 }},
   15158 // njn: inlined i386-asm.h
   15159 //#include "i386-asm.h"
   15160 //---------------------------------------------------------------------------
   15161      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
   15162      DEF_ASM_OP0(popa, 0x61)
   15163      DEF_ASM_OP0(clc, 0xf8)
   15164      DEF_ASM_OP0(cld, 0xfc)
   15165      DEF_ASM_OP0(cli, 0xfa)
   15166      DEF_ASM_OP0(clts, 0x0f06)
   15167      DEF_ASM_OP0(cmc, 0xf5)
   15168      DEF_ASM_OP0(lahf, 0x9f)
   15169      DEF_ASM_OP0(sahf, 0x9e)
   15170      DEF_ASM_OP0(pushfl, 0x9c)
   15171      DEF_ASM_OP0(popfl, 0x9d)
   15172      DEF_ASM_OP0(pushf, 0x9c)
   15173      DEF_ASM_OP0(popf, 0x9d)
   15174      DEF_ASM_OP0(stc, 0xf9)
   15175      DEF_ASM_OP0(std, 0xfd)
   15176      DEF_ASM_OP0(sti, 0xfb)
   15177      DEF_ASM_OP0(aaa, 0x37)
   15178      DEF_ASM_OP0(aas, 0x3f)
   15179      DEF_ASM_OP0(daa, 0x27)
   15180      DEF_ASM_OP0(das, 0x2f)
   15181      DEF_ASM_OP0(aad, 0xd50a)
   15182      DEF_ASM_OP0(aam, 0xd40a)
   15183      DEF_ASM_OP0(cbw, 0x6698)
   15184      DEF_ASM_OP0(cwd, 0x6699)
   15185      DEF_ASM_OP0(cwde, 0x98)
   15186      DEF_ASM_OP0(cdq, 0x99)
   15187      DEF_ASM_OP0(cbtw, 0x6698)
   15188      DEF_ASM_OP0(cwtl, 0x98)
   15189      DEF_ASM_OP0(cwtd, 0x6699)
   15190      DEF_ASM_OP0(cltd, 0x99)
   15191      DEF_ASM_OP0(int3, 0xcc)
   15192      DEF_ASM_OP0(into, 0xce)
   15193      DEF_ASM_OP0(iret, 0xcf)
   15194      DEF_ASM_OP0(rsm, 0x0faa)
   15195      DEF_ASM_OP0(hlt, 0xf4)
   15196      DEF_ASM_OP0(wait, 0x9b)
   15197      DEF_ASM_OP0(nop, 0x90)
   15198      DEF_ASM_OP0(xlat, 0xd7)
   15199 
   15200      /* strings */
   15201 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
   15202 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
   15203 
   15204 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
   15205 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
   15206 
   15207 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
   15208 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
   15209 
   15210 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
   15211 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
   15212 
   15213 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
   15214 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
   15215 
   15216 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
   15217 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
   15218 
   15219      /* bits */
   15220 
   15221 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   15222 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   15223 
   15224 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15225 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15226 
   15227 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15228 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15229 
   15230 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15231 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15232 
   15233 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15234 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15235 
   15236      /* prefixes */
   15237      DEF_ASM_OP0(aword, 0x67)
   15238      DEF_ASM_OP0(addr16, 0x67)
   15239      DEF_ASM_OP0(word, 0x66)
   15240      DEF_ASM_OP0(data16, 0x66)
   15241      DEF_ASM_OP0(lock, 0xf0)
   15242      DEF_ASM_OP0(rep, 0xf3)
   15243      DEF_ASM_OP0(repe, 0xf3)
   15244      DEF_ASM_OP0(repz, 0xf3)
   15245      DEF_ASM_OP0(repne, 0xf2)
   15246      DEF_ASM_OP0(repnz, 0xf2)
   15247 
   15248      DEF_ASM_OP0(invd, 0x0f08)
   15249      DEF_ASM_OP0(wbinvd, 0x0f09)
   15250      DEF_ASM_OP0(cpuid, 0x0fa2)
   15251      DEF_ASM_OP0(wrmsr, 0x0f30)
   15252      DEF_ASM_OP0(rdtsc, 0x0f31)
   15253      DEF_ASM_OP0(rdmsr, 0x0f32)
   15254      DEF_ASM_OP0(rdpmc, 0x0f33)
   15255      DEF_ASM_OP0(ud2, 0x0f0b)
   15256 
   15257      /* NOTE: we took the same order as gas opcode definition order */
   15258 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
   15259 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
   15260 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   15261 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15262 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
   15263 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
   15264 
   15265 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
   15266 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
   15267 
   15268 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
   15269 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
   15270 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
   15271 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
   15272 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
   15273 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
   15274 
   15275 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
   15276 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
   15277 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   15278 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
   15279 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   15280 
   15281 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
   15282 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   15283 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
   15284 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
   15285 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
   15286 
   15287 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
   15288 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   15289 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
   15290 
   15291 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
   15292 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
   15293 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   15294 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15295 
   15296 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
   15297 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
   15298 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
   15299 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
   15300 
   15301 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
   15302 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
   15303 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
   15304 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
   15305 
   15306 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
   15307 
   15308 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15309 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15310 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15311 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15312 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15313 
   15314      /* arith */
   15315 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
   15316 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15317 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
   15318 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   15319 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
   15320 
   15321 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15322 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   15323 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
   15324 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   15325 
   15326 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
   15327 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15328 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
   15329 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15330 
   15331 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15332 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15333 
   15334 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15335 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15336 
   15337 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
   15338 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
   15339 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
   15340 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
   15341 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
   15342 
   15343 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15344 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   15345 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15346 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   15347 
   15348      /* shifts */
   15349 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
   15350 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
   15351 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
   15352 
   15353 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   15354 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   15355 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   15356 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   15357 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   15358 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   15359 
   15360 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
   15361 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
   15362 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
   15363 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
   15364 
   15365 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
   15366 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
   15367 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
   15368 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
   15369 
   15370 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
   15371 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
   15372     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
   15373     DEF_ASM_OP0(leave, 0xc9)
   15374     DEF_ASM_OP0(ret, 0xc3)
   15375 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
   15376     DEF_ASM_OP0(lret, 0xcb)
   15377 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
   15378 
   15379 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
   15380     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   15381     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   15382     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   15383     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   15384     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
   15385     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
   15386 
   15387      /* float */
   15388      /* specific fcomp handling */
   15389 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
   15390 
   15391 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   15392 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   15393 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
   15394 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   15395 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   15396 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
   15397 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
   15398 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15399 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15400 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15401 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15402 
   15403      DEF_ASM_OP0(fucompp, 0xdae9)
   15404      DEF_ASM_OP0(ftst, 0xd9e4)
   15405      DEF_ASM_OP0(fxam, 0xd9e5)
   15406      DEF_ASM_OP0(fld1, 0xd9e8)
   15407      DEF_ASM_OP0(fldl2t, 0xd9e9)
   15408      DEF_ASM_OP0(fldl2e, 0xd9ea)
   15409      DEF_ASM_OP0(fldpi, 0xd9eb)
   15410      DEF_ASM_OP0(fldlg2, 0xd9ec)
   15411      DEF_ASM_OP0(fldln2, 0xd9ed)
   15412      DEF_ASM_OP0(fldz, 0xd9ee)
   15413 
   15414      DEF_ASM_OP0(f2xm1, 0xd9f0)
   15415      DEF_ASM_OP0(fyl2x, 0xd9f1)
   15416      DEF_ASM_OP0(fptan, 0xd9f2)
   15417      DEF_ASM_OP0(fpatan, 0xd9f3)
   15418      DEF_ASM_OP0(fxtract, 0xd9f4)
   15419      DEF_ASM_OP0(fprem1, 0xd9f5)
   15420      DEF_ASM_OP0(fdecstp, 0xd9f6)
   15421      DEF_ASM_OP0(fincstp, 0xd9f7)
   15422      DEF_ASM_OP0(fprem, 0xd9f8)
   15423      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
   15424      DEF_ASM_OP0(fsqrt, 0xd9fa)
   15425      DEF_ASM_OP0(fsincos, 0xd9fb)
   15426      DEF_ASM_OP0(frndint, 0xd9fc)
   15427      DEF_ASM_OP0(fscale, 0xd9fd)
   15428      DEF_ASM_OP0(fsin, 0xd9fe)
   15429      DEF_ASM_OP0(fcos, 0xd9ff)
   15430      DEF_ASM_OP0(fchs, 0xd9e0)
   15431      DEF_ASM_OP0(fabs, 0xd9e1)
   15432      DEF_ASM_OP0(fninit, 0xdbe3)
   15433      DEF_ASM_OP0(fnclex, 0xdbe2)
   15434      DEF_ASM_OP0(fnop, 0xd9d0)
   15435      DEF_ASM_OP0(fwait, 0x9b)
   15436 
   15437     /* fp load */
   15438     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
   15439     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
   15440     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
   15441 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
   15442     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
   15443     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
   15444     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
   15445     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
   15446     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
   15447 
   15448     /* fp store */
   15449     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
   15450     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
   15451     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
   15452     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
   15453 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
   15454     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
   15455     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
   15456     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
   15457     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
   15458     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
   15459 
   15460     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
   15461     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
   15462     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
   15463     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
   15464     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
   15465 
   15466     /* exchange */
   15467     DEF_ASM_OP0(fxch, 0xd9c9)
   15468 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
   15469 
   15470     /* misc FPU */
   15471     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
   15472     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
   15473 
   15474     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
   15475     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
   15476     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
   15477     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
   15478     DEF_ASM_OP0(fnstsw, 0xdfe0)
   15479 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
   15480 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
   15481     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
   15482 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
   15483 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
   15484     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
   15485     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
   15486     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   15487     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
   15488     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
   15489     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   15490     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
   15491     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
   15492     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
   15493     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
   15494     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
   15495 
   15496     /* segments */
   15497     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
   15498     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
   15499     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
   15500     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
   15501     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
   15502     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
   15503 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
   15504     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
   15505     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
   15506     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
   15507     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
   15508     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
   15509     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
   15510     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
   15511     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
   15512 
   15513     /* 486 */
   15514     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
   15515 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   15516 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   15517     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
   15518 
   15519     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
   15520     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
   15521 
   15522     /* pentium */
   15523     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
   15524 
   15525     /* pentium pro */
   15526     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
   15527 
   15528     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15529     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15530     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15531     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15532     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15533     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15534     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15535     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15536 
   15537     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15538     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15539     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15540     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15541 
   15542     /* mmx */
   15543     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
   15544     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
   15545 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
   15546     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15547 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
   15548     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15549     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15550     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15551     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15552     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15553     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15554     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15555     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15556     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15557     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15558     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15559     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15560     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15561     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15562     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15563     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15564     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15565     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15566     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15567     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15568     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15569     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15570     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15571 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15572     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15573 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15574     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15575 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15576     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15577 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15578     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15579 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15580     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15581 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15582     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15583 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15584     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15585 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   15586     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15587     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15588     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15589     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15590     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15591     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15592     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15593     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15594     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15595     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15596     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15597     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15598     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15599     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   15600 
   15601 #undef ALT
   15602 #undef DEF_ASM_OP0
   15603 #undef DEF_ASM_OP0L
   15604 #undef DEF_ASM_OP1
   15605 #undef DEF_ASM_OP2
   15606 #undef DEF_ASM_OP3
   15607 //---------------------------------------------------------------------------
   15608 
   15609     /* last operation */
   15610     { 0, },
   15611 };
   15612 
   15613 static const uint16_t op0_codes[] = {
   15614 #define ALT(x)
   15615 #define DEF_ASM_OP0(x, opcode) opcode,
   15616 #define DEF_ASM_OP0L(name, opcode, group, instr_type)
   15617 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
   15618 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
   15619 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
   15620 // njn: inlined i386-asm.h
   15621 //#include "i386-asm.h"
   15622 //---------------------------------------------------------------------------
   15623      DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
   15624      DEF_ASM_OP0(popa, 0x61)
   15625      DEF_ASM_OP0(clc, 0xf8)
   15626      DEF_ASM_OP0(cld, 0xfc)
   15627      DEF_ASM_OP0(cli, 0xfa)
   15628      DEF_ASM_OP0(clts, 0x0f06)
   15629      DEF_ASM_OP0(cmc, 0xf5)
   15630      DEF_ASM_OP0(lahf, 0x9f)
   15631      DEF_ASM_OP0(sahf, 0x9e)
   15632      DEF_ASM_OP0(pushfl, 0x9c)
   15633      DEF_ASM_OP0(popfl, 0x9d)
   15634      DEF_ASM_OP0(pushf, 0x9c)
   15635      DEF_ASM_OP0(popf, 0x9d)
   15636      DEF_ASM_OP0(stc, 0xf9)
   15637      DEF_ASM_OP0(std, 0xfd)
   15638      DEF_ASM_OP0(sti, 0xfb)
   15639      DEF_ASM_OP0(aaa, 0x37)
   15640      DEF_ASM_OP0(aas, 0x3f)
   15641      DEF_ASM_OP0(daa, 0x27)
   15642      DEF_ASM_OP0(das, 0x2f)
   15643      DEF_ASM_OP0(aad, 0xd50a)
   15644      DEF_ASM_OP0(aam, 0xd40a)
   15645      DEF_ASM_OP0(cbw, 0x6698)
   15646      DEF_ASM_OP0(cwd, 0x6699)
   15647      DEF_ASM_OP0(cwde, 0x98)
   15648      DEF_ASM_OP0(cdq, 0x99)
   15649      DEF_ASM_OP0(cbtw, 0x6698)
   15650      DEF_ASM_OP0(cwtl, 0x98)
   15651      DEF_ASM_OP0(cwtd, 0x6699)
   15652      DEF_ASM_OP0(cltd, 0x99)
   15653      DEF_ASM_OP0(int3, 0xcc)
   15654      DEF_ASM_OP0(into, 0xce)
   15655      DEF_ASM_OP0(iret, 0xcf)
   15656      DEF_ASM_OP0(rsm, 0x0faa)
   15657      DEF_ASM_OP0(hlt, 0xf4)
   15658      DEF_ASM_OP0(wait, 0x9b)
   15659      DEF_ASM_OP0(nop, 0x90)
   15660      DEF_ASM_OP0(xlat, 0xd7)
   15661 
   15662      /* strings */
   15663 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
   15664 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
   15665 
   15666 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
   15667 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
   15668 
   15669 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
   15670 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
   15671 
   15672 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
   15673 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
   15674 
   15675 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
   15676 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
   15677 
   15678 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
   15679 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
   15680 
   15681      /* bits */
   15682 
   15683 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   15684 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
   15685 
   15686 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15687 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15688 
   15689 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15690 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15691 
   15692 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15693 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15694 
   15695 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
   15696 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
   15697 
   15698      /* prefixes */
   15699      DEF_ASM_OP0(aword, 0x67)
   15700      DEF_ASM_OP0(addr16, 0x67)
   15701      DEF_ASM_OP0(word, 0x66)
   15702      DEF_ASM_OP0(data16, 0x66)
   15703      DEF_ASM_OP0(lock, 0xf0)
   15704      DEF_ASM_OP0(rep, 0xf3)
   15705      DEF_ASM_OP0(repe, 0xf3)
   15706      DEF_ASM_OP0(repz, 0xf3)
   15707      DEF_ASM_OP0(repne, 0xf2)
   15708      DEF_ASM_OP0(repnz, 0xf2)
   15709 
   15710      DEF_ASM_OP0(invd, 0x0f08)
   15711      DEF_ASM_OP0(wbinvd, 0x0f09)
   15712      DEF_ASM_OP0(cpuid, 0x0fa2)
   15713      DEF_ASM_OP0(wrmsr, 0x0f30)
   15714      DEF_ASM_OP0(rdtsc, 0x0f31)
   15715      DEF_ASM_OP0(rdmsr, 0x0f32)
   15716      DEF_ASM_OP0(rdpmc, 0x0f33)
   15717      DEF_ASM_OP0(ud2, 0x0f0b)
   15718 
   15719      /* NOTE: we took the same order as gas opcode definition order */
   15720 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
   15721 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
   15722 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   15723 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15724 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
   15725 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
   15726 
   15727 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
   15728 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
   15729 
   15730 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
   15731 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
   15732 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
   15733 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
   15734 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
   15735 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
   15736 
   15737 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
   15738 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
   15739 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   15740 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
   15741 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
   15742 
   15743 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
   15744 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   15745 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
   15746 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
   15747 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
   15748 
   15749 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
   15750 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
   15751 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
   15752 
   15753 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
   15754 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
   15755 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   15756 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15757 
   15758 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
   15759 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
   15760 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
   15761 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
   15762 
   15763 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
   15764 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
   15765 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
   15766 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
   15767 
   15768 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
   15769 
   15770 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15771 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15772 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15773 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15774 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
   15775 
   15776      /* arith */
   15777 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
   15778 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15779 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
   15780 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   15781 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
   15782 
   15783 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
   15784 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
   15785 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
   15786 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
   15787 
   15788 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
   15789 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15790 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
   15791 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15792 
   15793 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15794 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15795 
   15796 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15797 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15798 
   15799 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
   15800 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
   15801 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
   15802 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
   15803 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
   15804 
   15805 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15806 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   15807 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
   15808 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
   15809 
   15810      /* shifts */
   15811 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
   15812 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
   15813 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
   15814 
   15815 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   15816 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   15817 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   15818 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
   15819 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
   15820 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
   15821 
   15822 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
   15823 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
   15824 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
   15825 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
   15826 
   15827 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
   15828 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
   15829 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
   15830 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
   15831 
   15832 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
   15833 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
   15834     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
   15835     DEF_ASM_OP0(leave, 0xc9)
   15836     DEF_ASM_OP0(ret, 0xc3)
   15837 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
   15838     DEF_ASM_OP0(lret, 0xcb)
   15839 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
   15840 
   15841 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
   15842     DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   15843     DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
   15844     DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   15845     DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
   15846     DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
   15847     DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
   15848 
   15849      /* float */
   15850      /* specific fcomp handling */
   15851 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
   15852 
   15853 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   15854 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   15855 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
   15856 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
   15857 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
   15858 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
   15859 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
   15860 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15861 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15862 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15863 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
   15864 
   15865      DEF_ASM_OP0(fucompp, 0xdae9)
   15866      DEF_ASM_OP0(ftst, 0xd9e4)
   15867      DEF_ASM_OP0(fxam, 0xd9e5)
   15868      DEF_ASM_OP0(fld1, 0xd9e8)
   15869      DEF_ASM_OP0(fldl2t, 0xd9e9)
   15870      DEF_ASM_OP0(fldl2e, 0xd9ea)
   15871      DEF_ASM_OP0(fldpi, 0xd9eb)
   15872      DEF_ASM_OP0(fldlg2, 0xd9ec)
   15873      DEF_ASM_OP0(fldln2, 0xd9ed)
   15874      DEF_ASM_OP0(fldz, 0xd9ee)
   15875 
   15876      DEF_ASM_OP0(f2xm1, 0xd9f0)
   15877      DEF_ASM_OP0(fyl2x, 0xd9f1)
   15878      DEF_ASM_OP0(fptan, 0xd9f2)
   15879      DEF_ASM_OP0(fpatan, 0xd9f3)
   15880      DEF_ASM_OP0(fxtract, 0xd9f4)
   15881      DEF_ASM_OP0(fprem1, 0xd9f5)
   15882      DEF_ASM_OP0(fdecstp, 0xd9f6)
   15883      DEF_ASM_OP0(fincstp, 0xd9f7)
   15884      DEF_ASM_OP0(fprem, 0xd9f8)
   15885      DEF_ASM_OP0(fyl2xp1, 0xd9f9)
   15886      DEF_ASM_OP0(fsqrt, 0xd9fa)
   15887      DEF_ASM_OP0(fsincos, 0xd9fb)
   15888      DEF_ASM_OP0(frndint, 0xd9fc)
   15889      DEF_ASM_OP0(fscale, 0xd9fd)
   15890      DEF_ASM_OP0(fsin, 0xd9fe)
   15891      DEF_ASM_OP0(fcos, 0xd9ff)
   15892      DEF_ASM_OP0(fchs, 0xd9e0)
   15893      DEF_ASM_OP0(fabs, 0xd9e1)
   15894      DEF_ASM_OP0(fninit, 0xdbe3)
   15895      DEF_ASM_OP0(fnclex, 0xdbe2)
   15896      DEF_ASM_OP0(fnop, 0xd9d0)
   15897      DEF_ASM_OP0(fwait, 0x9b)
   15898 
   15899     /* fp load */
   15900     DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
   15901     DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
   15902     DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
   15903 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
   15904     DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
   15905     DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
   15906     DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
   15907     DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
   15908     DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
   15909 
   15910     /* fp store */
   15911     DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
   15912     DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
   15913     DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
   15914     DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
   15915 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
   15916     DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
   15917     DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
   15918     DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
   15919     DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
   15920     DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
   15921 
   15922     DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
   15923     DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
   15924     DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
   15925     DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
   15926     DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
   15927 
   15928     /* exchange */
   15929     DEF_ASM_OP0(fxch, 0xd9c9)
   15930 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
   15931 
   15932     /* misc FPU */
   15933     DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
   15934     DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
   15935 
   15936     DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
   15937     DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
   15938     DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
   15939     DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
   15940     DEF_ASM_OP0(fnstsw, 0xdfe0)
   15941 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
   15942 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
   15943     DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
   15944 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
   15945 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
   15946     DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
   15947     DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
   15948     DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   15949     DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
   15950     DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
   15951     DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
   15952     DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
   15953     DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
   15954     DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
   15955     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
   15956     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
   15957 
   15958     /* segments */
   15959     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
   15960     DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
   15961     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
   15962     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
   15963     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
   15964     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
   15965 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
   15966     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
   15967     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
   15968     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
   15969     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
   15970     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
   15971     DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
   15972     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
   15973     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
   15974 
   15975     /* 486 */
   15976     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
   15977 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   15978 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
   15979     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
   15980 
   15981     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
   15982     DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
   15983 
   15984     /* pentium */
   15985     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
   15986 
   15987     /* pentium pro */
   15988     ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
   15989 
   15990     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15991     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15992     DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15993     DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15994     DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15995     DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15996     DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15997     DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   15998 
   15999     DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   16000     DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   16001     DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
   16002     DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
   16003 
   16004     /* mmx */
   16005     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
   16006     DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
   16007 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
   16008     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16009 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
   16010     DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16011     DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16012     DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16013     DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16014     DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16015     DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16016     DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16017     DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16018     DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16019     DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16020     DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16021     DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16022     DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16023     DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16024     DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16025     DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16026     DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16027     DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16028     DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16029     DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16030     DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16031     DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16032     DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16033 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16034     DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16035 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16036     DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16037 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16038     DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16039 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16040     DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16041 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16042     DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16043 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16044     DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16045 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16046     DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16047 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
   16048     DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16049     DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16050     DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16051     DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16052     DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16053     DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16054     DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16055     DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16056     DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16057     DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16058     DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16059     DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16060     DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16061     DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
   16062 
   16063 #undef ALT
   16064 #undef DEF_ASM_OP0
   16065 #undef DEF_ASM_OP0L
   16066 #undef DEF_ASM_OP1
   16067 #undef DEF_ASM_OP2
   16068 #undef DEF_ASM_OP3
   16069 //---------------------------------------------------------------------------
   16070 };
   16071 
   16072 static inline int get_reg_shift(TCCState *s1)
   16073 {
   16074     int shift, v;
   16075 
   16076     v = asm_int_expr(s1);
   16077     switch(v) {
   16078     case 1:
   16079         shift = 0;
   16080         break;
   16081     case 2:
   16082         shift = 1;
   16083         break;
   16084     case 4:
   16085         shift = 2;
   16086         break;
   16087     case 8:
   16088         shift = 3;
   16089         break;
   16090     default:
   16091         expect("1, 2, 4 or 8 constant");
   16092         shift = 0;
   16093         break;
   16094     }
   16095     return shift;
   16096 }
   16097 
   16098 static int asm_parse_reg(void)
   16099 {
   16100     int reg;
   16101     if (tok != '%')
   16102         goto error_32;
   16103     next();
   16104     if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
   16105         reg = tok - TOK_ASM_eax;
   16106         next();
   16107         return reg;
   16108     } else {
   16109     error_32:
   16110         expect("32 bit register");
   16111         return 0;
   16112     }
   16113 }
   16114 
   16115 static void parse_operand(TCCState *s1, Operand *op)
   16116 {
   16117     ExprValue e;
   16118     int reg, indir;
   16119     const char *p;
   16120 
   16121     indir = 0;
   16122     if (tok == '*') {
   16123         next();
   16124         indir = OP_INDIR;
   16125     }
   16126 
   16127     if (tok == '%') {
   16128         next();
   16129         if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
   16130             reg = tok - TOK_ASM_al;
   16131             op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
   16132             op->reg = reg & 7;
   16133             if ((op->type & OP_REG) && op->reg == TREG_EAX)
   16134                 op->type |= OP_EAX;
   16135             else if (op->type == OP_REG8 && op->reg == TREG_ECX)
   16136                 op->type |= OP_CL;
   16137             else if (op->type == OP_REG16 && op->reg == TREG_EDX)
   16138                 op->type |= OP_DX;
   16139         } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
   16140             op->type = OP_DB;
   16141             op->reg = tok - TOK_ASM_dr0;
   16142         } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
   16143             op->type = OP_SEG;
   16144             op->reg = tok - TOK_ASM_es;
   16145         } else if (tok == TOK_ASM_st) {
   16146             op->type = OP_ST;
   16147             op->reg = 0;
   16148             next();
   16149             if (tok == '(') {
   16150                 next();
   16151                 if (tok != TOK_PPNUM)
   16152                     goto reg_error;
   16153                 p = tokc.cstr->data;
   16154                 reg = p[0] - '0';
   16155                 if ((unsigned)reg >= 8 || p[1] != '\0')
   16156                     goto reg_error;
   16157                 op->reg = reg;
   16158                 next();
   16159                 skip(')');
   16160             }
   16161             if (op->reg == 0)
   16162                 op->type |= OP_ST0;
   16163             goto no_skip;
   16164         } else {
   16165         reg_error:
   16166             error("unknown register");
   16167         }
   16168         next();
   16169     no_skip: ;
   16170     } else if (tok == '$') {
   16171         /* constant value */
   16172         next();
   16173         asm_expr(s1, &e);
   16174         op->type = OP_IM32;
   16175         op->e.v = e.v;
   16176         op->e.sym = e.sym;
   16177         if (!op->e.sym) {
   16178             if (op->e.v == (uint8_t)op->e.v)
   16179                 op->type |= OP_IM8;
   16180             if (op->e.v == (int8_t)op->e.v)
   16181                 op->type |= OP_IM8S;
   16182             if (op->e.v == (uint16_t)op->e.v)
   16183                 op->type |= OP_IM16;
   16184         }
   16185     } else {
   16186         /* address(reg,reg2,shift) with all variants */
   16187         op->type = OP_EA;
   16188         op->reg = -1;
   16189         op->reg2 = -1;
   16190         op->shift = 0;
   16191         if (tok != '(') {
   16192             asm_expr(s1, &e);
   16193             op->e.v = e.v;
   16194             op->e.sym = e.sym;
   16195         } else {
   16196             op->e.v = 0;
   16197             op->e.sym = NULL;
   16198         }
   16199         if (tok == '(') {
   16200             next();
   16201             if (tok != ',') {
   16202                 op->reg = asm_parse_reg();
   16203             }
   16204             if (tok == ',') {
   16205                 next();
   16206                 if (tok != ',') {
   16207                     op->reg2 = asm_parse_reg();
   16208                 }
   16209                 skip(',');
   16210                 op->shift = get_reg_shift(s1);
   16211             }
   16212             skip(')');
   16213         }
   16214         if (op->reg == -1 && op->reg2 == -1)
   16215             op->type |= OP_ADDR;
   16216     }
   16217     op->type |= indir;
   16218 }
   16219 
   16220 /* XXX: unify with C code output ? */
   16221 static void gen_expr32(ExprValue *pe)
   16222 {
   16223     if (pe->sym)
   16224         greloc(cur_text_section, pe->sym, ind, R_386_32);
   16225     gen_le32(pe->v);
   16226 }
   16227 
   16228 /* XXX: unify with C code output ? */
   16229 static void gen_disp32(ExprValue *pe)
   16230 {
   16231     Sym *sym;
   16232     sym = pe->sym;
   16233     if (sym) {
   16234         if (sym->r == cur_text_section->sh_num) {
   16235             /* same section: we can output an absolute value. Note
   16236                that the TCC compiler behaves differently here because
   16237                it always outputs a relocation to ease (future) code
   16238                elimination in the linker */
   16239             gen_le32(pe->v + (long)sym->next - ind - 4);
   16240         } else {
   16241             greloc(cur_text_section, sym, ind, R_386_PC32);
   16242             gen_le32(pe->v - 4);
   16243         }
   16244     } else {
   16245         /* put an empty PC32 relocation */
   16246         put_elf_reloc(symtab_section, cur_text_section,
   16247                       ind, R_386_PC32, 0);
   16248         gen_le32(pe->v - 4);
   16249     }
   16250 }
   16251 
   16252 
   16253 static void gen_le16(int v)
   16254 {
   16255     g(v);
   16256     g(v >> 8);
   16257 }
   16258 
   16259 /* generate the modrm operand */
   16260 static inline void asm_modrm(int reg, Operand *op)
   16261 {
   16262     int mod, reg1, reg2, sib_reg1;
   16263 
   16264     if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
   16265         g(0xc0 + (reg << 3) + op->reg);
   16266     } else if (op->reg == -1 && op->reg2 == -1) {
   16267         /* displacement only */
   16268         g(0x05 + (reg << 3));
   16269         gen_expr32(&op->e);
   16270     } else {
   16271         sib_reg1 = op->reg;
   16272         /* fist compute displacement encoding */
   16273         if (sib_reg1 == -1) {
   16274             sib_reg1 = 5;
   16275             mod = 0x00;
   16276         } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
   16277             mod = 0x00;
   16278         } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
   16279             mod = 0x40;
   16280         } else {
   16281             mod = 0x80;
   16282         }
   16283         /* compute if sib byte needed */
   16284         reg1 = op->reg;
   16285         if (op->reg2 != -1)
   16286             reg1 = 4;
   16287         g(mod + (reg << 3) + reg1);
   16288         if (reg1 == 4) {
   16289             /* add sib byte */
   16290             reg2 = op->reg2;
   16291             if (reg2 == -1)
   16292                 reg2 = 4; /* indicate no index */
   16293             g((op->shift << 6) + (reg2 << 3) + sib_reg1);
   16294         }
   16295 
   16296         /* add offset */
   16297         if (mod == 0x40) {
   16298             g(op->e.v);
   16299         } else if (mod == 0x80 || op->reg == -1) {
   16300             gen_expr32(&op->e);
   16301         }
   16302     }
   16303 }
   16304 
   16305 static void asm_opcode(TCCState *s1, int opcode)
   16306 {
   16307     const ASMInstr *pa;
   16308     int i, modrm_index, reg, v, op1, is_short_jmp;
   16309     int nb_ops, s, ss;
   16310     Operand ops[MAX_OPERANDS], *pop;
   16311     int op_type[3]; /* decoded op type */
   16312 
   16313     /* get operands */
   16314     pop = ops;
   16315     nb_ops = 0;
   16316     for(;;) {
   16317         if (tok == ';' || tok == TOK_LINEFEED)
   16318             break;
   16319         if (nb_ops >= MAX_OPERANDS) {
   16320             error("incorrect number of operands");
   16321         }
   16322         parse_operand(s1, pop);
   16323         pop++;
   16324         nb_ops++;
   16325         if (tok != ',')
   16326             break;
   16327         next();
   16328     }
   16329 
   16330     is_short_jmp = 0;
   16331     s = 0; /* avoid warning */
   16332 
   16333     /* optimize matching by using a lookup table (no hashing is needed
   16334        !) */
   16335     for(pa = asm_instrs; pa->sym != 0; pa++) {
   16336         s = 0;
   16337         if (pa->instr_type & OPC_FARITH) {
   16338             v = opcode - pa->sym;
   16339             if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
   16340                 continue;
   16341         } else if (pa->instr_type & OPC_ARITH) {
   16342             if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
   16343                 continue;
   16344             goto compute_size;
   16345         } else if (pa->instr_type & OPC_SHIFT) {
   16346             if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
   16347                 continue;
   16348             goto compute_size;
   16349         } else if (pa->instr_type & OPC_TEST) {
   16350             if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
   16351                 continue;
   16352         } else if (pa->instr_type & OPC_B) {
   16353             if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
   16354                 continue;
   16355         compute_size:
   16356             s = (opcode - pa->sym) & 3;
   16357         } else if (pa->instr_type & OPC_WL) {
   16358             if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
   16359                 continue;
   16360             s = opcode - pa->sym + 1;
   16361         } else {
   16362             if (pa->sym != opcode)
   16363                 continue;
   16364         }
   16365         if (pa->nb_ops != nb_ops)
   16366             continue;
   16367         /* now decode and check each operand */
   16368         for(i = 0; i < nb_ops; i++) {
   16369             int op1, op2;
   16370             op1 = pa->op_type[i];
   16371             op2 = op1 & 0x1f;
   16372             switch(op2) {
   16373             case OPT_IM:
   16374                 v = OP_IM8 | OP_IM16 | OP_IM32;
   16375                 break;
   16376             case OPT_REG:
   16377                 v = OP_REG8 | OP_REG16 | OP_REG32;
   16378                 break;
   16379             case OPT_REGW:
   16380                 v = OP_REG16 | OP_REG32;
   16381                 break;
   16382             case OPT_IMW:
   16383                 v = OP_IM16 | OP_IM32;
   16384                 break;
   16385             default:
   16386                 v = 1 << op2;
   16387                 break;
   16388             }
   16389             if (op1 & OPT_EA)
   16390                 v |= OP_EA;
   16391             op_type[i] = v;
   16392             if ((ops[i].type & v) == 0)
   16393                 goto next;
   16394         }
   16395         /* all is matching ! */
   16396         break;
   16397     next: ;
   16398     }
   16399     if (pa->sym == 0) {
   16400         if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
   16401             int b;
   16402             b = op0_codes[opcode - TOK_ASM_pusha];
   16403             if (b & 0xff00)
   16404                 g(b >> 8);
   16405             g(b);
   16406             return;
   16407         } else {
   16408             error("unknown opcode '%s'",
   16409                   get_tok_str(opcode, NULL));
   16410         }
   16411     }
   16412     /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
   16413     if (s == 3) {
   16414         for(i = 0; s == 3 && i < nb_ops; i++) {
   16415             if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
   16416                 s = reg_to_size[ops[i].type & OP_REG];
   16417         }
   16418         if (s == 3) {
   16419             if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
   16420                 (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
   16421                 s = 2;
   16422             else
   16423                 error("cannot infer opcode suffix");
   16424         }
   16425     }
   16426 
   16427     /* generate data16 prefix if needed */
   16428     ss = s;
   16429     if (s == 1 || (pa->instr_type & OPC_D16))
   16430         g(WORD_PREFIX_OPCODE);
   16431     else if (s == 2)
   16432         s = 1;
   16433     /* now generates the operation */
   16434     if (pa->instr_type & OPC_FWAIT)
   16435         g(0x9b);
   16436 
   16437     v = pa->opcode;
   16438     if (v == 0x69 || v == 0x69) {
   16439         /* kludge for imul $im, %reg */
   16440         nb_ops = 3;
   16441         ops[2] = ops[1];
   16442     } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
   16443         v--; /* int $3 case */
   16444         nb_ops = 0;
   16445     } else if ((v == 0x06 || v == 0x07)) {
   16446         if (ops[0].reg >= 4) {
   16447             /* push/pop %fs or %gs */
   16448             v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
   16449         } else {
   16450             v += ops[0].reg << 3;
   16451         }
   16452         nb_ops = 0;
   16453     } else if (v <= 0x05) {
   16454         /* arith case */
   16455         v += ((opcode - TOK_ASM_addb) >> 2) << 3;
   16456     } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
   16457         /* fpu arith case */
   16458         v += ((opcode - pa->sym) / 6) << 3;
   16459     }
   16460     if (pa->instr_type & OPC_REG) {
   16461         for(i = 0; i < nb_ops; i++) {
   16462             if (op_type[i] & (OP_REG | OP_ST)) {
   16463                 v += ops[i].reg;
   16464                 break;
   16465             }
   16466         }
   16467         /* mov $im, %reg case */
   16468         if (pa->opcode == 0xb0 && s >= 1)
   16469             v += 7;
   16470     }
   16471     if (pa->instr_type & OPC_B)
   16472         v += s;
   16473     if (pa->instr_type & OPC_TEST)
   16474         v += test_bits[opcode - pa->sym];
   16475     if (pa->instr_type & OPC_SHORTJMP) {
   16476         Sym *sym;
   16477         int jmp_disp;
   16478 
   16479         /* see if we can really generate the jump with a byte offset */
   16480         sym = ops[0].e.sym;
   16481         if (!sym)
   16482             goto no_short_jump;
   16483         if (sym->r != cur_text_section->sh_num)
   16484             goto no_short_jump;
   16485         jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
   16486         if (jmp_disp == (int8_t)jmp_disp) {
   16487             /* OK to generate jump */
   16488             is_short_jmp = 1;
   16489             ops[0].e.v = jmp_disp;
   16490         } else {
   16491         no_short_jump:
   16492             if (pa->instr_type & OPC_JMP) {
   16493                 /* long jump will be allowed. need to modify the
   16494                    opcode slightly */
   16495                 if (v == 0xeb)
   16496                     v = 0xe9;
   16497                 else
   16498                     v += 0x0f10;
   16499             } else {
   16500                 error("invalid displacement");
   16501             }
   16502         }
   16503     }
   16504     op1 = v >> 8;
   16505     if (op1)
   16506         g(op1);
   16507     g(v);
   16508 
   16509     /* search which operand will used for modrm */
   16510     modrm_index = 0;
   16511     if (pa->instr_type & OPC_SHIFT) {
   16512         reg = (opcode - pa->sym) >> 2;
   16513         if (reg == 6)
   16514             reg = 7;
   16515     } else if (pa->instr_type & OPC_ARITH) {
   16516         reg = (opcode - pa->sym) >> 2;
   16517     } else if (pa->instr_type & OPC_FARITH) {
   16518         reg = (opcode - pa->sym) / 6;
   16519     } else {
   16520         reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
   16521     }
   16522     if (pa->instr_type & OPC_MODRM) {
   16523         /* first look for an ea operand */
   16524         for(i = 0;i < nb_ops; i++) {
   16525             if (op_type[i] & OP_EA)
   16526                 goto modrm_found;
   16527         }
   16528         /* then if not found, a register or indirection (shift instructions) */
   16529         for(i = 0;i < nb_ops; i++) {
   16530             if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
   16531                 goto modrm_found;
   16532         }
   16533 #ifdef ASM_DEBUG
   16534         error("bad op table");
   16535 #endif
   16536     modrm_found:
   16537         modrm_index = i;
   16538         /* if a register is used in another operand then it is
   16539            used instead of group */
   16540         for(i = 0;i < nb_ops; i++) {
   16541             v = op_type[i];
   16542             if (i != modrm_index &&
   16543                 (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
   16544                 reg = ops[i].reg;
   16545                 break;
   16546             }
   16547         }
   16548 
   16549         asm_modrm(reg, &ops[modrm_index]);
   16550     }
   16551 
   16552     /* emit constants */
   16553     if (pa->opcode == 0x9a || pa->opcode == 0xea) {
   16554         /* ljmp or lcall kludge */
   16555         gen_expr32(&ops[1].e);
   16556         if (ops[0].e.sym)
   16557             error("cannot relocate");
   16558         gen_le16(ops[0].e.v);
   16559     } else {
   16560         for(i = 0;i < nb_ops; i++) {
   16561             v = op_type[i];
   16562             if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
   16563                 /* if multiple sizes are given it means we must look
   16564                    at the op size */
   16565                 if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
   16566                     v == (OP_IM16 | OP_IM32)) {
   16567                     if (ss == 0)
   16568                         v = OP_IM8;
   16569                     else if (ss == 1)
   16570                         v = OP_IM16;
   16571                     else
   16572                         v = OP_IM32;
   16573                 }
   16574                 if (v & (OP_IM8 | OP_IM8S)) {
   16575                     if (ops[i].e.sym)
   16576                         goto error_relocate;
   16577                     g(ops[i].e.v);
   16578                 } else if (v & OP_IM16) {
   16579                     if (ops[i].e.sym) {
   16580                     error_relocate:
   16581                         error("cannot relocate");
   16582                     }
   16583                     gen_le16(ops[i].e.v);
   16584                 } else {
   16585                     if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
   16586                         if (is_short_jmp)
   16587                             g(ops[i].e.v);
   16588                         else
   16589                             gen_disp32(&ops[i].e);
   16590                     } else {
   16591                         gen_expr32(&ops[i].e);
   16592                     }
   16593                 }
   16594             }
   16595         }
   16596     }
   16597 }
   16598 
   16599 #define NB_SAVED_REGS 3
   16600 #define NB_ASM_REGS 8
   16601 
   16602 /* return the constraint priority (we allocate first the lowest
   16603    numbered constraints) */
   16604 static inline int constraint_priority(const char *str)
   16605 {
   16606     int priority, c, pr;
   16607 
   16608     /* we take the lowest priority */
   16609     priority = 0;
   16610     for(;;) {
   16611         c = *str;
   16612         if (c == '\0')
   16613             break;
   16614         str++;
   16615         switch(c) {
   16616         case 'A':
   16617             pr = 0;
   16618             break;
   16619         case 'a':
   16620         case 'b':
   16621         case 'c':
   16622         case 'd':
   16623         case 'S':
   16624         case 'D':
   16625             pr = 1;
   16626             break;
   16627         case 'q':
   16628             pr = 2;
   16629             break;
   16630         case 'r':
   16631             pr = 3;
   16632             break;
   16633         case 'N':
   16634         case 'M':
   16635         case 'I':
   16636         case 'i':
   16637         case 'm':
   16638         case 'g':
   16639             pr = 4;
   16640             break;
   16641         default:
   16642             error("unknown constraint '%c'", c);
   16643             pr = 0;
   16644         }
   16645         if (pr > priority)
   16646             priority = pr;
   16647     }
   16648     return priority;
   16649 }
   16650 
   16651 static const char *skip_constraint_modifiers(const char *p)
   16652 {
   16653     while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
   16654         p++;
   16655     return p;
   16656 }
   16657 
   16658 #define REG_OUT_MASK 0x01
   16659 #define REG_IN_MASK  0x02
   16660 
   16661 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
   16662 
   16663 static void asm_compute_constraints(ASMOperand *operands,
   16664                                     int nb_operands, int nb_outputs,
   16665                                     const uint8_t *clobber_regs,
   16666                                     int *pout_reg)
   16667 {
   16668     ASMOperand *op;
   16669     int sorted_op[MAX_ASM_OPERANDS];
   16670     int i, j, k, p1, p2, tmp, reg, c, reg_mask;
   16671     const char *str;
   16672     uint8_t regs_allocated[NB_ASM_REGS];
   16673 
   16674     /* init fields */
   16675     for(i=0;i<nb_operands;i++) {
   16676         op = &operands[i];
   16677         op->input_index = -1;
   16678         op->ref_index = -1;
   16679         op->reg = -1;
   16680         op->is_memory = 0;
   16681         op->is_rw = 0;
   16682     }
   16683     /* compute constraint priority and evaluate references to output
   16684        constraints if input constraints */
   16685     for(i=0;i<nb_operands;i++) {
   16686         op = &operands[i];
   16687         str = op->constraint;
   16688         str = skip_constraint_modifiers(str);
   16689         if (isnum(*str) || *str == '[') {
   16690             /* this is a reference to another constraint */
   16691             k = find_constraint(operands, nb_operands, str, NULL);
   16692             if ((unsigned)k >= i || i < nb_outputs)
   16693                 error("invalid reference in constraint %d ('%s')",
   16694                       i, str);
   16695             op->ref_index = k;
   16696             if (operands[k].input_index >= 0)
   16697                 error("cannot reference twice the same operand");
   16698             operands[k].input_index = i;
   16699             op->priority = 5;
   16700         } else {
   16701             op->priority = constraint_priority(str);
   16702         }
   16703     }
   16704 
   16705     /* sort operands according to their priority */
   16706     for(i=0;i<nb_operands;i++)
   16707         sorted_op[i] = i;
   16708     for(i=0;i<nb_operands - 1;i++) {
   16709         for(j=i+1;j<nb_operands;j++) {
   16710             p1 = operands[sorted_op[i]].priority;
   16711             p2 = operands[sorted_op[j]].priority;
   16712             if (p2 < p1) {
   16713                 tmp = sorted_op[i];
   16714                 sorted_op[i] = sorted_op[j];
   16715                 sorted_op[j] = tmp;
   16716             }
   16717         }
   16718     }
   16719 
   16720     for(i = 0;i < NB_ASM_REGS; i++) {
   16721         if (clobber_regs[i])
   16722             regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
   16723         else
   16724             regs_allocated[i] = 0;
   16725     }
   16726     /* esp cannot be used */
   16727     regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK;
   16728     /* ebp cannot be used yet */
   16729     regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK;
   16730 
   16731     /* allocate registers and generate corresponding asm moves */
   16732     for(i=0;i<nb_operands;i++) {
   16733         j = sorted_op[i];
   16734         op = &operands[j];
   16735         str = op->constraint;
   16736         /* no need to allocate references */
   16737         if (op->ref_index >= 0)
   16738             continue;
   16739         /* select if register is used for output, input or both */
   16740         if (op->input_index >= 0) {
   16741             reg_mask = REG_IN_MASK | REG_OUT_MASK;
   16742         } else if (j < nb_outputs) {
   16743             reg_mask = REG_OUT_MASK;
   16744         } else {
   16745             reg_mask = REG_IN_MASK;
   16746         }
   16747     try_next:
   16748         c = *str++;
   16749         switch(c) {
   16750         case '=':
   16751             goto try_next;
   16752         case '+':
   16753             op->is_rw = 1;
   16754             /* FALL THRU */
   16755         case '&':
   16756             if (j >= nb_outputs)
   16757                 error("'%c' modifier can only be applied to outputs", c);
   16758             reg_mask = REG_IN_MASK | REG_OUT_MASK;
   16759             goto try_next;
   16760         case 'A':
   16761             /* allocate both eax and edx */
   16762             if (is_reg_allocated(TREG_EAX) ||
   16763                 is_reg_allocated(TREG_EDX))
   16764                 goto try_next;
   16765             op->is_llong = 1;
   16766             op->reg = TREG_EAX;
   16767             regs_allocated[TREG_EAX] |= reg_mask;
   16768             regs_allocated[TREG_EDX] |= reg_mask;
   16769             break;
   16770         case 'a':
   16771             reg = TREG_EAX;
   16772             goto alloc_reg;
   16773         case 'b':
   16774             reg = 3;
   16775             goto alloc_reg;
   16776         case 'c':
   16777             reg = TREG_ECX;
   16778             goto alloc_reg;
   16779         case 'd':
   16780             reg = TREG_EDX;
   16781             goto alloc_reg;
   16782         case 'S':
   16783             reg = 6;
   16784             goto alloc_reg;
   16785         case 'D':
   16786             reg = 7;
   16787         alloc_reg:
   16788             if (is_reg_allocated(reg))
   16789                 goto try_next;
   16790             goto reg_found;
   16791         case 'q':
   16792             /* eax, ebx, ecx or edx */
   16793             for(reg = 0; reg < 4; reg++) {
   16794                 if (!is_reg_allocated(reg))
   16795                     goto reg_found;
   16796             }
   16797             goto try_next;
   16798         case 'r':
   16799             /* any general register */
   16800             for(reg = 0; reg < 8; reg++) {
   16801                 if (!is_reg_allocated(reg))
   16802                     goto reg_found;
   16803             }
   16804             goto try_next;
   16805         reg_found:
   16806             /* now we can reload in the register */
   16807             op->is_llong = 0;
   16808             op->reg = reg;
   16809             regs_allocated[reg] |= reg_mask;
   16810             break;
   16811         case 'i':
   16812             if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
   16813                 goto try_next;
   16814             break;
   16815         case 'I':
   16816         case 'N':
   16817         case 'M':
   16818             if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
   16819                 goto try_next;
   16820             break;
   16821         case 'm':
   16822         case 'g':
   16823             /* nothing special to do because the operand is already in
   16824                memory, except if the pointer itself is stored in a
   16825                memory variable (VT_LLOCAL case) */
   16826             /* XXX: fix constant case */
   16827             /* if it is a reference to a memory zone, it must lie
   16828                in a register, so we reserve the register in the
   16829                input registers and a load will be generated
   16830                later */
   16831             if (j < nb_outputs || c == 'm') {
   16832                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
   16833                     /* any general register */
   16834                     for(reg = 0; reg < 8; reg++) {
   16835                         if (!(regs_allocated[reg] & REG_IN_MASK))
   16836                             goto reg_found1;
   16837                     }
   16838                     goto try_next;
   16839                 reg_found1:
   16840                     /* now we can reload in the register */
   16841                     regs_allocated[reg] |= REG_IN_MASK;
   16842                     op->reg = reg;
   16843                     op->is_memory = 1;
   16844                 }
   16845             }
   16846             break;
   16847         default:
   16848             error("asm constraint %d ('%s') could not be satisfied",
   16849                   j, op->constraint);
   16850             break;
   16851         }
   16852         /* if a reference is present for that operand, we assign it too */
   16853         if (op->input_index >= 0) {
   16854             operands[op->input_index].reg = op->reg;
   16855             operands[op->input_index].is_llong = op->is_llong;
   16856         }
   16857     }
   16858 
   16859     /* compute out_reg. It is used to store outputs registers to memory
   16860        locations references by pointers (VT_LLOCAL case) */
   16861     *pout_reg = -1;
   16862     for(i=0;i<nb_operands;i++) {
   16863         op = &operands[i];
   16864         if (op->reg >= 0 &&
   16865             (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
   16866             !op->is_memory) {
   16867             for(reg = 0; reg < 8; reg++) {
   16868                 if (!(regs_allocated[reg] & REG_OUT_MASK))
   16869                     goto reg_found2;
   16870             }
   16871             error("could not find free output register for reloading");
   16872         reg_found2:
   16873             *pout_reg = reg;
   16874             break;
   16875         }
   16876     }
   16877 
   16878     /* print sorted constraints */
   16879 #ifdef ASM_DEBUG
   16880     for(i=0;i<nb_operands;i++) {
   16881         j = sorted_op[i];
   16882         op = &operands[j];
   16883         printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
   16884                j,
   16885                op->id ? get_tok_str(op->id, NULL) : "",
   16886                op->constraint,
   16887                op->vt->r,
   16888                op->reg);
   16889     }
   16890     if (*pout_reg >= 0)
   16891         printf("out_reg=%d\n", *pout_reg);
   16892 #endif
   16893 }
   16894 
   16895 static void subst_asm_operand(CString *add_str,
   16896                               SValue *sv, int modifier)
   16897 {
   16898     int r, reg, size, val;
   16899     char buf[64];
   16900 
   16901     r = sv->r;
   16902     if ((r & VT_VALMASK) == VT_CONST) {
   16903         if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
   16904             cstr_ccat(add_str, '$');
   16905         if (r & VT_SYM) {
   16906             cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
   16907             if (sv->c.i != 0) {
   16908                 cstr_ccat(add_str, '+');
   16909             } else {
   16910                 return;
   16911             }
   16912         }
   16913         val = sv->c.i;
   16914         if (modifier == 'n')
   16915             val = -val;
   16916         snprintf(buf, sizeof(buf), "%d", sv->c.i);
   16917         cstr_cat(add_str, buf);
   16918     } else if ((r & VT_VALMASK) == VT_LOCAL) {
   16919         snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
   16920         cstr_cat(add_str, buf);
   16921     } else if (r & VT_LVAL) {
   16922         reg = r & VT_VALMASK;
   16923         if (reg >= VT_CONST)
   16924             error("internal compiler error");
   16925         snprintf(buf, sizeof(buf), "(%%%s)",
   16926                  get_tok_str(TOK_ASM_eax + reg, NULL));
   16927         cstr_cat(add_str, buf);
   16928     } else {
   16929         /* register case */
   16930         reg = r & VT_VALMASK;
   16931         if (reg >= VT_CONST)
   16932             error("internal compiler error");
   16933 
   16934         /* choose register operand size */
   16935         if ((sv->type.t & VT_BTYPE) == VT_BYTE)
   16936             size = 1;
   16937         else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
   16938             size = 2;
   16939         else
   16940             size = 4;
   16941         if (size == 1 && reg >= 4)
   16942             size = 4;
   16943 
   16944         if (modifier == 'b') {
   16945             if (reg >= 4)
   16946                 error("cannot use byte register");
   16947             size = 1;
   16948         } else if (modifier == 'h') {
   16949             if (reg >= 4)
   16950                 error("cannot use byte register");
   16951             size = -1;
   16952         } else if (modifier == 'w') {
   16953             size = 2;
   16954         }
   16955 
   16956         switch(size) {
   16957         case -1:
   16958             reg = TOK_ASM_ah + reg;
   16959             break;
   16960         case 1:
   16961             reg = TOK_ASM_al + reg;
   16962             break;
   16963         case 2:
   16964             reg = TOK_ASM_ax + reg;
   16965             break;
   16966         default:
   16967             reg = TOK_ASM_eax + reg;
   16968             break;
   16969         }
   16970         snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
   16971         cstr_cat(add_str, buf);
   16972     }
   16973 }
   16974 
   16975 /* generate prolog and epilog code for asm statement */
   16976 static void asm_gen_code(ASMOperand *operands, int nb_operands,
   16977                          int nb_outputs, int is_output,
   16978                          uint8_t *clobber_regs,
   16979                          int out_reg)
   16980 {
   16981     uint8_t regs_allocated[NB_ASM_REGS];
   16982     ASMOperand *op;
   16983     int i, reg;
   16984     static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
   16985 
   16986     /* mark all used registers */
   16987     memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
   16988     for(i = 0; i < nb_operands;i++) {
   16989         op = &operands[i];
   16990         if (op->reg >= 0)
   16991             regs_allocated[op->reg] = 1;
   16992     }
   16993     if (!is_output) {
   16994         /* generate reg save code */
   16995         for(i = 0; i < NB_SAVED_REGS; i++) {
   16996             reg = reg_saved[i];
   16997             if (regs_allocated[reg])
   16998                 g(0x50 + reg);
   16999         }
   17000 
   17001         /* generate load code */
   17002         for(i = 0; i < nb_operands; i++) {
   17003             op = &operands[i];
   17004             if (op->reg >= 0) {
   17005                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
   17006                     op->is_memory) {
   17007                     /* memory reference case (for both input and
   17008                        output cases) */
   17009                     SValue sv;
   17010                     sv = *op->vt;
   17011                     sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
   17012                     load(op->reg, &sv);
   17013                 } else if (i >= nb_outputs || op->is_rw) {
   17014                     /* load value in register */
   17015                     load(op->reg, op->vt);
   17016                     if (op->is_llong) {
   17017                         SValue sv;
   17018                         sv = *op->vt;
   17019                         sv.c.ul += 4;
   17020                         load(TREG_EDX, &sv);
   17021                     }
   17022                 }
   17023             }
   17024         }
   17025     } else {
   17026         /* generate save code */
   17027         for(i = 0 ; i < nb_outputs; i++) {
   17028             op = &operands[i];
   17029             if (op->reg >= 0) {
   17030                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
   17031                     if (!op->is_memory) {
   17032                         SValue sv;
   17033                         sv = *op->vt;
   17034                         sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
   17035                         load(out_reg, &sv);
   17036 
   17037                         sv.r = (sv.r & ~VT_VALMASK) | out_reg;
   17038                         store(op->reg, &sv);
   17039                     }
   17040                 } else {
   17041                     store(op->reg, op->vt);
   17042                     if (op->is_llong) {
   17043                         SValue sv;
   17044                         sv = *op->vt;
   17045                         sv.c.ul += 4;
   17046                         store(TREG_EDX, &sv);
   17047                     }
   17048                 }
   17049             }
   17050         }
   17051         /* generate reg restore code */
   17052         for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
   17053             reg = reg_saved[i];
   17054             if (regs_allocated[reg])
   17055                 g(0x58 + reg);
   17056         }
   17057     }
   17058 }
   17059 
   17060 static void asm_clobber(uint8_t *clobber_regs, const char *str)
   17061 {
   17062     int reg;
   17063     TokenSym *ts;
   17064 
   17065     if (!strcmp(str, "memory") ||
   17066         !strcmp(str, "cc"))
   17067         return;
   17068     ts = tok_alloc(str, strlen(str));
   17069     reg = ts->tok;
   17070     if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
   17071         reg -= TOK_ASM_eax;
   17072     } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
   17073         reg -= TOK_ASM_ax;
   17074     } else {
   17075         error("invalid clobber register '%s'", str);
   17076     }
   17077     clobber_regs[reg] = 1;
   17078 }
   17079 //---------------------------------------------------------------------------
   17080 #endif
   17081 // njn: inlined tccasm.c
   17082 //#include "tccasm.c"
   17083 //---------------------------------------------------------------------------
   17084 /*
   17085  *  GAS like assembler for TCC
   17086  *
   17087  *  Copyright (c) 2001-2004 Fabrice Bellard
   17088  *
   17089  * This library is free software; you can redistribute it and/or
   17090  * modify it under the terms of the GNU Lesser General Public
   17091  * License as published by the Free Software Foundation; either
   17092  * version 2 of the License, or (at your option) any later version.
   17093  *
   17094  * This library is distributed in the hope that it will be useful,
   17095  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17096  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17097  * Lesser General Public License for more details.
   17098  *
   17099  * You should have received a copy of the GNU Lesser General Public
   17100  * License along with this library; if not, write to the Free Software
   17101  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   17102  */
   17103 
   17104 static int asm_get_local_label_name(TCCState *s1, unsigned int n)
   17105 {
   17106     char buf[64];
   17107     TokenSym *ts;
   17108 
   17109     snprintf(buf, sizeof(buf), "L..%u", n);
   17110     ts = tok_alloc(buf, strlen(buf));
   17111     return ts->tok;
   17112 }
   17113 
   17114 static void asm_expr(TCCState *s1, ExprValue *pe);
   17115 
   17116 /* We do not use the C expression parser to handle symbols. Maybe the
   17117    C expression parser could be tweaked to do so. */
   17118 
   17119 static void asm_expr_unary(TCCState *s1, ExprValue *pe)
   17120 {
   17121     Sym *sym;
   17122     int op, n, label;
   17123     const char *p;
   17124 
   17125     switch(tok) {
   17126     case TOK_PPNUM:
   17127         p = tokc.cstr->data;
   17128         n = strtoul(p, (char **)&p, 0);
   17129         if (*p == 'b' || *p == 'f') {
   17130             /* backward or forward label */
   17131             label = asm_get_local_label_name(s1, n);
   17132             sym = label_find(label);
   17133             if (*p == 'b') {
   17134                 /* backward : find the last corresponding defined label */
   17135                 if (sym && sym->r == 0)
   17136                     sym = sym->prev_tok;
   17137                 if (!sym)
   17138                     error("local label '%d' not found backward", n);
   17139             } else {
   17140                 /* forward */
   17141                 if (!sym || sym->r) {
   17142                     /* if the last label is defined, then define a new one */
   17143                     sym = label_push(&s1->asm_labels, label, 0);
   17144                     sym->type.t = VT_STATIC | VT_VOID;
   17145                 }
   17146             }
   17147             pe->v = 0;
   17148             pe->sym = sym;
   17149         } else if (*p == '\0') {
   17150             pe->v = n;
   17151             pe->sym = NULL;
   17152         } else {
   17153             error("invalid number syntax");
   17154         }
   17155         next();
   17156         break;
   17157     case '+':
   17158         next();
   17159         asm_expr_unary(s1, pe);
   17160         break;
   17161     case '-':
   17162     case '~':
   17163         op = tok;
   17164         next();
   17165         asm_expr_unary(s1, pe);
   17166         if (pe->sym)
   17167             error("invalid operation with label");
   17168         if (op == '-')
   17169             pe->v = -pe->v;
   17170         else
   17171             pe->v = ~pe->v;
   17172         break;
   17173     case TOK_CCHAR:
   17174     case TOK_LCHAR:
   17175 	pe->v = tokc.i;
   17176 	pe->sym = NULL;
   17177 	next();
   17178 	break;
   17179     case '(':
   17180         next();
   17181         asm_expr(s1, pe);
   17182         skip(')');
   17183         break;
   17184     default:
   17185         if (tok >= TOK_IDENT) {
   17186             /* label case : if the label was not found, add one */
   17187             sym = label_find(tok);
   17188             if (!sym) {
   17189                 sym = label_push(&s1->asm_labels, tok, 0);
   17190                 /* NOTE: by default, the symbol is global */
   17191                 sym->type.t = VT_VOID;
   17192             }
   17193             if (sym->r == SHN_ABS) {
   17194                 /* if absolute symbol, no need to put a symbol value */
   17195                 pe->v = (long)sym->next;
   17196                 pe->sym = NULL;
   17197             } else {
   17198                 pe->v = 0;
   17199                 pe->sym = sym;
   17200             }
   17201             next();
   17202         } else {
   17203             error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
   17204         }
   17205         break;
   17206     }
   17207 }
   17208 
   17209 static void asm_expr_prod(TCCState *s1, ExprValue *pe)
   17210 {
   17211     int op;
   17212     ExprValue e2;
   17213 
   17214     asm_expr_unary(s1, pe);
   17215     for(;;) {
   17216         op = tok;
   17217         if (op != '*' && op != '/' && op != '%' &&
   17218             op != TOK_SHL && op != TOK_SAR)
   17219             break;
   17220         next();
   17221         asm_expr_unary(s1, &e2);
   17222         if (pe->sym || e2.sym)
   17223             error("invalid operation with label");
   17224         switch(op) {
   17225         case '*':
   17226             pe->v *= e2.v;
   17227             break;
   17228         case '/':
   17229             if (e2.v == 0) {
   17230             div_error:
   17231                 error("division by zero");
   17232             }
   17233             pe->v /= e2.v;
   17234             break;
   17235         case '%':
   17236             if (e2.v == 0)
   17237                 goto div_error;
   17238             pe->v %= e2.v;
   17239             break;
   17240         case TOK_SHL:
   17241             pe->v <<= e2.v;
   17242             break;
   17243         default:
   17244         case TOK_SAR:
   17245             pe->v >>= e2.v;
   17246             break;
   17247         }
   17248     }
   17249 }
   17250 
   17251 static void asm_expr_logic(TCCState *s1, ExprValue *pe)
   17252 {
   17253     int op;
   17254     ExprValue e2;
   17255 
   17256     asm_expr_prod(s1, pe);
   17257     for(;;) {
   17258         op = tok;
   17259         if (op != '&' && op != '|' && op != '^')
   17260             break;
   17261         next();
   17262         asm_expr_prod(s1, &e2);
   17263         if (pe->sym || e2.sym)
   17264             error("invalid operation with label");
   17265         switch(op) {
   17266         case '&':
   17267             pe->v &= e2.v;
   17268             break;
   17269         case '|':
   17270             pe->v |= e2.v;
   17271             break;
   17272         default:
   17273         case '^':
   17274             pe->v ^= e2.v;
   17275             break;
   17276         }
   17277     }
   17278 }
   17279 
   17280 static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
   17281 {
   17282     int op;
   17283     ExprValue e2;
   17284 
   17285     asm_expr_logic(s1, pe);
   17286     for(;;) {
   17287         op = tok;
   17288         if (op != '+' && op != '-')
   17289             break;
   17290         next();
   17291         asm_expr_logic(s1, &e2);
   17292         if (op == '+') {
   17293             if (pe->sym != NULL && e2.sym != NULL)
   17294                 goto cannot_relocate;
   17295             pe->v += e2.v;
   17296             if (pe->sym == NULL && e2.sym != NULL)
   17297                 pe->sym = e2.sym;
   17298         } else {
   17299             pe->v -= e2.v;
   17300             /* NOTE: we are less powerful than gas in that case
   17301                because we store only one symbol in the expression */
   17302             if (!pe->sym && !e2.sym) {
   17303                 /* OK */
   17304             } else if (pe->sym && !e2.sym) {
   17305                 /* OK */
   17306             } else if (pe->sym && e2.sym) {
   17307                 if (pe->sym == e2.sym) {
   17308                     /* OK */
   17309                 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
   17310                     /* we also accept defined symbols in the same section */
   17311                     pe->v += (long)pe->sym->next - (long)e2.sym->next;
   17312                 } else {
   17313                     goto cannot_relocate;
   17314                 }
   17315                 pe->sym = NULL; /* same symbols can be substracted to NULL */
   17316             } else {
   17317             cannot_relocate:
   17318                 error("invalid operation with label");
   17319             }
   17320         }
   17321     }
   17322 }
   17323 
   17324 static void asm_expr(TCCState *s1, ExprValue *pe)
   17325 {
   17326     asm_expr_sum(s1, pe);
   17327 }
   17328 
   17329 static int asm_int_expr(TCCState *s1)
   17330 {
   17331     ExprValue e;
   17332     asm_expr(s1, &e);
   17333     if (e.sym)
   17334         expect("constant");
   17335     return e.v;
   17336 }
   17337 
   17338 /* NOTE: the same name space as C labels is used to avoid using too
   17339    much memory when storing labels in TokenStrings */
   17340 static void asm_new_label1(TCCState *s1, int label, int is_local,
   17341                            int sh_num, long value)
   17342 {
   17343     Sym *sym;
   17344 
   17345     sym = label_find(label);
   17346     if (sym) {
   17347         if (sym->r) {
   17348             /* the label is already defined */
   17349             if (!is_local) {
   17350                 error("assembler label '%s' already defined",
   17351                       get_tok_str(label, NULL));
   17352             } else {
   17353                 /* redefinition of local labels is possible */
   17354                 goto new_label;
   17355             }
   17356         }
   17357     } else {
   17358     new_label:
   17359         sym = label_push(&s1->asm_labels, label, 0);
   17360         sym->type.t = VT_STATIC | VT_VOID;
   17361     }
   17362     sym->r = sh_num;
   17363     sym->next = (void *)value;
   17364 }
   17365 
   17366 static void asm_new_label(TCCState *s1, int label, int is_local)
   17367 {
   17368     asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
   17369 }
   17370 
   17371 static void asm_free_labels(TCCState *st)
   17372 {
   17373     Sym *s, *s1;
   17374     Section *sec;
   17375 
   17376     for(s = st->asm_labels; s != NULL; s = s1) {
   17377         s1 = s->prev;
   17378         /* define symbol value in object file */
   17379         if (s->r) {
   17380             if (s->r == SHN_ABS)
   17381                 sec = SECTION_ABS;
   17382             else
   17383                 sec = st->sections[s->r];
   17384             put_extern_sym2(s, sec, (long)s->next, 0, 0);
   17385         }
   17386         /* remove label */
   17387         table_ident[s->v - TOK_IDENT]->sym_label = NULL;
   17388         sym_free(s);
   17389     }
   17390     st->asm_labels = NULL;
   17391 }
   17392 
   17393 static void use_section1(TCCState *s1, Section *sec)
   17394 {
   17395     cur_text_section->data_offset = ind;
   17396     cur_text_section = sec;
   17397     ind = cur_text_section->data_offset;
   17398 }
   17399 
   17400 static void use_section(TCCState *s1, const char *name)
   17401 {
   17402     Section *sec;
   17403     sec = find_section(s1, name);
   17404     use_section1(s1, sec);
   17405 }
   17406 
   17407 static void asm_parse_directive(TCCState *s1)
   17408 {
   17409     int n, offset, v, size, tok1;
   17410     Section *sec;
   17411     uint8_t *ptr;
   17412 
   17413     /* assembler directive */
   17414     next();
   17415     sec = cur_text_section;
   17416     switch(tok) {
   17417     case TOK_ASM_align:
   17418     case TOK_ASM_skip:
   17419     case TOK_ASM_space:
   17420         tok1 = tok;
   17421         next();
   17422         n = asm_int_expr(s1);
   17423         if (tok1 == TOK_ASM_align) {
   17424             if (n < 0 || (n & (n-1)) != 0)
   17425                 error("alignment must be a positive power of two");
   17426             offset = (ind + n - 1) & -n;
   17427             size = offset - ind;
   17428             /* the section must have a compatible alignment */
   17429             if (sec->sh_addralign < n)
   17430                 sec->sh_addralign = n;
   17431         } else {
   17432             size = n;
   17433         }
   17434         v = 0;
   17435         if (tok == ',') {
   17436             next();
   17437             v = asm_int_expr(s1);
   17438         }
   17439     zero_pad:
   17440         if (sec->sh_type != SHT_NOBITS) {
   17441             sec->data_offset = ind;
   17442             ptr = section_ptr_add(sec, size);
   17443             memset(ptr, v, size);
   17444         }
   17445         ind += size;
   17446         break;
   17447     case TOK_ASM_quad:
   17448         next();
   17449         for(;;) {
   17450             uint64_t vl;
   17451             const char *p;
   17452 
   17453             p = tokc.cstr->data;
   17454             if (tok != TOK_PPNUM) {
   17455             error_constant:
   17456                 error("64 bit constant");
   17457             }
   17458             vl = strtoll(p, (char **)&p, 0);
   17459             if (*p != '\0')
   17460                 goto error_constant;
   17461             next();
   17462             if (sec->sh_type != SHT_NOBITS) {
   17463                 /* XXX: endianness */
   17464                 gen_le32(vl);
   17465                 gen_le32(vl >> 32);
   17466             } else {
   17467                 ind += 8;
   17468             }
   17469             if (tok != ',')
   17470                 break;
   17471             next();
   17472         }
   17473         break;
   17474     case TOK_ASM_byte:
   17475         size = 1;
   17476         goto asm_data;
   17477     case TOK_ASM_word:
   17478     case TOK_SHORT:
   17479         size = 2;
   17480         goto asm_data;
   17481     case TOK_LONG:
   17482     case TOK_INT:
   17483         size = 4;
   17484     asm_data:
   17485         next();
   17486         for(;;) {
   17487             ExprValue e;
   17488             asm_expr(s1, &e);
   17489             if (sec->sh_type != SHT_NOBITS) {
   17490                 if (size == 4) {
   17491                     gen_expr32(&e);
   17492                 } else {
   17493                     if (e.sym)
   17494                         expect("constant");
   17495                     if (size == 1)
   17496                         g(e.v);
   17497                     else
   17498                         gen_le16(e.v);
   17499                 }
   17500             } else {
   17501                 ind += size;
   17502             }
   17503             if (tok != ',')
   17504                 break;
   17505             next();
   17506         }
   17507         break;
   17508     case TOK_ASM_fill:
   17509         {
   17510             int repeat, size, val, i, j;
   17511             uint8_t repeat_buf[8];
   17512             next();
   17513             repeat = asm_int_expr(s1);
   17514             if (repeat < 0) {
   17515                 error("repeat < 0; .fill ignored");
   17516                 break;
   17517             }
   17518             size = 1;
   17519             val = 0;
   17520             if (tok == ',') {
   17521                 next();
   17522                 size = asm_int_expr(s1);
   17523                 if (size < 0) {
   17524                     error("size < 0; .fill ignored");
   17525                     break;
   17526                 }
   17527                 if (size > 8)
   17528                     size = 8;
   17529                 if (tok == ',') {
   17530                     next();
   17531                     val = asm_int_expr(s1);
   17532                 }
   17533             }
   17534             /* XXX: endianness */
   17535             repeat_buf[0] = val;
   17536             repeat_buf[1] = val >> 8;
   17537             repeat_buf[2] = val >> 16;
   17538             repeat_buf[3] = val >> 24;
   17539             repeat_buf[4] = 0;
   17540             repeat_buf[5] = 0;
   17541             repeat_buf[6] = 0;
   17542             repeat_buf[7] = 0;
   17543             for(i = 0; i < repeat; i++) {
   17544                 for(j = 0; j < size; j++) {
   17545                     g(repeat_buf[j]);
   17546                 }
   17547             }
   17548         }
   17549         break;
   17550     case TOK_ASM_org:
   17551         {
   17552             unsigned long n;
   17553             next();
   17554             /* XXX: handle section symbols too */
   17555             n = asm_int_expr(s1);
   17556             if (n < ind)
   17557                 error("attempt to .org backwards");
   17558             v = 0;
   17559             size = n - ind;
   17560             goto zero_pad;
   17561         }
   17562         break;
   17563     case TOK_ASM_globl:
   17564     case TOK_ASM_global:
   17565 	{
   17566             Sym *sym;
   17567 
   17568             next();
   17569             sym = label_find(tok);
   17570             if (!sym) {
   17571                 sym = label_push(&s1->asm_labels, tok, 0);
   17572                 sym->type.t = VT_VOID;
   17573             }
   17574             sym->type.t &= ~VT_STATIC;
   17575             next();
   17576 	}
   17577 	break;
   17578     case TOK_ASM_string:
   17579     case TOK_ASM_ascii:
   17580     case TOK_ASM_asciz:
   17581         {
   17582             const uint8_t *p;
   17583             int i, size, t;
   17584 
   17585             t = tok;
   17586             next();
   17587             for(;;) {
   17588                 if (tok != TOK_STR)
   17589                     expect("string constant");
   17590                 p = tokc.cstr->data;
   17591                 size = tokc.cstr->size;
   17592                 if (t == TOK_ASM_ascii && size > 0)
   17593                     size--;
   17594                 for(i = 0; i < size; i++)
   17595                     g(p[i]);
   17596                 next();
   17597                 if (tok == ',') {
   17598                     next();
   17599                 } else if (tok != TOK_STR) {
   17600                     break;
   17601                 }
   17602             }
   17603 	}
   17604 	break;
   17605     case TOK_ASM_text:
   17606     case TOK_ASM_data:
   17607     case TOK_ASM_bss:
   17608 	{
   17609             char sname[64];
   17610             tok1 = tok;
   17611             n = 0;
   17612             next();
   17613             if (tok != ';' && tok != TOK_LINEFEED) {
   17614 		n = asm_int_expr(s1);
   17615 		next();
   17616             }
   17617             sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
   17618             use_section(s1, sname);
   17619 	}
   17620 	break;
   17621     case TOK_SECTION1:
   17622         {
   17623             char sname[256];
   17624 
   17625             /* XXX: support more options */
   17626             next();
   17627             sname[0] = '\0';
   17628             while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
   17629                 if (tok == TOK_STR)
   17630                     pstrcat(sname, sizeof(sname), tokc.cstr->data);
   17631                 else
   17632                     pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
   17633                 next();
   17634             }
   17635             if (tok == ',') {
   17636                 /* skip section options */
   17637                 next();
   17638                 if (tok != TOK_STR)
   17639                     expect("string constant");
   17640                 next();
   17641             }
   17642             last_text_section = cur_text_section;
   17643             use_section(s1, sname);
   17644         }
   17645         break;
   17646     case TOK_ASM_previous:
   17647         {
   17648             Section *sec;
   17649             next();
   17650             if (!last_text_section)
   17651                 error("no previous section referenced");
   17652             sec = cur_text_section;
   17653             use_section1(s1, last_text_section);
   17654             last_text_section = sec;
   17655         }
   17656         break;
   17657     default:
   17658         error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
   17659         break;
   17660     }
   17661 }
   17662 
   17663 
   17664 /* assemble a file */
   17665 static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
   17666 {
   17667     int opcode;
   17668 
   17669 #if 0
   17670     /* print stats about opcodes */
   17671     {
   17672         const ASMInstr *pa;
   17673         int freq[4];
   17674         int op_vals[500];
   17675         int nb_op_vals, i, j;
   17676 
   17677         nb_op_vals = 0;
   17678         memset(freq, 0, sizeof(freq));
   17679         for(pa = asm_instrs; pa->sym != 0; pa++) {
   17680             freq[pa->nb_ops]++;
   17681             for(i=0;i<pa->nb_ops;i++) {
   17682                 for(j=0;j<nb_op_vals;j++) {
   17683                     if (pa->op_type[i] == op_vals[j])
   17684                         goto found;
   17685                 }
   17686                 op_vals[nb_op_vals++] = pa->op_type[i];
   17687             found: ;
   17688             }
   17689         }
   17690         for(i=0;i<nb_op_vals;i++) {
   17691             int v = op_vals[i];
   17692             if ((v & (v - 1)) != 0)
   17693                 printf("%3d: %08x\n", i, v);
   17694         }
   17695         printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
   17696                sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
   17697                freq[0], freq[1], freq[2], freq[3]);
   17698     }
   17699 #endif
   17700 
   17701     /* XXX: undefine C labels */
   17702 
   17703     ch = file->buf_ptr[0];
   17704     tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
   17705     parse_flags = PARSE_FLAG_ASM_COMMENTS;
   17706     if (do_preprocess)
   17707         parse_flags |= PARSE_FLAG_PREPROCESS;
   17708     next();
   17709     for(;;) {
   17710         if (tok == TOK_EOF)
   17711             break;
   17712         parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
   17713     redo:
   17714         if (tok == '#') {
   17715             /* horrible gas comment */
   17716             while (tok != TOK_LINEFEED)
   17717                 next();
   17718         } else if (tok == '.') {
   17719             asm_parse_directive(s1);
   17720         } else if (tok == TOK_PPNUM) {
   17721             const char *p;
   17722             int n;
   17723             p = tokc.cstr->data;
   17724             n = strtoul(p, (char **)&p, 10);
   17725             if (*p != '\0')
   17726                 expect("':'");
   17727             /* new local label */
   17728             asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
   17729             next();
   17730             skip(':');
   17731             goto redo;
   17732         } else if (tok >= TOK_IDENT) {
   17733             /* instruction or label */
   17734             opcode = tok;
   17735             next();
   17736             if (tok == ':') {
   17737                 /* new label */
   17738                 asm_new_label(s1, opcode, 0);
   17739                 next();
   17740                 goto redo;
   17741             } else if (tok == '=') {
   17742                 int n;
   17743                 next();
   17744                 n = asm_int_expr(s1);
   17745                 asm_new_label1(s1, opcode, 0, SHN_ABS, n);
   17746                 goto redo;
   17747             } else {
   17748                 asm_opcode(s1, opcode);
   17749             }
   17750         }
   17751         /* end of line */
   17752         if (tok != ';' && tok != TOK_LINEFEED){
   17753             expect("end of line");
   17754         }
   17755         parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
   17756         next();
   17757     }
   17758 
   17759     asm_free_labels(s1);
   17760 
   17761     return 0;
   17762 }
   17763 
   17764 /* Assemble the current file */
   17765 static int tcc_assemble(TCCState *s1, int do_preprocess)
   17766 {
   17767     Sym *define_start;
   17768     int ret;
   17769 
   17770     preprocess_init(s1);
   17771 
   17772     /* default section is text */
   17773     cur_text_section = text_section;
   17774     ind = cur_text_section->data_offset;
   17775 
   17776     define_start = define_stack;
   17777 
   17778     ret = tcc_assemble_internal(s1, do_preprocess);
   17779 
   17780     cur_text_section->data_offset = ind;
   17781 
   17782     free_defines(define_start);
   17783 
   17784     return ret;
   17785 }
   17786 
   17787 /********************************************************************/
   17788 /* GCC inline asm support */
   17789 
   17790 /* assemble the string 'str' in the current C compilation unit without
   17791    C preprocessing. NOTE: str is modified by modifying the '\0' at the
   17792    end */
   17793 static void tcc_assemble_inline(TCCState *s1, char *str, int len)
   17794 {
   17795     BufferedFile *bf, *saved_file;
   17796     int saved_parse_flags, *saved_macro_ptr;
   17797 
   17798     bf = tcc_malloc(sizeof(BufferedFile));
   17799     memset(bf, 0, sizeof(BufferedFile));
   17800     bf->fd = -1;
   17801     bf->buf_ptr = str;
   17802     bf->buf_end = str + len;
   17803     str[len] = CH_EOB;
   17804     /* same name as current file so that errors are correctly
   17805        reported */
   17806     pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
   17807     bf->line_num = file->line_num;
   17808     saved_file = file;
   17809     file = bf;
   17810     saved_parse_flags = parse_flags;
   17811     saved_macro_ptr = macro_ptr;
   17812     macro_ptr = NULL;
   17813 
   17814     tcc_assemble_internal(s1, 0);
   17815 
   17816     parse_flags = saved_parse_flags;
   17817     macro_ptr = saved_macro_ptr;
   17818     file = saved_file;
   17819     tcc_free(bf);
   17820 }
   17821 
   17822 /* find a constraint by its number or id (gcc 3 extended
   17823    syntax). return -1 if not found. Return in *pp in char after the
   17824    constraint */
   17825 static int find_constraint(ASMOperand *operands, int nb_operands,
   17826                            const char *name, const char **pp)
   17827 {
   17828     int index;
   17829     TokenSym *ts;
   17830     const char *p;
   17831 
   17832     if (isnum(*name)) {
   17833         index = 0;
   17834         while (isnum(*name)) {
   17835             index = (index * 10) + (*name) - '0';
   17836             name++;
   17837         }
   17838         if ((unsigned)index >= nb_operands)
   17839             index = -1;
   17840     } else if (*name == '[') {
   17841         name++;
   17842         p = strchr(name, ']');
   17843         if (p) {
   17844             ts = tok_alloc(name, p - name);
   17845             for(index = 0; index < nb_operands; index++) {
   17846                 if (operands[index].id == ts->tok)
   17847                     goto found;
   17848             }
   17849             index = -1;
   17850         found:
   17851             name = p + 1;
   17852         } else {
   17853             index = -1;
   17854         }
   17855     } else {
   17856         index = -1;
   17857     }
   17858     if (pp)
   17859         *pp = name;
   17860     return index;
   17861 }
   17862 
   17863 static void subst_asm_operands(ASMOperand *operands, int nb_operands,
   17864                                int nb_outputs,
   17865                                CString *out_str, CString *in_str)
   17866 {
   17867     int c, index, modifier;
   17868     const char *str;
   17869     ASMOperand *op;
   17870     SValue sv;
   17871 
   17872     cstr_new(out_str);
   17873     str = in_str->data;
   17874     for(;;) {
   17875         c = *str++;
   17876         if (c == '%') {
   17877             if (*str == '%') {
   17878                 str++;
   17879                 goto add_char;
   17880             }
   17881             modifier = 0;
   17882             if (*str == 'c' || *str == 'n' ||
   17883                 *str == 'b' || *str == 'w' || *str == 'h')
   17884                 modifier = *str++;
   17885             index = find_constraint(operands, nb_operands, str, &str);
   17886             if (index < 0)
   17887                 error("invalid operand reference after %%");
   17888             op = &operands[index];
   17889             sv = *op->vt;
   17890             if (op->reg >= 0) {
   17891                 sv.r = op->reg;
   17892                 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL)
   17893                     sv.r |= VT_LVAL;
   17894             }
   17895             subst_asm_operand(out_str, &sv, modifier);
   17896         } else {
   17897         add_char:
   17898             cstr_ccat(out_str, c);
   17899             if (c == '\0')
   17900                 break;
   17901         }
   17902     }
   17903 }
   17904 
   17905 
   17906 static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
   17907                                int is_output)
   17908 {
   17909     ASMOperand *op;
   17910     int nb_operands;
   17911 
   17912     if (tok != ':') {
   17913         nb_operands = *nb_operands_ptr;
   17914         for(;;) {
   17915             if (nb_operands >= MAX_ASM_OPERANDS)
   17916                 error("too many asm operands");
   17917             op = &operands[nb_operands++];
   17918             op->id = 0;
   17919             if (tok == '[') {
   17920                 next();
   17921                 if (tok < TOK_IDENT)
   17922                     expect("identifier");
   17923                 op->id = tok;
   17924                 next();
   17925                 skip(']');
   17926             }
   17927             if (tok != TOK_STR)
   17928                 expect("string constant");
   17929             op->constraint = tcc_malloc(tokc.cstr->size);
   17930             strcpy(op->constraint, tokc.cstr->data);
   17931             next();
   17932             skip('(');
   17933             gexpr();
   17934             if (is_output) {
   17935                 test_lvalue();
   17936             } else {
   17937                 /* we want to avoid LLOCAL case, except when the 'm'
   17938                    constraint is used. Note that it may come from
   17939                    register storage, so we need to convert (reg)
   17940                    case */
   17941                 if ((vtop->r & VT_LVAL) &&
   17942                     ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
   17943                      (vtop->r & VT_VALMASK) < VT_CONST) &&
   17944                     !strchr(op->constraint, 'm')) {
   17945                     gv(RC_INT);
   17946                 }
   17947             }
   17948             op->vt = vtop;
   17949             skip(')');
   17950             if (tok == ',') {
   17951                 next();
   17952             } else {
   17953                 break;
   17954             }
   17955         }
   17956         *nb_operands_ptr = nb_operands;
   17957     }
   17958 }
   17959 
   17960 static void parse_asm_str(CString *astr)
   17961 {
   17962     skip('(');
   17963     /* read the string */
   17964     if (tok != TOK_STR)
   17965         expect("string constant");
   17966     cstr_new(astr);
   17967     while (tok == TOK_STR) {
   17968         /* XXX: add \0 handling too ? */
   17969         cstr_cat(astr, tokc.cstr->data);
   17970         next();
   17971     }
   17972     cstr_ccat(astr, '\0');
   17973 }
   17974 
   17975 /* parse the GCC asm() instruction */
   17976 static void asm_instr(void)
   17977 {
   17978     CString astr, astr1;
   17979     ASMOperand operands[MAX_ASM_OPERANDS];
   17980     int nb_inputs __attribute__((unused));
   17981     int nb_outputs, nb_operands, i, must_subst, out_reg;
   17982     uint8_t clobber_regs[NB_ASM_REGS];
   17983 
   17984     next();
   17985     /* since we always generate the asm() instruction, we can ignore
   17986        volatile */
   17987     if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
   17988         next();
   17989     }
   17990     parse_asm_str(&astr);
   17991     nb_operands = 0;
   17992     nb_outputs = 0;
   17993     must_subst = 0;
   17994     memset(clobber_regs, 0, sizeof(clobber_regs));
   17995     if (tok == ':') {
   17996         next();
   17997         must_subst = 1;
   17998         /* output args */
   17999         parse_asm_operands(operands, &nb_operands, 1);
   18000         nb_outputs = nb_operands;
   18001         if (tok == ':') {
   18002             next();
   18003             /* input args */
   18004             parse_asm_operands(operands, &nb_operands, 0);
   18005             if (tok == ':') {
   18006                 /* clobber list */
   18007                 /* XXX: handle registers */
   18008                 next();
   18009                 for(;;) {
   18010                     if (tok != TOK_STR)
   18011                         expect("string constant");
   18012                     asm_clobber(clobber_regs, tokc.cstr->data);
   18013                     next();
   18014                     if (tok == ',') {
   18015                         next();
   18016                     } else {
   18017                         break;
   18018                     }
   18019                 }
   18020             }
   18021         }
   18022     }
   18023     skip(')');
   18024     /* NOTE: we do not eat the ';' so that we can restore the current
   18025        token after the assembler parsing */
   18026     if (tok != ';')
   18027         expect("';'");
   18028     nb_inputs = nb_operands - nb_outputs;
   18029 
   18030     /* save all values in the memory */
   18031     save_regs(0);
   18032 
   18033     /* compute constraints */
   18034     asm_compute_constraints(operands, nb_operands, nb_outputs,
   18035                             clobber_regs, &out_reg);
   18036 
   18037     /* substitute the operands in the asm string. No substitution is
   18038        done if no operands (GCC behaviour) */
   18039 #ifdef ASM_DEBUG
   18040     printf("asm: \"%s\"\n", (char *)astr.data);
   18041 #endif
   18042     if (must_subst) {
   18043         subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
   18044         cstr_free(&astr);
   18045     } else {
   18046         astr1 = astr;
   18047     }
   18048 #ifdef ASM_DEBUG
   18049     printf("subst_asm: \"%s\"\n", (char *)astr1.data);
   18050 #endif
   18051 
   18052     /* generate loads */
   18053     asm_gen_code(operands, nb_operands, nb_outputs, 0,
   18054                  clobber_regs, out_reg);
   18055 
   18056     /* assemble the string with tcc internal assembler */
   18057     tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
   18058 
   18059     /* restore the current C token */
   18060     next();
   18061 
   18062     /* store the output values if needed */
   18063     asm_gen_code(operands, nb_operands, nb_outputs, 1,
   18064                  clobber_regs, out_reg);
   18065 
   18066     /* free everything */
   18067     for(i=0;i<nb_operands;i++) {
   18068         ASMOperand *op;
   18069         op = &operands[i];
   18070         tcc_free(op->constraint);
   18071         vpop();
   18072     }
   18073     cstr_free(&astr1);
   18074 }
   18075 
   18076 static void asm_global_instr(void)
   18077 {
   18078     CString astr;
   18079 
   18080     next();
   18081     parse_asm_str(&astr);
   18082     skip(')');
   18083     /* NOTE: we do not eat the ';' so that we can restore the current
   18084        token after the assembler parsing */
   18085     if (tok != ';')
   18086         expect("';'");
   18087 
   18088 #ifdef ASM_DEBUG
   18089     printf("asm_global: \"%s\"\n", (char *)astr.data);
   18090 #endif
   18091     cur_text_section = text_section;
   18092     ind = cur_text_section->data_offset;
   18093 
   18094     /* assemble the string with tcc internal assembler */
   18095     tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
   18096 
   18097     cur_text_section->data_offset = ind;
   18098 
   18099     /* restore the current C token */
   18100     next();
   18101 
   18102     cstr_free(&astr);
   18103 }
   18104 //---------------------------------------------------------------------------
   18105 
   18106 #else
   18107 static void asm_instr(void)
   18108 {
   18109     error("inline asm() not supported");
   18110 }
   18111 static void asm_global_instr(void)
   18112 {
   18113     error("inline asm() not supported");
   18114 }
   18115 #endif
   18116 
   18117 // njn: inlined tccelf.c
   18118 //#include "tccelf.c"
   18119 //---------------------------------------------------------------------------
   18120 /*
   18121  *  ELF file handling for TCC
   18122  *
   18123  *  Copyright (c) 2001-2004 Fabrice Bellard
   18124  *
   18125  * This library is free software; you can redistribute it and/or
   18126  * modify it under the terms of the GNU Lesser General Public
   18127  * License as published by the Free Software Foundation; either
   18128  * version 2 of the License, or (at your option) any later version.
   18129  *
   18130  * This library is distributed in the hope that it will be useful,
   18131  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18132  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18133  * Lesser General Public License for more details.
   18134  *
   18135  * You should have received a copy of the GNU Lesser General Public
   18136  * License along with this library; if not, write to the Free Software
   18137  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18138  */
   18139 
   18140 static int put_elf_str(Section *s, const char *sym)
   18141 {
   18142     int offset, len;
   18143     char *ptr;
   18144 
   18145     len = strlen(sym) + 1;
   18146     offset = s->data_offset;
   18147     ptr = section_ptr_add(s, len);
   18148     memcpy(ptr, sym, len);
   18149     return offset;
   18150 }
   18151 
   18152 /* elf symbol hashing function */
   18153 static unsigned long elf_hash(const unsigned char *name)
   18154 {
   18155     unsigned long h = 0, g;
   18156 
   18157     while (*name) {
   18158         h = (h << 4) + *name++;
   18159         g = h & 0xf0000000;
   18160         if (g)
   18161             h ^= g >> 24;
   18162         h &= ~g;
   18163     }
   18164     return h;
   18165 }
   18166 
   18167 /* rebuild hash table of section s */
   18168 /* NOTE: we do factorize the hash table code to go faster */
   18169 static void rebuild_hash(Section *s, unsigned int nb_buckets)
   18170 {
   18171     Elf32_Sym *sym;
   18172     int *ptr, *hash, nb_syms, sym_index, h;
   18173     char *strtab;
   18174 
   18175     strtab = s->link->data;
   18176     nb_syms = s->data_offset / sizeof(Elf32_Sym);
   18177 
   18178     s->hash->data_offset = 0;
   18179     ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
   18180     ptr[0] = nb_buckets;
   18181     ptr[1] = nb_syms;
   18182     ptr += 2;
   18183     hash = ptr;
   18184     memset(hash, 0, (nb_buckets + 1) * sizeof(int));
   18185     ptr += nb_buckets + 1;
   18186 
   18187     sym = (Elf32_Sym *)s->data + 1;
   18188     for(sym_index = 1; sym_index < nb_syms; sym_index++) {
   18189         if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
   18190             h = elf_hash(strtab + sym->st_name) % nb_buckets;
   18191             *ptr = hash[h];
   18192             hash[h] = sym_index;
   18193         } else {
   18194             *ptr = 0;
   18195         }
   18196         ptr++;
   18197         sym++;
   18198     }
   18199 }
   18200 
   18201 /* return the symbol number */
   18202 static int put_elf_sym(Section *s,
   18203                        unsigned long value, unsigned long size,
   18204                        int info, int other, int shndx, const char *name)
   18205 {
   18206     int name_offset, sym_index;
   18207     int nbuckets, h;
   18208     Elf32_Sym *sym;
   18209     Section *hs;
   18210 
   18211     sym = section_ptr_add(s, sizeof(Elf32_Sym));
   18212     if (name)
   18213         name_offset = put_elf_str(s->link, name);
   18214     else
   18215         name_offset = 0;
   18216     /* XXX: endianness */
   18217     sym->st_name = name_offset;
   18218     sym->st_value = value;
   18219     sym->st_size = size;
   18220     sym->st_info = info;
   18221     sym->st_other = other;
   18222     sym->st_shndx = shndx;
   18223     sym_index = sym - (Elf32_Sym *)s->data;
   18224     hs = s->hash;
   18225     if (hs) {
   18226         int *ptr, *base;
   18227         ptr = section_ptr_add(hs, sizeof(int));
   18228         base = (int *)hs->data;
   18229         /* only add global or weak symbols */
   18230         if (ELF32_ST_BIND(info) != STB_LOCAL) {
   18231             /* add another hashing entry */
   18232             nbuckets = base[0];
   18233             h = elf_hash(name) % nbuckets;
   18234             *ptr = base[2 + h];
   18235             base[2 + h] = sym_index;
   18236             base[1]++;
   18237             /* we resize the hash table */
   18238             hs->nb_hashed_syms++;
   18239             if (hs->nb_hashed_syms > 2 * nbuckets) {
   18240                 rebuild_hash(s, 2 * nbuckets);
   18241             }
   18242         } else {
   18243             *ptr = 0;
   18244             base[1]++;
   18245         }
   18246     }
   18247     return sym_index;
   18248 }
   18249 
   18250 /* find global ELF symbol 'name' and return its index. Return 0 if not
   18251    found. */
   18252 static int find_elf_sym(Section *s, const char *name)
   18253 {
   18254     Elf32_Sym *sym;
   18255     Section *hs;
   18256     int nbuckets, sym_index, h;
   18257     const char *name1;
   18258 
   18259     hs = s->hash;
   18260     if (!hs)
   18261         return 0;
   18262     nbuckets = ((int *)hs->data)[0];
   18263     h = elf_hash(name) % nbuckets;
   18264     sym_index = ((int *)hs->data)[2 + h];
   18265     while (sym_index != 0) {
   18266         sym = &((Elf32_Sym *)s->data)[sym_index];
   18267         name1 = s->link->data + sym->st_name;
   18268         if (!strcmp(name, name1))
   18269             return sym_index;
   18270         sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
   18271     }
   18272     return 0;
   18273 }
   18274 
   18275 /* return elf symbol value or error */
   18276 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
   18277 {
   18278     int sym_index;
   18279     Elf32_Sym *sym;
   18280 
   18281     sym_index = find_elf_sym(symtab_section, name);
   18282     if (!sym_index)
   18283         return -1;
   18284     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   18285     *pval = sym->st_value;
   18286     return 0;
   18287 }
   18288 
   18289 void *tcc_get_symbol_err(TCCState *s, const char *name)
   18290 {
   18291     unsigned long val;
   18292     if (tcc_get_symbol(s, &val, name) < 0)
   18293         error("%s not defined", name);
   18294     return (void *)val;
   18295 }
   18296 
   18297 /* add an elf symbol : check if it is already defined and patch
   18298    it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
   18299 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
   18300                        int info, int other, int sh_num, const char *name)
   18301 {
   18302     Elf32_Sym *esym;
   18303     int sym_bind, sym_index, sym_type, esym_bind;
   18304 
   18305     sym_bind = ELF32_ST_BIND(info);
   18306     sym_type = ELF32_ST_TYPE(info);
   18307 
   18308     if (sym_bind != STB_LOCAL) {
   18309         /* we search global or weak symbols */
   18310         sym_index = find_elf_sym(s, name);
   18311         if (!sym_index)
   18312             goto do_def;
   18313         esym = &((Elf32_Sym *)s->data)[sym_index];
   18314         if (esym->st_shndx != SHN_UNDEF) {
   18315             esym_bind = ELF32_ST_BIND(esym->st_info);
   18316             if (sh_num == SHN_UNDEF) {
   18317                 /* ignore adding of undefined symbol if the
   18318                    corresponding symbol is already defined */
   18319             } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
   18320                 /* global overrides weak, so patch */
   18321                 goto do_patch;
   18322             } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
   18323                 /* weak is ignored if already global */
   18324             } else {
   18325 #if 0
   18326                 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
   18327                        sym_bind, sh_num, esym_bind, esym->st_shndx);
   18328 #endif
   18329                 /* NOTE: we accept that two DLL define the same symbol */
   18330                 if (s != tcc_state->dynsymtab_section)
   18331                     error_noabort("'%s' defined twice", name);
   18332             }
   18333         } else {
   18334         do_patch:
   18335             esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
   18336             esym->st_shndx = sh_num;
   18337             esym->st_value = value;
   18338             esym->st_size = size;
   18339             esym->st_other = other;
   18340         }
   18341     } else {
   18342     do_def:
   18343         sym_index = put_elf_sym(s, value, size,
   18344                                 ELF32_ST_INFO(sym_bind, sym_type), other,
   18345                                 sh_num, name);
   18346     }
   18347     return sym_index;
   18348 }
   18349 
   18350 /* put relocation */
   18351 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
   18352                           int type, int symbol)
   18353 {
   18354     char buf[256];
   18355     Section *sr;
   18356     Elf32_Rel *rel;
   18357 
   18358     sr = s->reloc;
   18359     if (!sr) {
   18360         /* if no relocation section, create it */
   18361         snprintf(buf, sizeof(buf), ".rel%s", s->name);
   18362         /* if the symtab is allocated, then we consider the relocation
   18363            are also */
   18364         sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
   18365         sr->sh_entsize = sizeof(Elf32_Rel);
   18366         sr->link = symtab;
   18367         sr->sh_info = s->sh_num;
   18368         s->reloc = sr;
   18369     }
   18370     rel = section_ptr_add(sr, sizeof(Elf32_Rel));
   18371     rel->r_offset = offset;
   18372     rel->r_info = ELF32_R_INFO(symbol, type);
   18373 }
   18374 
   18375 /* put stab debug information */
   18376 
   18377 typedef struct {
   18378     unsigned long n_strx;         /* index into string table of name */
   18379     unsigned char n_type;         /* type of symbol */
   18380     unsigned char n_other;        /* misc info (usually empty) */
   18381     unsigned short n_desc;        /* description field */
   18382     unsigned long n_value;        /* value of symbol */
   18383 } Stab_Sym;
   18384 
   18385 static void put_stabs(const char *str, int type, int other, int desc,
   18386                       unsigned long value)
   18387 {
   18388     Stab_Sym *sym;
   18389 
   18390     sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
   18391     if (str) {
   18392         sym->n_strx = put_elf_str(stabstr_section, str);
   18393     } else {
   18394         sym->n_strx = 0;
   18395     }
   18396     sym->n_type = type;
   18397     sym->n_other = other;
   18398     sym->n_desc = desc;
   18399     sym->n_value = value;
   18400 }
   18401 
   18402 static void put_stabs_r(const char *str, int type, int other, int desc,
   18403                         unsigned long value, Section *sec, int sym_index)
   18404 {
   18405     put_stabs(str, type, other, desc, value);
   18406     put_elf_reloc(symtab_section, stab_section,
   18407                   stab_section->data_offset - sizeof(unsigned long),
   18408                   R_DATA_32, sym_index);
   18409 }
   18410 
   18411 static void put_stabn(int type, int other, int desc, int value)
   18412 {
   18413     put_stabs(NULL, type, other, desc, value);
   18414 }
   18415 
   18416 static void put_stabd(int type, int other, int desc)
   18417 {
   18418     put_stabs(NULL, type, other, desc, 0);
   18419 }
   18420 
   18421 /* In an ELF file symbol table, the local symbols must appear below
   18422    the global and weak ones. Since TCC cannot sort it while generating
   18423    the code, we must do it after. All the relocation tables are also
   18424    modified to take into account the symbol table sorting */
   18425 static void sort_syms(TCCState *s1, Section *s)
   18426 {
   18427     int *old_to_new_syms;
   18428     Elf32_Sym *new_syms;
   18429     int nb_syms, i;
   18430     Elf32_Sym *p, *q;
   18431     Elf32_Rel *rel, *rel_end;
   18432     Section *sr;
   18433     int type, sym_index;
   18434 
   18435     nb_syms = s->data_offset / sizeof(Elf32_Sym);
   18436     new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
   18437     old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
   18438 
   18439     /* first pass for local symbols */
   18440     p = (Elf32_Sym *)s->data;
   18441     q = new_syms;
   18442     for(i = 0; i < nb_syms; i++) {
   18443         if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
   18444             old_to_new_syms[i] = q - new_syms;
   18445             *q++ = *p;
   18446         }
   18447         p++;
   18448     }
   18449     /* save the number of local symbols in section header */
   18450     s->sh_info = q - new_syms;
   18451 
   18452     /* then second pass for non local symbols */
   18453     p = (Elf32_Sym *)s->data;
   18454     for(i = 0; i < nb_syms; i++) {
   18455         if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
   18456             old_to_new_syms[i] = q - new_syms;
   18457             *q++ = *p;
   18458         }
   18459         p++;
   18460     }
   18461 
   18462     /* we copy the new symbols to the old */
   18463     memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
   18464     tcc_free(new_syms);
   18465 
   18466     /* now we modify all the relocations */
   18467     for(i = 1; i < s1->nb_sections; i++) {
   18468         sr = s1->sections[i];
   18469         if (sr->sh_type == SHT_REL && sr->link == s) {
   18470             rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
   18471             for(rel = (Elf32_Rel *)sr->data;
   18472                 rel < rel_end;
   18473                 rel++) {
   18474                 sym_index = ELF32_R_SYM(rel->r_info);
   18475                 type = ELF32_R_TYPE(rel->r_info);
   18476                 sym_index = old_to_new_syms[sym_index];
   18477                 rel->r_info = ELF32_R_INFO(sym_index, type);
   18478             }
   18479         }
   18480     }
   18481 
   18482     tcc_free(old_to_new_syms);
   18483 }
   18484 
   18485 /* relocate common symbols in the .bss section */
   18486 static void relocate_common_syms(void)
   18487 {
   18488     Elf32_Sym *sym, *sym_end;
   18489     unsigned long offset, align;
   18490 
   18491     sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
   18492     for(sym = (Elf32_Sym *)symtab_section->data + 1;
   18493         sym < sym_end;
   18494         sym++) {
   18495         if (sym->st_shndx == SHN_COMMON) {
   18496             /* align symbol */
   18497             align = sym->st_value;
   18498             offset = bss_section->data_offset;
   18499             offset = (offset + align - 1) & -align;
   18500             sym->st_value = offset;
   18501             sym->st_shndx = bss_section->sh_num;
   18502             offset += sym->st_size;
   18503             bss_section->data_offset = offset;
   18504         }
   18505     }
   18506 }
   18507 
   18508 /* relocate symbol table, resolve undefined symbols if do_resolve is
   18509    true and output error if undefined symbol. */
   18510 static void relocate_syms(TCCState *s1, int do_resolve)
   18511 {
   18512     Elf32_Sym *sym, *esym, *sym_end;
   18513     int sym_bind, sh_num, sym_index;
   18514     const char *name;
   18515     unsigned long addr;
   18516 
   18517     sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
   18518     for(sym = (Elf32_Sym *)symtab_section->data + 1;
   18519         sym < sym_end;
   18520         sym++) {
   18521         sh_num = sym->st_shndx;
   18522         if (sh_num == SHN_UNDEF) {
   18523             name = strtab_section->data + sym->st_name;
   18524             if (do_resolve) {
   18525                 name = symtab_section->link->data + sym->st_name;
   18526                 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
   18527                 if (addr) {
   18528                     sym->st_value = addr;
   18529                     goto found;
   18530                 }
   18531             } else if (s1->dynsym) {
   18532                 /* if dynamic symbol exist, then use it */
   18533                 sym_index = find_elf_sym(s1->dynsym, name);
   18534                 if (sym_index) {
   18535                     esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
   18536                     sym->st_value = esym->st_value;
   18537                     goto found;
   18538                 }
   18539             }
   18540             /* XXX: _fp_hw seems to be part of the ABI, so we ignore
   18541                it */
   18542             if (!strcmp(name, "_fp_hw"))
   18543                 goto found;
   18544             /* only weak symbols are accepted to be undefined. Their
   18545                value is zero */
   18546             sym_bind = ELF32_ST_BIND(sym->st_info);
   18547             if (sym_bind == STB_WEAK) {
   18548                 sym->st_value = 0;
   18549             } else {
   18550                 error_noabort("undefined symbol '%s'", name);
   18551             }
   18552         } else if (sh_num < SHN_LORESERVE) {
   18553             /* add section base */
   18554             sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
   18555         }
   18556     found: ;
   18557     }
   18558 }
   18559 
   18560 /* relocate a given section (CPU dependent) */
   18561 static void relocate_section(TCCState *s1, Section *s)
   18562 {
   18563     Section *sr;
   18564     Elf32_Rel *rel, *rel_end, *qrel;
   18565     Elf32_Sym *sym;
   18566     int type, sym_index;
   18567     unsigned char *ptr;
   18568     unsigned long val, addr;
   18569 #if defined(TCC_TARGET_I386)
   18570     int esym_index;
   18571 #endif
   18572 
   18573     sr = s->reloc;
   18574     rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
   18575     qrel = (Elf32_Rel *)sr->data;
   18576     for(rel = qrel;
   18577         rel < rel_end;
   18578         rel++) {
   18579         ptr = s->data + rel->r_offset;
   18580 
   18581         sym_index = ELF32_R_SYM(rel->r_info);
   18582         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   18583         val = sym->st_value;
   18584         type = ELF32_R_TYPE(rel->r_info);
   18585         addr = s->sh_addr + rel->r_offset;
   18586 
   18587         /* CPU specific */
   18588         switch(type) {
   18589 #if defined(TCC_TARGET_I386)
   18590         case R_386_32:
   18591             if (s1->output_type == TCC_OUTPUT_DLL) {
   18592                 esym_index = s1->symtab_to_dynsym[sym_index];
   18593                 qrel->r_offset = rel->r_offset;
   18594                 if (esym_index) {
   18595                     qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
   18596                     qrel++;
   18597                     break;
   18598                 } else {
   18599                     qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
   18600                     qrel++;
   18601                 }
   18602             }
   18603             *(int *)ptr += val;
   18604             break;
   18605         case R_386_PC32:
   18606             if (s1->output_type == TCC_OUTPUT_DLL) {
   18607                 /* DLL relocation */
   18608                 esym_index = s1->symtab_to_dynsym[sym_index];
   18609                 if (esym_index) {
   18610                     qrel->r_offset = rel->r_offset;
   18611                     qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
   18612                     qrel++;
   18613                     break;
   18614                 }
   18615             }
   18616             *(int *)ptr += val - addr;
   18617             break;
   18618         case R_386_PLT32:
   18619             *(int *)ptr += val - addr;
   18620             break;
   18621         case R_386_GLOB_DAT:
   18622         case R_386_JMP_SLOT:
   18623             *(int *)ptr = val;
   18624             break;
   18625         case R_386_GOTPC:
   18626             *(int *)ptr += s1->got->sh_addr - addr;
   18627             break;
   18628         case R_386_GOTOFF:
   18629             *(int *)ptr += val - s1->got->sh_addr;
   18630             break;
   18631         case R_386_GOT32:
   18632             /* we load the got offset */
   18633             *(int *)ptr += s1->got_offsets[sym_index];
   18634             break;
   18635 #elif defined(TCC_TARGET_ARM)
   18636 	case R_ARM_PC24:
   18637 	case R_ARM_PLT32:
   18638 	    {
   18639                 int x;
   18640                 x = (*(int *)ptr)&0xffffff;
   18641                 (*(int *)ptr) &= 0xff000000;
   18642                 if (x & 0x800000)
   18643                     x -= 0x1000000;
   18644                 x *= 4;
   18645                 x += val - addr;
   18646                 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
   18647                     error("can't relocate value at %x",addr);
   18648                 x >>= 2;
   18649                 x &= 0xffffff;
   18650                 (*(int *)ptr) |= x;
   18651 	    }
   18652 	    break;
   18653 	case R_ARM_ABS32:
   18654 	    *(int *)ptr += val;
   18655 	    break;
   18656 	case R_ARM_GOTPC:
   18657 	    *(int *)ptr += s1->got->sh_addr - addr;
   18658 	    break;
   18659         case R_ARM_GOT32:
   18660             /* we load the got offset */
   18661             *(int *)ptr += s1->got_offsets[sym_index];
   18662             break;
   18663 	case R_ARM_COPY:
   18664             break;
   18665 	default:
   18666 	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
   18667                     type,addr,(unsigned int )ptr,val);
   18668             break;
   18669 #elif defined(TCC_TARGET_C67)
   18670 	case R_C60_32:
   18671 	    *(int *)ptr += val;
   18672 	    break;
   18673         case R_C60LO16:
   18674             {
   18675                 uint32_t orig;
   18676 
   18677                 /* put the low 16 bits of the absolute address */
   18678                 // add to what is already there
   18679 
   18680                 orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
   18681                 orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
   18682 
   18683                 //patch both at once - assumes always in pairs Low - High
   18684 
   18685                 *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
   18686                 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
   18687             }
   18688             break;
   18689         case R_C60HI16:
   18690             break;
   18691         default:
   18692 	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
   18693                     type,addr,(unsigned int )ptr,val);
   18694             break;
   18695 #else
   18696 #error unsupported processor
   18697 #endif
   18698         }
   18699     }
   18700     /* if the relocation is allocated, we change its symbol table */
   18701     if (sr->sh_flags & SHF_ALLOC)
   18702         sr->link = s1->dynsym;
   18703 }
   18704 
   18705 /* relocate relocation table in 'sr' */
   18706 static void relocate_rel(TCCState *s1, Section *sr)
   18707 {
   18708     Section *s;
   18709     Elf32_Rel *rel, *rel_end;
   18710 
   18711     s = s1->sections[sr->sh_info];
   18712     rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
   18713     for(rel = (Elf32_Rel *)sr->data;
   18714         rel < rel_end;
   18715         rel++) {
   18716         rel->r_offset += s->sh_addr;
   18717     }
   18718 }
   18719 
   18720 /* count the number of dynamic relocations so that we can reserve
   18721    their space */
   18722 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
   18723 {
   18724     Elf32_Rel *rel, *rel_end;
   18725     int sym_index, esym_index, type, count;
   18726 
   18727     count = 0;
   18728     rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
   18729     for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
   18730         sym_index = ELF32_R_SYM(rel->r_info);
   18731         type = ELF32_R_TYPE(rel->r_info);
   18732         switch(type) {
   18733         case R_386_32:
   18734             count++;
   18735             break;
   18736         case R_386_PC32:
   18737             esym_index = s1->symtab_to_dynsym[sym_index];
   18738             if (esym_index)
   18739                 count++;
   18740             break;
   18741         default:
   18742             break;
   18743         }
   18744     }
   18745     if (count) {
   18746         /* allocate the section */
   18747         sr->sh_flags |= SHF_ALLOC;
   18748         sr->sh_size = count * sizeof(Elf32_Rel);
   18749     }
   18750     return count;
   18751 }
   18752 
   18753 static void put_got_offset(TCCState *s1, int index, unsigned long val)
   18754 {
   18755     int n;
   18756     unsigned long *tab;
   18757 
   18758     if (index >= s1->nb_got_offsets) {
   18759         /* find immediately bigger power of 2 and reallocate array */
   18760         n = 1;
   18761         while (index >= n)
   18762             n *= 2;
   18763         tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
   18764         if (!tab)
   18765             error("memory full");
   18766         s1->got_offsets = tab;
   18767         memset(s1->got_offsets + s1->nb_got_offsets, 0,
   18768                (n - s1->nb_got_offsets) * sizeof(unsigned long));
   18769         s1->nb_got_offsets = n;
   18770     }
   18771     s1->got_offsets[index] = val;
   18772 }
   18773 
   18774 /* XXX: suppress that */
   18775 static void put32(unsigned char *p, uint32_t val)
   18776 {
   18777     p[0] = val;
   18778     p[1] = val >> 8;
   18779     p[2] = val >> 16;
   18780     p[3] = val >> 24;
   18781 }
   18782 
   18783 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
   18784 static uint32_t get32(unsigned char *p)
   18785 {
   18786     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
   18787 }
   18788 #endif
   18789 
   18790 static void build_got(TCCState *s1)
   18791 {
   18792     unsigned char *ptr;
   18793 
   18794     /* if no got, then create it */
   18795     s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
   18796     s1->got->sh_entsize = 4;
   18797     add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
   18798                 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
   18799     ptr = section_ptr_add(s1->got, 3 * sizeof(int));
   18800     /* keep space for _DYNAMIC pointer, if present */
   18801     put32(ptr, 0);
   18802     /* two dummy got entries */
   18803     put32(ptr + 4, 0);
   18804     put32(ptr + 8, 0);
   18805 }
   18806 
   18807 /* put a got entry corresponding to a symbol in symtab_section. 'size'
   18808    and 'info' can be modified if more precise info comes from the DLL */
   18809 static void put_got_entry(TCCState *s1,
   18810                           int reloc_type, unsigned long size, int info,
   18811                           int sym_index)
   18812 {
   18813     int index;
   18814     const char *name;
   18815     Elf32_Sym *sym;
   18816     unsigned long offset;
   18817     int *ptr;
   18818 
   18819     if (!s1->got)
   18820         build_got(s1);
   18821 
   18822     /* if a got entry already exists for that symbol, no need to add one */
   18823     if (sym_index < s1->nb_got_offsets &&
   18824         s1->got_offsets[sym_index] != 0)
   18825         return;
   18826 
   18827     put_got_offset(s1, sym_index, s1->got->data_offset);
   18828 
   18829     if (s1->dynsym) {
   18830         sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   18831         name = symtab_section->link->data + sym->st_name;
   18832         offset = sym->st_value;
   18833 #ifdef TCC_TARGET_I386
   18834         if (reloc_type == R_386_JMP_SLOT) {
   18835             Section *plt;
   18836             uint8_t *p;
   18837             int modrm;
   18838 
   18839             /* if we build a DLL, we add a %ebx offset */
   18840             if (s1->output_type == TCC_OUTPUT_DLL)
   18841                 modrm = 0xa3;
   18842             else
   18843                 modrm = 0x25;
   18844 
   18845             /* add a PLT entry */
   18846             plt = s1->plt;
   18847             if (plt->data_offset == 0) {
   18848                 /* first plt entry */
   18849                 p = section_ptr_add(plt, 16);
   18850                 p[0] = 0xff; /* pushl got + 4 */
   18851                 p[1] = modrm + 0x10;
   18852                 put32(p + 2, 4);
   18853                 p[6] = 0xff; /* jmp *(got + 8) */
   18854                 p[7] = modrm;
   18855                 put32(p + 8, 8);
   18856             }
   18857 
   18858             p = section_ptr_add(plt, 16);
   18859             p[0] = 0xff; /* jmp *(got + x) */
   18860             p[1] = modrm;
   18861             put32(p + 2, s1->got->data_offset);
   18862             p[6] = 0x68; /* push $xxx */
   18863             put32(p + 7, (plt->data_offset - 32) >> 1);
   18864             p[11] = 0xe9; /* jmp plt_start */
   18865             put32(p + 12, -(plt->data_offset));
   18866 
   18867             /* the symbol is modified so that it will be relocated to
   18868                the PLT */
   18869             if (s1->output_type == TCC_OUTPUT_EXE)
   18870                 offset = plt->data_offset - 16;
   18871         }
   18872 #elif defined(TCC_TARGET_ARM)
   18873 	if (reloc_type == R_ARM_JUMP_SLOT) {
   18874             Section *plt;
   18875             uint8_t *p;
   18876 
   18877             /* if we build a DLL, we add a %ebx offset */
   18878             if (s1->output_type == TCC_OUTPUT_DLL)
   18879                 error("DLLs unimplemented!");
   18880 
   18881             /* add a PLT entry */
   18882             plt = s1->plt;
   18883             if (plt->data_offset == 0) {
   18884                 /* first plt entry */
   18885                 p = section_ptr_add(plt, 16);
   18886 		put32(p     , 0xe52de004);
   18887 		put32(p +  4, 0xe59fe010);
   18888 		put32(p +  8, 0xe08fe00e);
   18889 		put32(p + 12, 0xe5bef008);
   18890             }
   18891 
   18892             p = section_ptr_add(plt, 16);
   18893 	    put32(p  , 0xe59fc004);
   18894 	    put32(p+4, 0xe08fc00c);
   18895 	    put32(p+8, 0xe59cf000);
   18896 	    put32(p+12, s1->got->data_offset);
   18897 
   18898             /* the symbol is modified so that it will be relocated to
   18899                the PLT */
   18900             if (s1->output_type == TCC_OUTPUT_EXE)
   18901                 offset = plt->data_offset - 16;
   18902         }
   18903 #elif defined(TCC_TARGET_C67)
   18904         error("C67 got not implemented");
   18905 #else
   18906 #error unsupported CPU
   18907 #endif
   18908         index = put_elf_sym(s1->dynsym, offset,
   18909                             size, info, 0, sym->st_shndx, name);
   18910         /* put a got entry */
   18911         put_elf_reloc(s1->dynsym, s1->got,
   18912                       s1->got->data_offset,
   18913                       reloc_type, index);
   18914     }
   18915     ptr = section_ptr_add(s1->got, sizeof(int));
   18916     *ptr = 0;
   18917 }
   18918 
   18919 /* build GOT and PLT entries */
   18920 static void build_got_entries(TCCState *s1)
   18921 {
   18922     Section *s, *symtab __attribute__((unused));
   18923     Elf32_Rel *rel, *rel_end;
   18924     Elf32_Sym *sym;
   18925     int i, type, reloc_type, sym_index;
   18926 
   18927     for(i = 1; i < s1->nb_sections; i++) {
   18928         s = s1->sections[i];
   18929         if (s->sh_type != SHT_REL)
   18930             continue;
   18931         /* no need to handle got relocations */
   18932         if (s->link != symtab_section)
   18933             continue;
   18934         symtab = s->link;
   18935         rel_end = (Elf32_Rel *)(s->data + s->data_offset);
   18936         for(rel = (Elf32_Rel *)s->data;
   18937             rel < rel_end;
   18938             rel++) {
   18939             type = ELF32_R_TYPE(rel->r_info);
   18940             switch(type) {
   18941 #if defined(TCC_TARGET_I386)
   18942             case R_386_GOT32:
   18943             case R_386_GOTOFF:
   18944             case R_386_GOTPC:
   18945             case R_386_PLT32:
   18946                 if (!s1->got)
   18947                     build_got(s1);
   18948                 if (type == R_386_GOT32 || type == R_386_PLT32) {
   18949                     sym_index = ELF32_R_SYM(rel->r_info);
   18950                     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   18951                     /* look at the symbol got offset. If none, then add one */
   18952                     if (type == R_386_GOT32)
   18953                         reloc_type = R_386_GLOB_DAT;
   18954                     else
   18955                         reloc_type = R_386_JMP_SLOT;
   18956                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
   18957                                   sym_index);
   18958                 }
   18959                 break;
   18960 #elif defined(TCC_TARGET_ARM)
   18961 	    case R_ARM_GOT32:
   18962             case R_ARM_GOTOFF:
   18963             case R_ARM_GOTPC:
   18964             case R_ARM_PLT32:
   18965                 if (!s1->got)
   18966                     build_got(s1);
   18967                 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
   18968                     sym_index = ELF32_R_SYM(rel->r_info);
   18969                     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   18970                     /* look at the symbol got offset. If none, then add one */
   18971                     if (type == R_ARM_GOT32)
   18972                         reloc_type = R_ARM_GLOB_DAT;
   18973                     else
   18974                         reloc_type = R_ARM_JUMP_SLOT;
   18975                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
   18976                                   sym_index);
   18977                 }
   18978                 break;
   18979 #elif defined(TCC_TARGET_C67)
   18980 	    case R_C60_GOT32:
   18981             case R_C60_GOTOFF:
   18982             case R_C60_GOTPC:
   18983             case R_C60_PLT32:
   18984                 if (!s1->got)
   18985                     build_got(s1);
   18986                 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
   18987                     sym_index = ELF32_R_SYM(rel->r_info);
   18988                     sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   18989                     /* look at the symbol got offset. If none, then add one */
   18990                     if (type == R_C60_GOT32)
   18991                         reloc_type = R_C60_GLOB_DAT;
   18992                     else
   18993                         reloc_type = R_C60_JMP_SLOT;
   18994                     put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
   18995                                   sym_index);
   18996                 }
   18997                 break;
   18998 #else
   18999 #error unsupported CPU
   19000 #endif
   19001             default:
   19002                 break;
   19003             }
   19004         }
   19005     }
   19006 }
   19007 
   19008 static Section *new_symtab(TCCState *s1,
   19009                            const char *symtab_name, int sh_type, int sh_flags,
   19010                            const char *strtab_name,
   19011                            const char *hash_name, int hash_sh_flags)
   19012 {
   19013     Section *symtab, *strtab, *hash;
   19014     int *ptr, nb_buckets;
   19015 
   19016     symtab = new_section(s1, symtab_name, sh_type, sh_flags);
   19017     symtab->sh_entsize = sizeof(Elf32_Sym);
   19018     strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
   19019     put_elf_str(strtab, "");
   19020     symtab->link = strtab;
   19021     put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
   19022 
   19023     nb_buckets = 1;
   19024 
   19025     hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
   19026     hash->sh_entsize = sizeof(int);
   19027     symtab->hash = hash;
   19028     hash->link = symtab;
   19029 
   19030     ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
   19031     ptr[0] = nb_buckets;
   19032     ptr[1] = 1;
   19033     memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
   19034     return symtab;
   19035 }
   19036 
   19037 /* put dynamic tag */
   19038 static void put_dt(Section *dynamic, int dt, unsigned long val)
   19039 {
   19040     Elf32_Dyn *dyn;
   19041     dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
   19042     dyn->d_tag = dt;
   19043     dyn->d_un.d_val = val;
   19044 }
   19045 
   19046 static void add_init_array_defines(TCCState *s1, const char *section_name)
   19047 {
   19048     Section *s;
   19049     long end_offset;
   19050     char sym_start[1024];
   19051     char sym_end[1024];
   19052 
   19053     snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
   19054     snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
   19055 
   19056     s = find_section(s1, section_name);
   19057     if (!s) {
   19058         end_offset = 0;
   19059         s = data_section;
   19060     } else {
   19061         end_offset = s->data_offset;
   19062     }
   19063 
   19064     add_elf_sym(symtab_section,
   19065                 0, 0,
   19066                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19067                 s->sh_num, sym_start);
   19068     add_elf_sym(symtab_section,
   19069                 end_offset, 0,
   19070                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19071                 s->sh_num, sym_end);
   19072 }
   19073 
   19074 /* add tcc runtime libraries */
   19075 static void tcc_add_runtime(TCCState *s1)
   19076 {
   19077     char buf[1024];
   19078 
   19079 #ifdef CONFIG_TCC_BCHECK
   19080     if (do_bounds_check) {
   19081         unsigned long *ptr;
   19082         Section *init_section;
   19083         unsigned char *pinit;
   19084         int sym_index;
   19085 
   19086         /* XXX: add an object file to do that */
   19087         ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
   19088         *ptr = 0;
   19089         add_elf_sym(symtab_section, 0, 0,
   19090                     ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19091                     bounds_section->sh_num, "__bounds_start");
   19092         /* add bound check code */
   19093         snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
   19094         tcc_add_file(s1, buf);
   19095 #ifdef TCC_TARGET_I386
   19096         if (s1->output_type != TCC_OUTPUT_MEMORY) {
   19097             /* add 'call __bound_init()' in .init section */
   19098             init_section = find_section(s1, ".init");
   19099             pinit = section_ptr_add(init_section, 5);
   19100             pinit[0] = 0xe8;
   19101             put32(pinit + 1, -4);
   19102             sym_index = find_elf_sym(symtab_section, "__bound_init");
   19103             put_elf_reloc(symtab_section, init_section,
   19104                           init_section->data_offset - 4, R_386_PC32, sym_index);
   19105         }
   19106 #endif
   19107     }
   19108 #endif
   19109     /* add libc */
   19110     if (!s1->nostdlib) {
   19111         tcc_add_library(s1, "c");
   19112 
   19113         snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
   19114         tcc_add_file(s1, buf);
   19115     }
   19116     /* add crt end if not memory output */
   19117     if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
   19118         tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
   19119     }
   19120 }
   19121 
   19122 /* add various standard linker symbols (must be done after the
   19123    sections are filled (for example after allocating common
   19124    symbols)) */
   19125 static void tcc_add_linker_symbols(TCCState *s1)
   19126 {
   19127     char buf[1024];
   19128     int i;
   19129     Section *s;
   19130 
   19131     add_elf_sym(symtab_section,
   19132                 text_section->data_offset, 0,
   19133                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19134                 text_section->sh_num, "_etext");
   19135     add_elf_sym(symtab_section,
   19136                 data_section->data_offset, 0,
   19137                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19138                 data_section->sh_num, "_edata");
   19139     add_elf_sym(symtab_section,
   19140                 bss_section->data_offset, 0,
   19141                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19142                 bss_section->sh_num, "_end");
   19143     /* horrible new standard ldscript defines */
   19144     add_init_array_defines(s1, ".preinit_array");
   19145     add_init_array_defines(s1, ".init_array");
   19146     add_init_array_defines(s1, ".fini_array");
   19147 
   19148     /* add start and stop symbols for sections whose name can be
   19149        expressed in C */
   19150     for(i = 1; i < s1->nb_sections; i++) {
   19151         s = s1->sections[i];
   19152         if (s->sh_type == SHT_PROGBITS &&
   19153             (s->sh_flags & SHF_ALLOC)) {
   19154             const char *p;
   19155             int ch;
   19156 
   19157             /* check if section name can be expressed in C */
   19158             p = s->name;
   19159             for(;;) {
   19160                 ch = *p;
   19161                 if (!ch)
   19162                     break;
   19163                 if (!isid(ch) && !isnum(ch))
   19164                     goto next_sec;
   19165                 p++;
   19166             }
   19167             snprintf(buf, sizeof(buf), "__start_%s", s->name);
   19168             add_elf_sym(symtab_section,
   19169                         0, 0,
   19170                         ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19171                         s->sh_num, buf);
   19172             snprintf(buf, sizeof(buf), "__stop_%s", s->name);
   19173             add_elf_sym(symtab_section,
   19174                         s->data_offset, 0,
   19175                         ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   19176                         s->sh_num, buf);
   19177         }
   19178     next_sec: ;
   19179     }
   19180 }
   19181 
   19182 /* name of ELF interpreter */
   19183 #ifdef __FreeBSD__
   19184 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
   19185 #else
   19186 static char elf_interp[] = "/lib/ld-linux.so.2";
   19187 #endif
   19188 
   19189 static void tcc_output_binary(TCCState *s1, FILE *f,
   19190                               const int *section_order)
   19191 {
   19192     Section *s;
   19193     int i, offset, size;
   19194 
   19195     offset = 0;
   19196     for(i=1;i<s1->nb_sections;i++) {
   19197         s = s1->sections[section_order[i]];
   19198         if (s->sh_type != SHT_NOBITS &&
   19199             (s->sh_flags & SHF_ALLOC)) {
   19200             while (offset < s->sh_offset) {
   19201                 fputc(0, f);
   19202                 offset++;
   19203             }
   19204             size = s->sh_size;
   19205             dummy_size_t = fwrite(s->data, 1, size, f);
   19206             offset += size;
   19207         }
   19208     }
   19209 }
   19210 
   19211 /* output an ELF file */
   19212 /* XXX: suppress unneeded sections */
   19213 int tcc_output_file(TCCState *s1, const char *filename)
   19214 {
   19215     Elf32_Ehdr ehdr;
   19216     FILE *f;
   19217     int fd, mode, ret;
   19218     int *section_order;
   19219     int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
   19220     unsigned long addr;
   19221     Section *strsec, *s;
   19222     Elf32_Shdr shdr, *sh;
   19223     Elf32_Phdr *phdr, *ph;
   19224     Section *interp, *dynamic, *dynstr;
   19225     unsigned long saved_dynamic_data_offset;
   19226     Elf32_Sym *sym;
   19227     int type, file_type;
   19228     unsigned long rel_addr, rel_size;
   19229 
   19230     file_type = s1->output_type;
   19231     s1->nb_errors = 0;
   19232 
   19233     if (file_type != TCC_OUTPUT_OBJ) {
   19234         tcc_add_runtime(s1);
   19235     }
   19236 
   19237     phdr = NULL;
   19238     section_order = NULL;
   19239     interp = NULL;
   19240     dynamic = NULL;
   19241     dynstr = NULL; /* avoid warning */
   19242     saved_dynamic_data_offset = 0; /* avoid warning */
   19243 
   19244     if (file_type != TCC_OUTPUT_OBJ) {
   19245         relocate_common_syms();
   19246 
   19247         tcc_add_linker_symbols(s1);
   19248 
   19249         if (!s1->static_link) {
   19250             const char *name;
   19251             int sym_index, index;
   19252             Elf32_Sym *esym, *sym_end;
   19253 
   19254             if (file_type == TCC_OUTPUT_EXE) {
   19255                 char *ptr;
   19256                 /* add interpreter section only if executable */
   19257                 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
   19258                 interp->sh_addralign = 1;
   19259                 ptr = section_ptr_add(interp, sizeof(elf_interp));
   19260                 strcpy(ptr, elf_interp);
   19261             }
   19262 
   19263             /* add dynamic symbol table */
   19264             s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
   19265                                     ".dynstr",
   19266                                     ".hash", SHF_ALLOC);
   19267             dynstr = s1->dynsym->link;
   19268 
   19269             /* add dynamic section */
   19270             dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
   19271                                   SHF_ALLOC | SHF_WRITE);
   19272             dynamic->link = dynstr;
   19273             dynamic->sh_entsize = sizeof(Elf32_Dyn);
   19274 
   19275             /* add PLT */
   19276             s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
   19277                                   SHF_ALLOC | SHF_EXECINSTR);
   19278             s1->plt->sh_entsize = 4;
   19279 
   19280             build_got(s1);
   19281 
   19282             /* scan for undefined symbols and see if they are in the
   19283                dynamic symbols. If a symbol STT_FUNC is found, then we
   19284                add it in the PLT. If a symbol STT_OBJECT is found, we
   19285                add it in the .bss section with a suitable relocation */
   19286             sym_end = (Elf32_Sym *)(symtab_section->data +
   19287                                     symtab_section->data_offset);
   19288             if (file_type == TCC_OUTPUT_EXE) {
   19289                 for(sym = (Elf32_Sym *)symtab_section->data + 1;
   19290                     sym < sym_end;
   19291                     sym++) {
   19292                     if (sym->st_shndx == SHN_UNDEF) {
   19293                         name = symtab_section->link->data + sym->st_name;
   19294                         sym_index = find_elf_sym(s1->dynsymtab_section, name);
   19295                         if (sym_index) {
   19296                             esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
   19297                             type = ELF32_ST_TYPE(esym->st_info);
   19298                             if (type == STT_FUNC) {
   19299                                 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
   19300                                               esym->st_info,
   19301                                               sym - (Elf32_Sym *)symtab_section->data);
   19302                             } else if (type == STT_OBJECT) {
   19303                                 unsigned long offset;
   19304                                 offset = bss_section->data_offset;
   19305                                 /* XXX: which alignment ? */
   19306                                 offset = (offset + 16 - 1) & -16;
   19307                                 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
   19308                                                     esym->st_info, 0,
   19309                                                     bss_section->sh_num, name);
   19310                                 put_elf_reloc(s1->dynsym, bss_section,
   19311                                               offset, R_COPY, index);
   19312                                 offset += esym->st_size;
   19313                                 bss_section->data_offset = offset;
   19314                             }
   19315                         } else {
   19316                                 /* STB_WEAK undefined symbols are accepted */
   19317                                 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
   19318                                    it */
   19319                             if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
   19320                                 !strcmp(name, "_fp_hw")) {
   19321                             } else {
   19322                                 error_noabort("undefined symbol '%s'", name);
   19323                             }
   19324                         }
   19325                     } else if (s1->rdynamic &&
   19326                                ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
   19327                         /* if -rdynamic option, then export all non
   19328                            local symbols */
   19329                         name = symtab_section->link->data + sym->st_name;
   19330                         put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
   19331                                     sym->st_info, 0,
   19332                                     sym->st_shndx, name);
   19333                     }
   19334                 }
   19335 
   19336                 if (s1->nb_errors)
   19337                     goto fail;
   19338 
   19339                 /* now look at unresolved dynamic symbols and export
   19340                    corresponding symbol */
   19341                 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
   19342                                         s1->dynsymtab_section->data_offset);
   19343                 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
   19344                     esym < sym_end;
   19345                     esym++) {
   19346                     if (esym->st_shndx == SHN_UNDEF) {
   19347                         name = s1->dynsymtab_section->link->data + esym->st_name;
   19348                         sym_index = find_elf_sym(symtab_section, name);
   19349                         if (sym_index) {
   19350                             /* XXX: avoid adding a symbol if already
   19351                                present because of -rdynamic ? */
   19352                             sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   19353                             put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
   19354                                         sym->st_info, 0,
   19355                                         sym->st_shndx, name);
   19356                         } else {
   19357                             if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
   19358                                 /* weak symbols can stay undefined */
   19359                             } else {
   19360                                 warning("undefined dynamic symbol '%s'", name);
   19361                             }
   19362                         }
   19363                     }
   19364                 }
   19365             } else {
   19366                 int nb_syms;
   19367                 /* shared library case : we simply export all the global symbols */
   19368                 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
   19369                 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
   19370                 for(sym = (Elf32_Sym *)symtab_section->data + 1;
   19371                     sym < sym_end;
   19372                     sym++) {
   19373                     if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
   19374                         name = symtab_section->link->data + sym->st_name;
   19375                         index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
   19376                                             sym->st_info, 0,
   19377                                             sym->st_shndx, name);
   19378                         s1->symtab_to_dynsym[sym -
   19379                                             (Elf32_Sym *)symtab_section->data] =
   19380                             index;
   19381                     }
   19382                 }
   19383             }
   19384 
   19385             build_got_entries(s1);
   19386 
   19387             /* add a list of needed dlls */
   19388             for(i = 0; i < s1->nb_loaded_dlls; i++) {
   19389                 DLLReference *dllref = s1->loaded_dlls[i];
   19390                 if (dllref->level == 0)
   19391                     put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
   19392             }
   19393             /* XXX: currently, since we do not handle PIC code, we
   19394                must relocate the readonly segments */
   19395             if (file_type == TCC_OUTPUT_DLL)
   19396                 put_dt(dynamic, DT_TEXTREL, 0);
   19397 
   19398             /* add necessary space for other entries */
   19399             saved_dynamic_data_offset = dynamic->data_offset;
   19400             dynamic->data_offset += 8 * 9;
   19401         } else {
   19402             /* still need to build got entries in case of static link */
   19403             build_got_entries(s1);
   19404         }
   19405     }
   19406 
   19407     memset(&ehdr, 0, sizeof(ehdr));
   19408 
   19409     /* we add a section for symbols */
   19410     strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
   19411     put_elf_str(strsec, "");
   19412 
   19413     /* compute number of sections */
   19414     shnum = s1->nb_sections;
   19415 
   19416     /* this array is used to reorder sections in the output file */
   19417     section_order = tcc_malloc(sizeof(int) * shnum);
   19418     section_order[0] = 0;
   19419     sh_order_index = 1;
   19420 
   19421     /* compute number of program headers */
   19422     switch(file_type) {
   19423     default:
   19424     case TCC_OUTPUT_OBJ:
   19425         phnum = 0;
   19426         break;
   19427     case TCC_OUTPUT_EXE:
   19428         if (!s1->static_link)
   19429             phnum = 4;
   19430         else
   19431             phnum = 2;
   19432         break;
   19433     case TCC_OUTPUT_DLL:
   19434         phnum = 3;
   19435         break;
   19436     }
   19437 
   19438     /* allocate strings for section names and decide if an unallocated
   19439        section should be output */
   19440     /* NOTE: the strsec section comes last, so its size is also
   19441        correct ! */
   19442     for(i = 1; i < s1->nb_sections; i++) {
   19443         s = s1->sections[i];
   19444         s->sh_name = put_elf_str(strsec, s->name);
   19445         /* when generating a DLL, we include relocations but we may
   19446            patch them */
   19447         if (file_type == TCC_OUTPUT_DLL &&
   19448             s->sh_type == SHT_REL &&
   19449             !(s->sh_flags & SHF_ALLOC)) {
   19450             prepare_dynamic_rel(s1, s);
   19451         } else if (do_debug ||
   19452             file_type == TCC_OUTPUT_OBJ ||
   19453             (s->sh_flags & SHF_ALLOC) ||
   19454             i == (s1->nb_sections - 1)) {
   19455             /* we output all sections if debug or object file */
   19456             s->sh_size = s->data_offset;
   19457         }
   19458     }
   19459 
   19460     /* allocate program segment headers */
   19461     phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
   19462 
   19463     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
   19464         file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
   19465     } else {
   19466         file_offset = 0;
   19467     }
   19468     if (phnum > 0) {
   19469         /* compute section to program header mapping */
   19470         if (s1->has_text_addr) {
   19471             int a_offset, p_offset;
   19472             addr = s1->text_addr;
   19473             /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
   19474                ELF_PAGE_SIZE */
   19475             a_offset = addr & (ELF_PAGE_SIZE - 1);
   19476             p_offset = file_offset & (ELF_PAGE_SIZE - 1);
   19477             if (a_offset < p_offset)
   19478                 a_offset += ELF_PAGE_SIZE;
   19479             file_offset += (a_offset - p_offset);
   19480         } else {
   19481             if (file_type == TCC_OUTPUT_DLL)
   19482                 addr = 0;
   19483             else
   19484                 addr = ELF_START_ADDR;
   19485             /* compute address after headers */
   19486             addr += (file_offset & (ELF_PAGE_SIZE - 1));
   19487         }
   19488 
   19489         /* dynamic relocation table information, for .dynamic section */
   19490         rel_size = 0;
   19491         rel_addr = 0;
   19492 
   19493         /* leave one program header for the program interpreter */
   19494         ph = &phdr[0];
   19495         if (interp)
   19496             ph++;
   19497 
   19498         for(j = 0; j < 2; j++) {
   19499             ph->p_type = PT_LOAD;
   19500             if (j == 0)
   19501                 ph->p_flags = PF_R | PF_X;
   19502             else
   19503                 ph->p_flags = PF_R | PF_W;
   19504             ph->p_align = ELF_PAGE_SIZE;
   19505 
   19506             /* we do the following ordering: interp, symbol tables,
   19507                relocations, progbits, nobits */
   19508             /* XXX: do faster and simpler sorting */
   19509             for(k = 0; k < 5; k++) {
   19510                 for(i = 1; i < s1->nb_sections; i++) {
   19511                     s = s1->sections[i];
   19512                     /* compute if section should be included */
   19513                     if (j == 0) {
   19514                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
   19515                             SHF_ALLOC)
   19516                             continue;
   19517                     } else {
   19518                         if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
   19519                             (SHF_ALLOC | SHF_WRITE))
   19520                             continue;
   19521                     }
   19522                     if (s == interp) {
   19523                         if (k != 0)
   19524                             continue;
   19525                     } else if (s->sh_type == SHT_DYNSYM ||
   19526                                s->sh_type == SHT_STRTAB ||
   19527                                s->sh_type == SHT_HASH) {
   19528                         if (k != 1)
   19529                             continue;
   19530                     } else if (s->sh_type == SHT_REL) {
   19531                         if (k != 2)
   19532                             continue;
   19533                     } else if (s->sh_type == SHT_NOBITS) {
   19534                         if (k != 4)
   19535                             continue;
   19536                     } else {
   19537                         if (k != 3)
   19538                             continue;
   19539                     }
   19540                     section_order[sh_order_index++] = i;
   19541 
   19542                     /* section matches: we align it and add its size */
   19543                     tmp = addr;
   19544                     addr = (addr + s->sh_addralign - 1) &
   19545                         ~(s->sh_addralign - 1);
   19546                     file_offset += addr - tmp;
   19547                     s->sh_offset = file_offset;
   19548                     s->sh_addr = addr;
   19549 
   19550                     /* update program header infos */
   19551                     if (ph->p_offset == 0) {
   19552                         ph->p_offset = file_offset;
   19553                         ph->p_vaddr = addr;
   19554                         ph->p_paddr = ph->p_vaddr;
   19555                     }
   19556                     /* update dynamic relocation infos */
   19557                     if (s->sh_type == SHT_REL) {
   19558                         if (rel_size == 0)
   19559                             rel_addr = addr;
   19560                         rel_size += s->sh_size;
   19561                     }
   19562                     addr += s->sh_size;
   19563                     if (s->sh_type != SHT_NOBITS)
   19564                         file_offset += s->sh_size;
   19565                 }
   19566             }
   19567             ph->p_filesz = file_offset - ph->p_offset;
   19568             ph->p_memsz = addr - ph->p_vaddr;
   19569             ph++;
   19570             if (j == 0) {
   19571                 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
   19572                     /* if in the middle of a page, we duplicate the page in
   19573                        memory so that one copy is RX and the other is RW */
   19574                     if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
   19575                         addr += ELF_PAGE_SIZE;
   19576                 } else {
   19577                     addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
   19578                     file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
   19579                         ~(ELF_PAGE_SIZE - 1);
   19580                 }
   19581             }
   19582         }
   19583 
   19584         /* if interpreter, then add corresponding program header */
   19585         if (interp) {
   19586             ph = &phdr[0];
   19587 
   19588             ph->p_type = PT_INTERP;
   19589             ph->p_offset = interp->sh_offset;
   19590             ph->p_vaddr = interp->sh_addr;
   19591             ph->p_paddr = ph->p_vaddr;
   19592             ph->p_filesz = interp->sh_size;
   19593             ph->p_memsz = interp->sh_size;
   19594             ph->p_flags = PF_R;
   19595             ph->p_align = interp->sh_addralign;
   19596         }
   19597 
   19598         /* if dynamic section, then add corresponding program header */
   19599         if (dynamic) {
   19600             Elf32_Sym *sym_end;
   19601 
   19602             ph = &phdr[phnum - 1];
   19603 
   19604             ph->p_type = PT_DYNAMIC;
   19605             ph->p_offset = dynamic->sh_offset;
   19606             ph->p_vaddr = dynamic->sh_addr;
   19607             ph->p_paddr = ph->p_vaddr;
   19608             ph->p_filesz = dynamic->sh_size;
   19609             ph->p_memsz = dynamic->sh_size;
   19610             ph->p_flags = PF_R | PF_W;
   19611             ph->p_align = dynamic->sh_addralign;
   19612 
   19613             /* put GOT dynamic section address */
   19614             put32(s1->got->data, dynamic->sh_addr);
   19615 
   19616             /* relocate the PLT */
   19617             if (file_type == TCC_OUTPUT_EXE) {
   19618                 uint8_t *p, *p_end;
   19619 
   19620                 p = s1->plt->data;
   19621                 p_end = p + s1->plt->data_offset;
   19622                 if (p < p_end) {
   19623 #if defined(TCC_TARGET_I386)
   19624                     put32(p + 2, get32(p + 2) + s1->got->sh_addr);
   19625                     put32(p + 8, get32(p + 8) + s1->got->sh_addr);
   19626                     p += 16;
   19627                     while (p < p_end) {
   19628                         put32(p + 2, get32(p + 2) + s1->got->sh_addr);
   19629                         p += 16;
   19630                     }
   19631 #elif defined(TCC_TARGET_ARM)
   19632 		    int x;
   19633 		    x=s1->got->sh_addr - s1->plt->sh_addr - 12;
   19634 		    p +=16;
   19635 		    while (p < p_end) {
   19636 		        put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
   19637 			p += 16;
   19638 		    }
   19639 #elif defined(TCC_TARGET_C67)
   19640                     /* XXX: TODO */
   19641 #else
   19642 #error unsupported CPU
   19643 #endif
   19644                 }
   19645             }
   19646 
   19647             /* relocate symbols in .dynsym */
   19648             sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
   19649             for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
   19650                 sym < sym_end;
   19651                 sym++) {
   19652                 if (sym->st_shndx == SHN_UNDEF) {
   19653                     /* relocate to the PLT if the symbol corresponds
   19654                        to a PLT entry */
   19655                     if (sym->st_value)
   19656                         sym->st_value += s1->plt->sh_addr;
   19657                 } else if (sym->st_shndx < SHN_LORESERVE) {
   19658                     /* do symbol relocation */
   19659                     sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
   19660                 }
   19661             }
   19662 
   19663             /* put dynamic section entries */
   19664             dynamic->data_offset = saved_dynamic_data_offset;
   19665             put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
   19666             put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
   19667             put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
   19668             put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
   19669             put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
   19670             put_dt(dynamic, DT_REL, rel_addr);
   19671             put_dt(dynamic, DT_RELSZ, rel_size);
   19672             put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
   19673             put_dt(dynamic, DT_NULL, 0);
   19674         }
   19675 
   19676         ehdr.e_phentsize = sizeof(Elf32_Phdr);
   19677         ehdr.e_phnum = phnum;
   19678         ehdr.e_phoff = sizeof(Elf32_Ehdr);
   19679     }
   19680 
   19681     /* all other sections come after */
   19682     for(i = 1; i < s1->nb_sections; i++) {
   19683         s = s1->sections[i];
   19684         if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
   19685             continue;
   19686         section_order[sh_order_index++] = i;
   19687 
   19688         file_offset = (file_offset + s->sh_addralign - 1) &
   19689             ~(s->sh_addralign - 1);
   19690         s->sh_offset = file_offset;
   19691         if (s->sh_type != SHT_NOBITS)
   19692             file_offset += s->sh_size;
   19693     }
   19694 
   19695     /* if building executable or DLL, then relocate each section
   19696        except the GOT which is already relocated */
   19697     if (file_type != TCC_OUTPUT_OBJ) {
   19698         relocate_syms(s1, 0);
   19699 
   19700         if (s1->nb_errors != 0) {
   19701         fail:
   19702             ret = -1;
   19703             goto the_end;
   19704         }
   19705 
   19706         /* relocate sections */
   19707         /* XXX: ignore sections with allocated relocations ? */
   19708         for(i = 1; i < s1->nb_sections; i++) {
   19709             s = s1->sections[i];
   19710             if (s->reloc && s != s1->got)
   19711                 relocate_section(s1, s);
   19712         }
   19713 
   19714         /* relocate relocation entries if the relocation tables are
   19715            allocated in the executable */
   19716         for(i = 1; i < s1->nb_sections; i++) {
   19717             s = s1->sections[i];
   19718             if ((s->sh_flags & SHF_ALLOC) &&
   19719                 s->sh_type == SHT_REL) {
   19720                 relocate_rel(s1, s);
   19721             }
   19722         }
   19723 
   19724         /* get entry point address */
   19725         if (file_type == TCC_OUTPUT_EXE)
   19726             ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
   19727         else
   19728             ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
   19729     }
   19730 
   19731     /* write elf file */
   19732     if (file_type == TCC_OUTPUT_OBJ)
   19733         mode = 0666;
   19734     else
   19735         mode = 0777;
   19736     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
   19737     if (fd < 0) {
   19738         error_noabort("could not write '%s'", filename);
   19739         goto fail;
   19740     }
   19741     f = fdopen(fd, "wb");
   19742 
   19743 #ifdef TCC_TARGET_COFF
   19744     if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
   19745         tcc_output_coff(s1, f);
   19746     } else
   19747 #endif
   19748     if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
   19749         sort_syms(s1, symtab_section);
   19750 
   19751         /* align to 4 */
   19752         file_offset = (file_offset + 3) & -4;
   19753 
   19754         /* fill header */
   19755         ehdr.e_ident[0] = ELFMAG0;
   19756         ehdr.e_ident[1] = ELFMAG1;
   19757         ehdr.e_ident[2] = ELFMAG2;
   19758         ehdr.e_ident[3] = ELFMAG3;
   19759         ehdr.e_ident[4] = ELFCLASS32;
   19760         ehdr.e_ident[5] = ELFDATA2LSB;
   19761         ehdr.e_ident[6] = EV_CURRENT;
   19762 #ifdef __FreeBSD__
   19763         ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
   19764 #endif
   19765 #ifdef TCC_TARGET_ARM
   19766         ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
   19767 #endif
   19768         switch(file_type) {
   19769         default:
   19770         case TCC_OUTPUT_EXE:
   19771             ehdr.e_type = ET_EXEC;
   19772             break;
   19773         case TCC_OUTPUT_DLL:
   19774             ehdr.e_type = ET_DYN;
   19775             break;
   19776         case TCC_OUTPUT_OBJ:
   19777             ehdr.e_type = ET_REL;
   19778             break;
   19779         }
   19780         ehdr.e_machine = EM_TCC_TARGET;
   19781         ehdr.e_version = EV_CURRENT;
   19782         ehdr.e_shoff = file_offset;
   19783         ehdr.e_ehsize = sizeof(Elf32_Ehdr);
   19784         ehdr.e_shentsize = sizeof(Elf32_Shdr);
   19785         ehdr.e_shnum = shnum;
   19786         ehdr.e_shstrndx = shnum - 1;
   19787 
   19788         dummy_size_t = fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
   19789         dummy_size_t = fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
   19790         offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
   19791 
   19792         for(i=1;i<s1->nb_sections;i++) {
   19793             s = s1->sections[section_order[i]];
   19794             if (s->sh_type != SHT_NOBITS) {
   19795                 while (offset < s->sh_offset) {
   19796                     fputc(0, f);
   19797                     offset++;
   19798                 }
   19799                 size = s->sh_size;
   19800                 dummy_size_t = fwrite(s->data, 1, size, f);
   19801                 offset += size;
   19802             }
   19803         }
   19804 
   19805         /* output section headers */
   19806         while (offset < ehdr.e_shoff) {
   19807             fputc(0, f);
   19808             offset++;
   19809         }
   19810 
   19811         for(i=0;i<s1->nb_sections;i++) {
   19812             sh = &shdr;
   19813             memset(sh, 0, sizeof(Elf32_Shdr));
   19814             s = s1->sections[i];
   19815             if (s) {
   19816                 sh->sh_name = s->sh_name;
   19817                 sh->sh_type = s->sh_type;
   19818                 sh->sh_flags = s->sh_flags;
   19819                 sh->sh_entsize = s->sh_entsize;
   19820                 sh->sh_info = s->sh_info;
   19821                 if (s->link)
   19822                     sh->sh_link = s->link->sh_num;
   19823                 sh->sh_addralign = s->sh_addralign;
   19824                 sh->sh_addr = s->sh_addr;
   19825                 sh->sh_offset = s->sh_offset;
   19826                 sh->sh_size = s->sh_size;
   19827             }
   19828             dummy_size_t = fwrite(sh, 1, sizeof(Elf32_Shdr), f);
   19829         }
   19830     } else {
   19831         tcc_output_binary(s1, f, section_order);
   19832     }
   19833     fclose(f);
   19834 
   19835     ret = 0;
   19836  the_end:
   19837     tcc_free(s1->symtab_to_dynsym);
   19838     tcc_free(section_order);
   19839     tcc_free(phdr);
   19840     tcc_free(s1->got_offsets);
   19841     return ret;
   19842 }
   19843 
   19844 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
   19845 {
   19846     void *data;
   19847 
   19848     data = tcc_malloc(size);
   19849     lseek(fd, file_offset, SEEK_SET);
   19850     dummy_size_t = read(fd, data, size);
   19851     return data;
   19852 }
   19853 
   19854 typedef struct SectionMergeInfo {
   19855     Section *s;            /* corresponding existing section */
   19856     unsigned long offset;  /* offset of the new section in the existing section */
   19857     uint8_t new_section;       /* true if section 's' was added */
   19858     uint8_t link_once;         /* true if link once section */
   19859 } SectionMergeInfo;
   19860 
   19861 /* load an object file and merge it with current files */
   19862 /* XXX: handle correctly stab (debug) info */
   19863 static int tcc_load_object_file(TCCState *s1,
   19864                                 int fd, unsigned long file_offset)
   19865 {
   19866     Elf32_Ehdr ehdr;
   19867     Elf32_Shdr *shdr, *sh;
   19868     int size, i, j, offset, offseti, nb_syms, sym_index, ret;
   19869     unsigned char *strsec, *strtab;
   19870     int *old_to_new_syms;
   19871     char *sh_name, *name;
   19872     SectionMergeInfo *sm_table, *sm;
   19873     Elf32_Sym *sym, *symtab;
   19874     Elf32_Rel *rel, *rel_end;
   19875     Section *s;
   19876 
   19877     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
   19878         goto fail1;
   19879     if (ehdr.e_ident[0] != ELFMAG0 ||
   19880         ehdr.e_ident[1] != ELFMAG1 ||
   19881         ehdr.e_ident[2] != ELFMAG2 ||
   19882         ehdr.e_ident[3] != ELFMAG3)
   19883         goto fail1;
   19884     /* test if object file */
   19885     if (ehdr.e_type != ET_REL)
   19886         goto fail1;
   19887     /* test CPU specific stuff */
   19888     if (ehdr.e_ident[5] != ELFDATA2LSB ||
   19889         ehdr.e_machine != EM_TCC_TARGET) {
   19890     fail1:
   19891         error_noabort("invalid object file");
   19892         return -1;
   19893     }
   19894     /* read sections */
   19895     shdr = load_data(fd, file_offset + ehdr.e_shoff,
   19896                      sizeof(Elf32_Shdr) * ehdr.e_shnum);
   19897     sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
   19898 
   19899     /* load section names */
   19900     sh = &shdr[ehdr.e_shstrndx];
   19901     strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
   19902 
   19903     /* load symtab and strtab */
   19904     old_to_new_syms = NULL;
   19905     symtab = NULL;
   19906     strtab = NULL;
   19907     nb_syms = 0;
   19908     for(i = 1; i < ehdr.e_shnum; i++) {
   19909         sh = &shdr[i];
   19910         if (sh->sh_type == SHT_SYMTAB) {
   19911             if (symtab) {
   19912                 error_noabort("object must contain only one symtab");
   19913             fail:
   19914                 ret = -1;
   19915                 goto the_end;
   19916             }
   19917             nb_syms = sh->sh_size / sizeof(Elf32_Sym);
   19918             symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
   19919             sm_table[i].s = symtab_section;
   19920 
   19921             /* now load strtab */
   19922             sh = &shdr[sh->sh_link];
   19923             strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
   19924         }
   19925     }
   19926 
   19927     /* now examine each section and try to merge its content with the
   19928        ones in memory */
   19929     for(i = 1; i < ehdr.e_shnum; i++) {
   19930         /* no need to examine section name strtab */
   19931         if (i == ehdr.e_shstrndx)
   19932             continue;
   19933         sh = &shdr[i];
   19934         sh_name = strsec + sh->sh_name;
   19935         /* ignore sections types we do not handle */
   19936         if (sh->sh_type != SHT_PROGBITS &&
   19937             sh->sh_type != SHT_REL &&
   19938             sh->sh_type != SHT_NOBITS)
   19939             continue;
   19940         if (sh->sh_addralign < 1)
   19941             sh->sh_addralign = 1;
   19942         /* find corresponding section, if any */
   19943         for(j = 1; j < s1->nb_sections;j++) {
   19944             s = s1->sections[j];
   19945             if (!strcmp(s->name, sh_name)) {
   19946                 if (!strncmp(sh_name, ".gnu.linkonce",
   19947                              sizeof(".gnu.linkonce") - 1)) {
   19948                     /* if a 'linkonce' section is already present, we
   19949                        do not add it again. It is a little tricky as
   19950                        symbols can still be defined in
   19951                        it. */
   19952                     sm_table[i].link_once = 1;
   19953                     goto next;
   19954                 } else {
   19955                     goto found;
   19956                 }
   19957             }
   19958         }
   19959         /* not found: create new section */
   19960         s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
   19961         /* take as much info as possible from the section. sh_link and
   19962            sh_info will be updated later */
   19963         s->sh_addralign = sh->sh_addralign;
   19964         s->sh_entsize = sh->sh_entsize;
   19965         sm_table[i].new_section = 1;
   19966     found:
   19967         if (sh->sh_type != s->sh_type) {
   19968             error_noabort("invalid section type");
   19969             goto fail;
   19970         }
   19971 
   19972         /* align start of section */
   19973         offset = s->data_offset;
   19974         size = sh->sh_addralign - 1;
   19975         offset = (offset + size) & ~size;
   19976         if (sh->sh_addralign > s->sh_addralign)
   19977             s->sh_addralign = sh->sh_addralign;
   19978         s->data_offset = offset;
   19979         sm_table[i].offset = offset;
   19980         sm_table[i].s = s;
   19981         /* concatenate sections */
   19982         size = sh->sh_size;
   19983         if (sh->sh_type != SHT_NOBITS) {
   19984             unsigned char *ptr;
   19985             lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
   19986             ptr = section_ptr_add(s, size);
   19987             dummy_size_t = read(fd, ptr, size);
   19988         } else {
   19989             s->data_offset += size;
   19990         }
   19991     next: ;
   19992     }
   19993 
   19994     /* second short pass to update sh_link and sh_info fields of new
   19995        sections */
   19996     sm = sm_table;
   19997     for(i = 1; i < ehdr.e_shnum; i++) {
   19998         s = sm_table[i].s;
   19999         if (!s || !sm_table[i].new_section)
   20000             continue;
   20001         sh = &shdr[i];
   20002         if (sh->sh_link > 0)
   20003             s->link = sm_table[sh->sh_link].s;
   20004         if (sh->sh_type == SHT_REL) {
   20005             s->sh_info = sm_table[sh->sh_info].s->sh_num;
   20006             /* update backward link */
   20007             s1->sections[s->sh_info]->reloc = s;
   20008         }
   20009     }
   20010 
   20011     /* resolve symbols */
   20012     old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
   20013 
   20014     sym = symtab + 1;
   20015     for(i = 1; i < nb_syms; i++, sym++) {
   20016         if (sym->st_shndx != SHN_UNDEF &&
   20017             sym->st_shndx < SHN_LORESERVE) {
   20018             sm = &sm_table[sym->st_shndx];
   20019             if (sm->link_once) {
   20020                 /* if a symbol is in a link once section, we use the
   20021                    already defined symbol. It is very important to get
   20022                    correct relocations */
   20023                 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
   20024                     name = strtab + sym->st_name;
   20025                     sym_index = find_elf_sym(symtab_section, name);
   20026                     if (sym_index)
   20027                         old_to_new_syms[i] = sym_index;
   20028                 }
   20029                 continue;
   20030             }
   20031             /* if no corresponding section added, no need to add symbol */
   20032             if (!sm->s)
   20033                 continue;
   20034             /* convert section number */
   20035             sym->st_shndx = sm->s->sh_num;
   20036             /* offset value */
   20037             sym->st_value += sm->offset;
   20038         }
   20039         /* add symbol */
   20040         name = strtab + sym->st_name;
   20041         sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
   20042                                 sym->st_info, sym->st_other,
   20043                                 sym->st_shndx, name);
   20044         old_to_new_syms[i] = sym_index;
   20045     }
   20046 
   20047     /* third pass to patch relocation entries */
   20048     for(i = 1; i < ehdr.e_shnum; i++) {
   20049         s = sm_table[i].s;
   20050         if (!s)
   20051             continue;
   20052         sh = &shdr[i];
   20053         offset = sm_table[i].offset;
   20054         switch(s->sh_type) {
   20055         case SHT_REL:
   20056             /* take relocation offset information */
   20057             offseti = sm_table[sh->sh_info].offset;
   20058             rel_end = (Elf32_Rel *)(s->data + s->data_offset);
   20059             for(rel = (Elf32_Rel *)(s->data + offset);
   20060                 rel < rel_end;
   20061                 rel++) {
   20062                 int type;
   20063                 unsigned sym_index;
   20064                 /* convert symbol index */
   20065                 type = ELF32_R_TYPE(rel->r_info);
   20066                 sym_index = ELF32_R_SYM(rel->r_info);
   20067                 /* NOTE: only one symtab assumed */
   20068                 if (sym_index >= nb_syms)
   20069                     goto invalid_reloc;
   20070                 sym_index = old_to_new_syms[sym_index];
   20071                 if (!sym_index) {
   20072                 invalid_reloc:
   20073                     error_noabort("Invalid relocation entry");
   20074                     goto fail;
   20075                 }
   20076                 rel->r_info = ELF32_R_INFO(sym_index, type);
   20077                 /* offset the relocation offset */
   20078                 rel->r_offset += offseti;
   20079             }
   20080             break;
   20081         default:
   20082             break;
   20083         }
   20084     }
   20085 
   20086     ret = 0;
   20087  the_end:
   20088     tcc_free(symtab);
   20089     tcc_free(strtab);
   20090     tcc_free(old_to_new_syms);
   20091     tcc_free(sm_table);
   20092     tcc_free(strsec);
   20093     tcc_free(shdr);
   20094     return ret;
   20095 }
   20096 
   20097 #define ARMAG  "!<arch>\012"	/* For COFF and a.out archives */
   20098 
   20099 typedef struct ArchiveHeader {
   20100     char ar_name[16];		/* name of this member */
   20101     char ar_date[12];		/* file mtime */
   20102     char ar_uid[6];		/* owner uid; printed as decimal */
   20103     char ar_gid[6];		/* owner gid; printed as decimal */
   20104     char ar_mode[8];		/* file mode, printed as octal   */
   20105     char ar_size[10];		/* file size, printed as decimal */
   20106     char ar_fmag[2];		/* should contain ARFMAG */
   20107 } ArchiveHeader;
   20108 
   20109 static int get_be32(const uint8_t *b)
   20110 {
   20111     return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
   20112 }
   20113 
   20114 /* load only the objects which resolve undefined symbols */
   20115 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
   20116 {
   20117     int i, bound, nsyms, sym_index, off, ret;
   20118     uint8_t *data;
   20119     const char *ar_names, *p;
   20120     const uint8_t *ar_index;
   20121     Elf32_Sym *sym;
   20122 
   20123     data = tcc_malloc(size);
   20124     if (read(fd, data, size) != size)
   20125         goto fail;
   20126     nsyms = get_be32(data);
   20127     ar_index = data + 4;
   20128     ar_names = ar_index + nsyms * 4;
   20129 
   20130     do {
   20131 	bound = 0;
   20132 	for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
   20133 	    sym_index = find_elf_sym(symtab_section, p);
   20134 	    if(sym_index) {
   20135 		sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
   20136 		if(sym->st_shndx == SHN_UNDEF) {
   20137 		    off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
   20138 #if 0
   20139 		    printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
   20140 #endif
   20141 		    ++bound;
   20142 		    lseek(fd, off, SEEK_SET);
   20143 		    if(tcc_load_object_file(s1, fd, off) < 0) {
   20144                     fail:
   20145                         ret = -1;
   20146                         goto the_end;
   20147                     }
   20148 		}
   20149 	    }
   20150 	}
   20151     } while(bound);
   20152     ret = 0;
   20153  the_end:
   20154     tcc_free(data);
   20155     return ret;
   20156 }
   20157 
   20158 /* load a '.a' file */
   20159 static int tcc_load_archive(TCCState *s1, int fd)
   20160 {
   20161     ArchiveHeader hdr;
   20162     char ar_size[11];
   20163     char ar_name[17];
   20164     char magic[8];
   20165     int size, len, i;
   20166     unsigned long file_offset;
   20167 
   20168     /* skip magic which was already checked */
   20169     dummy_size_t = read(fd, magic, sizeof(magic));
   20170 
   20171     for(;;) {
   20172         len = read(fd, &hdr, sizeof(hdr));
   20173         if (len == 0)
   20174             break;
   20175         if (len != sizeof(hdr)) {
   20176             error_noabort("invalid archive");
   20177             return -1;
   20178         }
   20179         memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
   20180         ar_size[sizeof(hdr.ar_size)] = '\0';
   20181         size = strtol(ar_size, NULL, 0);
   20182         memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
   20183         for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
   20184             if (ar_name[i] != ' ')
   20185                 break;
   20186         }
   20187         ar_name[i + 1] = '\0';
   20188         //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
   20189         file_offset = lseek(fd, 0, SEEK_CUR);
   20190         /* align to even */
   20191         size = (size + 1) & ~1;
   20192         if (!strcmp(ar_name, "/")) {
   20193             /* coff symbol table : we handle it */
   20194 	    if(s1->alacarte_link)
   20195 		return tcc_load_alacarte(s1, fd, size);
   20196         } else if (!strcmp(ar_name, "//") ||
   20197                    !strcmp(ar_name, "__.SYMDEF") ||
   20198                    !strcmp(ar_name, "__.SYMDEF/") ||
   20199                    !strcmp(ar_name, "ARFILENAMES/")) {
   20200             /* skip symbol table or archive names */
   20201         } else {
   20202             if (tcc_load_object_file(s1, fd, file_offset) < 0)
   20203                 return -1;
   20204         }
   20205         lseek(fd, file_offset + size, SEEK_SET);
   20206     }
   20207     return 0;
   20208 }
   20209 
   20210 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
   20211    is referenced by the user (so it should be added as DT_NEEDED in
   20212    the generated ELF file) */
   20213 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
   20214 {
   20215     Elf32_Ehdr ehdr;
   20216     Elf32_Shdr *shdr, *sh, *sh1;
   20217     int i, nb_syms, nb_dts, sym_bind, ret;
   20218     Elf32_Sym *sym, *dynsym;
   20219     Elf32_Dyn *dt, *dynamic;
   20220     unsigned char *dynstr;
   20221     const char *name, *soname, *p;
   20222     DLLReference *dllref;
   20223 
   20224     dummy_size_t = read(fd, &ehdr, sizeof(ehdr));
   20225 
   20226     /* test CPU specific stuff */
   20227     if (ehdr.e_ident[5] != ELFDATA2LSB ||
   20228         ehdr.e_machine != EM_TCC_TARGET) {
   20229         error_noabort("bad architecture");
   20230         return -1;
   20231     }
   20232 
   20233     /* read sections */
   20234     shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
   20235 
   20236     /* load dynamic section and dynamic symbols */
   20237     nb_syms = 0;
   20238     nb_dts = 0;
   20239     dynamic = NULL;
   20240     dynsym = NULL; /* avoid warning */
   20241     dynstr = NULL; /* avoid warning */
   20242     for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
   20243         switch(sh->sh_type) {
   20244         case SHT_DYNAMIC:
   20245             nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
   20246             dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
   20247             break;
   20248         case SHT_DYNSYM:
   20249             nb_syms = sh->sh_size / sizeof(Elf32_Sym);
   20250             dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
   20251             sh1 = &shdr[sh->sh_link];
   20252             dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
   20253             break;
   20254         default:
   20255             break;
   20256         }
   20257     }
   20258 
   20259     /* compute the real library name */
   20260     soname = filename;
   20261     p = strrchr(soname, '/');
   20262     if (p)
   20263         soname = p + 1;
   20264 
   20265     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
   20266         if (dt->d_tag == DT_SONAME) {
   20267             soname = dynstr + dt->d_un.d_val;
   20268         }
   20269     }
   20270 
   20271     /* if the dll is already loaded, do not load it */
   20272     for(i = 0; i < s1->nb_loaded_dlls; i++) {
   20273         dllref = s1->loaded_dlls[i];
   20274         if (!strcmp(soname, dllref->name)) {
   20275             /* but update level if needed */
   20276             if (level < dllref->level)
   20277                 dllref->level = level;
   20278             ret = 0;
   20279             goto the_end;
   20280         }
   20281     }
   20282 
   20283     //    printf("loading dll '%s'\n", soname);
   20284 
   20285     /* add the dll and its level */
   20286     dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
   20287     dllref->level = level;
   20288     strcpy(dllref->name, soname);
   20289     dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
   20290 
   20291     /* add dynamic symbols in dynsym_section */
   20292     for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
   20293         sym_bind = ELF32_ST_BIND(sym->st_info);
   20294         if (sym_bind == STB_LOCAL)
   20295             continue;
   20296         name = dynstr + sym->st_name;
   20297         add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
   20298                     sym->st_info, sym->st_other, sym->st_shndx, name);
   20299     }
   20300 
   20301     /* load all referenced DLLs */
   20302     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
   20303         switch(dt->d_tag) {
   20304         case DT_NEEDED:
   20305             name = dynstr + dt->d_un.d_val;
   20306             for(i = 0; i < s1->nb_loaded_dlls; i++) {
   20307                 dllref = s1->loaded_dlls[i];
   20308                 if (!strcmp(name, dllref->name))
   20309                     goto already_loaded;
   20310             }
   20311             if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
   20312                 error_noabort("referenced dll '%s' not found", name);
   20313                 ret = -1;
   20314                 goto the_end;
   20315             }
   20316         already_loaded:
   20317             break;
   20318         }
   20319     }
   20320     ret = 0;
   20321  the_end:
   20322     tcc_free(dynstr);
   20323     tcc_free(dynsym);
   20324     tcc_free(dynamic);
   20325     tcc_free(shdr);
   20326     return ret;
   20327 }
   20328 
   20329 #define LD_TOK_NAME 256
   20330 #define LD_TOK_EOF  (-1)
   20331 
   20332 /* return next ld script token */
   20333 static int ld_next(TCCState *s1, char *name, int name_size)
   20334 {
   20335     int c;
   20336     char *q;
   20337 
   20338  redo:
   20339     switch(ch) {
   20340     case ' ':
   20341     case '\t':
   20342     case '\f':
   20343     case '\v':
   20344     case '\r':
   20345     case '\n':
   20346         inp();
   20347         goto redo;
   20348     case '/':
   20349         minp();
   20350         if (ch == '*') {
   20351             file->buf_ptr = parse_comment(file->buf_ptr);
   20352             ch = file->buf_ptr[0];
   20353             goto redo;
   20354         } else {
   20355             q = name;
   20356             *q++ = '/';
   20357             goto parse_name;
   20358         }
   20359         break;
   20360     case 'a' ... 'z':
   20361     case 'A' ... 'Z':
   20362     case '_':
   20363     case '\\':
   20364     case '.':
   20365     case '$':
   20366     case '~':
   20367         q = name;
   20368     parse_name:
   20369         for(;;) {
   20370             if (!((ch >= 'a' && ch <= 'z') ||
   20371                   (ch >= 'A' && ch <= 'Z') ||
   20372                   (ch >= '0' && ch <= '9') ||
   20373                   strchr("/.-_+=$:\\,~", ch)))
   20374                 break;
   20375             if ((q - name) < name_size - 1) {
   20376                 *q++ = ch;
   20377             }
   20378             minp();
   20379         }
   20380         *q = '\0';
   20381         c = LD_TOK_NAME;
   20382         break;
   20383     case CH_EOF:
   20384         c = LD_TOK_EOF;
   20385         break;
   20386     default:
   20387         c = ch;
   20388         inp();
   20389         break;
   20390     }
   20391 #if 0
   20392     printf("tok=%c %d\n", c, c);
   20393     if (c == LD_TOK_NAME)
   20394         printf("  name=%s\n", name);
   20395 #endif
   20396     return c;
   20397 }
   20398 
   20399 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
   20400    files */
   20401 static int tcc_load_ldscript(TCCState *s1)
   20402 {
   20403     char cmd[64];
   20404     char filename[1024];
   20405     int t;
   20406 
   20407     ch = file->buf_ptr[0];
   20408     ch = handle_eob();
   20409     for(;;) {
   20410         t = ld_next(s1, cmd, sizeof(cmd));
   20411         if (t == LD_TOK_EOF)
   20412             return 0;
   20413         else if (t != LD_TOK_NAME)
   20414             return -1;
   20415         if (!strcmp(cmd, "INPUT") ||
   20416             !strcmp(cmd, "GROUP")) {
   20417             t = ld_next(s1, cmd, sizeof(cmd));
   20418             if (t != '(')
   20419                 expect("(");
   20420             t = ld_next(s1, filename, sizeof(filename));
   20421             for(;;) {
   20422                 if (t == LD_TOK_EOF) {
   20423                     error_noabort("unexpected end of file");
   20424                     return -1;
   20425                 } else if (t == ')') {
   20426                     break;
   20427                 } else if (t != LD_TOK_NAME) {
   20428                     error_noabort("filename expected");
   20429                     return -1;
   20430                 }
   20431                 tcc_add_file(s1, filename);
   20432                 t = ld_next(s1, filename, sizeof(filename));
   20433                 if (t == ',') {
   20434                     t = ld_next(s1, filename, sizeof(filename));
   20435                 }
   20436             }
   20437         } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
   20438                    !strcmp(cmd, "TARGET")) {
   20439             /* ignore some commands */
   20440             t = ld_next(s1, cmd, sizeof(cmd));
   20441             if (t != '(')
   20442                 expect("(");
   20443             for(;;) {
   20444                 t = ld_next(s1, filename, sizeof(filename));
   20445                 if (t == LD_TOK_EOF) {
   20446                     error_noabort("unexpected end of file");
   20447                     return -1;
   20448                 } else if (t == ')') {
   20449                     break;
   20450                 }
   20451             }
   20452         } else {
   20453             return -1;
   20454         }
   20455     }
   20456     return 0;
   20457 }
   20458 //---------------------------------------------------------------------------
   20459 
   20460 #ifdef TCC_TARGET_COFF
   20461 #include "tcccoff.c"
   20462 #endif
   20463 
   20464 #ifdef TCC_TARGET_PE
   20465 #include "tccpe.c"
   20466 #endif
   20467 
   20468 /* print the position in the source file of PC value 'pc' by reading
   20469    the stabs debug information */
   20470 static void rt_printline(unsigned long wanted_pc)
   20471 {
   20472     Stab_Sym *sym, *sym_end;
   20473     char func_name[128], last_func_name[128];
   20474     unsigned long func_addr, last_pc, pc;
   20475     const char *incl_files[INCLUDE_STACK_SIZE];
   20476     int incl_index, len, last_line_num, i;
   20477     const char *str, *p;
   20478 
   20479     fprintf(stderr, "0x%08lx:", wanted_pc);
   20480 
   20481     func_name[0] = '\0';
   20482     func_addr = 0;
   20483     incl_index = 0;
   20484     last_func_name[0] = '\0';
   20485     last_pc = 0xffffffff;
   20486     last_line_num = 1;
   20487     sym = (Stab_Sym *)stab_section->data + 1;
   20488     sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
   20489     while (sym < sym_end) {
   20490         switch(sym->n_type) {
   20491             /* function start or end */
   20492         case N_FUN:
   20493             if (sym->n_strx == 0) {
   20494                 /* we test if between last line and end of function */
   20495                 pc = sym->n_value + func_addr;
   20496                 if (wanted_pc >= last_pc && wanted_pc < pc)
   20497                     goto found;
   20498                 func_name[0] = '\0';
   20499                 func_addr = 0;
   20500             } else {
   20501                 str = stabstr_section->data + sym->n_strx;
   20502                 p = strchr(str, ':');
   20503                 if (!p) {
   20504                     pstrcpy(func_name, sizeof(func_name), str);
   20505                 } else {
   20506                     len = p - str;
   20507                     if (len > sizeof(func_name) - 1)
   20508                         len = sizeof(func_name) - 1;
   20509                     memcpy(func_name, str, len);
   20510                     func_name[len] = '\0';
   20511                 }
   20512                 func_addr = sym->n_value;
   20513             }
   20514             break;
   20515             /* line number info */
   20516         case N_SLINE:
   20517             pc = sym->n_value + func_addr;
   20518             if (wanted_pc >= last_pc && wanted_pc < pc)
   20519                 goto found;
   20520             last_pc = pc;
   20521             last_line_num = sym->n_desc;
   20522             /* XXX: slow! */
   20523             strcpy(last_func_name, func_name);
   20524             break;
   20525             /* include files */
   20526         case N_BINCL:
   20527             str = stabstr_section->data + sym->n_strx;
   20528         add_incl:
   20529             if (incl_index < INCLUDE_STACK_SIZE) {
   20530                 incl_files[incl_index++] = str;
   20531             }
   20532             break;
   20533         case N_EINCL:
   20534             if (incl_index > 1)
   20535                 incl_index--;
   20536             break;
   20537         case N_SO:
   20538             if (sym->n_strx == 0) {
   20539                 incl_index = 0; /* end of translation unit */
   20540             } else {
   20541                 str = stabstr_section->data + sym->n_strx;
   20542                 /* do not add path */
   20543                 len = strlen(str);
   20544                 if (len > 0 && str[len - 1] != '/')
   20545                     goto add_incl;
   20546             }
   20547             break;
   20548         }
   20549         sym++;
   20550     }
   20551 
   20552     /* second pass: we try symtab symbols (no line number info) */
   20553     incl_index = 0;
   20554     {
   20555         Elf32_Sym *sym, *sym_end;
   20556         int type;
   20557 
   20558         sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
   20559         for(sym = (Elf32_Sym *)symtab_section->data + 1;
   20560             sym < sym_end;
   20561             sym++) {
   20562             type = ELF32_ST_TYPE(sym->st_info);
   20563             if (type == STT_FUNC) {
   20564                 if (wanted_pc >= sym->st_value &&
   20565                     wanted_pc < sym->st_value + sym->st_size) {
   20566                     pstrcpy(last_func_name, sizeof(last_func_name),
   20567                             strtab_section->data + sym->st_name);
   20568                     goto found;
   20569                 }
   20570             }
   20571         }
   20572     }
   20573     /* did not find any info: */
   20574     fprintf(stderr, " ???\n");
   20575     return;
   20576  found:
   20577     if (last_func_name[0] != '\0') {
   20578         fprintf(stderr, " %s()", last_func_name);
   20579     }
   20580     if (incl_index > 0) {
   20581         fprintf(stderr, " (%s:%d",
   20582                 incl_files[incl_index - 1], last_line_num);
   20583         for(i = incl_index - 2; i >= 0; i--)
   20584             fprintf(stderr, ", included from %s", incl_files[i]);
   20585         fprintf(stderr, ")");
   20586     }
   20587     fprintf(stderr, "\n");
   20588 }
   20589 
   20590 #if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
   20591 
   20592 /* return the PC at frame level 'level'. Return non zero if not found */
   20593 static int rt_get_caller_pc(unsigned long *paddr,
   20594                             ucontext_t *uc, int level)
   20595 {
   20596     unsigned long fp __attribute__((unused));
   20597     //int i;
   20598 
   20599     if (level == 0) {
   20600         *paddr = 12345; //uc->uc_mcontext.gregs[REG_EIP];
   20601         return 0;
   20602     } else {
   20603         fp = 23456; //uc->uc_mcontext.gregs[REG_EBP];
   20604         return 0;
   20605     }
   20606 }
   20607 
   20608 /* emit a run time error at position 'pc' */
   20609 void rt_error(ucontext_t *uc, const char *fmt, ...)
   20610 {
   20611     va_list ap;
   20612     unsigned long pc = 0;  // shut gcc up
   20613     int i;
   20614 
   20615     va_start(ap, fmt);
   20616     fprintf(stderr, "Runtime error: ");
   20617     vfprintf(stderr, fmt, ap);
   20618     fprintf(stderr, "\n");
   20619     for(i=0;i<num_callers;i++) {
   20620         if (rt_get_caller_pc(&pc, uc, i) < 0)
   20621             break;
   20622         if (i == 0)
   20623             fprintf(stderr, "at ");
   20624         else
   20625             fprintf(stderr, "by ");
   20626         rt_printline(pc);
   20627     }
   20628     exit(255);
   20629     va_end(ap);
   20630 }
   20631 
   20632 /* signal handler for fatal errors */
   20633 static void sig_error(int signum, siginfo_t *siginf, void *puc)
   20634 {
   20635     ucontext_t *uc = puc;
   20636 
   20637     switch(signum) {
   20638     case SIGFPE:
   20639         switch(siginf->si_code) {
   20640         case FPE_INTDIV:
   20641         case FPE_FLTDIV:
   20642             rt_error(uc, "division by zero");
   20643             break;
   20644         default:
   20645             rt_error(uc, "floating point exception");
   20646             break;
   20647         }
   20648         break;
   20649     case SIGBUS:
   20650     case SIGSEGV:
   20651         if (rt_bound_error_msg && *rt_bound_error_msg)
   20652             rt_error(uc, *rt_bound_error_msg);
   20653         else
   20654             rt_error(uc, "dereferencing invalid pointer");
   20655         break;
   20656     case SIGILL:
   20657         rt_error(uc, "illegal instruction");
   20658         break;
   20659     case SIGABRT:
   20660         rt_error(uc, "abort() called");
   20661         break;
   20662     default:
   20663         rt_error(uc, "caught signal %d", signum);
   20664         break;
   20665     }
   20666     exit(255);
   20667 }
   20668 #endif
   20669 
   20670 /* do all relocations (needed before using tcc_get_symbol()) */
   20671 int tcc_relocate(TCCState *s1)
   20672 {
   20673     Section *s;
   20674     int i;
   20675 
   20676     s1->nb_errors = 0;
   20677 
   20678 #ifdef TCC_TARGET_PE
   20679     pe_add_runtime(s1);
   20680 #else
   20681     tcc_add_runtime(s1);
   20682 #endif
   20683 
   20684     relocate_common_syms();
   20685 
   20686     tcc_add_linker_symbols(s1);
   20687 
   20688     build_got_entries(s1);
   20689 
   20690     /* compute relocation address : section are relocated in place. We
   20691        also alloc the bss space */
   20692     for(i = 1; i < s1->nb_sections; i++) {
   20693         s = s1->sections[i];
   20694         if (s->sh_flags & SHF_ALLOC) {
   20695             if (s->sh_type == SHT_NOBITS)
   20696                 s->data = tcc_mallocz(s->data_offset);
   20697             s->sh_addr = (unsigned long)s->data;
   20698         }
   20699     }
   20700 
   20701     relocate_syms(s1, 1);
   20702 
   20703     if (s1->nb_errors != 0)
   20704         return -1;
   20705 
   20706     /* relocate each section */
   20707     for(i = 1; i < s1->nb_sections; i++) {
   20708         s = s1->sections[i];
   20709         if (s->reloc)
   20710             relocate_section(s1, s);
   20711     }
   20712     return 0;
   20713 }
   20714 
   20715 /* launch the compiled program with the given arguments */
   20716 int tcc_run(TCCState *s1, int argc, char **argv)
   20717 {
   20718     int (*prog_main)(int, char **);
   20719 
   20720     if (tcc_relocate(s1) < 0)
   20721         return -1;
   20722 
   20723     prog_main = tcc_get_symbol_err(s1, "main");
   20724 
   20725     if (do_debug) {
   20726 #if defined(WIN32) || defined(CONFIG_TCCBOOT)
   20727         error("debug mode currently not available for Windows");
   20728 #else
   20729         struct sigaction sigact;
   20730         /* install TCC signal handlers to print debug info on fatal
   20731            runtime errors */
   20732         sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
   20733         sigact.sa_sigaction = sig_error;
   20734         sigemptyset(&sigact.sa_mask);
   20735         sigaction(SIGFPE, &sigact, NULL);
   20736         sigaction(SIGILL, &sigact, NULL);
   20737         sigaction(SIGSEGV, &sigact, NULL);
   20738         sigaction(SIGBUS, &sigact, NULL);
   20739         sigaction(SIGABRT, &sigact, NULL);
   20740 #endif
   20741     }
   20742 
   20743 #ifdef CONFIG_TCC_BCHECK
   20744     if (do_bounds_check) {
   20745         void (*bound_init)(void);
   20746 
   20747         /* set error function */
   20748         rt_bound_error_msg = (void *)tcc_get_symbol_err(s1,
   20749                                                         "__bound_error_msg");
   20750 
   20751         /* XXX: use .init section so that it also work in binary ? */
   20752         bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init");
   20753         bound_init();
   20754     }
   20755 #endif
   20756     return (*prog_main)(argc, argv);
   20757 }
   20758 
   20759 TCCState *tcc_new(void)
   20760 {
   20761     const char *p, *r;
   20762     TCCState *s;
   20763     TokenSym *ts __attribute__((unused));
   20764     int i, c;
   20765 
   20766     s = tcc_mallocz(sizeof(TCCState));
   20767     if (!s)
   20768         return NULL;
   20769     tcc_state = s;
   20770     s->output_type = TCC_OUTPUT_MEMORY;
   20771 
   20772     /* init isid table */
   20773     for(i=0;i<256;i++)
   20774         isidnum_table[i] = isid(i) || isnum(i);
   20775 
   20776     /* add all tokens */
   20777     table_ident = NULL;
   20778     memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
   20779 
   20780     tok_ident = TOK_IDENT;
   20781     p = tcc_keywords;
   20782     while (*p) {
   20783         r = p;
   20784         for(;;) {
   20785             c = *r++;
   20786             if (c == '\0')
   20787                 break;
   20788         }
   20789         ts = tok_alloc(p, r - p - 1);
   20790         p = r;
   20791     }
   20792 
   20793     /* we add dummy defines for some special macros to speed up tests
   20794        and to have working defined() */
   20795     define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
   20796     define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
   20797     define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
   20798     define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
   20799 
   20800     /* standard defines */
   20801     tcc_define_symbol(s, "__STDC__", NULL);
   20802 #if defined(TCC_TARGET_I386)
   20803     tcc_define_symbol(s, "__i386__", NULL);
   20804 #endif
   20805 #if defined(TCC_TARGET_ARM)
   20806     tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
   20807     tcc_define_symbol(s, "__arm_elf__", NULL);
   20808     tcc_define_symbol(s, "__arm_elf", NULL);
   20809     tcc_define_symbol(s, "arm_elf", NULL);
   20810     tcc_define_symbol(s, "__arm__", NULL);
   20811     tcc_define_symbol(s, "__arm", NULL);
   20812     tcc_define_symbol(s, "arm", NULL);
   20813     tcc_define_symbol(s, "__APCS_32__", NULL);
   20814 #endif
   20815 #if defined(linux)
   20816     tcc_define_symbol(s, "__linux__", NULL);
   20817     tcc_define_symbol(s, "linux", NULL);
   20818 #endif
   20819     /* tiny C specific defines */
   20820     tcc_define_symbol(s, "__TINYC__", NULL);
   20821 
   20822     /* tiny C & gcc defines */
   20823     tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
   20824     tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
   20825     tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
   20826 
   20827     /* default library paths */
   20828 #ifdef TCC_TARGET_PE
   20829     {
   20830         char buf[1024];
   20831         snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
   20832         tcc_add_library_path(s, buf);
   20833     }
   20834 #else
   20835     tcc_add_library_path(s, "/usr/local/lib");
   20836     tcc_add_library_path(s, "/usr/lib");
   20837     tcc_add_library_path(s, "/lib");
   20838 #endif
   20839 
   20840     /* no section zero */
   20841     dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
   20842 
   20843     /* create standard sections */
   20844     text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
   20845     data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
   20846     bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
   20847 
   20848     /* symbols are always generated for linking stage */
   20849     symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
   20850                                 ".strtab",
   20851                                 ".hashtab", SHF_PRIVATE);
   20852     strtab_section = symtab_section->link;
   20853 
   20854     /* private symbol table for dynamic symbols */
   20855     s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
   20856                                       ".dynstrtab",
   20857                                       ".dynhashtab", SHF_PRIVATE);
   20858     s->alacarte_link = 1;
   20859 
   20860 #ifdef CHAR_IS_UNSIGNED
   20861     s->char_is_unsigned = 1;
   20862 #endif
   20863 #if defined(TCC_TARGET_PE) && 0
   20864     /* XXX: currently the PE linker is not ready to support that */
   20865     s->leading_underscore = 1;
   20866 #endif
   20867     return s;
   20868 }
   20869 
   20870 void tcc_delete(TCCState *s1)
   20871 {
   20872     int i, n;
   20873 
   20874     /* free -D defines */
   20875     free_defines(NULL);
   20876 
   20877     /* free tokens */
   20878     n = tok_ident - TOK_IDENT;
   20879     for(i = 0; i < n; i++)
   20880         tcc_free(table_ident[i]);
   20881     tcc_free(table_ident);
   20882 
   20883     /* free all sections */
   20884 
   20885     free_section(symtab_section->hash);
   20886 
   20887     free_section(s1->dynsymtab_section->hash);
   20888     free_section(s1->dynsymtab_section->link);
   20889     free_section(s1->dynsymtab_section);
   20890 
   20891     for(i = 1; i < s1->nb_sections; i++)
   20892         free_section(s1->sections[i]);
   20893     tcc_free(s1->sections);
   20894 
   20895     /* free loaded dlls array */
   20896     for(i = 0; i < s1->nb_loaded_dlls; i++)
   20897         tcc_free(s1->loaded_dlls[i]);
   20898     tcc_free(s1->loaded_dlls);
   20899 
   20900     /* library paths */
   20901     for(i = 0; i < s1->nb_library_paths; i++)
   20902         tcc_free(s1->library_paths[i]);
   20903     tcc_free(s1->library_paths);
   20904 
   20905     /* cached includes */
   20906     for(i = 0; i < s1->nb_cached_includes; i++)
   20907         tcc_free(s1->cached_includes[i]);
   20908     tcc_free(s1->cached_includes);
   20909 
   20910     for(i = 0; i < s1->nb_include_paths; i++)
   20911         tcc_free(s1->include_paths[i]);
   20912     tcc_free(s1->include_paths);
   20913 
   20914     for(i = 0; i < s1->nb_sysinclude_paths; i++)
   20915         tcc_free(s1->sysinclude_paths[i]);
   20916     tcc_free(s1->sysinclude_paths);
   20917 
   20918     tcc_free(s1);
   20919 }
   20920 
   20921 int tcc_add_include_path(TCCState *s1, const char *pathname)
   20922 {
   20923     char *pathname1;
   20924 
   20925     pathname1 = tcc_strdup(pathname);
   20926     dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
   20927     return 0;
   20928 }
   20929 
   20930 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
   20931 {
   20932     char *pathname1;
   20933 
   20934     pathname1 = tcc_strdup(pathname);
   20935     dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
   20936     return 0;
   20937 }
   20938 
   20939 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
   20940 {
   20941     const char *ext, *filename1;
   20942     Elf32_Ehdr ehdr;
   20943     int fd, ret;
   20944     BufferedFile *saved_file;
   20945 
   20946     /* find source file type with extension */
   20947     filename1 = strrchr(filename, '/');
   20948     if (filename1)
   20949         filename1++;
   20950     else
   20951         filename1 = filename;
   20952     ext = strrchr(filename1, '.');
   20953     if (ext)
   20954         ext++;
   20955 
   20956     /* open the file */
   20957     saved_file = file;
   20958     file = tcc_open(s1, filename);
   20959     if (!file) {
   20960         if (flags & AFF_PRINT_ERROR) {
   20961             error_noabort("file '%s' not found", filename);
   20962         }
   20963         ret = -1;
   20964         goto fail1;
   20965     }
   20966 
   20967     if (!ext || !strcmp(ext, "c")) {
   20968         /* C file assumed */
   20969         ret = tcc_compile(s1);
   20970     } else
   20971 #ifdef CONFIG_TCC_ASM
   20972     if (!strcmp(ext, "S")) {
   20973         /* preprocessed assembler */
   20974         ret = tcc_assemble(s1, 1);
   20975     } else if (!strcmp(ext, "s")) {
   20976         /* non preprocessed assembler */
   20977         ret = tcc_assemble(s1, 0);
   20978     } else
   20979 #endif
   20980 #ifdef TCC_TARGET_PE
   20981     if (!strcmp(ext, "def")) {
   20982         ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
   20983     } else
   20984 #endif
   20985     {
   20986         fd = file->fd;
   20987         /* assume executable format: auto guess file type */
   20988         ret = read(fd, &ehdr, sizeof(ehdr));
   20989         lseek(fd, 0, SEEK_SET);
   20990         if (ret <= 0) {
   20991             error_noabort("could not read header");
   20992             goto fail;
   20993         } else if (ret != sizeof(ehdr)) {
   20994             goto try_load_script;
   20995         }
   20996 
   20997         if (ehdr.e_ident[0] == ELFMAG0 &&
   20998             ehdr.e_ident[1] == ELFMAG1 &&
   20999             ehdr.e_ident[2] == ELFMAG2 &&
   21000             ehdr.e_ident[3] == ELFMAG3) {
   21001             file->line_num = 0; /* do not display line number if error */
   21002             if (ehdr.e_type == ET_REL) {
   21003                 ret = tcc_load_object_file(s1, fd, 0);
   21004             } else if (ehdr.e_type == ET_DYN) {
   21005                 if (s1->output_type == TCC_OUTPUT_MEMORY) {
   21006 #ifdef TCC_TARGET_PE
   21007                     ret = -1;
   21008 #else
   21009                     void *h;
   21010 		    assert(0);
   21011 		    h = 0;
   21012                     //h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
   21013 		    // jrs: remove need for dlopen
   21014                     if (h)
   21015                         ret = 0;
   21016                     else
   21017                         ret = -1;
   21018 #endif
   21019                 } else {
   21020                     ret = tcc_load_dll(s1, fd, filename,
   21021                                        (flags & AFF_REFERENCED_DLL) != 0);
   21022                 }
   21023             } else {
   21024                 error_noabort("unrecognized ELF file");
   21025                 goto fail;
   21026             }
   21027         } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
   21028             file->line_num = 0; /* do not display line number if error */
   21029             ret = tcc_load_archive(s1, fd);
   21030         } else
   21031 #ifdef TCC_TARGET_COFF
   21032         if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
   21033             ret = tcc_load_coff(s1, fd);
   21034         } else
   21035 #endif
   21036         {
   21037             /* as GNU ld, consider it is an ld script if not recognized */
   21038         try_load_script:
   21039             ret = tcc_load_ldscript(s1);
   21040             if (ret < 0) {
   21041                 error_noabort("unrecognized file type");
   21042                 goto fail;
   21043             }
   21044         }
   21045     }
   21046  the_end:
   21047     tcc_close(file);
   21048  fail1:
   21049     file = saved_file;
   21050     return ret;
   21051  fail:
   21052     ret = -1;
   21053     goto the_end;
   21054 }
   21055 
   21056 int tcc_add_file(TCCState *s, const char *filename)
   21057 {
   21058     return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
   21059 }
   21060 
   21061 int tcc_add_library_path(TCCState *s, const char *pathname)
   21062 {
   21063     char *pathname1;
   21064 
   21065     pathname1 = tcc_strdup(pathname);
   21066     dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
   21067     return 0;
   21068 }
   21069 
   21070 /* find and load a dll. Return non zero if not found */
   21071 /* XXX: add '-rpath' option support ? */
   21072 static int tcc_add_dll(TCCState *s, const char *filename, int flags)
   21073 {
   21074     char buf[1024];
   21075     int i;
   21076 
   21077     for(i = 0; i < s->nb_library_paths; i++) {
   21078         snprintf(buf, sizeof(buf), "%s/%s",
   21079                  s->library_paths[i], filename);
   21080         if (tcc_add_file_internal(s, buf, flags) == 0)
   21081             return 0;
   21082     }
   21083     return -1;
   21084 }
   21085 
   21086 /* the library name is the same as the argument of the '-l' option */
   21087 int tcc_add_library(TCCState *s, const char *libraryname)
   21088 {
   21089     char buf[1024];
   21090     int i;
   21091 
   21092     /* first we look for the dynamic library if not static linking */
   21093     if (!s->static_link) {
   21094 #ifdef TCC_TARGET_PE
   21095         snprintf(buf, sizeof(buf), "%s.def", libraryname);
   21096 #else
   21097         snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
   21098 #endif
   21099         if (tcc_add_dll(s, buf, 0) == 0)
   21100             return 0;
   21101     }
   21102 
   21103     /* then we look for the static library */
   21104     for(i = 0; i < s->nb_library_paths; i++) {
   21105         snprintf(buf, sizeof(buf), "%s/lib%s.a",
   21106                  s->library_paths[i], libraryname);
   21107         if (tcc_add_file_internal(s, buf, 0) == 0)
   21108             return 0;
   21109     }
   21110     return -1;
   21111 }
   21112 
   21113 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
   21114 {
   21115     add_elf_sym(symtab_section, val, 0,
   21116                 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
   21117                 SHN_ABS, name);
   21118     return 0;
   21119 }
   21120 
   21121 int tcc_set_output_type(TCCState *s, int output_type)
   21122 {
   21123     s->output_type = output_type;
   21124 
   21125     if (!s->nostdinc) {
   21126         char buf[1024];
   21127 
   21128         /* default include paths */
   21129         /* XXX: reverse order needed if -isystem support */
   21130 #ifndef TCC_TARGET_PE
   21131         tcc_add_sysinclude_path(s, "/usr/local/include");
   21132         tcc_add_sysinclude_path(s, "/usr/include");
   21133 #endif
   21134         snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
   21135         tcc_add_sysinclude_path(s, buf);
   21136 #ifdef TCC_TARGET_PE
   21137         snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
   21138         tcc_add_sysinclude_path(s, buf);
   21139 #endif
   21140     }
   21141 
   21142     /* if bound checking, then add corresponding sections */
   21143 #ifdef CONFIG_TCC_BCHECK
   21144     if (do_bounds_check) {
   21145         /* define symbol */
   21146         tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
   21147         /* create bounds sections */
   21148         bounds_section = new_section(s, ".bounds",
   21149                                      SHT_PROGBITS, SHF_ALLOC);
   21150         lbounds_section = new_section(s, ".lbounds",
   21151                                       SHT_PROGBITS, SHF_ALLOC);
   21152     }
   21153 #endif
   21154 
   21155     if (s->char_is_unsigned) {
   21156         tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
   21157     }
   21158 
   21159     /* add debug sections */
   21160     if (do_debug) {
   21161         /* stab symbols */
   21162         stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
   21163         stab_section->sh_entsize = sizeof(Stab_Sym);
   21164         stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
   21165         put_elf_str(stabstr_section, "");
   21166         stab_section->link = stabstr_section;
   21167         /* put first entry */
   21168         put_stabs("", 0, 0, 0, 0);
   21169     }
   21170 
   21171     /* add libc crt1/crti objects */
   21172 #ifndef TCC_TARGET_PE
   21173     if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
   21174         !s->nostdlib) {
   21175         if (output_type != TCC_OUTPUT_DLL)
   21176             tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
   21177         tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
   21178     }
   21179 #endif
   21180     return 0;
   21181 }
   21182 
   21183 #define WD_ALL    0x0001 /* warning is activated when using -Wall */
   21184 #define FD_INVERT 0x0002 /* invert value before storing */
   21185 
   21186 typedef struct FlagDef {
   21187     uint16_t offset;
   21188     uint16_t flags;
   21189     const char *name;
   21190 } FlagDef;
   21191 
   21192 static const FlagDef warning_defs[] = {
   21193     { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
   21194     { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
   21195     { offsetof(TCCState, warn_error), 0, "error" },
   21196     { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
   21197       "implicit-function-declaration" },
   21198 };
   21199 
   21200 static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
   21201                     const char *name, int value)
   21202 {
   21203     int i;
   21204     const FlagDef *p;
   21205     const char *r;
   21206 
   21207     r = name;
   21208     if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
   21209         r += 3;
   21210         value = !value;
   21211     }
   21212     for(i = 0, p = flags; i < nb_flags; i++, p++) {
   21213         if (!strcmp(r, p->name))
   21214             goto found;
   21215     }
   21216     return -1;
   21217  found:
   21218     if (p->flags & FD_INVERT)
   21219         value = !value;
   21220     *(int *)((uint8_t *)s + p->offset) = value;
   21221     return 0;
   21222 }
   21223 
   21224 
   21225 /* set/reset a warning */
   21226 int tcc_set_warning(TCCState *s, const char *warning_name, int value)
   21227 {
   21228     int i;
   21229     const FlagDef *p;
   21230 
   21231     if (!strcmp(warning_name, "all")) {
   21232         for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
   21233             if (p->flags & WD_ALL)
   21234                 *(int *)((uint8_t *)s + p->offset) = 1;
   21235         }
   21236         return 0;
   21237     } else {
   21238         return set_flag(s, warning_defs, countof(warning_defs),
   21239                         warning_name, value);
   21240     }
   21241 }
   21242 
   21243 static const FlagDef flag_defs[] = {
   21244     { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
   21245     { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
   21246     { offsetof(TCCState, nocommon), FD_INVERT, "common" },
   21247     { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
   21248 };
   21249 
   21250 /* set/reset a flag */
   21251 int tcc_set_flag(TCCState *s, const char *flag_name, int value)
   21252 {
   21253     return set_flag(s, flag_defs, countof(flag_defs),
   21254                     flag_name, value);
   21255 }
   21256 
   21257 #if !defined(LIBTCC)
   21258 
   21259 /* extract the basename of a file */
   21260 static const char *tcc_basename(const char *name)
   21261 {
   21262     const char *p;
   21263     p = strrchr(name, '/');
   21264 #ifdef WIN32
   21265     if (!p)
   21266         p = strrchr(name, '\\');
   21267 #endif
   21268     if (!p)
   21269         p = name;
   21270     else
   21271         p++;
   21272     return p;
   21273 }
   21274 
   21275 static int64_t getclock_us(void)
   21276 {
   21277 #ifdef WIN32
   21278     struct _timeb tb;
   21279     _ftime(&tb);
   21280     return (tb.time * 1000LL + tb.millitm) * 1000LL;
   21281 #else
   21282     struct timeval tv;
   21283     gettimeofday(&tv, NULL);
   21284     return tv.tv_sec * 1000000LL + tv.tv_usec;
   21285 #endif
   21286 }
   21287 
   21288 void help(void)
   21289 {
   21290     printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2017 Fabrice Bellard\n"
   21291            "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
   21292            "           [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
   21293            "           [infile1 infile2...] [-run infile args...]\n"
   21294            "\n"
   21295            "General options:\n"
   21296            "  -v          display current version\n"
   21297            "  -c          compile only - generate an object file\n"
   21298            "  -o outfile  set output filename\n"
   21299            "  -Bdir       set tcc internal library path\n"
   21300            "  -bench      output compilation statistics\n"
   21301  	   "  -run        run compiled source\n"
   21302            "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
   21303            "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
   21304            "  -w          disable all warnings\n"
   21305            "Preprocessor options:\n"
   21306            "  -Idir       add include path 'dir'\n"
   21307            "  -Dsym[=val] define 'sym' with value 'val'\n"
   21308            "  -Usym       undefine 'sym'\n"
   21309            "Linker options:\n"
   21310            "  -Ldir       add library path 'dir'\n"
   21311            "  -llib       link with dynamic or static library 'lib'\n"
   21312            "  -shared     generate a shared library\n"
   21313            "  -static     static linking\n"
   21314            "  -rdynamic   export all global symbols to dynamic linker\n"
   21315            "  -r          relocatable output\n"
   21316            "Debugger options:\n"
   21317            "  -g          generate runtime debug info\n"
   21318 #ifdef CONFIG_TCC_BCHECK
   21319            "  -b          compile with built-in memory and bounds checker (implies -g)\n"
   21320 #endif
   21321            "  -bt N       show N callers in stack traces\n"
   21322            );
   21323 }
   21324 
   21325 #define TCC_OPTION_HAS_ARG 0x0001
   21326 #define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
   21327 
   21328 typedef struct TCCOption {
   21329     const char *name;
   21330     uint16_t index;
   21331     uint16_t flags;
   21332 } TCCOption;
   21333 
   21334 enum {
   21335     TCC_OPTION_HELP,
   21336     TCC_OPTION_I,
   21337     TCC_OPTION_D,
   21338     TCC_OPTION_U,
   21339     TCC_OPTION_L,
   21340     TCC_OPTION_B,
   21341     TCC_OPTION_l,
   21342     TCC_OPTION_bench,
   21343     TCC_OPTION_bt,
   21344     TCC_OPTION_b,
   21345     TCC_OPTION_g,
   21346     TCC_OPTION_c,
   21347     TCC_OPTION_static,
   21348     TCC_OPTION_shared,
   21349     TCC_OPTION_o,
   21350     TCC_OPTION_r,
   21351     TCC_OPTION_Wl,
   21352     TCC_OPTION_W,
   21353     TCC_OPTION_O,
   21354     TCC_OPTION_m,
   21355     TCC_OPTION_f,
   21356     TCC_OPTION_nostdinc,
   21357     TCC_OPTION_nostdlib,
   21358     TCC_OPTION_print_search_dirs,
   21359     TCC_OPTION_rdynamic,
   21360     TCC_OPTION_run,
   21361     TCC_OPTION_v,
   21362     TCC_OPTION_w,
   21363     TCC_OPTION_pipe,
   21364 };
   21365 
   21366 static const TCCOption tcc_options[] = {
   21367     { "h", TCC_OPTION_HELP, 0 },
   21368     { "?", TCC_OPTION_HELP, 0 },
   21369     { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
   21370     { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
   21371     { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
   21372     { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
   21373     { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
   21374     { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21375     { "bench", TCC_OPTION_bench, 0 },
   21376     { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
   21377 #ifdef CONFIG_TCC_BCHECK
   21378     { "b", TCC_OPTION_b, 0 },
   21379 #endif
   21380     { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21381     { "c", TCC_OPTION_c, 0 },
   21382     { "static", TCC_OPTION_static, 0 },
   21383     { "shared", TCC_OPTION_shared, 0 },
   21384     { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
   21385     { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21386     { "rdynamic", TCC_OPTION_rdynamic, 0 },
   21387     { "r", TCC_OPTION_r, 0 },
   21388     { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21389     { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21390     { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21391     { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
   21392     { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
   21393     { "nostdinc", TCC_OPTION_nostdinc, 0 },
   21394     { "nostdlib", TCC_OPTION_nostdlib, 0 },
   21395     { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
   21396     { "v", TCC_OPTION_v, 0 },
   21397     { "w", TCC_OPTION_w, 0 },
   21398     { "pipe", TCC_OPTION_pipe, 0},
   21399     { NULL },
   21400 };
   21401 
   21402 /* convert 'str' into an array of space separated strings */
   21403 static int expand_args(char ***pargv, const char *str)
   21404 {
   21405     const char *s1;
   21406     char **argv, *arg;
   21407     int argc, len;
   21408 
   21409     argc = 0;
   21410     argv = NULL;
   21411     for(;;) {
   21412         while (is_space(*str))
   21413             str++;
   21414         if (*str == '\0')
   21415             break;
   21416         s1 = str;
   21417         while (*str != '\0' && !is_space(*str))
   21418             str++;
   21419         len = str - s1;
   21420         arg = tcc_malloc(len + 1);
   21421         memcpy(arg, s1, len);
   21422         arg[len] = '\0';
   21423         dynarray_add((void ***)&argv, &argc, arg);
   21424     }
   21425     *pargv = argv;
   21426     return argc;
   21427 }
   21428 
   21429 static char **files;
   21430 static int nb_files, nb_libraries;
   21431 static int multiple_files;
   21432 static int print_search_dirs;
   21433 static int output_type;
   21434 static int reloc_output;
   21435 static const char *outfile;
   21436 
   21437 int parse_args(TCCState *s, int argc, char **argv)
   21438 {
   21439     int optind;
   21440     const TCCOption *popt;
   21441     const char *optarg, *p1, *r1;
   21442     char *r;
   21443 
   21444     optind = 0;
   21445     while (1) {
   21446         if (optind >= argc) {
   21447             if (nb_files == 0 && !print_search_dirs)
   21448                 goto show_help;
   21449             else
   21450                 break;
   21451         }
   21452         r = argv[optind++];
   21453         if (r[0] != '-') {
   21454             /* add a new file */
   21455             dynarray_add((void ***)&files, &nb_files, r);
   21456             if (!multiple_files) {
   21457                 optind--;
   21458                 /* argv[0] will be this file */
   21459                 break;
   21460             }
   21461         } else {
   21462             /* find option in table (match only the first chars */
   21463             popt = tcc_options;
   21464             for(;;) {
   21465                 p1 = popt->name;
   21466                 if (p1 == NULL)
   21467                     error("invalid option -- '%s'", r);
   21468                 r1 = r + 1;
   21469                 for(;;) {
   21470                     if (*p1 == '\0')
   21471                         goto option_found;
   21472                     if (*r1 != *p1)
   21473                         break;
   21474                     p1++;
   21475                     r1++;
   21476                 }
   21477                 popt++;
   21478             }
   21479         option_found:
   21480             if (popt->flags & TCC_OPTION_HAS_ARG) {
   21481                 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
   21482                     optarg = r1;
   21483                 } else {
   21484                     if (optind >= argc)
   21485                         error("argument to '%s' is missing", r);
   21486                     optarg = argv[optind++];
   21487                 }
   21488             } else {
   21489                 if (*r1 != '\0')
   21490                     goto show_help;
   21491                 optarg = NULL;
   21492             }
   21493 
   21494             switch(popt->index) {
   21495             case TCC_OPTION_HELP:
   21496             show_help:
   21497                 help();
   21498                 exit(1);
   21499             case TCC_OPTION_I:
   21500                 if (tcc_add_include_path(s, optarg) < 0)
   21501                     error("too many include paths");
   21502                 break;
   21503             case TCC_OPTION_D:
   21504                 {
   21505                     char *sym, *value;
   21506                     sym = (char *)optarg;
   21507                     value = strchr(sym, '=');
   21508                     if (value) {
   21509                         *value = '\0';
   21510                         value++;
   21511                     }
   21512                     tcc_define_symbol(s, sym, value);
   21513                 }
   21514                 break;
   21515             case TCC_OPTION_U:
   21516                 tcc_undefine_symbol(s, optarg);
   21517                 break;
   21518             case TCC_OPTION_L:
   21519                 tcc_add_library_path(s, optarg);
   21520                 break;
   21521             case TCC_OPTION_B:
   21522                 /* set tcc utilities path (mainly for tcc development) */
   21523                 tcc_lib_path = optarg;
   21524                 break;
   21525             case TCC_OPTION_l:
   21526                 dynarray_add((void ***)&files, &nb_files, r);
   21527                 nb_libraries++;
   21528                 break;
   21529             case TCC_OPTION_bench:
   21530                 do_bench = 1;
   21531                 break;
   21532             case TCC_OPTION_bt:
   21533                 num_callers = atoi(optarg);
   21534                 break;
   21535 #ifdef CONFIG_TCC_BCHECK
   21536             case TCC_OPTION_b:
   21537                 do_bounds_check = 1;
   21538                 do_debug = 1;
   21539                 break;
   21540 #endif
   21541             case TCC_OPTION_g:
   21542                 do_debug = 1;
   21543                 break;
   21544             case TCC_OPTION_c:
   21545                 multiple_files = 1;
   21546                 output_type = TCC_OUTPUT_OBJ;
   21547                 break;
   21548             case TCC_OPTION_static:
   21549                 s->static_link = 1;
   21550                 break;
   21551             case TCC_OPTION_shared:
   21552                 output_type = TCC_OUTPUT_DLL;
   21553                 break;
   21554             case TCC_OPTION_o:
   21555                 multiple_files = 1;
   21556                 outfile = optarg;
   21557                 break;
   21558             case TCC_OPTION_r:
   21559                 /* generate a .o merging several output files */
   21560                 reloc_output = 1;
   21561                 output_type = TCC_OUTPUT_OBJ;
   21562                 break;
   21563             case TCC_OPTION_nostdinc:
   21564                 s->nostdinc = 1;
   21565                 break;
   21566             case TCC_OPTION_nostdlib:
   21567                 s->nostdlib = 1;
   21568                 break;
   21569             case TCC_OPTION_print_search_dirs:
   21570                 print_search_dirs = 1;
   21571                 break;
   21572             case TCC_OPTION_run:
   21573                 {
   21574                     int argc1;
   21575                     char **argv1;
   21576                     argc1 = expand_args(&argv1, optarg);
   21577                     if (argc1 > 0) {
   21578                         parse_args(s, argc1, argv1);
   21579                     }
   21580                     multiple_files = 0;
   21581                     output_type = TCC_OUTPUT_MEMORY;
   21582                 }
   21583                 break;
   21584             case TCC_OPTION_v:
   21585                 printf("tcc version %s\n", TCC_VERSION);
   21586                 exit(0);
   21587             case TCC_OPTION_f:
   21588                 if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
   21589                     goto unsupported_option;
   21590                 break;
   21591             case TCC_OPTION_W:
   21592                 if (tcc_set_warning(s, optarg, 1) < 0 &&
   21593                     s->warn_unsupported)
   21594                     goto unsupported_option;
   21595                 break;
   21596             case TCC_OPTION_w:
   21597                 s->warn_none = 1;
   21598                 break;
   21599             case TCC_OPTION_rdynamic:
   21600                 s->rdynamic = 1;
   21601                 break;
   21602             case TCC_OPTION_Wl:
   21603                 {
   21604                     const char *p;
   21605                     if (strstart(optarg, "-Ttext,", &p)) {
   21606                         s->text_addr = strtoul(p, NULL, 16);
   21607                         s->has_text_addr = 1;
   21608                     } else if (strstart(optarg, "--oformat,", &p)) {
   21609                         if (strstart(p, "elf32-", NULL)) {
   21610                             s->output_format = TCC_OUTPUT_FORMAT_ELF;
   21611                         } else if (!strcmp(p, "binary")) {
   21612                             s->output_format = TCC_OUTPUT_FORMAT_BINARY;
   21613                         } else
   21614 #ifdef TCC_TARGET_COFF
   21615                         if (!strcmp(p, "coff")) {
   21616                             s->output_format = TCC_OUTPUT_FORMAT_COFF;
   21617                         } else
   21618 #endif
   21619                         {
   21620                             error("target %s not found", p);
   21621                         }
   21622                     } else {
   21623                         error("unsupported linker option '%s'", optarg);
   21624                     }
   21625                 }
   21626                 break;
   21627             default:
   21628                 if (s->warn_unsupported) {
   21629                 unsupported_option:
   21630                     warning("unsupported option '%s'", r);
   21631                 }
   21632                 break;
   21633             }
   21634         }
   21635     }
   21636     return optind;
   21637 }
   21638 
   21639 // njn: renamed main() as main2() in order to repeat it multiple times.
   21640 int main2(int argc, char **argv)
   21641 {
   21642     int i;
   21643     TCCState *s;
   21644     int nb_objfiles, ret, optind;
   21645     char objfilename[1024];
   21646     int64_t start_time = 0;
   21647 
   21648 #ifdef WIN32
   21649     /* on win32, we suppose the lib and includes are at the location
   21650        of 'tcc.exe' */
   21651     {
   21652         static char path[1024];
   21653         char *p, *d;
   21654 
   21655         GetModuleFileNameA(NULL, path, sizeof path);
   21656         p = d = strlwr(path);
   21657         while (*d)
   21658         {
   21659             if (*d == '\\') *d = '/', p = d;
   21660             ++d;
   21661         }
   21662         *p = '\0';
   21663         tcc_lib_path = path;
   21664     }
   21665 #endif
   21666 
   21667     s = tcc_new();
   21668     output_type = TCC_OUTPUT_EXE;
   21669     outfile = NULL;
   21670     multiple_files = 1;
   21671     files = NULL;
   21672     nb_files = 0;
   21673     nb_libraries = 0;
   21674     reloc_output = 0;
   21675     print_search_dirs = 0;
   21676 
   21677     optind = parse_args(s, argc - 1, argv + 1) + 1;
   21678 
   21679     if (print_search_dirs) {
   21680         /* enough for Linux kernel */
   21681         printf("install: %s/\n", tcc_lib_path);
   21682         return 0;
   21683     }
   21684 
   21685     nb_objfiles = nb_files - nb_libraries;
   21686 
   21687     /* if outfile provided without other options, we output an
   21688        executable */
   21689     if (outfile && output_type == TCC_OUTPUT_MEMORY)
   21690         output_type = TCC_OUTPUT_EXE;
   21691 
   21692     /* check -c consistency : only single file handled. XXX: checks file type */
   21693     if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
   21694         /* accepts only a single input file */
   21695         if (nb_objfiles != 1)
   21696             error("cannot specify multiple files with -c");
   21697         if (nb_libraries != 0)
   21698             error("cannot specify libraries with -c");
   21699     }
   21700 
   21701     if (output_type != TCC_OUTPUT_MEMORY) {
   21702         if (!outfile) {
   21703     /* compute default outfile name */
   21704             pstrcpy(objfilename, sizeof(objfilename) - 1,
   21705                     /* strip path */
   21706                     tcc_basename(files[0]));
   21707 #ifdef TCC_TARGET_PE
   21708             pe_guess_outfile(objfilename, output_type);
   21709 #else
   21710             if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
   21711                 char *ext = strrchr(objfilename, '.');
   21712             if (!ext)
   21713                 goto default_outfile;
   21714                 /* add .o extension */
   21715             strcpy(ext + 1, "o");
   21716         } else {
   21717         default_outfile:
   21718             pstrcpy(objfilename, sizeof(objfilename), "a.out");
   21719         }
   21720 #endif
   21721         outfile = objfilename;
   21722         }
   21723     }
   21724 
   21725     if (do_bench) {
   21726         start_time = getclock_us();
   21727     }
   21728 
   21729     tcc_set_output_type(s, output_type);
   21730 
   21731     /* compile or add each files or library */
   21732     for(i = 0;i < nb_files; i++) {
   21733         const char *filename;
   21734 
   21735         filename = files[i];
   21736         if (filename[0] == '-') {
   21737             if (tcc_add_library(s, filename + 2) < 0)
   21738                 error("cannot find %s", filename);
   21739         } else {
   21740             if (tcc_add_file(s, filename) < 0) {
   21741                 ret = 1;
   21742                 goto the_end;
   21743             }
   21744         }
   21745     }
   21746 
   21747     /* free all files */
   21748     tcc_free(files);
   21749 
   21750     if (do_bench) {
   21751         double total_time;
   21752         total_time = (double)(getclock_us() - start_time) / 1000000.0;
   21753         if (total_time < 0.001)
   21754             total_time = 0.001;
   21755         if (total_bytes < 1)
   21756             total_bytes = 1;
   21757         printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
   21758                tok_ident - TOK_IDENT, total_lines, total_bytes,
   21759                total_time, (int)(total_lines / total_time),
   21760                total_bytes / total_time / 1000000.0);
   21761     }
   21762 
   21763     if (s->output_type == TCC_OUTPUT_MEMORY) {
   21764         ret = tcc_run(s, argc - optind, argv + optind);
   21765     } else
   21766 #ifdef TCC_TARGET_PE
   21767     if (s->output_type != TCC_OUTPUT_OBJ) {
   21768         ret = tcc_output_pe(s, outfile);
   21769     } else
   21770 #endif
   21771     {
   21772         tcc_output_file(s, outfile);
   21773         ret = 0;
   21774     }
   21775  the_end:
   21776     /* XXX: cannot do it with bound checking because of the malloc hooks */
   21777     if (!do_bounds_check)
   21778         tcc_delete(s);
   21779 
   21780 #ifdef MEM_DEBUG
   21781     if (do_bench) {
   21782         printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
   21783     }
   21784 #endif
   21785     return ret;
   21786 }
   21787 
   21788 // njn: created this wrapper main() function to execute compilation multiple
   21789 // times.  TinyCC is fast!
   21790 // Nb: we get a link error, and TinyCC would normally return non-zero.  But
   21791 // the link error is not a problem for benchmarking purposes, so we return
   21792 // zero here (as required by vg_perf).
   21793 int main(int argc, char **argv)
   21794 {
   21795    #define REPS   30
   21796    int i;
   21797    for (i = 0; i < REPS; i++) {
   21798       main2(argc, argv);
   21799    }
   21800    return 0;
   21801 }
   21802 
   21803 #endif
   21804 
   21805 // njn: copied these in from libtcc1.c to avoid link errors when libtcc1.a
   21806 // is not present.
   21807 unsigned short __tcc_fpu_control = 0x137f;
   21808 unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
   21809 
   21810 #if 0
   21811 long long __shldi3(long long a, int b)
   21812 {
   21813 #ifdef __TINYC__
   21814     DWunion u;
   21815     u.ll = a;
   21816     if (b >= 32) {
   21817         u.s.high = (unsigned)u.s.low << (b - 32);
   21818         u.s.low = 0;
   21819     } else if (b != 0) {
   21820         u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b));
   21821         u.s.low = (unsigned)u.s.low << b;
   21822     }
   21823     return u.ll;
   21824 #else
   21825     return a << b;
   21826 #endif
   21827 }
   21828 #endif
   21829