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
65char* dummy_char_star;
66size_t dummy_size_t;
67
68// njn: inlined elf.h
69//#include "elf.h"
70//---------------------------------------------------------------------------
71/* This file defines standard ELF types, structures, and macros.
72   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
73   This file is part of the GNU C Library.
74   Contributed by Ian Lance Taylor <ian@cygnus.com>.
75
76   The GNU C Library is free software; you can redistribute it and/or
77   modify it under the terms of the GNU Library General Public License as
78   published by the Free Software Foundation; either version 2 of the
79   License, or (at your option) any later version.
80
81   The GNU C Library is distributed in the hope that it will be useful,
82   but WITHOUT ANY WARRANTY; without even the implied warranty of
83   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
84   Library General Public License for more details.
85
86   You should have received a copy of the GNU Library General Public
87   License along with the GNU C Library; see the file COPYING.LIB.  If not,
88   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
89   Boston, MA 02111-1307, USA.  */
90
91#ifndef _ELF_H
92#define	_ELF_H 1
93
94#ifndef WIN32
95#include <inttypes.h>
96#else
97#ifndef __int8_t_defined
98#define __int8_t_defined
99typedef signed char int8_t;
100typedef	short int int16_t;
101typedef	int int32_t;
102typedef long long int int64_t;
103#endif
104
105typedef unsigned char		uint8_t;
106typedef unsigned short int	uint16_t;
107typedef unsigned int		uint32_t;
108typedef unsigned long long int	uint64_t;
109#endif
110
111/* Standard ELF types.  */
112
113/* Type for a 16-bit quantity.  */
114typedef uint16_t Elf32_Half;
115typedef uint16_t Elf64_Half;
116
117/* Types for signed and unsigned 32-bit quantities.  */
118typedef uint32_t Elf32_Word;
119typedef	int32_t  Elf32_Sword;
120typedef uint32_t Elf64_Word;
121typedef	int32_t  Elf64_Sword;
122
123/* Types for signed and unsigned 64-bit quantities.  */
124typedef uint64_t Elf32_Xword;
125typedef	int64_t  Elf32_Sxword;
126typedef uint64_t Elf64_Xword;
127typedef	int64_t  Elf64_Sxword;
128
129/* Type of addresses.  */
130typedef uint32_t Elf32_Addr;
131typedef uint64_t Elf64_Addr;
132
133/* Type of file offsets.  */
134typedef uint32_t Elf32_Off;
135typedef uint64_t Elf64_Off;
136
137/* Type for section indices, which are 16-bit quantities.  */
138typedef uint16_t Elf32_Section;
139typedef uint16_t Elf64_Section;
140
141/* Type of symbol indices.  */
142typedef uint32_t Elf32_Symndx;
143typedef 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
150typedef 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
168typedef 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
300typedef 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
314typedef 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
376typedef 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
386typedef 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
399typedef struct
400{
401  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
402  Elf32_Half si_flags;			/* Per symbol flags */
403} Elf32_Syminfo;
404
405typedef 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
491typedef 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
502typedef 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
510typedef 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
517typedef 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
536typedef 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
548typedef 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
605typedef 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
615typedef 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
716typedef 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
728typedef 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
752typedef 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
759typedef 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
769typedef 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
780typedef 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
799typedef 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
809typedef 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
833typedef 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
844typedef 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
886typedef 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
893typedef 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
1173typedef 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
1189typedef 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
1198typedef 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
1249typedef 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
1388typedef 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
1397typedef 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
1419typedef 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
1712enum __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.
1739   To find the address, look in the corresponding external symbol.  */
1740__define_stab (N_GSYM, 0x20, "GSYM")
1741
1742/* Function name for BSD Fortran.  Only the name is significant.
1743   To find the address, look in the corresponding external symbol.  */
1744__define_stab (N_FNAME, 0x22, "FNAME")
1745
1746/* Function name or text-segment variable for C.  Value is its address.
1747   Desc is supposedly starting line number, but GCC doesn't set it
1748   and DBX seems not to miss it.  */
1749__define_stab (N_FUN, 0x24, "FUN")
1750
1751/* Data-segment variable with internal linkage.  Value is its address.
1752   "Static Sym".  */
1753__define_stab (N_STSYM, 0x26, "STSYM")
1754
1755/* BSS-segment variable with internal linkage.  Value is its address.  */
1756__define_stab (N_LCSYM, 0x28, "LCSYM")
1757
1758/* Name of main routine.  Only the name is significant.
1759   This is not used in C.  */
1760__define_stab (N_MAIN, 0x2a, "MAIN")
1761
1762/* Global symbol in Pascal.
1763   Supposedly the value is its line number; I'm skeptical.  */
1764__define_stab (N_PC, 0x30, "PC")
1765
1766/* Number of symbols:  0, files,,funcs,lines according to Ultrix V4.0. */
1767__define_stab (N_NSYMS, 0x32, "NSYMS")
1768
1769/* "No DST map for sym: name, ,0,type,ignored"  according to Ultrix V4.0. */
1770__define_stab (N_NOMAP, 0x34, "NOMAP")
1771
1772/* New stab from Solaris.  I don't know what it means, but it
1773   don't seem to contain useful information.  */
1774__define_stab (N_OBJ, 0x38, "OBJ")
1775
1776/* New stab from Solaris.  I don't know what it means, but it
1777   don't seem to contain useful information.  Possibly related to the
1778   optimization flags used in this module.  */
1779__define_stab (N_OPT, 0x3c, "OPT")
1780
1781/* Register variable.  Value is number of register.  */
1782__define_stab (N_RSYM, 0x40, "RSYM")
1783
1784/* Modula-2 compilation unit.  Can someone say what info it contains?  */
1785__define_stab (N_M2C, 0x42, "M2C")
1786
1787/* Line number in text segment.  Desc is the line number;
1788   value is corresponding address.  */
1789__define_stab (N_SLINE, 0x44, "SLINE")
1790
1791/* Similar, for data segment.  */
1792__define_stab (N_DSLINE, 0x46, "DSLINE")
1793
1794/* Similar, for bss segment.  */
1795__define_stab (N_BSLINE, 0x48, "BSLINE")
1796
1797/* Sun's source-code browser stabs.  ?? Don't know what the fields are.
1798   Supposedly the field is "path to associated .cb file".  THIS VALUE
1799   OVERLAPS WITH N_BSLINE!  */
1800__define_stab (N_BROWS, 0x48, "BROWS")
1801
1802/* GNU Modula-2 definition module dependency.  Value is the modification time
1803   of the definition file.  Other is non-zero if it is imported with the
1804   GNU M2 keyword %INITIALIZE.  Perhaps N_M2C can be used if there
1805   are enough empty fields? */
1806__define_stab(N_DEFD, 0x4a, "DEFD")
1807
1808/* THE FOLLOWING TWO STAB VALUES CONFLICT.  Happily, one is for Modula-2
1809   and one is for C++.   Still,... */
1810/* GNU C++ exception variable.  Name is variable name.  */
1811__define_stab (N_EHDECL, 0x50, "EHDECL")
1812/* Modula2 info "for imc":  name,,0,0,0  according to Ultrix V4.0.  */
1813__define_stab (N_MOD2, 0x50, "MOD2")
1814
1815/* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
1816   this entry is immediately followed by a CAUGHT stab saying what exception
1817   was caught.  Multiple CAUGHT stabs means that multiple exceptions
1818   can be caught here.  If Desc is 0, it means all exceptions are caught
1819   here.  */
1820__define_stab (N_CATCH, 0x54, "CATCH")
1821
1822/* Structure or union element.  Value is offset in the structure.  */
1823__define_stab (N_SSYM, 0x60, "SSYM")
1824
1825/* Name of main source file.
1826   Value is starting text address of the compilation.  */
1827__define_stab (N_SO, 0x64, "SO")
1828
1829/* Automatic variable in the stack.  Value is offset from frame pointer.
1830   Also used for type descriptions.  */
1831__define_stab (N_LSYM, 0x80, "LSYM")
1832
1833/* Beginning of an include file.  Only Sun uses this.
1834   In an object file, only the name is significant.
1835   The Sun linker puts data into some of the other fields.  */
1836__define_stab (N_BINCL, 0x82, "BINCL")
1837
1838/* Name of sub-source file (#include file).
1839   Value is starting text address of the compilation.  */
1840__define_stab (N_SOL, 0x84, "SOL")
1841
1842/* Parameter variable.  Value is offset from argument pointer.
1843   (On most machines the argument pointer is the same as the frame pointer.  */
1844__define_stab (N_PSYM, 0xa0, "PSYM")
1845
1846/* End of an include file.  No name.
1847   This and N_BINCL act as brackets around the file's output.
1848   In an object file, there is no significant data in this entry.
1849   The Sun linker puts data into some of the fields.  */
1850__define_stab (N_EINCL, 0xa2, "EINCL")
1851
1852/* Alternate entry point.  Value is its address.  */
1853__define_stab (N_ENTRY, 0xa4, "ENTRY")
1854
1855/* Beginning of lexical block.
1856   The desc is the nesting level in lexical blocks.
1857   The value is the address of the start of the text for the block.
1858   The variables declared inside the block *precede* the N_LBRAC symbol.  */
1859__define_stab (N_LBRAC, 0xc0, "LBRAC")
1860
1861/* Place holder for deleted include file.  Replaces a N_BINCL and everything
1862   up to the corresponding N_EINCL.  The Sun linker generates these when
1863   it finds multiple identical copies of the symbols from an include file.
1864   This appears only in output from the Sun linker.  */
1865__define_stab (N_EXCL, 0xc2, "EXCL")
1866
1867/* Modula-2 scope information.  Can someone say what info it contains?  */
1868__define_stab (N_SCOPE, 0xc4, "SCOPE")
1869
1870/* End of a lexical block.  Desc matches the N_LBRAC's desc.
1871   The value is the address of the end of the text for the block.  */
1872__define_stab (N_RBRAC, 0xe0, "RBRAC")
1873
1874/* Begin named common block.  Only the name is significant.  */
1875__define_stab (N_BCOMM, 0xe2, "BCOMM")
1876
1877/* End named common block.  Only the name is significant
1878   (and it should match the N_BCOMM).  */
1879__define_stab (N_ECOMM, 0xe4, "ECOMM")
1880
1881/* End common (local name): value is address.
1882   I'm not sure how this is used.  */
1883__define_stab (N_ECOML, 0xe8, "ECOML")
1884
1885/* These STAB's are used on Gould systems for Non-Base register symbols
1886   or something like that.  FIXME.  I have assigned the values at random
1887   since I don't have a Gould here.  Fixups from Gould folk welcome... */
1888__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
1889__define_stab (N_NBDATA, 0xF2, "NBDATA")
1890__define_stab (N_NBBSS,  0xF4, "NBBSS")
1891__define_stab (N_NBSTS,  0xF6, "NBSTS")
1892__define_stab (N_NBLCS,  0xF8, "NBLCS")
1893
1894/* Second symbol entry containing a length-value for the preceding entry.
1895   The value is the length.  */
1896__define_stab (N_LENG, 0xfe, "LENG")
1897
1898/* The above information, in matrix format.
1899
1900			STAB MATRIX
1901	_________________________________________________
1902	| 00 - 1F are not dbx stab symbols		|
1903	| In most cases, the low bit is the EXTernal bit|
1904
1905	| 00 UNDEF  | 02 ABS	| 04 TEXT   | 06 DATA	|
1906	| 01  |EXT  | 03  |EXT	| 05  |EXT  | 07  |EXT	|
1907
1908	| 08 BSS    | 0A INDR	| 0C FN_SEQ | 0E   	|
1909	| 09  |EXT  | 0B 	| 0D	    | 0F	|
1910
1911	| 10 	    | 12 COMM	| 14 SETA   | 16 SETT	|
1912	| 11	    | 13	| 15 	    | 17	|
1913
1914	| 18 SETD   | 1A SETB	| 1C SETV   | 1E WARNING|
1915	| 19	    | 1B	| 1D 	    | 1F FN	|
1916
1917	|_______________________________________________|
1918	| Debug entries with bit 01 set are unused.	|
1919	| 20 GSYM   | 22 FNAME	| 24 FUN    | 26 STSYM	|
1920	| 28 LCSYM  | 2A MAIN	| 2C	    | 2E	|
1921	| 30 PC	    | 32 NSYMS	| 34 NOMAP  | 36	|
1922	| 38 OBJ    | 3A	| 3C OPT    | 3E	|
1923	| 40 RSYM   | 42 M2C	| 44 SLINE  | 46 DSLINE |
1924	| 48 BSLINE*| 4A DEFD	| 4C        | 4E	|
1925	| 50 EHDECL*| 52	| 54 CATCH  | 56        |
1926	| 58        | 5A        | 5C        | 5E	|
1927	| 60 SSYM   | 62	| 64 SO	    | 66 	|
1928	| 68 	    | 6A	| 6C	    | 6E	|
1929	| 70	    | 72	| 74	    | 76	|
1930	| 78	    | 7A	| 7C	    | 7E	|
1931	| 80 LSYM   | 82 BINCL	| 84 SOL    | 86	|
1932	| 88	    | 8A	| 8C	    | 8E	|
1933	| 90	    | 92	| 94	    | 96	|
1934	| 98	    | 9A	| 9C	    | 9E	|
1935	| A0 PSYM   | A2 EINCL	| A4 ENTRY  | A6	|
1936	| A8	    | AA	| AC	    | AE	|
1937	| B0	    | B2	| B4	    | B6	|
1938	| B8	    | BA	| BC	    | BE	|
1939	| C0 LBRAC  | C2 EXCL	| C4 SCOPE  | C6	|
1940	| C8	    | CA	| CC	    | CE	|
1941	| D0	    | D2	| D4	    | D6	|
1942	| D8	    | DA	| DC	    | DE	|
1943	| E0 RBRAC  | E2 BCOMM	| E4 ECOMM  | E6	|
1944	| E8 ECOML  | EA	| EC	    | EE	|
1945	| F0	    | F2	| F4	    | F6	|
1946	| F8	    | FA	| FC	    | FE LENG	|
1947	+-----------------------------------------------+
1948 * 50 EHDECL is also MOD2.
1949 * 48 BSLINE is also BROWS.
1950 */
1951//---------------------------------------------------------------------------
1952LAST_UNUSED_STAB_CODE
1953};
1954
1955#undef __define_stab
1956
1957#endif /* __GNU_STAB_ */
1958//---------------------------------------------------------------------------
1959
1960#ifndef O_BINARY
1961#define O_BINARY 0
1962#endif
1963
1964// njn: inlined libtcc.h
1965//#include "libtcc.h"
1966//---------------------------------------------------------------------------
1967#ifndef LIBTCC_H
1968#define LIBTCC_H
1969
1970#ifdef __cplusplus
1971extern "C" {
1972#endif
1973
1974struct TCCState;
1975
1976typedef struct TCCState TCCState;
1977
1978/* create a new TCC compilation context */
1979TCCState *tcc_new(void);
1980
1981/* free a TCC compilation context */
1982void tcc_delete(TCCState *s);
1983
1984/* add debug information in the generated code */
1985void tcc_enable_debug(TCCState *s);
1986
1987/* set error/warning display callback */
1988void tcc_set_error_func(TCCState *s, void *error_opaque,
1989                        void (*error_func)(void *opaque, const char *msg));
1990
1991/* set/reset a warning */
1992int tcc_set_warning(TCCState *s, const char *warning_name, int value);
1993
1994/*****************************/
1995/* preprocessor */
1996
1997/* add include path */
1998int tcc_add_include_path(TCCState *s, const char *pathname);
1999
2000/* add in system include path */
2001int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
2002
2003/* define preprocessor symbol 'sym'. Can put optional value */
2004void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
2005
2006/* undefine preprocess symbol 'sym' */
2007void tcc_undefine_symbol(TCCState *s, const char *sym);
2008
2009/*****************************/
2010/* compiling */
2011
2012/* add a file (either a C file, dll, an object, a library or an ld
2013   script). Return -1 if error. */
2014int tcc_add_file(TCCState *s, const char *filename);
2015
2016/* compile a string containing a C source. Return non zero if
2017   error. */
2018int tcc_compile_string(TCCState *s, const char *buf);
2019
2020/*****************************/
2021/* linking commands */
2022
2023/* set output type. MUST BE CALLED before any compilation */
2024#define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
2025                                 output file) (default) */
2026#define TCC_OUTPUT_EXE      1 /* executable file */
2027#define TCC_OUTPUT_DLL      2 /* dynamic library */
2028#define TCC_OUTPUT_OBJ      3 /* object file */
2029int tcc_set_output_type(TCCState *s, int output_type);
2030
2031#define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
2032#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
2033#define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
2034
2035/* equivalent to -Lpath option */
2036int tcc_add_library_path(TCCState *s, const char *pathname);
2037
2038/* the library name is the same as the argument of the '-l' option */
2039int tcc_add_library(TCCState *s, const char *libraryname);
2040
2041/* add a symbol to the compiled program */
2042int tcc_add_symbol(TCCState *s, const char *name, unsigned long val);
2043
2044/* output an executable, library or object file. DO NOT call
2045   tcc_relocate() before. */
2046int tcc_output_file(TCCState *s, const char *filename);
2047
2048/* link and run main() function and return its value. DO NOT call
2049   tcc_relocate() before. */
2050int tcc_run(TCCState *s, int argc, char **argv);
2051
2052/* do all relocations (needed before using tcc_get_symbol()). Return
2053   non zero if link error. */
2054int tcc_relocate(TCCState *s);
2055
2056/* return symbol value. return 0 if OK, -1 if symbol not found */
2057int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name);
2058
2059#ifdef __cplusplus
2060}
2061#endif
2062
2063#endif
2064//---------------------------------------------------------------------------
2065
2066/* parser debug */
2067//#define PARSE_DEBUG
2068/* preprocessor debug */
2069//#define PP_DEBUG
2070/* include file debug */
2071//#define INC_DEBUG
2072
2073//#define MEM_DEBUG
2074
2075/* assembler debug */
2076//#define ASM_DEBUG
2077
2078/* target selection */
2079//#define TCC_TARGET_I386   /* i386 code generator */
2080//#define TCC_TARGET_ARM    /* ARMv4 code generator */
2081//#define TCC_TARGET_C67    /* TMS320C67xx code generator */
2082
2083/* default target is I386 */
2084#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
2085    !defined(TCC_TARGET_C67)
2086#define TCC_TARGET_I386
2087#endif
2088
2089#if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
2090    !defined(TCC_TARGET_C67)
2091#define CONFIG_TCC_BCHECK /* enable bound checking code */
2092#endif
2093
2094#if defined(WIN32) && !defined(TCC_TARGET_PE)
2095#define CONFIG_TCC_STATIC
2096#endif
2097
2098/* define it to include assembler support */
2099#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
2100#define CONFIG_TCC_ASM
2101#endif
2102
2103/* object format selection */
2104#if defined(TCC_TARGET_C67)
2105#define TCC_TARGET_COFF
2106#endif
2107
2108#define FALSE 0
2109#define false 0
2110#define TRUE 1
2111#define true 1
2112typedef int BOOL;
2113
2114/* path to find crt1.o, crti.o and crtn.o. Only needed when generating
2115   executables or dlls */
2116#define CONFIG_TCC_CRT_PREFIX "/usr/lib"
2117
2118#define INCLUDE_STACK_SIZE  32
2119#define IFDEF_STACK_SIZE    64
2120#define VSTACK_SIZE         256
2121#define STRING_MAX_SIZE     1024
2122#define PACK_STACK_SIZE     8
2123
2124#define TOK_HASH_SIZE       8192 /* must be a power of two */
2125#define TOK_ALLOC_INCR      512  /* must be a power of two */
2126#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
2127
2128/* token symbol management */
2129typedef struct TokenSym {
2130    struct TokenSym *hash_next;
2131    struct Sym *sym_define; /* direct pointer to define */
2132    struct Sym *sym_label; /* direct pointer to label */
2133    struct Sym *sym_struct; /* direct pointer to structure */
2134    struct Sym *sym_identifier; /* direct pointer to identifier */
2135    int tok; /* token number */
2136    int len;
2137    char str[1];
2138} TokenSym;
2139
2140typedef struct CString {
2141    int size; /* size in bytes */
2142    void *data; /* either 'char *' or 'int *' */
2143    int size_allocated;
2144    void *data_allocated; /* if non NULL, data has been malloced */
2145} CString;
2146
2147/* type definition */
2148typedef struct CType {
2149    int t;
2150    struct Sym *ref;
2151} CType;
2152
2153/* constant value */
2154typedef union CValue {
2155    long double ld;
2156    double d;
2157    float f;
2158    int i;
2159    unsigned int ui;
2160    unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
2161    long long ll;
2162    unsigned long long ull;
2163    struct CString *cstr;
2164    void *ptr;
2165    int tab[sizeof(long double) / sizeof(int)];
2166} CValue;
2167
2168/* value on stack */
2169typedef struct SValue {
2170    CType type;      /* type */
2171    unsigned short r;      /* register + flags */
2172    unsigned short r2;     /* second register, used for 'long long'
2173                              type. If not used, set to VT_CONST */
2174    CValue c;              /* constant, if VT_CONST */
2175    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
2176} SValue;
2177
2178/* symbol management */
2179typedef struct Sym {
2180    long v;    /* symbol token */
2181    long r;    /* associated register */
2182    long c;    /* associated number */
2183    CType type;    /* associated type */
2184    struct Sym *next; /* next related symbol */
2185    struct Sym *prev; /* prev symbol in stack */
2186    struct Sym *prev_tok; /* previous symbol for this token */
2187} Sym;
2188
2189/* section definition */
2190/* XXX: use directly ELF structure for parameters ? */
2191/* special flag to indicate that the section should not be linked to
2192   the other ones */
2193#define SHF_PRIVATE 0x80000000
2194
2195typedef struct Section {
2196    unsigned long data_offset; /* current data offset */
2197    unsigned char *data;       /* section data */
2198    unsigned long data_allocated; /* used for realloc() handling */
2199    int sh_name;             /* elf section name (only used during output) */
2200    int sh_num;              /* elf section number */
2201    int sh_type;             /* elf section type */
2202    int sh_flags;            /* elf section flags */
2203    int sh_info;             /* elf section info */
2204    int sh_addralign;        /* elf section alignment */
2205    int sh_entsize;          /* elf entry size */
2206    unsigned long sh_size;   /* section size (only used during output) */
2207    unsigned long sh_addr;      /* address at which the section is relocated */
2208    unsigned long sh_offset;      /* address at which the section is relocated */
2209    int nb_hashed_syms;      /* used to resize the hash table */
2210    struct Section *link;    /* link to another section */
2211    struct Section *reloc;   /* corresponding section for relocation, if any */
2212    struct Section *hash;     /* hash table for symbols */
2213    struct Section *next;
2214    char name[1];           /* section name */
2215} Section;
2216
2217typedef struct DLLReference {
2218    int level;
2219    char name[1];
2220} DLLReference;
2221
2222/* GNUC attribute definition */
2223typedef struct AttributeDef {
2224    int aligned;
2225    int packed;
2226    Section *section;
2227    unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
2228    unsigned char dllexport;
2229} AttributeDef;
2230
2231#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
2232#define SYM_FIELD      0x20000000 /* struct/union field symbol space */
2233#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
2234
2235/* stored in 'Sym.c' field */
2236#define FUNC_NEW       1 /* ansi function prototype */
2237#define FUNC_OLD       2 /* old function prototype */
2238#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
2239
2240/* stored in 'Sym.r' field */
2241#define FUNC_CDECL     0 /* standard c call */
2242#define FUNC_STDCALL   1 /* pascal c call */
2243#define FUNC_FASTCALL1 2 /* first param in %eax */
2244#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
2245#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
2246
2247/* field 'Sym.t' for macros */
2248#define MACRO_OBJ      0 /* object like macro */
2249#define MACRO_FUNC     1 /* function like macro */
2250
2251/* field 'Sym.r' for C labels */
2252#define LABEL_DEFINED  0 /* label is defined */
2253#define LABEL_FORWARD  1 /* label is forward defined */
2254#define LABEL_DECLARED 2 /* label is declared but never used */
2255
2256/* type_decl() types */
2257#define TYPE_ABSTRACT  1 /* type without variable */
2258#define TYPE_DIRECT    2 /* type with variable */
2259
2260#define IO_BUF_SIZE 8192
2261
2262typedef struct BufferedFile {
2263    uint8_t *buf_ptr;
2264    uint8_t *buf_end;
2265    int fd;
2266    int line_num;    /* current line number - here to simplify code */
2267    int ifndef_macro;  /* #ifndef macro / #endif search */
2268    int ifndef_macro_saved; /* saved ifndef_macro */
2269    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
2270    char inc_type;          /* type of include */
2271    char inc_filename[512]; /* filename specified by the user */
2272    char filename[1024];    /* current filename - here to simplify code */
2273    unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
2274} BufferedFile;
2275
2276#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
2277#define CH_EOF   (-1)   /* end of file */
2278
2279/* parsing state (used to save parser state to reparse part of the
2280   source several times) */
2281typedef struct ParseState {
2282    int *macro_ptr;
2283    int line_num;
2284    int tok;
2285    CValue tokc;
2286} ParseState;
2287
2288/* used to record tokens */
2289typedef struct TokenString {
2290    int *str;
2291    int len;
2292    int allocated_len;
2293    int last_line_num;
2294} TokenString;
2295
2296/* include file cache, used to find files faster and also to eliminate
2297   inclusion if the include file is protected by #ifndef ... #endif */
2298typedef struct CachedInclude {
2299    int ifndef_macro;
2300    int hash_next; /* -1 if none */
2301    char type; /* '"' or '>' to give include type */
2302    char filename[1]; /* path specified in #include */
2303} CachedInclude;
2304
2305#define CACHED_INCLUDES_HASH_SIZE 512
2306
2307/* parser */
2308static struct BufferedFile *file;
2309static int ch, tok;
2310static CValue tokc;
2311static CString tokcstr; /* current parsed string, if any */
2312/* additional informations about token */
2313static int tok_flags;
2314#define TOK_FLAG_BOL   0x0001 /* beginning of line before */
2315#define TOK_FLAG_BOF   0x0002 /* beginning of file before */
2316#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
2317
2318static int *macro_ptr, *macro_ptr_allocated;
2319static int *unget_saved_macro_ptr;
2320static int unget_saved_buffer[TOK_MAX_SIZE + 1];
2321static int unget_buffer_enabled;
2322static int parse_flags;
2323#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
2324#define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
2325#define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
2326                                        token. line feed is also
2327                                        returned at eof */
2328#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
2329
2330static Section *text_section, *data_section, *bss_section; /* predefined sections */
2331static Section *cur_text_section; /* current section where function code is
2332                              generated */
2333#ifdef CONFIG_TCC_ASM
2334static Section *last_text_section; /* to handle .previous asm directive */
2335#endif
2336/* bound check related sections */
2337static Section *bounds_section; /* contains global data bound description */
2338static Section *lbounds_section; /* contains local data bound description */
2339/* symbol sections */
2340static Section *symtab_section, *strtab_section;
2341
2342/* debug sections */
2343static Section *stab_section, *stabstr_section;
2344
2345/* loc : local variable index
2346   ind : output code index
2347   rsym: return symbol
2348   anon_sym: anonymous symbol index
2349*/
2350static long rsym, anon_sym, ind, loc;
2351/* expression generation modifiers */
2352static int const_wanted; /* true if constant wanted */
2353static int nocode_wanted; /* true if no code generation wanted for an expression */
2354static int global_expr;  /* true if compound literals must be allocated
2355                            globally (used during initializers parsing */
2356static CType func_vt; /* current function return type (used by return
2357                         instruction) */
2358static int func_vc;
2359static long last_line_num, last_ind, func_ind; /* debug last line number and pc */
2360static int tok_ident;
2361static TokenSym **table_ident;
2362static TokenSym *hash_ident[TOK_HASH_SIZE];
2363static char token_buf[STRING_MAX_SIZE + 1];
2364static char *funcname;
2365static Sym *global_stack, *local_stack;
2366static Sym *define_stack;
2367static Sym *global_label_stack, *local_label_stack;
2368/* symbol allocator */
2369#define SYM_POOL_NB (8192 / sizeof(Sym))
2370static Sym *sym_free_first;
2371
2372static SValue vstack[VSTACK_SIZE], *vtop;
2373/* some predefined types */
2374static CType char_pointer_type, func_old_type, int_type;
2375/* true if isid(c) || isnum(c) */
2376static unsigned char isidnum_table[256];
2377
2378/* compile with debug symbol (and use them if error during execution) */
2379static int do_debug = 0;
2380
2381/* compile with built-in memory and bounds checker */
2382static int do_bounds_check = 0;
2383
2384/* display benchmark infos */
2385#if !defined(LIBTCC)
2386static int do_bench = 0;
2387#endif
2388static int total_lines;
2389static int total_bytes;
2390
2391/* use GNU C extensions */
2392static int gnu_ext = 1;
2393
2394/* use Tiny C extensions */
2395static int tcc_ext = 1;
2396
2397/* max number of callers shown if error */
2398static int num_callers = 6;
2399static const char **rt_bound_error_msg;
2400
2401/* XXX: get rid of this ASAP */
2402static struct TCCState *tcc_state;
2403
2404/* give the path of the tcc libraries */
2405static const char *tcc_lib_path = CONFIG_TCCDIR;
2406
2407struct TCCState {
2408    int output_type;
2409
2410    BufferedFile **include_stack_ptr;
2411    int *ifdef_stack_ptr;
2412
2413    /* include file handling */
2414    char **include_paths;
2415    int nb_include_paths;
2416    char **sysinclude_paths;
2417    int nb_sysinclude_paths;
2418    CachedInclude **cached_includes;
2419    int nb_cached_includes;
2420
2421    char **library_paths;
2422    int nb_library_paths;
2423
2424    /* array of all loaded dlls (including those referenced by loaded
2425       dlls) */
2426    DLLReference **loaded_dlls;
2427    int nb_loaded_dlls;
2428
2429    /* sections */
2430    Section **sections;
2431    int nb_sections; /* number of sections, including first dummy section */
2432
2433    /* got handling */
2434    Section *got;
2435    Section *plt;
2436    unsigned long *got_offsets;
2437    int nb_got_offsets;
2438    /* give the correspondance from symtab indexes to dynsym indexes */
2439    int *symtab_to_dynsym;
2440
2441    /* temporary dynamic symbol sections (for dll loading) */
2442    Section *dynsymtab_section;
2443    /* exported dynamic symbol section */
2444    Section *dynsym;
2445
2446    int nostdinc; /* if true, no standard headers are added */
2447    int nostdlib; /* if true, no standard libraries are added */
2448
2449    int nocommon; /* if true, do not use common symbols for .bss data */
2450
2451    /* if true, static linking is performed */
2452    int static_link;
2453
2454    /* if true, all symbols are exported */
2455    int rdynamic;
2456
2457    /* if true, only link in referenced objects from archive */
2458    int alacarte_link;
2459
2460    /* address of text section */
2461    unsigned long text_addr;
2462    int has_text_addr;
2463
2464    /* output format, see TCC_OUTPUT_FORMAT_xxx */
2465    int output_format;
2466
2467    /* C language options */
2468    int char_is_unsigned;
2469    int leading_underscore;
2470
2471    /* warning switches */
2472    int warn_write_strings;
2473    int warn_unsupported;
2474    int warn_error;
2475    int warn_none;
2476    int warn_implicit_function_declaration;
2477
2478    /* error handling */
2479    void *error_opaque;
2480    void (*error_func)(void *opaque, const char *msg);
2481    int error_set_jmp_enabled;
2482    jmp_buf error_jmp_buf;
2483    int nb_errors;
2484
2485    /* tiny assembler state */
2486    Sym *asm_labels;
2487
2488    /* see include_stack_ptr */
2489    BufferedFile *include_stack[INCLUDE_STACK_SIZE];
2490
2491    /* see ifdef_stack_ptr */
2492    int ifdef_stack[IFDEF_STACK_SIZE];
2493
2494    /* see cached_includes */
2495    int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
2496
2497    /* pack stack */
2498    int pack_stack[PACK_STACK_SIZE];
2499    int *pack_stack_ptr;
2500};
2501
2502/* The current value can be: */
2503#define VT_VALMASK   0x00ff
2504#define VT_CONST     0x00f0  /* constant in vc
2505                              (must be first non register value) */
2506#define VT_LLOCAL    0x00f1  /* lvalue, offset on stack */
2507#define VT_LOCAL     0x00f2  /* offset on stack */
2508#define VT_CMP       0x00f3  /* the value is stored in processor flags (in vc) */
2509#define VT_JMP       0x00f4  /* value is the consequence of jmp true (even) */
2510#define VT_JMPI      0x00f5  /* value is the consequence of jmp false (odd) */
2511#define VT_LVAL      0x0100  /* var is an lvalue */
2512#define VT_SYM       0x0200  /* a symbol value is added */
2513#define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
2514                                char/short stored in integer registers) */
2515#define VT_MUSTBOUND 0x0800  /* bound checking must be done before
2516                                dereferencing value */
2517#define VT_BOUNDED   0x8000  /* value is bounded. The address of the
2518                                bounding function call point is in vc */
2519#define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
2520#define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
2521#define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
2522#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
2523
2524/* types */
2525#define VT_INT        0  /* integer type */
2526#define VT_BYTE       1  /* signed byte type */
2527#define VT_SHORT      2  /* short type */
2528#define VT_VOID       3  /* void type */
2529#define VT_PTR        4  /* pointer */
2530#define VT_ENUM       5  /* enum definition */
2531#define VT_FUNC       6  /* function type */
2532#define VT_STRUCT     7  /* struct/union definition */
2533#define VT_FLOAT      8  /* IEEE float */
2534#define VT_DOUBLE     9  /* IEEE double */
2535#define VT_LDOUBLE   10  /* IEEE long double */
2536#define VT_BOOL      11  /* ISOC99 boolean type */
2537#define VT_LLONG     12  /* 64 bit integer */
2538#define VT_LONG      13  /* long integer (NEVER USED as type, only
2539                            during parsing) */
2540#define VT_BTYPE      0x000f /* mask for basic type */
2541#define VT_UNSIGNED   0x0010  /* unsigned type */
2542#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
2543#define VT_BITFIELD   0x0040  /* bitfield modifier */
2544#define VT_CONSTANT   0x0800  /* const modifier */
2545#define VT_VOLATILE   0x1000  /* volatile modifier */
2546#define VT_SIGNED     0x2000  /* signed type */
2547
2548/* storage */
2549#define VT_EXTERN  0x00000080  /* extern definition */
2550#define VT_STATIC  0x00000100  /* static variable */
2551#define VT_TYPEDEF 0x00000200  /* typedef definition */
2552#define VT_INLINE  0x00000400  /* inline definition */
2553
2554#define VT_STRUCT_SHIFT 16   /* shift for bitfield shift values */
2555
2556/* type mask (except storage) */
2557#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
2558#define VT_TYPE    (~(VT_STORAGE))
2559
2560/* token values */
2561
2562/* warning: the following compare tokens depend on i386 asm code */
2563#define TOK_ULT 0x92
2564#define TOK_UGE 0x93
2565#define TOK_EQ  0x94
2566#define TOK_NE  0x95
2567#define TOK_ULE 0x96
2568#define TOK_UGT 0x97
2569#define TOK_LT  0x9c
2570#define TOK_GE  0x9d
2571#define TOK_LE  0x9e
2572#define TOK_GT  0x9f
2573
2574#define TOK_LAND  0xa0
2575#define TOK_LOR   0xa1
2576
2577#define TOK_DEC   0xa2
2578#define TOK_MID   0xa3 /* inc/dec, to void constant */
2579#define TOK_INC   0xa4
2580#define TOK_UDIV  0xb0 /* unsigned division */
2581#define TOK_UMOD  0xb1 /* unsigned modulo */
2582#define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
2583#define TOK_CINT   0xb3 /* number in tokc */
2584#define TOK_CCHAR 0xb4 /* char constant in tokc */
2585#define TOK_STR   0xb5 /* pointer to string in tokc */
2586#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
2587#define TOK_LCHAR    0xb7
2588#define TOK_LSTR     0xb8
2589#define TOK_CFLOAT   0xb9 /* float constant */
2590#define TOK_LINENUM  0xba /* line number info */
2591#define TOK_CDOUBLE  0xc0 /* double constant */
2592#define TOK_CLDOUBLE 0xc1 /* long double constant */
2593#define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
2594#define TOK_ADDC1    0xc3 /* add with carry generation */
2595#define TOK_ADDC2    0xc4 /* add with carry use */
2596#define TOK_SUBC1    0xc5 /* add with carry generation */
2597#define TOK_SUBC2    0xc6 /* add with carry use */
2598#define TOK_CUINT    0xc8 /* unsigned int constant */
2599#define TOK_CLLONG   0xc9 /* long long constant */
2600#define TOK_CULLONG  0xca /* unsigned long long constant */
2601#define TOK_ARROW    0xcb
2602#define TOK_DOTS     0xcc /* three dots */
2603#define TOK_SHR      0xcd /* unsigned shift right */
2604#define TOK_PPNUM    0xce /* preprocessor number */
2605
2606#define TOK_SHL   0x01 /* shift left */
2607#define TOK_SAR   0x02 /* signed shift right */
2608
2609/* assignement operators : normal operator or 0x80 */
2610#define TOK_A_MOD 0xa5
2611#define TOK_A_AND 0xa6
2612#define TOK_A_MUL 0xaa
2613#define TOK_A_ADD 0xab
2614#define TOK_A_SUB 0xad
2615#define TOK_A_DIV 0xaf
2616#define TOK_A_XOR 0xde
2617#define TOK_A_OR  0xfc
2618#define TOK_A_SHL 0x81
2619#define TOK_A_SAR 0x82
2620
2621#ifndef offsetof
2622#define offsetof(type, field) ((size_t) &((type *)0)->field)
2623#endif
2624
2625#ifndef countof
2626#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
2627#endif
2628
2629/* WARNING: the content of this string encodes token numbers */
2630static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
2631
2632#define TOK_EOF       (-1)  /* end of file */
2633#define TOK_LINEFEED  10    /* line feed */
2634
2635/* all identificators and strings have token above that */
2636#define TOK_IDENT 256
2637
2638/* only used for i386 asm opcodes definitions */
2639#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
2640
2641#define DEF_BWL(x) \
2642 DEF(TOK_ASM_ ## x ## b, #x "b") \
2643 DEF(TOK_ASM_ ## x ## w, #x "w") \
2644 DEF(TOK_ASM_ ## x ## l, #x "l") \
2645 DEF(TOK_ASM_ ## x, #x)
2646
2647#define DEF_WL(x) \
2648 DEF(TOK_ASM_ ## x ## w, #x "w") \
2649 DEF(TOK_ASM_ ## x ## l, #x "l") \
2650 DEF(TOK_ASM_ ## x, #x)
2651
2652#define DEF_FP1(x) \
2653 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
2654 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
2655 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
2656 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
2657
2658#define DEF_FP(x) \
2659 DEF(TOK_ASM_ ## f ## x, "f" #x ) \
2660 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
2661 DEF_FP1(x)
2662
2663#define DEF_ASMTEST(x) \
2664 DEF_ASM(x ## o) \
2665 DEF_ASM(x ## no) \
2666 DEF_ASM(x ## b) \
2667 DEF_ASM(x ## c) \
2668 DEF_ASM(x ## nae) \
2669 DEF_ASM(x ## nb) \
2670 DEF_ASM(x ## nc) \
2671 DEF_ASM(x ## ae) \
2672 DEF_ASM(x ## e) \
2673 DEF_ASM(x ## z) \
2674 DEF_ASM(x ## ne) \
2675 DEF_ASM(x ## nz) \
2676 DEF_ASM(x ## be) \
2677 DEF_ASM(x ## na) \
2678 DEF_ASM(x ## nbe) \
2679 DEF_ASM(x ## a) \
2680 DEF_ASM(x ## s) \
2681 DEF_ASM(x ## ns) \
2682 DEF_ASM(x ## p) \
2683 DEF_ASM(x ## pe) \
2684 DEF_ASM(x ## np) \
2685 DEF_ASM(x ## po) \
2686 DEF_ASM(x ## l) \
2687 DEF_ASM(x ## nge) \
2688 DEF_ASM(x ## nl) \
2689 DEF_ASM(x ## ge) \
2690 DEF_ASM(x ## le) \
2691 DEF_ASM(x ## ng) \
2692 DEF_ASM(x ## nle) \
2693 DEF_ASM(x ## g)
2694
2695#define TOK_ASM_int TOK_INT
2696
2697enum tcc_token {
2698    TOK_LAST = TOK_IDENT - 1,
2699#define DEF(id, str) id,
2700// njn: inlined tcctok.h
2701//#include "tcctok.h"
2702//---------------------------------------------------------------------------
2703/* keywords */
2704     DEF(TOK_INT, "int")
2705     DEF(TOK_VOID, "void")
2706     DEF(TOK_CHAR, "char")
2707     DEF(TOK_IF, "if")
2708     DEF(TOK_ELSE, "else")
2709     DEF(TOK_WHILE, "while")
2710     DEF(TOK_BREAK, "break")
2711     DEF(TOK_RETURN, "return")
2712     DEF(TOK_FOR, "for")
2713     DEF(TOK_EXTERN, "extern")
2714     DEF(TOK_STATIC, "static")
2715     DEF(TOK_UNSIGNED, "unsigned")
2716     DEF(TOK_GOTO, "goto")
2717     DEF(TOK_DO, "do")
2718     DEF(TOK_CONTINUE, "continue")
2719     DEF(TOK_SWITCH, "switch")
2720     DEF(TOK_CASE, "case")
2721
2722     DEF(TOK_CONST1, "const")
2723     DEF(TOK_CONST2, "__const") /* gcc keyword */
2724     DEF(TOK_CONST3, "__const__") /* gcc keyword */
2725     DEF(TOK_VOLATILE1, "volatile")
2726     DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
2727     DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
2728     DEF(TOK_LONG, "long")
2729     DEF(TOK_REGISTER, "register")
2730     DEF(TOK_SIGNED1, "signed")
2731     DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
2732     DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
2733     DEF(TOK_AUTO, "auto")
2734     DEF(TOK_INLINE1, "inline")
2735     DEF(TOK_INLINE2, "__inline") /* gcc keyword */
2736     DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
2737     DEF(TOK_RESTRICT1, "restrict")
2738     DEF(TOK_RESTRICT2, "__restrict")
2739     DEF(TOK_RESTRICT3, "__restrict__")
2740     DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
2741
2742     DEF(TOK_FLOAT, "float")
2743     DEF(TOK_DOUBLE, "double")
2744     DEF(TOK_BOOL, "_Bool")
2745     DEF(TOK_SHORT, "short")
2746     DEF(TOK_STRUCT, "struct")
2747     DEF(TOK_UNION, "union")
2748     DEF(TOK_TYPEDEF, "typedef")
2749     DEF(TOK_DEFAULT, "default")
2750     DEF(TOK_ENUM, "enum")
2751     DEF(TOK_SIZEOF, "sizeof")
2752     DEF(TOK_ATTRIBUTE1, "__attribute")
2753     DEF(TOK_ATTRIBUTE2, "__attribute__")
2754     DEF(TOK_ALIGNOF1, "__alignof")
2755     DEF(TOK_ALIGNOF2, "__alignof__")
2756     DEF(TOK_TYPEOF1, "typeof")
2757     DEF(TOK_TYPEOF2, "__typeof")
2758     DEF(TOK_TYPEOF3, "__typeof__")
2759     DEF(TOK_LABEL, "__label__")
2760     DEF(TOK_ASM1, "asm")
2761     DEF(TOK_ASM2, "__asm")
2762     DEF(TOK_ASM3, "__asm__")
2763
2764/*********************************************************************/
2765/* the following are not keywords. They are included to ease parsing */
2766/* preprocessor only */
2767     DEF(TOK_DEFINE, "define")
2768     DEF(TOK_INCLUDE, "include")
2769     DEF(TOK_INCLUDE_NEXT, "include_next")
2770     DEF(TOK_IFDEF, "ifdef")
2771     DEF(TOK_IFNDEF, "ifndef")
2772     DEF(TOK_ELIF, "elif")
2773     DEF(TOK_ENDIF, "endif")
2774     DEF(TOK_DEFINED, "defined")
2775     DEF(TOK_UNDEF, "undef")
2776     DEF(TOK_ERROR, "error")
2777     DEF(TOK_WARNING, "warning")
2778     DEF(TOK_LINE, "line")
2779     DEF(TOK_PRAGMA, "pragma")
2780     DEF(TOK___LINE__, "__LINE__")
2781     DEF(TOK___FILE__, "__FILE__")
2782     DEF(TOK___DATE__, "__DATE__")
2783     DEF(TOK___TIME__, "__TIME__")
2784     DEF(TOK___FUNCTION__, "__FUNCTION__")
2785     DEF(TOK___VA_ARGS__, "__VA_ARGS__")
2786
2787/* special identifiers */
2788     DEF(TOK___FUNC__, "__func__")
2789
2790/* attribute identifiers */
2791/* XXX: handle all tokens generically since speed is not critical */
2792     DEF(TOK_SECTION1, "section")
2793     DEF(TOK_SECTION2, "__section__")
2794     DEF(TOK_ALIGNED1, "aligned")
2795     DEF(TOK_ALIGNED2, "__aligned__")
2796     DEF(TOK_PACKED1, "packed")
2797     DEF(TOK_PACKED2, "__packed__")
2798     DEF(TOK_UNUSED1, "unused")
2799     DEF(TOK_UNUSED2, "__unused__")
2800     DEF(TOK_CDECL1, "cdecl")
2801     DEF(TOK_CDECL2, "__cdecl")
2802     DEF(TOK_CDECL3, "__cdecl__")
2803     DEF(TOK_STDCALL1, "stdcall")
2804     DEF(TOK_STDCALL2, "__stdcall")
2805     DEF(TOK_STDCALL3, "__stdcall__")
2806     DEF(TOK_DLLEXPORT, "dllexport")
2807     DEF(TOK_NORETURN1, "noreturn")
2808     DEF(TOK_NORETURN2, "__noreturn__")
2809     DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
2810     DEF(TOK_builtin_constant_p, "__builtin_constant_p")
2811     DEF(TOK_REGPARM1, "regparm")
2812     DEF(TOK_REGPARM2, "__regparm__")
2813
2814/* pragma */
2815     DEF(TOK_pack, "pack")
2816#if !defined(TCC_TARGET_I386)
2817     /* already defined for assembler */
2818     DEF(TOK_ASM_push, "push")
2819     DEF(TOK_ASM_pop, "pop")
2820#endif
2821
2822/* builtin functions or variables */
2823     DEF(TOK_memcpy, "memcpy")
2824     DEF(TOK_memset, "memset")
2825     DEF(TOK_alloca, "alloca")
2826     DEF(TOK___divdi3, "__divdi3")
2827     DEF(TOK___moddi3, "__moddi3")
2828     DEF(TOK___udivdi3, "__udivdi3")
2829     DEF(TOK___umoddi3, "__umoddi3")
2830#if defined(TCC_TARGET_ARM)
2831     DEF(TOK___divsi3, "__divsi3")
2832     DEF(TOK___modsi3, "__modsi3")
2833     DEF(TOK___udivsi3, "__udivsi3")
2834     DEF(TOK___umodsi3, "__umodsi3")
2835     DEF(TOK___sardi3, "__ashrdi3")
2836     DEF(TOK___shrdi3, "__lshrdi3")
2837     DEF(TOK___shldi3, "__ashldi3")
2838     DEF(TOK___slltold, "__slltold")
2839     DEF(TOK___fixunssfsi, "__fixunssfsi")
2840     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
2841     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
2842     DEF(TOK___fixsfdi, "__fixsfdi")
2843     DEF(TOK___fixdfdi, "__fixdfdi")
2844     DEF(TOK___fixxfdi, "__fixxfdi")
2845#elif defined(TCC_TARGET_C67)
2846     DEF(TOK__divi, "_divi")
2847     DEF(TOK__divu, "_divu")
2848     DEF(TOK__divf, "_divf")
2849     DEF(TOK__divd, "_divd")
2850     DEF(TOK__remi, "_remi")
2851     DEF(TOK__remu, "_remu")
2852     DEF(TOK___sardi3, "__sardi3")
2853     DEF(TOK___shrdi3, "__shrdi3")
2854     DEF(TOK___shldi3, "__shldi3")
2855#else
2856     /* XXX: same names on i386 ? */
2857     DEF(TOK___sardi3, "__sardi3")
2858     DEF(TOK___shrdi3, "__shrdi3")
2859     DEF(TOK___shldi3, "__shldi3")
2860#endif
2861     DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
2862     DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
2863     DEF(TOK___ulltof, "__ulltof")
2864     DEF(TOK___ulltod, "__ulltod")
2865     DEF(TOK___ulltold, "__ulltold")
2866     DEF(TOK___fixunssfdi, "__fixunssfdi")
2867     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
2868     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
2869     DEF(TOK___chkstk, "__chkstk")
2870
2871/* bound checking symbols */
2872#ifdef CONFIG_TCC_BCHECK
2873     DEF(TOK___bound_ptr_add, "__bound_ptr_add")
2874     DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
2875     DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
2876     DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
2877     DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
2878     DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
2879     DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
2880     DEF(TOK___bound_local_new, "__bound_local_new")
2881     DEF(TOK___bound_local_delete, "__bound_local_delete")
2882     DEF(TOK_malloc, "malloc")
2883     DEF(TOK_free, "free")
2884     DEF(TOK_realloc, "realloc")
2885     DEF(TOK_memalign, "memalign")
2886     DEF(TOK_calloc, "calloc")
2887     DEF(TOK_memmove, "memmove")
2888     DEF(TOK_strlen, "strlen")
2889     DEF(TOK_strcpy, "strcpy")
2890#endif
2891
2892/* Tiny Assembler */
2893
2894 DEF_ASM(byte)
2895 DEF_ASM(align)
2896 DEF_ASM(skip)
2897 DEF_ASM(space)
2898 DEF_ASM(string)
2899 DEF_ASM(asciz)
2900 DEF_ASM(ascii)
2901 DEF_ASM(globl)
2902 DEF_ASM(global)
2903 DEF_ASM(text)
2904 DEF_ASM(data)
2905 DEF_ASM(bss)
2906 DEF_ASM(previous)
2907 DEF_ASM(fill)
2908 DEF_ASM(org)
2909 DEF_ASM(quad)
2910
2911#ifdef TCC_TARGET_I386
2912
2913/* WARNING: relative order of tokens is important. */
2914 DEF_ASM(al)
2915 DEF_ASM(cl)
2916 DEF_ASM(dl)
2917 DEF_ASM(bl)
2918 DEF_ASM(ah)
2919 DEF_ASM(ch)
2920 DEF_ASM(dh)
2921 DEF_ASM(bh)
2922 DEF_ASM(ax)
2923 DEF_ASM(cx)
2924 DEF_ASM(dx)
2925 DEF_ASM(bx)
2926 DEF_ASM(sp)
2927 DEF_ASM(bp)
2928 DEF_ASM(si)
2929 DEF_ASM(di)
2930 DEF_ASM(eax)
2931 DEF_ASM(ecx)
2932 DEF_ASM(edx)
2933 DEF_ASM(ebx)
2934 DEF_ASM(esp)
2935 DEF_ASM(ebp)
2936 DEF_ASM(esi)
2937 DEF_ASM(edi)
2938 DEF_ASM(mm0)
2939 DEF_ASM(mm1)
2940 DEF_ASM(mm2)
2941 DEF_ASM(mm3)
2942 DEF_ASM(mm4)
2943 DEF_ASM(mm5)
2944 DEF_ASM(mm6)
2945 DEF_ASM(mm7)
2946 DEF_ASM(xmm0)
2947 DEF_ASM(xmm1)
2948 DEF_ASM(xmm2)
2949 DEF_ASM(xmm3)
2950 DEF_ASM(xmm4)
2951 DEF_ASM(xmm5)
2952 DEF_ASM(xmm6)
2953 DEF_ASM(xmm7)
2954 DEF_ASM(cr0)
2955 DEF_ASM(cr1)
2956 DEF_ASM(cr2)
2957 DEF_ASM(cr3)
2958 DEF_ASM(cr4)
2959 DEF_ASM(cr5)
2960 DEF_ASM(cr6)
2961 DEF_ASM(cr7)
2962 DEF_ASM(tr0)
2963 DEF_ASM(tr1)
2964 DEF_ASM(tr2)
2965 DEF_ASM(tr3)
2966 DEF_ASM(tr4)
2967 DEF_ASM(tr5)
2968 DEF_ASM(tr6)
2969 DEF_ASM(tr7)
2970 DEF_ASM(db0)
2971 DEF_ASM(db1)
2972 DEF_ASM(db2)
2973 DEF_ASM(db3)
2974 DEF_ASM(db4)
2975 DEF_ASM(db5)
2976 DEF_ASM(db6)
2977 DEF_ASM(db7)
2978 DEF_ASM(dr0)
2979 DEF_ASM(dr1)
2980 DEF_ASM(dr2)
2981 DEF_ASM(dr3)
2982 DEF_ASM(dr4)
2983 DEF_ASM(dr5)
2984 DEF_ASM(dr6)
2985 DEF_ASM(dr7)
2986 DEF_ASM(es)
2987 DEF_ASM(cs)
2988 DEF_ASM(ss)
2989 DEF_ASM(ds)
2990 DEF_ASM(fs)
2991 DEF_ASM(gs)
2992 DEF_ASM(st)
2993
2994 DEF_BWL(mov)
2995
2996 /* generic two operands */
2997 DEF_BWL(add)
2998 DEF_BWL(or)
2999 DEF_BWL(adc)
3000 DEF_BWL(sbb)
3001 DEF_BWL(and)
3002 DEF_BWL(sub)
3003 DEF_BWL(xor)
3004 DEF_BWL(cmp)
3005
3006 /* unary ops */
3007 DEF_BWL(inc)
3008 DEF_BWL(dec)
3009 DEF_BWL(not)
3010 DEF_BWL(neg)
3011 DEF_BWL(mul)
3012 DEF_BWL(imul)
3013 DEF_BWL(div)
3014 DEF_BWL(idiv)
3015
3016 DEF_BWL(xchg)
3017 DEF_BWL(test)
3018
3019 /* shifts */
3020 DEF_BWL(rol)
3021 DEF_BWL(ror)
3022 DEF_BWL(rcl)
3023 DEF_BWL(rcr)
3024 DEF_BWL(shl)
3025 DEF_BWL(shr)
3026 DEF_BWL(sar)
3027
3028 DEF_ASM(shldw)
3029 DEF_ASM(shldl)
3030 DEF_ASM(shld)
3031 DEF_ASM(shrdw)
3032 DEF_ASM(shrdl)
3033 DEF_ASM(shrd)
3034
3035 DEF_ASM(pushw)
3036 DEF_ASM(pushl)
3037 DEF_ASM(push)
3038 DEF_ASM(popw)
3039 DEF_ASM(popl)
3040 DEF_ASM(pop)
3041 DEF_BWL(in)
3042 DEF_BWL(out)
3043
3044 DEF_WL(movzb)
3045
3046 DEF_ASM(movzwl)
3047 DEF_ASM(movsbw)
3048 DEF_ASM(movsbl)
3049 DEF_ASM(movswl)
3050
3051 DEF_WL(lea)
3052
3053 DEF_ASM(les)
3054 DEF_ASM(lds)
3055 DEF_ASM(lss)
3056 DEF_ASM(lfs)
3057 DEF_ASM(lgs)
3058
3059 DEF_ASM(call)
3060 DEF_ASM(jmp)
3061 DEF_ASM(lcall)
3062 DEF_ASM(ljmp)
3063
3064 DEF_ASMTEST(j)
3065
3066 DEF_ASMTEST(set)
3067 DEF_ASMTEST(cmov)
3068
3069 DEF_WL(bsf)
3070 DEF_WL(bsr)
3071 DEF_WL(bt)
3072 DEF_WL(bts)
3073 DEF_WL(btr)
3074 DEF_WL(btc)
3075
3076 DEF_WL(lsl)
3077
3078 /* generic FP ops */
3079 DEF_FP(add)
3080 DEF_FP(mul)
3081
3082 DEF_ASM(fcom)
3083 DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
3084 DEF_FP1(com)
3085
3086 DEF_FP(comp)
3087 DEF_FP(sub)
3088 DEF_FP(subr)
3089 DEF_FP(div)
3090 DEF_FP(divr)
3091
3092 DEF_BWL(xadd)
3093 DEF_BWL(cmpxchg)
3094
3095 /* string ops */
3096 DEF_BWL(cmps)
3097 DEF_BWL(scmp)
3098 DEF_BWL(ins)
3099 DEF_BWL(outs)
3100 DEF_BWL(lods)
3101 DEF_BWL(slod)
3102 DEF_BWL(movs)
3103 DEF_BWL(smov)
3104 DEF_BWL(scas)
3105 DEF_BWL(ssca)
3106 DEF_BWL(stos)
3107 DEF_BWL(ssto)
3108
3109 /* generic asm ops */
3110
3111#define ALT(x)
3112#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
3113#define DEF_ASM_OP0L(name, opcode, group, instr_type)
3114#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
3115#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
3116#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
3117// njn: inlined i386-asm.h
3118//#include "i386-asm.h"
3119//---------------------------------------------------------------------------
3120     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
3121     DEF_ASM_OP0(popa, 0x61)
3122     DEF_ASM_OP0(clc, 0xf8)
3123     DEF_ASM_OP0(cld, 0xfc)
3124     DEF_ASM_OP0(cli, 0xfa)
3125     DEF_ASM_OP0(clts, 0x0f06)
3126     DEF_ASM_OP0(cmc, 0xf5)
3127     DEF_ASM_OP0(lahf, 0x9f)
3128     DEF_ASM_OP0(sahf, 0x9e)
3129     DEF_ASM_OP0(pushfl, 0x9c)
3130     DEF_ASM_OP0(popfl, 0x9d)
3131     DEF_ASM_OP0(pushf, 0x9c)
3132     DEF_ASM_OP0(popf, 0x9d)
3133     DEF_ASM_OP0(stc, 0xf9)
3134     DEF_ASM_OP0(std, 0xfd)
3135     DEF_ASM_OP0(sti, 0xfb)
3136     DEF_ASM_OP0(aaa, 0x37)
3137     DEF_ASM_OP0(aas, 0x3f)
3138     DEF_ASM_OP0(daa, 0x27)
3139     DEF_ASM_OP0(das, 0x2f)
3140     DEF_ASM_OP0(aad, 0xd50a)
3141     DEF_ASM_OP0(aam, 0xd40a)
3142     DEF_ASM_OP0(cbw, 0x6698)
3143     DEF_ASM_OP0(cwd, 0x6699)
3144     DEF_ASM_OP0(cwde, 0x98)
3145     DEF_ASM_OP0(cdq, 0x99)
3146     DEF_ASM_OP0(cbtw, 0x6698)
3147     DEF_ASM_OP0(cwtl, 0x98)
3148     DEF_ASM_OP0(cwtd, 0x6699)
3149     DEF_ASM_OP0(cltd, 0x99)
3150     DEF_ASM_OP0(int3, 0xcc)
3151     DEF_ASM_OP0(into, 0xce)
3152     DEF_ASM_OP0(iret, 0xcf)
3153     DEF_ASM_OP0(rsm, 0x0faa)
3154     DEF_ASM_OP0(hlt, 0xf4)
3155     DEF_ASM_OP0(wait, 0x9b)
3156     DEF_ASM_OP0(nop, 0x90)
3157     DEF_ASM_OP0(xlat, 0xd7)
3158
3159     /* strings */
3160ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3161ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3162
3163ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3164ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3165
3166ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3167ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3168
3169ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3170ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3171
3172ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3173ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3174
3175ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3176ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3177
3178     /* bits */
3179
3180ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3181ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3182
3183ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3184ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3185
3186ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3187ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3188
3189ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3190ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3191
3192ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3193ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3194
3195     /* prefixes */
3196     DEF_ASM_OP0(aword, 0x67)
3197     DEF_ASM_OP0(addr16, 0x67)
3198     DEF_ASM_OP0(word, 0x66)
3199     DEF_ASM_OP0(data16, 0x66)
3200     DEF_ASM_OP0(lock, 0xf0)
3201     DEF_ASM_OP0(rep, 0xf3)
3202     DEF_ASM_OP0(repe, 0xf3)
3203     DEF_ASM_OP0(repz, 0xf3)
3204     DEF_ASM_OP0(repne, 0xf2)
3205     DEF_ASM_OP0(repnz, 0xf2)
3206
3207     DEF_ASM_OP0(invd, 0x0f08)
3208     DEF_ASM_OP0(wbinvd, 0x0f09)
3209     DEF_ASM_OP0(cpuid, 0x0fa2)
3210     DEF_ASM_OP0(wrmsr, 0x0f30)
3211     DEF_ASM_OP0(rdtsc, 0x0f31)
3212     DEF_ASM_OP0(rdmsr, 0x0f32)
3213     DEF_ASM_OP0(rdpmc, 0x0f33)
3214     DEF_ASM_OP0(ud2, 0x0f0b)
3215
3216     /* NOTE: we took the same order as gas opcode definition order */
3217ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3218ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3219ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3220ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3221ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3222ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3223
3224ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3225ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3226
3227ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3228ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3229ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3230ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3231ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3232ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3233
3234ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3235ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3236ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3237ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3238ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3239
3240ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3241ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3242ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3243ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3244ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3245
3246ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3247ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3248ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3249
3250ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3251ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3252ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3253ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3254
3255ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3256ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3257ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3258ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3259
3260ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3261ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3262ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3263ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3264
3265ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3266
3267ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3268ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3269ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3270ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3271ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3272
3273     /* arith */
3274ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
3275ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3276ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3277ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3278ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3279
3280ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3281ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3282ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3283ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3284
3285ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3286ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3287ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3288ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3289
3290ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3291ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3292
3293ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3294ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3295
3296ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3297ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3298ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3299ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3300ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3301
3302ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3303ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3304ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3305ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3306
3307     /* shifts */
3308ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3309ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3310ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3311
3312ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3313ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3314ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3315ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3316ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3317ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3318
3319ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3320ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3321ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3322ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3323
3324ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3325ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3326ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3327ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3328
3329ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3330ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3331    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3332    DEF_ASM_OP0(leave, 0xc9)
3333    DEF_ASM_OP0(ret, 0xc3)
3334ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3335    DEF_ASM_OP0(lret, 0xcb)
3336ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3337
3338ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3339    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3340    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3341    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3342    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3343    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3344    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3345
3346     /* float */
3347     /* specific fcomp handling */
3348ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3349
3350ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3351ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3352ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3353ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3354ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3355ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3356ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3357ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3358ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3359ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3360ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3361
3362     DEF_ASM_OP0(fucompp, 0xdae9)
3363     DEF_ASM_OP0(ftst, 0xd9e4)
3364     DEF_ASM_OP0(fxam, 0xd9e5)
3365     DEF_ASM_OP0(fld1, 0xd9e8)
3366     DEF_ASM_OP0(fldl2t, 0xd9e9)
3367     DEF_ASM_OP0(fldl2e, 0xd9ea)
3368     DEF_ASM_OP0(fldpi, 0xd9eb)
3369     DEF_ASM_OP0(fldlg2, 0xd9ec)
3370     DEF_ASM_OP0(fldln2, 0xd9ed)
3371     DEF_ASM_OP0(fldz, 0xd9ee)
3372
3373     DEF_ASM_OP0(f2xm1, 0xd9f0)
3374     DEF_ASM_OP0(fyl2x, 0xd9f1)
3375     DEF_ASM_OP0(fptan, 0xd9f2)
3376     DEF_ASM_OP0(fpatan, 0xd9f3)
3377     DEF_ASM_OP0(fxtract, 0xd9f4)
3378     DEF_ASM_OP0(fprem1, 0xd9f5)
3379     DEF_ASM_OP0(fdecstp, 0xd9f6)
3380     DEF_ASM_OP0(fincstp, 0xd9f7)
3381     DEF_ASM_OP0(fprem, 0xd9f8)
3382     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3383     DEF_ASM_OP0(fsqrt, 0xd9fa)
3384     DEF_ASM_OP0(fsincos, 0xd9fb)
3385     DEF_ASM_OP0(frndint, 0xd9fc)
3386     DEF_ASM_OP0(fscale, 0xd9fd)
3387     DEF_ASM_OP0(fsin, 0xd9fe)
3388     DEF_ASM_OP0(fcos, 0xd9ff)
3389     DEF_ASM_OP0(fchs, 0xd9e0)
3390     DEF_ASM_OP0(fabs, 0xd9e1)
3391     DEF_ASM_OP0(fninit, 0xdbe3)
3392     DEF_ASM_OP0(fnclex, 0xdbe2)
3393     DEF_ASM_OP0(fnop, 0xd9d0)
3394     DEF_ASM_OP0(fwait, 0x9b)
3395
3396    /* fp load */
3397    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3398    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3399    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3400ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3401    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3402    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3403    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3404    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3405    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3406
3407    /* fp store */
3408    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
3409    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3410    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3411    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3412ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3413    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3414    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3415    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3416    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3417    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3418
3419    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3420    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3421    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3422    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3423    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3424
3425    /* exchange */
3426    DEF_ASM_OP0(fxch, 0xd9c9)
3427ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3428
3429    /* misc FPU */
3430    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3431    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3432
3433    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3434    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3435    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3436    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3437    DEF_ASM_OP0(fnstsw, 0xdfe0)
3438ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3439ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3440    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3441ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3442ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3443    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3444    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3445    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3446    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3447    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3448    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3449    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3450    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3451    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3452    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3453    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3454
3455    /* segments */
3456    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3457    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3458    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3459    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3460    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3461    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3462ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3463    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3464    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3465    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3466    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3467    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3468    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3469    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3470    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3471
3472    /* 486 */
3473    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3474ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3475ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3476    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3477
3478    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3479    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3480
3481    /* pentium */
3482    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3483
3484    /* pentium pro */
3485    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3486
3487    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3488    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3489    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3490    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3491    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3492    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3493    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3494    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3495
3496    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3497    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3498    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3499    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3500
3501    /* mmx */
3502    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
3503    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3504ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3505    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3506ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3507    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3508    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3509    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3510    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3511    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3512    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3513    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3514    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3515    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3516    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3517    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3518    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3519    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3520    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3521    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3522    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3523    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3524    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3525    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3526    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3527    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3528    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3529    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3530ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3531    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3532ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3533    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3534ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3535    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3536ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3537    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3538ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3539    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3540ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3541    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3542ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3543    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3544ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3545    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3546    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3547    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3548    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3549    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3550    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3551    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3552    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3553    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3554    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3555    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3556    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3557    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3558    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3559
3560#undef ALT
3561#undef DEF_ASM_OP0
3562#undef DEF_ASM_OP0L
3563#undef DEF_ASM_OP1
3564#undef DEF_ASM_OP2
3565#undef DEF_ASM_OP3
3566//---------------------------------------------------------------------------
3567
3568#define ALT(x)
3569#define DEF_ASM_OP0(name, opcode)
3570#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
3571#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
3572#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
3573#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
3574// njn: inlined i386-asm.h
3575//#include "i386-asm.h"
3576//---------------------------------------------------------------------------
3577     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
3578     DEF_ASM_OP0(popa, 0x61)
3579     DEF_ASM_OP0(clc, 0xf8)
3580     DEF_ASM_OP0(cld, 0xfc)
3581     DEF_ASM_OP0(cli, 0xfa)
3582     DEF_ASM_OP0(clts, 0x0f06)
3583     DEF_ASM_OP0(cmc, 0xf5)
3584     DEF_ASM_OP0(lahf, 0x9f)
3585     DEF_ASM_OP0(sahf, 0x9e)
3586     DEF_ASM_OP0(pushfl, 0x9c)
3587     DEF_ASM_OP0(popfl, 0x9d)
3588     DEF_ASM_OP0(pushf, 0x9c)
3589     DEF_ASM_OP0(popf, 0x9d)
3590     DEF_ASM_OP0(stc, 0xf9)
3591     DEF_ASM_OP0(std, 0xfd)
3592     DEF_ASM_OP0(sti, 0xfb)
3593     DEF_ASM_OP0(aaa, 0x37)
3594     DEF_ASM_OP0(aas, 0x3f)
3595     DEF_ASM_OP0(daa, 0x27)
3596     DEF_ASM_OP0(das, 0x2f)
3597     DEF_ASM_OP0(aad, 0xd50a)
3598     DEF_ASM_OP0(aam, 0xd40a)
3599     DEF_ASM_OP0(cbw, 0x6698)
3600     DEF_ASM_OP0(cwd, 0x6699)
3601     DEF_ASM_OP0(cwde, 0x98)
3602     DEF_ASM_OP0(cdq, 0x99)
3603     DEF_ASM_OP0(cbtw, 0x6698)
3604     DEF_ASM_OP0(cwtl, 0x98)
3605     DEF_ASM_OP0(cwtd, 0x6699)
3606     DEF_ASM_OP0(cltd, 0x99)
3607     DEF_ASM_OP0(int3, 0xcc)
3608     DEF_ASM_OP0(into, 0xce)
3609     DEF_ASM_OP0(iret, 0xcf)
3610     DEF_ASM_OP0(rsm, 0x0faa)
3611     DEF_ASM_OP0(hlt, 0xf4)
3612     DEF_ASM_OP0(wait, 0x9b)
3613     DEF_ASM_OP0(nop, 0x90)
3614     DEF_ASM_OP0(xlat, 0xd7)
3615
3616     /* strings */
3617ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
3618ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
3619
3620ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
3621ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
3622
3623ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
3624ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
3625
3626ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
3627ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
3628
3629ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
3630ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
3631
3632ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
3633ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
3634
3635     /* bits */
3636
3637ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3638ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
3639
3640ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3641ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3642
3643ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3644ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3645
3646ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3647ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3648
3649ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
3650ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
3651
3652     /* prefixes */
3653     DEF_ASM_OP0(aword, 0x67)
3654     DEF_ASM_OP0(addr16, 0x67)
3655     DEF_ASM_OP0(word, 0x66)
3656     DEF_ASM_OP0(data16, 0x66)
3657     DEF_ASM_OP0(lock, 0xf0)
3658     DEF_ASM_OP0(rep, 0xf3)
3659     DEF_ASM_OP0(repe, 0xf3)
3660     DEF_ASM_OP0(repz, 0xf3)
3661     DEF_ASM_OP0(repne, 0xf2)
3662     DEF_ASM_OP0(repnz, 0xf2)
3663
3664     DEF_ASM_OP0(invd, 0x0f08)
3665     DEF_ASM_OP0(wbinvd, 0x0f09)
3666     DEF_ASM_OP0(cpuid, 0x0fa2)
3667     DEF_ASM_OP0(wrmsr, 0x0f30)
3668     DEF_ASM_OP0(rdtsc, 0x0f31)
3669     DEF_ASM_OP0(rdmsr, 0x0f32)
3670     DEF_ASM_OP0(rdpmc, 0x0f33)
3671     DEF_ASM_OP0(ud2, 0x0f0b)
3672
3673     /* NOTE: we took the same order as gas opcode definition order */
3674ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
3675ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
3676ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3677ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3678ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
3679ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
3680
3681ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
3682ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
3683
3684ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
3685ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
3686ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
3687ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
3688ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
3689ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
3690
3691ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
3692ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
3693ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3694ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
3695ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
3696
3697ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
3698ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3699ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
3700ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
3701ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
3702
3703ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
3704ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
3705ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
3706
3707ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
3708ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
3709ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3710ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3711
3712ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
3713ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
3714ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
3715ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
3716
3717ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
3718ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
3719ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
3720ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
3721
3722ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
3723
3724ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3725ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3726ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3727ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3728ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
3729
3730     /* arith */
3731ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
3732ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3733ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
3734ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3735ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
3736
3737ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
3738ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
3739ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
3740ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
3741
3742ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
3743ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3744ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
3745ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3746
3747ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3748ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3749
3750ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3751ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3752
3753ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
3754ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
3755ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
3756ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
3757ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
3758
3759ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3760ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3761ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
3762ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
3763
3764     /* shifts */
3765ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
3766ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
3767ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
3768
3769ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3770ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3771ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3772ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
3773ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
3774ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
3775
3776ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
3777ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
3778ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
3779ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
3780
3781ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
3782ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
3783ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
3784ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
3785
3786ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
3787ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
3788    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
3789    DEF_ASM_OP0(leave, 0xc9)
3790    DEF_ASM_OP0(ret, 0xc3)
3791ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
3792    DEF_ASM_OP0(lret, 0xcb)
3793ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
3794
3795ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
3796    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3797    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
3798    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3799    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
3800    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
3801    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
3802
3803     /* float */
3804     /* specific fcomp handling */
3805ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
3806
3807ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3808ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3809ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
3810ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
3811ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
3812ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
3813ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
3814ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3815ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3816ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3817ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
3818
3819     DEF_ASM_OP0(fucompp, 0xdae9)
3820     DEF_ASM_OP0(ftst, 0xd9e4)
3821     DEF_ASM_OP0(fxam, 0xd9e5)
3822     DEF_ASM_OP0(fld1, 0xd9e8)
3823     DEF_ASM_OP0(fldl2t, 0xd9e9)
3824     DEF_ASM_OP0(fldl2e, 0xd9ea)
3825     DEF_ASM_OP0(fldpi, 0xd9eb)
3826     DEF_ASM_OP0(fldlg2, 0xd9ec)
3827     DEF_ASM_OP0(fldln2, 0xd9ed)
3828     DEF_ASM_OP0(fldz, 0xd9ee)
3829
3830     DEF_ASM_OP0(f2xm1, 0xd9f0)
3831     DEF_ASM_OP0(fyl2x, 0xd9f1)
3832     DEF_ASM_OP0(fptan, 0xd9f2)
3833     DEF_ASM_OP0(fpatan, 0xd9f3)
3834     DEF_ASM_OP0(fxtract, 0xd9f4)
3835     DEF_ASM_OP0(fprem1, 0xd9f5)
3836     DEF_ASM_OP0(fdecstp, 0xd9f6)
3837     DEF_ASM_OP0(fincstp, 0xd9f7)
3838     DEF_ASM_OP0(fprem, 0xd9f8)
3839     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
3840     DEF_ASM_OP0(fsqrt, 0xd9fa)
3841     DEF_ASM_OP0(fsincos, 0xd9fb)
3842     DEF_ASM_OP0(frndint, 0xd9fc)
3843     DEF_ASM_OP0(fscale, 0xd9fd)
3844     DEF_ASM_OP0(fsin, 0xd9fe)
3845     DEF_ASM_OP0(fcos, 0xd9ff)
3846     DEF_ASM_OP0(fchs, 0xd9e0)
3847     DEF_ASM_OP0(fabs, 0xd9e1)
3848     DEF_ASM_OP0(fninit, 0xdbe3)
3849     DEF_ASM_OP0(fnclex, 0xdbe2)
3850     DEF_ASM_OP0(fnop, 0xd9d0)
3851     DEF_ASM_OP0(fwait, 0x9b)
3852
3853    /* fp load */
3854    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
3855    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
3856    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
3857ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
3858    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
3859    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
3860    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
3861    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
3862    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
3863
3864    /* fp store */
3865    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
3866    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
3867    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
3868    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
3869ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
3870    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
3871    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
3872    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
3873    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
3874    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
3875
3876    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
3877    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
3878    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
3879    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
3880    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
3881
3882    /* exchange */
3883    DEF_ASM_OP0(fxch, 0xd9c9)
3884ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
3885
3886    /* misc FPU */
3887    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
3888    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
3889
3890    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
3891    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
3892    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
3893    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
3894    DEF_ASM_OP0(fnstsw, 0xdfe0)
3895ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
3896ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
3897    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
3898ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
3899ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
3900    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
3901    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
3902    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3903    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
3904    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
3905    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
3906    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
3907    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
3908    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
3909    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
3910    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
3911
3912    /* segments */
3913    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
3914    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
3915    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
3916    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
3917    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
3918    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
3919ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
3920    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
3921    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
3922    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
3923    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
3924    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
3925    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
3926    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
3927    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
3928
3929    /* 486 */
3930    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
3931ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3932ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
3933    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
3934
3935    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
3936    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
3937
3938    /* pentium */
3939    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
3940
3941    /* pentium pro */
3942    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
3943
3944    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3945    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3946    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3947    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3948    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3949    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3950    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3951    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3952
3953    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3954    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3955    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
3956    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
3957
3958    /* mmx */
3959    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
3960    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
3961ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
3962    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3963ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
3964    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3965    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3966    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3967    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3968    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3969    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3970    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3971    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3972    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3973    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3974    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3975    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3976    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3977    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3978    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3979    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3980    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3981    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3982    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3983    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3984    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3985    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3986    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3987ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3988    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3989ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3990    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3991ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
3992    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3993ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3994    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3995ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
3996    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3997ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
3998    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
3999ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4000    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4001ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4002    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4003    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4004    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4005    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4006    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4007    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4008    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4009    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4010    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4011    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4012    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4013    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4014    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4015    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4016
4017#undef ALT
4018#undef DEF_ASM_OP0
4019#undef DEF_ASM_OP0L
4020#undef DEF_ASM_OP1
4021#undef DEF_ASM_OP2
4022#undef DEF_ASM_OP3
4023//---------------------------------------------------------------------------
4024
4025#endif
4026//---------------------------------------------------------------------------
4027#undef DEF
4028};
4029
4030static const char tcc_keywords[] =
4031#define DEF(id, str) str "\0"
4032// njn: inlined tcctok.h
4033//#include "tcctok.h"
4034//---------------------------------------------------------------------------
4035/* keywords */
4036     DEF(TOK_INT, "int")
4037     DEF(TOK_VOID, "void")
4038     DEF(TOK_CHAR, "char")
4039     DEF(TOK_IF, "if")
4040     DEF(TOK_ELSE, "else")
4041     DEF(TOK_WHILE, "while")
4042     DEF(TOK_BREAK, "break")
4043     DEF(TOK_RETURN, "return")
4044     DEF(TOK_FOR, "for")
4045     DEF(TOK_EXTERN, "extern")
4046     DEF(TOK_STATIC, "static")
4047     DEF(TOK_UNSIGNED, "unsigned")
4048     DEF(TOK_GOTO, "goto")
4049     DEF(TOK_DO, "do")
4050     DEF(TOK_CONTINUE, "continue")
4051     DEF(TOK_SWITCH, "switch")
4052     DEF(TOK_CASE, "case")
4053
4054     DEF(TOK_CONST1, "const")
4055     DEF(TOK_CONST2, "__const") /* gcc keyword */
4056     DEF(TOK_CONST3, "__const__") /* gcc keyword */
4057     DEF(TOK_VOLATILE1, "volatile")
4058     DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
4059     DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
4060     DEF(TOK_LONG, "long")
4061     DEF(TOK_REGISTER, "register")
4062     DEF(TOK_SIGNED1, "signed")
4063     DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
4064     DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
4065     DEF(TOK_AUTO, "auto")
4066     DEF(TOK_INLINE1, "inline")
4067     DEF(TOK_INLINE2, "__inline") /* gcc keyword */
4068     DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
4069     DEF(TOK_RESTRICT1, "restrict")
4070     DEF(TOK_RESTRICT2, "__restrict")
4071     DEF(TOK_RESTRICT3, "__restrict__")
4072     DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
4073
4074     DEF(TOK_FLOAT, "float")
4075     DEF(TOK_DOUBLE, "double")
4076     DEF(TOK_BOOL, "_Bool")
4077     DEF(TOK_SHORT, "short")
4078     DEF(TOK_STRUCT, "struct")
4079     DEF(TOK_UNION, "union")
4080     DEF(TOK_TYPEDEF, "typedef")
4081     DEF(TOK_DEFAULT, "default")
4082     DEF(TOK_ENUM, "enum")
4083     DEF(TOK_SIZEOF, "sizeof")
4084     DEF(TOK_ATTRIBUTE1, "__attribute")
4085     DEF(TOK_ATTRIBUTE2, "__attribute__")
4086     DEF(TOK_ALIGNOF1, "__alignof")
4087     DEF(TOK_ALIGNOF2, "__alignof__")
4088     DEF(TOK_TYPEOF1, "typeof")
4089     DEF(TOK_TYPEOF2, "__typeof")
4090     DEF(TOK_TYPEOF3, "__typeof__")
4091     DEF(TOK_LABEL, "__label__")
4092     DEF(TOK_ASM1, "asm")
4093     DEF(TOK_ASM2, "__asm")
4094     DEF(TOK_ASM3, "__asm__")
4095
4096/*********************************************************************/
4097/* the following are not keywords. They are included to ease parsing */
4098/* preprocessor only */
4099     DEF(TOK_DEFINE, "define")
4100     DEF(TOK_INCLUDE, "include")
4101     DEF(TOK_INCLUDE_NEXT, "include_next")
4102     DEF(TOK_IFDEF, "ifdef")
4103     DEF(TOK_IFNDEF, "ifndef")
4104     DEF(TOK_ELIF, "elif")
4105     DEF(TOK_ENDIF, "endif")
4106     DEF(TOK_DEFINED, "defined")
4107     DEF(TOK_UNDEF, "undef")
4108     DEF(TOK_ERROR, "error")
4109     DEF(TOK_WARNING, "warning")
4110     DEF(TOK_LINE, "line")
4111     DEF(TOK_PRAGMA, "pragma")
4112     DEF(TOK___LINE__, "__LINE__")
4113     DEF(TOK___FILE__, "__FILE__")
4114     DEF(TOK___DATE__, "__DATE__")
4115     DEF(TOK___TIME__, "__TIME__")
4116     DEF(TOK___FUNCTION__, "__FUNCTION__")
4117     DEF(TOK___VA_ARGS__, "__VA_ARGS__")
4118
4119/* special identifiers */
4120     DEF(TOK___FUNC__, "__func__")
4121
4122/* attribute identifiers */
4123/* XXX: handle all tokens generically since speed is not critical */
4124     DEF(TOK_SECTION1, "section")
4125     DEF(TOK_SECTION2, "__section__")
4126     DEF(TOK_ALIGNED1, "aligned")
4127     DEF(TOK_ALIGNED2, "__aligned__")
4128     DEF(TOK_PACKED1, "packed")
4129     DEF(TOK_PACKED2, "__packed__")
4130     DEF(TOK_UNUSED1, "unused")
4131     DEF(TOK_UNUSED2, "__unused__")
4132     DEF(TOK_CDECL1, "cdecl")
4133     DEF(TOK_CDECL2, "__cdecl")
4134     DEF(TOK_CDECL3, "__cdecl__")
4135     DEF(TOK_STDCALL1, "stdcall")
4136     DEF(TOK_STDCALL2, "__stdcall")
4137     DEF(TOK_STDCALL3, "__stdcall__")
4138     DEF(TOK_DLLEXPORT, "dllexport")
4139     DEF(TOK_NORETURN1, "noreturn")
4140     DEF(TOK_NORETURN2, "__noreturn__")
4141     DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
4142     DEF(TOK_builtin_constant_p, "__builtin_constant_p")
4143     DEF(TOK_REGPARM1, "regparm")
4144     DEF(TOK_REGPARM2, "__regparm__")
4145
4146/* pragma */
4147     DEF(TOK_pack, "pack")
4148#if !defined(TCC_TARGET_I386)
4149     /* already defined for assembler */
4150     DEF(TOK_ASM_push, "push")
4151     DEF(TOK_ASM_pop, "pop")
4152#endif
4153
4154/* builtin functions or variables */
4155     DEF(TOK_memcpy, "memcpy")
4156     DEF(TOK_memset, "memset")
4157     DEF(TOK_alloca, "alloca")
4158     DEF(TOK___divdi3, "__divdi3")
4159     DEF(TOK___moddi3, "__moddi3")
4160     DEF(TOK___udivdi3, "__udivdi3")
4161     DEF(TOK___umoddi3, "__umoddi3")
4162#if defined(TCC_TARGET_ARM)
4163     DEF(TOK___divsi3, "__divsi3")
4164     DEF(TOK___modsi3, "__modsi3")
4165     DEF(TOK___udivsi3, "__udivsi3")
4166     DEF(TOK___umodsi3, "__umodsi3")
4167     DEF(TOK___sardi3, "__ashrdi3")
4168     DEF(TOK___shrdi3, "__lshrdi3")
4169     DEF(TOK___shldi3, "__ashldi3")
4170     DEF(TOK___slltold, "__slltold")
4171     DEF(TOK___fixunssfsi, "__fixunssfsi")
4172     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
4173     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
4174     DEF(TOK___fixsfdi, "__fixsfdi")
4175     DEF(TOK___fixdfdi, "__fixdfdi")
4176     DEF(TOK___fixxfdi, "__fixxfdi")
4177#elif defined(TCC_TARGET_C67)
4178     DEF(TOK__divi, "_divi")
4179     DEF(TOK__divu, "_divu")
4180     DEF(TOK__divf, "_divf")
4181     DEF(TOK__divd, "_divd")
4182     DEF(TOK__remi, "_remi")
4183     DEF(TOK__remu, "_remu")
4184     DEF(TOK___sardi3, "__sardi3")
4185     DEF(TOK___shrdi3, "__shrdi3")
4186     DEF(TOK___shldi3, "__shldi3")
4187#else
4188     /* XXX: same names on i386 ? */
4189     DEF(TOK___sardi3, "__sardi3")
4190     DEF(TOK___shrdi3, "__shrdi3")
4191     DEF(TOK___shldi3, "__shldi3")
4192#endif
4193     DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
4194     DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
4195     DEF(TOK___ulltof, "__ulltof")
4196     DEF(TOK___ulltod, "__ulltod")
4197     DEF(TOK___ulltold, "__ulltold")
4198     DEF(TOK___fixunssfdi, "__fixunssfdi")
4199     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
4200     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
4201     DEF(TOK___chkstk, "__chkstk")
4202
4203/* bound checking symbols */
4204#ifdef CONFIG_TCC_BCHECK
4205     DEF(TOK___bound_ptr_add, "__bound_ptr_add")
4206     DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
4207     DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
4208     DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
4209     DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
4210     DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
4211     DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
4212     DEF(TOK___bound_local_new, "__bound_local_new")
4213     DEF(TOK___bound_local_delete, "__bound_local_delete")
4214     DEF(TOK_malloc, "malloc")
4215     DEF(TOK_free, "free")
4216     DEF(TOK_realloc, "realloc")
4217     DEF(TOK_memalign, "memalign")
4218     DEF(TOK_calloc, "calloc")
4219     DEF(TOK_memmove, "memmove")
4220     DEF(TOK_strlen, "strlen")
4221     DEF(TOK_strcpy, "strcpy")
4222#endif
4223
4224/* Tiny Assembler */
4225
4226 DEF_ASM(byte)
4227 DEF_ASM(align)
4228 DEF_ASM(skip)
4229 DEF_ASM(space)
4230 DEF_ASM(string)
4231 DEF_ASM(asciz)
4232 DEF_ASM(ascii)
4233 DEF_ASM(globl)
4234 DEF_ASM(global)
4235 DEF_ASM(text)
4236 DEF_ASM(data)
4237 DEF_ASM(bss)
4238 DEF_ASM(previous)
4239 DEF_ASM(fill)
4240 DEF_ASM(org)
4241 DEF_ASM(quad)
4242
4243#ifdef TCC_TARGET_I386
4244
4245/* WARNING: relative order of tokens is important. */
4246 DEF_ASM(al)
4247 DEF_ASM(cl)
4248 DEF_ASM(dl)
4249 DEF_ASM(bl)
4250 DEF_ASM(ah)
4251 DEF_ASM(ch)
4252 DEF_ASM(dh)
4253 DEF_ASM(bh)
4254 DEF_ASM(ax)
4255 DEF_ASM(cx)
4256 DEF_ASM(dx)
4257 DEF_ASM(bx)
4258 DEF_ASM(sp)
4259 DEF_ASM(bp)
4260 DEF_ASM(si)
4261 DEF_ASM(di)
4262 DEF_ASM(eax)
4263 DEF_ASM(ecx)
4264 DEF_ASM(edx)
4265 DEF_ASM(ebx)
4266 DEF_ASM(esp)
4267 DEF_ASM(ebp)
4268 DEF_ASM(esi)
4269 DEF_ASM(edi)
4270 DEF_ASM(mm0)
4271 DEF_ASM(mm1)
4272 DEF_ASM(mm2)
4273 DEF_ASM(mm3)
4274 DEF_ASM(mm4)
4275 DEF_ASM(mm5)
4276 DEF_ASM(mm6)
4277 DEF_ASM(mm7)
4278 DEF_ASM(xmm0)
4279 DEF_ASM(xmm1)
4280 DEF_ASM(xmm2)
4281 DEF_ASM(xmm3)
4282 DEF_ASM(xmm4)
4283 DEF_ASM(xmm5)
4284 DEF_ASM(xmm6)
4285 DEF_ASM(xmm7)
4286 DEF_ASM(cr0)
4287 DEF_ASM(cr1)
4288 DEF_ASM(cr2)
4289 DEF_ASM(cr3)
4290 DEF_ASM(cr4)
4291 DEF_ASM(cr5)
4292 DEF_ASM(cr6)
4293 DEF_ASM(cr7)
4294 DEF_ASM(tr0)
4295 DEF_ASM(tr1)
4296 DEF_ASM(tr2)
4297 DEF_ASM(tr3)
4298 DEF_ASM(tr4)
4299 DEF_ASM(tr5)
4300 DEF_ASM(tr6)
4301 DEF_ASM(tr7)
4302 DEF_ASM(db0)
4303 DEF_ASM(db1)
4304 DEF_ASM(db2)
4305 DEF_ASM(db3)
4306 DEF_ASM(db4)
4307 DEF_ASM(db5)
4308 DEF_ASM(db6)
4309 DEF_ASM(db7)
4310 DEF_ASM(dr0)
4311 DEF_ASM(dr1)
4312 DEF_ASM(dr2)
4313 DEF_ASM(dr3)
4314 DEF_ASM(dr4)
4315 DEF_ASM(dr5)
4316 DEF_ASM(dr6)
4317 DEF_ASM(dr7)
4318 DEF_ASM(es)
4319 DEF_ASM(cs)
4320 DEF_ASM(ss)
4321 DEF_ASM(ds)
4322 DEF_ASM(fs)
4323 DEF_ASM(gs)
4324 DEF_ASM(st)
4325
4326 DEF_BWL(mov)
4327
4328 /* generic two operands */
4329 DEF_BWL(add)
4330 DEF_BWL(or)
4331 DEF_BWL(adc)
4332 DEF_BWL(sbb)
4333 DEF_BWL(and)
4334 DEF_BWL(sub)
4335 DEF_BWL(xor)
4336 DEF_BWL(cmp)
4337
4338 /* unary ops */
4339 DEF_BWL(inc)
4340 DEF_BWL(dec)
4341 DEF_BWL(not)
4342 DEF_BWL(neg)
4343 DEF_BWL(mul)
4344 DEF_BWL(imul)
4345 DEF_BWL(div)
4346 DEF_BWL(idiv)
4347
4348 DEF_BWL(xchg)
4349 DEF_BWL(test)
4350
4351 /* shifts */
4352 DEF_BWL(rol)
4353 DEF_BWL(ror)
4354 DEF_BWL(rcl)
4355 DEF_BWL(rcr)
4356 DEF_BWL(shl)
4357 DEF_BWL(shr)
4358 DEF_BWL(sar)
4359
4360 DEF_ASM(shldw)
4361 DEF_ASM(shldl)
4362 DEF_ASM(shld)
4363 DEF_ASM(shrdw)
4364 DEF_ASM(shrdl)
4365 DEF_ASM(shrd)
4366
4367 DEF_ASM(pushw)
4368 DEF_ASM(pushl)
4369 DEF_ASM(push)
4370 DEF_ASM(popw)
4371 DEF_ASM(popl)
4372 DEF_ASM(pop)
4373 DEF_BWL(in)
4374 DEF_BWL(out)
4375
4376 DEF_WL(movzb)
4377
4378 DEF_ASM(movzwl)
4379 DEF_ASM(movsbw)
4380 DEF_ASM(movsbl)
4381 DEF_ASM(movswl)
4382
4383 DEF_WL(lea)
4384
4385 DEF_ASM(les)
4386 DEF_ASM(lds)
4387 DEF_ASM(lss)
4388 DEF_ASM(lfs)
4389 DEF_ASM(lgs)
4390
4391 DEF_ASM(call)
4392 DEF_ASM(jmp)
4393 DEF_ASM(lcall)
4394 DEF_ASM(ljmp)
4395
4396 DEF_ASMTEST(j)
4397
4398 DEF_ASMTEST(set)
4399 DEF_ASMTEST(cmov)
4400
4401 DEF_WL(bsf)
4402 DEF_WL(bsr)
4403 DEF_WL(bt)
4404 DEF_WL(bts)
4405 DEF_WL(btr)
4406 DEF_WL(btc)
4407
4408 DEF_WL(lsl)
4409
4410 /* generic FP ops */
4411 DEF_FP(add)
4412 DEF_FP(mul)
4413
4414 DEF_ASM(fcom)
4415 DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
4416 DEF_FP1(com)
4417
4418 DEF_FP(comp)
4419 DEF_FP(sub)
4420 DEF_FP(subr)
4421 DEF_FP(div)
4422 DEF_FP(divr)
4423
4424 DEF_BWL(xadd)
4425 DEF_BWL(cmpxchg)
4426
4427 /* string ops */
4428 DEF_BWL(cmps)
4429 DEF_BWL(scmp)
4430 DEF_BWL(ins)
4431 DEF_BWL(outs)
4432 DEF_BWL(lods)
4433 DEF_BWL(slod)
4434 DEF_BWL(movs)
4435 DEF_BWL(smov)
4436 DEF_BWL(scas)
4437 DEF_BWL(ssca)
4438 DEF_BWL(stos)
4439 DEF_BWL(ssto)
4440
4441 /* generic asm ops */
4442
4443#define ALT(x)
4444#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
4445#define DEF_ASM_OP0L(name, opcode, group, instr_type)
4446#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
4447#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
4448#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
4449// njn: inlined i386-asm.h
4450//#include "i386-asm.h"
4451//---------------------------------------------------------------------------
4452     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
4453     DEF_ASM_OP0(popa, 0x61)
4454     DEF_ASM_OP0(clc, 0xf8)
4455     DEF_ASM_OP0(cld, 0xfc)
4456     DEF_ASM_OP0(cli, 0xfa)
4457     DEF_ASM_OP0(clts, 0x0f06)
4458     DEF_ASM_OP0(cmc, 0xf5)
4459     DEF_ASM_OP0(lahf, 0x9f)
4460     DEF_ASM_OP0(sahf, 0x9e)
4461     DEF_ASM_OP0(pushfl, 0x9c)
4462     DEF_ASM_OP0(popfl, 0x9d)
4463     DEF_ASM_OP0(pushf, 0x9c)
4464     DEF_ASM_OP0(popf, 0x9d)
4465     DEF_ASM_OP0(stc, 0xf9)
4466     DEF_ASM_OP0(std, 0xfd)
4467     DEF_ASM_OP0(sti, 0xfb)
4468     DEF_ASM_OP0(aaa, 0x37)
4469     DEF_ASM_OP0(aas, 0x3f)
4470     DEF_ASM_OP0(daa, 0x27)
4471     DEF_ASM_OP0(das, 0x2f)
4472     DEF_ASM_OP0(aad, 0xd50a)
4473     DEF_ASM_OP0(aam, 0xd40a)
4474     DEF_ASM_OP0(cbw, 0x6698)
4475     DEF_ASM_OP0(cwd, 0x6699)
4476     DEF_ASM_OP0(cwde, 0x98)
4477     DEF_ASM_OP0(cdq, 0x99)
4478     DEF_ASM_OP0(cbtw, 0x6698)
4479     DEF_ASM_OP0(cwtl, 0x98)
4480     DEF_ASM_OP0(cwtd, 0x6699)
4481     DEF_ASM_OP0(cltd, 0x99)
4482     DEF_ASM_OP0(int3, 0xcc)
4483     DEF_ASM_OP0(into, 0xce)
4484     DEF_ASM_OP0(iret, 0xcf)
4485     DEF_ASM_OP0(rsm, 0x0faa)
4486     DEF_ASM_OP0(hlt, 0xf4)
4487     DEF_ASM_OP0(wait, 0x9b)
4488     DEF_ASM_OP0(nop, 0x90)
4489     DEF_ASM_OP0(xlat, 0xd7)
4490
4491     /* strings */
4492ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4493ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4494
4495ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4496ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4497
4498ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4499ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4500
4501ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4502ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4503
4504ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4505ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4506
4507ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4508ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4509
4510     /* bits */
4511
4512ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4513ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4514
4515ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4516ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4517
4518ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4519ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4520
4521ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4522ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4523
4524ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4525ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4526
4527     /* prefixes */
4528     DEF_ASM_OP0(aword, 0x67)
4529     DEF_ASM_OP0(addr16, 0x67)
4530     DEF_ASM_OP0(word, 0x66)
4531     DEF_ASM_OP0(data16, 0x66)
4532     DEF_ASM_OP0(lock, 0xf0)
4533     DEF_ASM_OP0(rep, 0xf3)
4534     DEF_ASM_OP0(repe, 0xf3)
4535     DEF_ASM_OP0(repz, 0xf3)
4536     DEF_ASM_OP0(repne, 0xf2)
4537     DEF_ASM_OP0(repnz, 0xf2)
4538
4539     DEF_ASM_OP0(invd, 0x0f08)
4540     DEF_ASM_OP0(wbinvd, 0x0f09)
4541     DEF_ASM_OP0(cpuid, 0x0fa2)
4542     DEF_ASM_OP0(wrmsr, 0x0f30)
4543     DEF_ASM_OP0(rdtsc, 0x0f31)
4544     DEF_ASM_OP0(rdmsr, 0x0f32)
4545     DEF_ASM_OP0(rdpmc, 0x0f33)
4546     DEF_ASM_OP0(ud2, 0x0f0b)
4547
4548     /* NOTE: we took the same order as gas opcode definition order */
4549ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
4550ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
4551ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4552ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4553ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
4554ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
4555
4556ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
4557ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
4558
4559ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
4560ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
4561ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
4562ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
4563ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
4564ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
4565
4566ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
4567ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
4568ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4569ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
4570ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
4571
4572ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
4573ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4574ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
4575ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
4576ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
4577
4578ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
4579ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
4580ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
4581
4582ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
4583ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
4584ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4585ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4586
4587ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
4588ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
4589ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
4590ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
4591
4592ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
4593ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
4594ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
4595ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
4596
4597ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
4598
4599ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4600ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4601ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4602ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4603ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
4604
4605     /* arith */
4606ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
4607ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4608ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
4609ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4610ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
4611
4612ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
4613ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
4614ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
4615ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
4616
4617ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
4618ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4619ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
4620ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4621
4622ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4623ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4624
4625ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4626ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4627
4628ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
4629ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
4630ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
4631ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
4632ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
4633
4634ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4635ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4636ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
4637ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
4638
4639     /* shifts */
4640ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
4641ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
4642ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
4643
4644ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4645ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4646ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4647ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
4648ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
4649ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
4650
4651ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
4652ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
4653ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
4654ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
4655
4656ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
4657ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
4658ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
4659ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
4660
4661ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
4662ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
4663    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
4664    DEF_ASM_OP0(leave, 0xc9)
4665    DEF_ASM_OP0(ret, 0xc3)
4666ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
4667    DEF_ASM_OP0(lret, 0xcb)
4668ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
4669
4670ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
4671    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4672    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
4673    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4674    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
4675    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
4676    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
4677
4678     /* float */
4679     /* specific fcomp handling */
4680ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
4681
4682ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4683ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4684ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
4685ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
4686ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
4687ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
4688ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
4689ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4690ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4691ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4692ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
4693
4694     DEF_ASM_OP0(fucompp, 0xdae9)
4695     DEF_ASM_OP0(ftst, 0xd9e4)
4696     DEF_ASM_OP0(fxam, 0xd9e5)
4697     DEF_ASM_OP0(fld1, 0xd9e8)
4698     DEF_ASM_OP0(fldl2t, 0xd9e9)
4699     DEF_ASM_OP0(fldl2e, 0xd9ea)
4700     DEF_ASM_OP0(fldpi, 0xd9eb)
4701     DEF_ASM_OP0(fldlg2, 0xd9ec)
4702     DEF_ASM_OP0(fldln2, 0xd9ed)
4703     DEF_ASM_OP0(fldz, 0xd9ee)
4704
4705     DEF_ASM_OP0(f2xm1, 0xd9f0)
4706     DEF_ASM_OP0(fyl2x, 0xd9f1)
4707     DEF_ASM_OP0(fptan, 0xd9f2)
4708     DEF_ASM_OP0(fpatan, 0xd9f3)
4709     DEF_ASM_OP0(fxtract, 0xd9f4)
4710     DEF_ASM_OP0(fprem1, 0xd9f5)
4711     DEF_ASM_OP0(fdecstp, 0xd9f6)
4712     DEF_ASM_OP0(fincstp, 0xd9f7)
4713     DEF_ASM_OP0(fprem, 0xd9f8)
4714     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
4715     DEF_ASM_OP0(fsqrt, 0xd9fa)
4716     DEF_ASM_OP0(fsincos, 0xd9fb)
4717     DEF_ASM_OP0(frndint, 0xd9fc)
4718     DEF_ASM_OP0(fscale, 0xd9fd)
4719     DEF_ASM_OP0(fsin, 0xd9fe)
4720     DEF_ASM_OP0(fcos, 0xd9ff)
4721     DEF_ASM_OP0(fchs, 0xd9e0)
4722     DEF_ASM_OP0(fabs, 0xd9e1)
4723     DEF_ASM_OP0(fninit, 0xdbe3)
4724     DEF_ASM_OP0(fnclex, 0xdbe2)
4725     DEF_ASM_OP0(fnop, 0xd9d0)
4726     DEF_ASM_OP0(fwait, 0x9b)
4727
4728    /* fp load */
4729    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
4730    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
4731    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
4732ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
4733    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
4734    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
4735    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
4736    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
4737    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
4738
4739    /* fp store */
4740    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
4741    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
4742    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
4743    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
4744ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
4745    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
4746    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
4747    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
4748    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
4749    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
4750
4751    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
4752    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
4753    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
4754    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
4755    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
4756
4757    /* exchange */
4758    DEF_ASM_OP0(fxch, 0xd9c9)
4759ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
4760
4761    /* misc FPU */
4762    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
4763    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
4764
4765    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
4766    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
4767    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
4768    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
4769    DEF_ASM_OP0(fnstsw, 0xdfe0)
4770ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
4771ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
4772    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
4773ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
4774ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
4775    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
4776    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
4777    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4778    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
4779    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
4780    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
4781    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
4782    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
4783    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
4784    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
4785    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
4786
4787    /* segments */
4788    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
4789    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
4790    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
4791    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
4792    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
4793    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
4794ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
4795    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
4796    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
4797    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
4798    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
4799    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
4800    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
4801    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
4802    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
4803
4804    /* 486 */
4805    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
4806ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4807ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
4808    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
4809
4810    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
4811    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
4812
4813    /* pentium */
4814    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
4815
4816    /* pentium pro */
4817    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
4818
4819    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4820    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4821    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4822    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4823    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4824    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4825    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4826    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4827
4828    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4829    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4830    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
4831    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
4832
4833    /* mmx */
4834    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
4835    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
4836ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
4837    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4838ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
4839    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4840    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4841    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4842    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4843    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4844    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4845    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4846    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4847    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4848    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4849    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4850    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4851    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4852    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4853    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4854    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4855    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4856    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4857    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4858    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4859    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4860    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4861    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4862ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4863    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4864ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4865    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4866ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
4867    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4868ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4869    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4870ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
4871    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4872ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4873    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4874ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4875    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4876ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
4877    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4878    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4879    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4880    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4881    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4882    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4883    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4884    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4885    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4886    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4887    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4888    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4889    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4890    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
4891
4892#undef ALT
4893#undef DEF_ASM_OP0
4894#undef DEF_ASM_OP0L
4895#undef DEF_ASM_OP1
4896#undef DEF_ASM_OP2
4897#undef DEF_ASM_OP3
4898//---------------------------------------------------------------------------
4899
4900#define ALT(x)
4901#define DEF_ASM_OP0(name, opcode)
4902#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
4903#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
4904#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
4905#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
4906// njn: inlined i386-asm.h
4907//#include "i386-asm.h"
4908//---------------------------------------------------------------------------
4909     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
4910     DEF_ASM_OP0(popa, 0x61)
4911     DEF_ASM_OP0(clc, 0xf8)
4912     DEF_ASM_OP0(cld, 0xfc)
4913     DEF_ASM_OP0(cli, 0xfa)
4914     DEF_ASM_OP0(clts, 0x0f06)
4915     DEF_ASM_OP0(cmc, 0xf5)
4916     DEF_ASM_OP0(lahf, 0x9f)
4917     DEF_ASM_OP0(sahf, 0x9e)
4918     DEF_ASM_OP0(pushfl, 0x9c)
4919     DEF_ASM_OP0(popfl, 0x9d)
4920     DEF_ASM_OP0(pushf, 0x9c)
4921     DEF_ASM_OP0(popf, 0x9d)
4922     DEF_ASM_OP0(stc, 0xf9)
4923     DEF_ASM_OP0(std, 0xfd)
4924     DEF_ASM_OP0(sti, 0xfb)
4925     DEF_ASM_OP0(aaa, 0x37)
4926     DEF_ASM_OP0(aas, 0x3f)
4927     DEF_ASM_OP0(daa, 0x27)
4928     DEF_ASM_OP0(das, 0x2f)
4929     DEF_ASM_OP0(aad, 0xd50a)
4930     DEF_ASM_OP0(aam, 0xd40a)
4931     DEF_ASM_OP0(cbw, 0x6698)
4932     DEF_ASM_OP0(cwd, 0x6699)
4933     DEF_ASM_OP0(cwde, 0x98)
4934     DEF_ASM_OP0(cdq, 0x99)
4935     DEF_ASM_OP0(cbtw, 0x6698)
4936     DEF_ASM_OP0(cwtl, 0x98)
4937     DEF_ASM_OP0(cwtd, 0x6699)
4938     DEF_ASM_OP0(cltd, 0x99)
4939     DEF_ASM_OP0(int3, 0xcc)
4940     DEF_ASM_OP0(into, 0xce)
4941     DEF_ASM_OP0(iret, 0xcf)
4942     DEF_ASM_OP0(rsm, 0x0faa)
4943     DEF_ASM_OP0(hlt, 0xf4)
4944     DEF_ASM_OP0(wait, 0x9b)
4945     DEF_ASM_OP0(nop, 0x90)
4946     DEF_ASM_OP0(xlat, 0xd7)
4947
4948     /* strings */
4949ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
4950ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
4951
4952ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
4953ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
4954
4955ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
4956ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
4957
4958ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
4959ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
4960
4961ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
4962ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
4963
4964ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
4965ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
4966
4967     /* bits */
4968
4969ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4970ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
4971
4972ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4973ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4974
4975ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4976ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4977
4978ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4979ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4980
4981ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
4982ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
4983
4984     /* prefixes */
4985     DEF_ASM_OP0(aword, 0x67)
4986     DEF_ASM_OP0(addr16, 0x67)
4987     DEF_ASM_OP0(word, 0x66)
4988     DEF_ASM_OP0(data16, 0x66)
4989     DEF_ASM_OP0(lock, 0xf0)
4990     DEF_ASM_OP0(rep, 0xf3)
4991     DEF_ASM_OP0(repe, 0xf3)
4992     DEF_ASM_OP0(repz, 0xf3)
4993     DEF_ASM_OP0(repne, 0xf2)
4994     DEF_ASM_OP0(repnz, 0xf2)
4995
4996     DEF_ASM_OP0(invd, 0x0f08)
4997     DEF_ASM_OP0(wbinvd, 0x0f09)
4998     DEF_ASM_OP0(cpuid, 0x0fa2)
4999     DEF_ASM_OP0(wrmsr, 0x0f30)
5000     DEF_ASM_OP0(rdtsc, 0x0f31)
5001     DEF_ASM_OP0(rdmsr, 0x0f32)
5002     DEF_ASM_OP0(rdpmc, 0x0f33)
5003     DEF_ASM_OP0(ud2, 0x0f0b)
5004
5005     /* NOTE: we took the same order as gas opcode definition order */
5006ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
5007ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
5008ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5009ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5010ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
5011ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
5012
5013ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
5014ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
5015
5016ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
5017ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
5018ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
5019ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
5020ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
5021ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
5022
5023ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
5024ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
5025ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5026ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
5027ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
5028
5029ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
5030ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5031ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
5032ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
5033ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
5034
5035ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
5036ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
5037ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
5038
5039ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
5040ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
5041ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5042ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5043
5044ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
5045ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
5046ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
5047ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
5048
5049ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
5050ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
5051ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
5052ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
5053
5054ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
5055
5056ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5057ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5058ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5059ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5060ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
5061
5062     /* arith */
5063ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
5064ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5065ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
5066ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5067ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
5068
5069ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
5070ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
5071ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
5072ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
5073
5074ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
5075ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5076ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
5077ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5078
5079ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5080ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5081
5082ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5083ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5084
5085ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
5086ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
5087ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
5088ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
5089ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
5090
5091ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5092ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5093ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
5094ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
5095
5096     /* shifts */
5097ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
5098ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
5099ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
5100
5101ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5102ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5103ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5104ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
5105ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
5106ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
5107
5108ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
5109ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
5110ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
5111ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
5112
5113ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
5114ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
5115ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
5116ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
5117
5118ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
5119ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
5120    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
5121    DEF_ASM_OP0(leave, 0xc9)
5122    DEF_ASM_OP0(ret, 0xc3)
5123ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
5124    DEF_ASM_OP0(lret, 0xcb)
5125ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
5126
5127ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
5128    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5129    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
5130    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5131    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
5132    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
5133    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
5134
5135     /* float */
5136     /* specific fcomp handling */
5137ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
5138
5139ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5140ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5141ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
5142ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
5143ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
5144ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
5145ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
5146ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5147ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5148ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5149ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
5150
5151     DEF_ASM_OP0(fucompp, 0xdae9)
5152     DEF_ASM_OP0(ftst, 0xd9e4)
5153     DEF_ASM_OP0(fxam, 0xd9e5)
5154     DEF_ASM_OP0(fld1, 0xd9e8)
5155     DEF_ASM_OP0(fldl2t, 0xd9e9)
5156     DEF_ASM_OP0(fldl2e, 0xd9ea)
5157     DEF_ASM_OP0(fldpi, 0xd9eb)
5158     DEF_ASM_OP0(fldlg2, 0xd9ec)
5159     DEF_ASM_OP0(fldln2, 0xd9ed)
5160     DEF_ASM_OP0(fldz, 0xd9ee)
5161
5162     DEF_ASM_OP0(f2xm1, 0xd9f0)
5163     DEF_ASM_OP0(fyl2x, 0xd9f1)
5164     DEF_ASM_OP0(fptan, 0xd9f2)
5165     DEF_ASM_OP0(fpatan, 0xd9f3)
5166     DEF_ASM_OP0(fxtract, 0xd9f4)
5167     DEF_ASM_OP0(fprem1, 0xd9f5)
5168     DEF_ASM_OP0(fdecstp, 0xd9f6)
5169     DEF_ASM_OP0(fincstp, 0xd9f7)
5170     DEF_ASM_OP0(fprem, 0xd9f8)
5171     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
5172     DEF_ASM_OP0(fsqrt, 0xd9fa)
5173     DEF_ASM_OP0(fsincos, 0xd9fb)
5174     DEF_ASM_OP0(frndint, 0xd9fc)
5175     DEF_ASM_OP0(fscale, 0xd9fd)
5176     DEF_ASM_OP0(fsin, 0xd9fe)
5177     DEF_ASM_OP0(fcos, 0xd9ff)
5178     DEF_ASM_OP0(fchs, 0xd9e0)
5179     DEF_ASM_OP0(fabs, 0xd9e1)
5180     DEF_ASM_OP0(fninit, 0xdbe3)
5181     DEF_ASM_OP0(fnclex, 0xdbe2)
5182     DEF_ASM_OP0(fnop, 0xd9d0)
5183     DEF_ASM_OP0(fwait, 0x9b)
5184
5185    /* fp load */
5186    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
5187    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
5188    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
5189ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
5190    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
5191    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
5192    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
5193    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
5194    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
5195
5196    /* fp store */
5197    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
5198    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
5199    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
5200    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
5201ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
5202    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
5203    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
5204    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
5205    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
5206    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
5207
5208    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
5209    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
5210    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
5211    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
5212    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
5213
5214    /* exchange */
5215    DEF_ASM_OP0(fxch, 0xd9c9)
5216ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
5217
5218    /* misc FPU */
5219    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
5220    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
5221
5222    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
5223    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
5224    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
5225    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
5226    DEF_ASM_OP0(fnstsw, 0xdfe0)
5227ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
5228ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
5229    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
5230ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
5231ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
5232    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
5233    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
5234    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5235    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
5236    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
5237    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
5238    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
5239    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
5240    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
5241    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
5242    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
5243
5244    /* segments */
5245    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
5246    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
5247    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
5248    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
5249    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
5250    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
5251ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
5252    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
5253    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
5254    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
5255    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
5256    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
5257    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
5258    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
5259    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
5260
5261    /* 486 */
5262    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
5263ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5264ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
5265    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
5266
5267    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
5268    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
5269
5270    /* pentium */
5271    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
5272
5273    /* pentium pro */
5274    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
5275
5276    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5277    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5278    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5279    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5280    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5281    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5282    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5283    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5284
5285    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5286    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5287    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
5288    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
5289
5290    /* mmx */
5291    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
5292    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
5293ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
5294    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5295ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
5296    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5297    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5298    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5299    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5300    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5301    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5302    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5303    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5304    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5305    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5306    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5307    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5308    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5309    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5310    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5311    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5312    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5313    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5314    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5315    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5316    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5317    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5318    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5319ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5320    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5321ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5322    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5323ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
5324    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5325ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5326    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5327ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
5328    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5329ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5330    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5331ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5332    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5333ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
5334    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5335    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5336    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5337    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5338    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5339    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5340    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5341    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5342    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5343    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5344    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5345    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5346    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5347    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
5348
5349#undef ALT
5350#undef DEF_ASM_OP0
5351#undef DEF_ASM_OP0L
5352#undef DEF_ASM_OP1
5353#undef DEF_ASM_OP2
5354#undef DEF_ASM_OP3
5355//---------------------------------------------------------------------------
5356
5357#endif
5358//---------------------------------------------------------------------------
5359#undef DEF
5360;
5361
5362#define TOK_UIDENT TOK_DEFINE
5363
5364#ifdef WIN32
5365int __stdcall GetModuleFileNameA(void *, char *, int);
5366void *__stdcall GetProcAddress(void *, const char *);
5367void *__stdcall GetModuleHandleA(const char *);
5368void *__stdcall LoadLibraryA(const char *);
5369int __stdcall FreeConsole(void);
5370
5371#define snprintf _snprintf
5372#define vsnprintf _vsnprintf
5373#ifndef __GNUC__
5374  #define strtold (long double)strtod
5375  #define strtof (float)strtod
5376  #define strtoll (long long)strtol
5377#endif
5378#elif defined(TCC_UCLIBC) || defined(__FreeBSD__)
5379/* currently incorrect */
5380long double strtold(const char *nptr, char **endptr)
5381{
5382    return (long double)strtod(nptr, endptr);
5383}
5384float strtof(const char *nptr, char **endptr)
5385{
5386    return (float)strtod(nptr, endptr);
5387}
5388#else
5389/* XXX: need to define this to use them in non ISOC99 context */
5390extern float strtof (const char *__nptr, char **__endptr);
5391extern long double strtold (const char *__nptr, char **__endptr);
5392#endif
5393
5394static char *pstrcpy(char *buf, int buf_size, const char *s);
5395static char *pstrcat(char *buf, int buf_size, const char *s);
5396static const char *tcc_basename(const char *name);
5397
5398static void next(void);
5399static void next_nomacro(void);
5400static void parse_expr_type(CType *type);
5401static void expr_type(CType *type);
5402static void unary_type(CType *type);
5403static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
5404                  int case_reg, int is_expr);
5405static int expr_const(void);
5406static void expr_eq(void);
5407static void gexpr(void);
5408static void gen_inline_functions(void);
5409static void decl(int l);
5410static void decl_initializer(CType *type, Section *sec, unsigned long c,
5411                             int first, int size_only);
5412static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
5413                                   int has_init, int v, int scope);
5414int gv(int rc);
5415void gv2(int rc1, int rc2);
5416void move_reg(int r, int s);
5417void save_regs(int n);
5418void save_reg(int r);
5419void vpop(void);
5420void vswap(void);
5421void vdup(void);
5422int get_reg(int rc);
5423int get_reg_ex(int rc,int rc2);
5424
5425struct macro_level {
5426    struct macro_level *prev;
5427    int *p;
5428};
5429
5430static void macro_subst(TokenString *tok_str, Sym **nested_list,
5431                        const int *macro_str, struct macro_level **can_read_stream);
5432void gen_op(int op);
5433void force_charshort_cast(int t);
5434static void gen_cast(CType *type);
5435void vstore(void);
5436static Sym *sym_find(int v);
5437static Sym *sym_push(int v, CType *type, int r, int c);
5438
5439/* type handling */
5440static int type_size(CType *type, int *a);
5441static inline CType *pointed_type(CType *type);
5442static int pointed_size(CType *type);
5443static int lvalue_type(int t);
5444static int parse_btype(CType *type, AttributeDef *ad);
5445static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
5446static int is_compatible_types(CType *type1, CType *type2);
5447
5448int ieee_finite(double d);
5449void error(const char *fmt, ...);
5450void vpushi(int v);
5451void vrott(int n);
5452void vnrott(int n);
5453void lexpand_nr(void);
5454static void vpush_global_sym(CType *type, int v);
5455void vset(CType *type, int r, int v);
5456void type_to_str(char *buf, int buf_size,
5457                 CType *type, const char *varstr);
5458char *get_tok_str(int v, CValue *cv);
5459static Sym *get_sym_ref(CType *type, Section *sec,
5460                        unsigned long offset, unsigned long size);
5461static Sym *external_global_sym(int v, CType *type, int r);
5462
5463/* section generation */
5464static void section_realloc(Section *sec, unsigned long new_size);
5465static void *section_ptr_add(Section *sec, unsigned long size);
5466static void put_extern_sym(Sym *sym, Section *section,
5467                           unsigned long value, unsigned long size);
5468static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
5469static int put_elf_str(Section *s, const char *sym);
5470static int put_elf_sym(Section *s,
5471                       unsigned long value, unsigned long size,
5472                       int info, int other, int shndx, const char *name);
5473static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
5474                       int info, int other, int sh_num, const char *name);
5475static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
5476                          int type, int symbol);
5477static void put_stabs(const char *str, int type, int other, int desc,
5478                      unsigned long value);
5479static void put_stabs_r(const char *str, int type, int other, int desc,
5480                        unsigned long value, Section *sec, int sym_index);
5481static void put_stabn(int type, int other, int desc, int value);
5482static void put_stabd(int type, int other, int desc);
5483static int tcc_add_dll(TCCState *s, const char *filename, int flags);
5484
5485#define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
5486#define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
5487static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
5488
5489/* tcccoff.c */
5490int tcc_output_coff(TCCState *s1, FILE *f);
5491
5492/* tccpe.c */
5493void *resolve_sym(TCCState *s1, const char *sym, int type);
5494int pe_load_def_file(struct TCCState *s1, FILE *fp);
5495void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
5496unsigned long pe_add_runtime(struct TCCState *s1);
5497int tcc_output_pe(struct TCCState *s1, const char *filename);
5498
5499/* tccasm.c */
5500
5501#ifdef CONFIG_TCC_ASM
5502
5503typedef struct ExprValue {
5504    uint32_t v;
5505    Sym *sym;
5506} ExprValue;
5507
5508#define MAX_ASM_OPERANDS 30
5509
5510typedef struct ASMOperand {
5511    int id; /* GCC 3 optionnal identifier (0 if number only supported */
5512    char *constraint;
5513    char asm_str[16]; /* computed asm string for operand */
5514    SValue *vt; /* C value of the expression */
5515    int ref_index; /* if >= 0, gives reference to a output constraint */
5516    int input_index; /* if >= 0, gives reference to an input constraint */
5517    int priority; /* priority, used to assign registers */
5518    int reg; /* if >= 0, register number used for this operand */
5519    int is_llong; /* true if double register value */
5520    int is_memory; /* true if memory operand */
5521    int is_rw;     /* for '+' modifier */
5522} ASMOperand;
5523
5524static void asm_expr(TCCState *s1, ExprValue *pe);
5525static int asm_int_expr(TCCState *s1);
5526static int find_constraint(ASMOperand *operands, int nb_operands,
5527                           const char *name, const char **pp);
5528
5529static int tcc_assemble(TCCState *s1, int do_preprocess);
5530
5531#endif
5532
5533static void asm_instr(void);
5534static void asm_global_instr(void);
5535
5536/* true if float/double/long double type */
5537static inline int is_float(int t)
5538{
5539    int bt;
5540    bt = t & VT_BTYPE;
5541    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
5542}
5543
5544#ifdef TCC_TARGET_I386
5545// njn: inlined i386-gen.c
5546//#include "i386-gen.c"
5547//---------------------------------------------------------------------------
5548/*
5549 *  X86 code generator for TCC
5550 *
5551 *  Copyright (c) 2001-2004 Fabrice Bellard
5552 *
5553 * This library is free software; you can redistribute it and/or
5554 * modify it under the terms of the GNU Lesser General Public
5555 * License as published by the Free Software Foundation; either
5556 * version 2 of the License, or (at your option) any later version.
5557 *
5558 * This library is distributed in the hope that it will be useful,
5559 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5560 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
5561 * Lesser General Public License for more details.
5562 *
5563 * You should have received a copy of the GNU Lesser General Public
5564 * License along with this library; if not, write to the Free Software
5565 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
5566 */
5567
5568/* number of available registers */
5569#define NB_REGS             4
5570
5571/* a register can belong to several classes. The classes must be
5572   sorted from more general to more precise (see gv2() code which does
5573   assumptions on it). */
5574#define RC_INT     0x0001 /* generic integer register */
5575#define RC_FLOAT   0x0002 /* generic float register */
5576#define RC_EAX     0x0004
5577#define RC_ST0     0x0008
5578#define RC_ECX     0x0010
5579#define RC_EDX     0x0020
5580#define RC_IRET    RC_EAX /* function return: integer register */
5581#define RC_LRET    RC_EDX /* function return: second integer register */
5582#define RC_FRET    RC_ST0 /* function return: float register */
5583
5584/* pretty names for the registers */
5585enum {
5586    TREG_EAX = 0,
5587    TREG_ECX,
5588    TREG_EDX,
5589    TREG_ST0,
5590};
5591
5592int reg_classes[NB_REGS] = {
5593    /* eax */ RC_INT | RC_EAX,
5594    /* ecx */ RC_INT | RC_ECX,
5595    /* edx */ RC_INT | RC_EDX,
5596    /* st0 */ RC_FLOAT | RC_ST0,
5597};
5598
5599/* return registers for function */
5600#define REG_IRET TREG_EAX /* single word int return register */
5601#define REG_LRET TREG_EDX /* second word return register (for long long) */
5602#define REG_FRET TREG_ST0 /* float return register */
5603
5604/* defined if function parameters must be evaluated in reverse order */
5605#define INVERT_FUNC_PARAMS
5606
5607/* defined if structures are passed as pointers. Otherwise structures
5608   are directly pushed on stack. */
5609//#define FUNC_STRUCT_PARAM_AS_PTR
5610
5611/* pointer size, in bytes */
5612#define PTR_SIZE 4
5613
5614/* long double size and alignment, in bytes */
5615#define LDOUBLE_SIZE  12
5616#define LDOUBLE_ALIGN 4
5617/* maximum alignment (for aligned attribute support) */
5618#define MAX_ALIGN     8
5619
5620/******************************************************/
5621/* ELF defines */
5622
5623#define EM_TCC_TARGET EM_386
5624
5625/* relocation type for 32 bit data relocation */
5626#define R_DATA_32   R_386_32
5627#define R_JMP_SLOT  R_386_JMP_SLOT
5628#define R_COPY      R_386_COPY
5629
5630#define ELF_START_ADDR 0x08048000
5631#define ELF_PAGE_SIZE  0x1000
5632
5633/******************************************************/
5634
5635static unsigned long func_sub_sp_offset;
5636static unsigned long func_bound_offset;
5637static int func_ret_sub;
5638
5639/* XXX: make it faster ? */
5640void g(int c)
5641{
5642    int ind1;
5643    ind1 = ind + 1;
5644    if (ind1 > cur_text_section->data_allocated)
5645        section_realloc(cur_text_section, ind1);
5646    cur_text_section->data[ind] = c;
5647    ind = ind1;
5648}
5649
5650void o(unsigned int c)
5651{
5652    while (c) {
5653        g(c);
5654        c = c >> 8;
5655    }
5656}
5657
5658void gen_le32(int c)
5659{
5660    g(c);
5661    g(c >> 8);
5662    g(c >> 16);
5663    g(c >> 24);
5664}
5665
5666/* output a symbol and patch all calls to it */
5667void gsym_addr(int t, int a)
5668{
5669    int n, *ptr;
5670    while (t) {
5671        ptr = (int *)(cur_text_section->data + t);
5672        n = *ptr; /* next value */
5673        *ptr = a - t - 4;
5674        t = n;
5675    }
5676}
5677
5678void gsym(int t)
5679{
5680    gsym_addr(t, ind);
5681}
5682
5683/* psym is used to put an instruction with a data field which is a
5684   reference to a symbol. It is in fact the same as oad ! */
5685#define psym oad
5686
5687/* instruction + 4 bytes data. Return the address of the data */
5688static int oad(int c, int s)
5689{
5690    int ind1;
5691
5692    o(c);
5693    ind1 = ind + 4;
5694    if (ind1 > cur_text_section->data_allocated)
5695        section_realloc(cur_text_section, ind1);
5696    *(int *)(cur_text_section->data + ind) = s;
5697    s = ind;
5698    ind = ind1;
5699    return s;
5700}
5701
5702/* output constant with relocation if 'r & VT_SYM' is true */
5703static void gen_addr32(int r, Sym *sym, int c)
5704{
5705    if (r & VT_SYM)
5706        greloc(cur_text_section, sym, ind, R_386_32);
5707    gen_le32(c);
5708}
5709
5710/* generate a modrm reference. 'op_reg' contains the addtionnal 3
5711   opcode bits */
5712static void gen_modrm(int op_reg, int r, Sym *sym, int c)
5713{
5714    op_reg = op_reg << 3;
5715    if ((r & VT_VALMASK) == VT_CONST) {
5716        /* constant memory reference */
5717        o(0x05 | op_reg);
5718        gen_addr32(r, sym, c);
5719    } else if ((r & VT_VALMASK) == VT_LOCAL) {
5720        /* currently, we use only ebp as base */
5721        if (c == (char)c) {
5722            /* short reference */
5723            o(0x45 | op_reg);
5724            g(c);
5725        } else {
5726            oad(0x85 | op_reg, c);
5727        }
5728    } else {
5729        g(0x00 | op_reg | (r & VT_VALMASK));
5730    }
5731}
5732
5733
5734/* load 'r' from value 'sv' */
5735void load(int r, SValue *sv)
5736{
5737    int v, t, ft, fc, fr;
5738    SValue v1;
5739
5740    fr = sv->r;
5741    ft = sv->type.t;
5742    fc = sv->c.ul;
5743
5744    v = fr & VT_VALMASK;
5745    if (fr & VT_LVAL) {
5746        if (v == VT_LLOCAL) {
5747            v1.type.t = VT_INT;
5748            v1.r = VT_LOCAL | VT_LVAL;
5749            v1.c.ul = fc;
5750            load(r, &v1);
5751            fr = r;
5752        }
5753        if ((ft & VT_BTYPE) == VT_FLOAT) {
5754            o(0xd9); /* flds */
5755            r = 0;
5756        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
5757            o(0xdd); /* fldl */
5758            r = 0;
5759        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
5760            o(0xdb); /* fldt */
5761            r = 5;
5762        } else if ((ft & VT_TYPE) == VT_BYTE) {
5763            o(0xbe0f);   /* movsbl */
5764        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
5765            o(0xb60f);   /* movzbl */
5766        } else if ((ft & VT_TYPE) == VT_SHORT) {
5767            o(0xbf0f);   /* movswl */
5768        } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
5769            o(0xb70f);   /* movzwl */
5770        } else {
5771            o(0x8b);     /* movl */
5772        }
5773        gen_modrm(r, fr, sv->sym, fc);
5774    } else {
5775        if (v == VT_CONST) {
5776            o(0xb8 + r); /* mov $xx, r */
5777            gen_addr32(fr, sv->sym, fc);
5778        } else if (v == VT_LOCAL) {
5779            o(0x8d); /* lea xxx(%ebp), r */
5780            gen_modrm(r, VT_LOCAL, sv->sym, fc);
5781        } else if (v == VT_CMP) {
5782            oad(0xb8 + r, 0); /* mov $0, r */
5783            o(0x0f); /* setxx %br */
5784            o(fc);
5785            o(0xc0 + r);
5786        } else if (v == VT_JMP || v == VT_JMPI) {
5787            t = v & 1;
5788            oad(0xb8 + r, t); /* mov $1, r */
5789            o(0x05eb); /* jmp after */
5790            gsym(fc);
5791            oad(0xb8 + r, t ^ 1); /* mov $0, r */
5792        } else if (v != r) {
5793            o(0x89);
5794            o(0xc0 + r + v * 8); /* mov v, r */
5795        }
5796    }
5797}
5798
5799/* store register 'r' in lvalue 'v' */
5800void store(int r, SValue *v)
5801{
5802    int fr, bt, ft, fc;
5803
5804    ft = v->type.t;
5805    fc = v->c.ul;
5806    fr = v->r & VT_VALMASK;
5807    bt = ft & VT_BTYPE;
5808    /* XXX: incorrect if float reg to reg */
5809    if (bt == VT_FLOAT) {
5810        o(0xd9); /* fsts */
5811        r = 2;
5812    } else if (bt == VT_DOUBLE) {
5813        o(0xdd); /* fstpl */
5814        r = 2;
5815    } else if (bt == VT_LDOUBLE) {
5816        o(0xc0d9); /* fld %st(0) */
5817        o(0xdb); /* fstpt */
5818        r = 7;
5819    } else {
5820        if (bt == VT_SHORT)
5821            o(0x66);
5822        if (bt == VT_BYTE || bt == VT_BOOL)
5823            o(0x88);
5824        else
5825            o(0x89);
5826    }
5827    if (fr == VT_CONST ||
5828        fr == VT_LOCAL ||
5829        (v->r & VT_LVAL)) {
5830        gen_modrm(r, v->r, v->sym, fc);
5831    } else if (fr != r) {
5832        o(0xc0 + fr + r * 8); /* mov r, fr */
5833    }
5834}
5835
5836static void gadd_sp(int val)
5837{
5838    if (val == (char)val) {
5839        o(0xc483);
5840        g(val);
5841    } else {
5842        oad(0xc481, val); /* add $xxx, %esp */
5843    }
5844}
5845
5846/* 'is_jmp' is '1' if it is a jump */
5847static void gcall_or_jmp(int is_jmp)
5848{
5849    int r;
5850    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
5851        /* constant case */
5852        if (vtop->r & VT_SYM) {
5853            /* relocation case */
5854            greloc(cur_text_section, vtop->sym,
5855                   ind + 1, R_386_PC32);
5856        } else {
5857            /* put an empty PC32 relocation */
5858            put_elf_reloc(symtab_section, cur_text_section,
5859                          ind + 1, R_386_PC32, 0);
5860        }
5861        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
5862    } else {
5863        /* otherwise, indirect call */
5864        r = gv(RC_INT);
5865        o(0xff); /* call/jmp *r */
5866        o(0xd0 + r + (is_jmp << 4));
5867    }
5868}
5869
5870static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
5871
5872/* Generate function call. The function address is pushed first, then
5873   all the parameters in call order. This functions pops all the
5874   parameters and the function address. */
5875void gfunc_call(int nb_args)
5876{
5877    int size, align, r, args_size, i, func_call;
5878    Sym *func_sym;
5879
5880    args_size = 0;
5881    for(i = 0;i < nb_args; i++) {
5882        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
5883            size = type_size(&vtop->type, &align);
5884            /* align to stack align size */
5885            size = (size + 3) & ~3;
5886            /* allocate the necessary size on stack */
5887            oad(0xec81, size); /* sub $xxx, %esp */
5888            /* generate structure store */
5889            r = get_reg(RC_INT);
5890            o(0x89); /* mov %esp, r */
5891            o(0xe0 + r);
5892            vset(&vtop->type, r | VT_LVAL, 0);
5893            vswap();
5894            vstore();
5895            args_size += size;
5896        } else if (is_float(vtop->type.t)) {
5897            gv(RC_FLOAT); /* only one float register */
5898            if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
5899                size = 4;
5900            else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
5901                size = 8;
5902            else
5903                size = 12;
5904            oad(0xec81, size); /* sub $xxx, %esp */
5905            if (size == 12)
5906                o(0x7cdb);
5907            else
5908                o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
5909            g(0x24);
5910            g(0x00);
5911            args_size += size;
5912        } else {
5913            /* simple type (currently always same size) */
5914            /* XXX: implicit cast ? */
5915            r = gv(RC_INT);
5916            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
5917                size = 8;
5918                o(0x50 + vtop->r2); /* push r */
5919            } else {
5920                size = 4;
5921            }
5922            o(0x50 + r); /* push r */
5923            args_size += size;
5924        }
5925        vtop--;
5926    }
5927    save_regs(0); /* save used temporary registers */
5928    func_sym = vtop->type.ref;
5929    func_call = func_sym->r;
5930    /* fast call case */
5931    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5932        int fastcall_nb_regs;
5933        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5934        for(i = 0;i < fastcall_nb_regs; i++) {
5935            if (args_size <= 0)
5936                break;
5937            o(0x58 + fastcall_regs[i]); /* pop r */
5938            /* XXX: incorrect for struct/floats */
5939            args_size -= 4;
5940        }
5941    }
5942    gcall_or_jmp(0);
5943    if (args_size && func_sym->r != FUNC_STDCALL)
5944        gadd_sp(args_size);
5945    vtop--;
5946}
5947
5948#ifdef TCC_TARGET_PE
5949#define FUNC_PROLOG_SIZE 10
5950#else
5951#define FUNC_PROLOG_SIZE 9
5952#endif
5953
5954/* generate function prolog of type 't' */
5955void gfunc_prolog(CType *func_type)
5956{
5957    int addr, align, size, func_call, fastcall_nb_regs;
5958    int param_index, param_addr;
5959    Sym *sym;
5960    CType *type;
5961
5962    sym = func_type->ref;
5963    func_call = sym->r;
5964    addr = 8;
5965    loc = 0;
5966    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
5967        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
5968    } else {
5969        fastcall_nb_regs = 0;
5970    }
5971    param_index = 0;
5972
5973    ind += FUNC_PROLOG_SIZE;
5974    func_sub_sp_offset = ind;
5975    /* if the function returns a structure, then add an
5976       implicit pointer parameter */
5977    func_vt = sym->type;
5978    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
5979        /* XXX: fastcall case ? */
5980        func_vc = addr;
5981        addr += 4;
5982        param_index++;
5983    }
5984    /* define parameters */
5985    while ((sym = sym->next) != NULL) {
5986        type = &sym->type;
5987        size = type_size(type, &align);
5988        size = (size + 3) & ~3;
5989#ifdef FUNC_STRUCT_PARAM_AS_PTR
5990        /* structs are passed as pointer */
5991        if ((type->t & VT_BTYPE) == VT_STRUCT) {
5992            size = 4;
5993        }
5994#endif
5995        if (param_index < fastcall_nb_regs) {
5996            /* save FASTCALL register */
5997            loc -= 4;
5998            o(0x89);     /* movl */
5999            gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc);
6000            param_addr = loc;
6001        } else {
6002            param_addr = addr;
6003            addr += size;
6004        }
6005        sym_push(sym->v & ~SYM_FIELD, type,
6006                 VT_LOCAL | VT_LVAL, param_addr);
6007        param_index++;
6008    }
6009    func_ret_sub = 0;
6010    /* pascal type call ? */
6011    if (func_call == FUNC_STDCALL)
6012        func_ret_sub = addr - 8;
6013
6014    /* leave some room for bound checking code */
6015    if (do_bounds_check) {
6016        oad(0xb8, 0); /* lbound section pointer */
6017        oad(0xb8, 0); /* call to function */
6018        func_bound_offset = lbounds_section->data_offset;
6019    }
6020}
6021
6022/* generate function epilog */
6023void gfunc_epilog(void)
6024{
6025    int v, saved_ind;
6026
6027#ifdef CONFIG_TCC_BCHECK
6028    if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
6029        int saved_ind;
6030        int *bounds_ptr;
6031        Sym *sym, *sym_data;
6032        /* add end of table info */
6033        bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
6034        *bounds_ptr = 0;
6035        /* generate bound local allocation */
6036        saved_ind = ind;
6037        ind = func_sub_sp_offset;
6038        sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
6039                               func_bound_offset, lbounds_section->data_offset);
6040        greloc(cur_text_section, sym_data,
6041               ind + 1, R_386_32);
6042        oad(0xb8, 0); /* mov %eax, xxx */
6043        sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
6044        greloc(cur_text_section, sym,
6045               ind + 1, R_386_PC32);
6046        oad(0xe8, -4);
6047        ind = saved_ind;
6048        /* generate bound check local freeing */
6049        o(0x5250); /* save returned value, if any */
6050        greloc(cur_text_section, sym_data,
6051               ind + 1, R_386_32);
6052        oad(0xb8, 0); /* mov %eax, xxx */
6053        sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
6054        greloc(cur_text_section, sym,
6055               ind + 1, R_386_PC32);
6056        oad(0xe8, -4);
6057        o(0x585a); /* restore returned value, if any */
6058    }
6059#endif
6060    o(0xc9); /* leave */
6061    if (func_ret_sub == 0) {
6062        o(0xc3); /* ret */
6063    } else {
6064        o(0xc2); /* ret n */
6065        g(func_ret_sub);
6066        g(func_ret_sub >> 8);
6067    }
6068    /* align local size to word & save local variables */
6069
6070    v = (-loc + 3) & -4;
6071    saved_ind = ind;
6072    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
6073#ifdef TCC_TARGET_PE
6074    if (v >= 4096) {
6075        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
6076        oad(0xb8, v); /* mov stacksize, %eax */
6077        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
6078        greloc(cur_text_section, sym, ind-4, R_386_PC32);
6079    } else
6080#endif
6081    {
6082        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
6083        o(0xec81);  /* sub esp, stacksize */
6084        gen_le32(v);
6085#if FUNC_PROLOG_SIZE == 10
6086        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
6087#endif
6088    }
6089    ind = saved_ind;
6090}
6091
6092/* generate a jump to a label */
6093long gjmp(int t)
6094{
6095    return psym(0xe9, t);
6096}
6097
6098/* generate a jump to a fixed address */
6099void gjmp_addr(int a)
6100{
6101    int r;
6102    r = a - ind - 2;
6103    if (r == (char)r) {
6104        g(0xeb);
6105        g(r);
6106    } else {
6107        oad(0xe9, a - ind - 5);
6108    }
6109}
6110
6111/* generate a test. set 'inv' to invert test. Stack entry is popped */
6112int gtst(int inv, int t)
6113{
6114    int v, *p;
6115
6116    v = vtop->r & VT_VALMASK;
6117    if (v == VT_CMP) {
6118        /* fast case : can jump directly since flags are set */
6119        g(0x0f);
6120        t = psym((vtop->c.i - 16) ^ inv, t);
6121    } else if (v == VT_JMP || v == VT_JMPI) {
6122        /* && or || optimization */
6123        if ((v & 1) == inv) {
6124            /* insert vtop->c jump list in t */
6125            p = &vtop->c.i;
6126            while (*p != 0)
6127                p = (int *)(cur_text_section->data + *p);
6128            *p = t;
6129            t = vtop->c.i;
6130        } else {
6131            t = gjmp(t);
6132            gsym(vtop->c.i);
6133        }
6134    } else {
6135        if (is_float(vtop->type.t)) {
6136            vpushi(0);
6137            gen_op(TOK_NE);
6138        }
6139        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6140            /* constant jmp optimization */
6141            if ((vtop->c.i != 0) != inv)
6142                t = gjmp(t);
6143        } else {
6144            v = gv(RC_INT);
6145            o(0x85);
6146            o(0xc0 + v * 9);
6147            g(0x0f);
6148            t = psym(0x85 ^ inv, t);
6149        }
6150    }
6151    vtop--;
6152    return t;
6153}
6154
6155/* generate an integer binary operation */
6156void gen_opi(int op)
6157{
6158    int r, fr, opc, c;
6159
6160    switch(op) {
6161    case '+':
6162    case TOK_ADDC1: /* add with carry generation */
6163        opc = 0;
6164    gen_op8:
6165        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6166            /* constant case */
6167            vswap();
6168            r = gv(RC_INT);
6169            vswap();
6170            c = vtop->c.i;
6171            if (c == (char)c) {
6172                /* XXX: generate inc and dec for smaller code ? */
6173                o(0x83);
6174                o(0xc0 | (opc << 3) | r);
6175                g(c);
6176            } else {
6177                o(0x81);
6178                oad(0xc0 | (opc << 3) | r, c);
6179            }
6180        } else {
6181            gv2(RC_INT, RC_INT);
6182            r = vtop[-1].r;
6183            fr = vtop[0].r;
6184            o((opc << 3) | 0x01);
6185            o(0xc0 + r + fr * 8);
6186        }
6187        vtop--;
6188        if (op >= TOK_ULT && op <= TOK_GT) {
6189            vtop->r = VT_CMP;
6190            vtop->c.i = op;
6191        }
6192        break;
6193    case '-':
6194    case TOK_SUBC1: /* sub with carry generation */
6195        opc = 5;
6196        goto gen_op8;
6197    case TOK_ADDC2: /* add with carry use */
6198        opc = 2;
6199        goto gen_op8;
6200    case TOK_SUBC2: /* sub with carry use */
6201        opc = 3;
6202        goto gen_op8;
6203    case '&':
6204        opc = 4;
6205        goto gen_op8;
6206    case '^':
6207        opc = 6;
6208        goto gen_op8;
6209    case '|':
6210        opc = 1;
6211        goto gen_op8;
6212    case '*':
6213        gv2(RC_INT, RC_INT);
6214        r = vtop[-1].r;
6215        fr = vtop[0].r;
6216        vtop--;
6217        o(0xaf0f); /* imul fr, r */
6218        o(0xc0 + fr + r * 8);
6219        break;
6220    case TOK_SHL:
6221        opc = 4;
6222        goto gen_shift;
6223    case TOK_SHR:
6224        opc = 5;
6225        goto gen_shift;
6226    case TOK_SAR:
6227        opc = 7;
6228    gen_shift:
6229        opc = 0xc0 | (opc << 3);
6230        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
6231            /* constant case */
6232            vswap();
6233            r = gv(RC_INT);
6234            vswap();
6235            c = vtop->c.i & 0x1f;
6236            o(0xc1); /* shl/shr/sar $xxx, r */
6237            o(opc | r);
6238            g(c);
6239        } else {
6240            /* we generate the shift in ecx */
6241            gv2(RC_INT, RC_ECX);
6242            r = vtop[-1].r;
6243            o(0xd3); /* shl/shr/sar %cl, r */
6244            o(opc | r);
6245        }
6246        vtop--;
6247        break;
6248    case '/':
6249    case TOK_UDIV:
6250    case TOK_PDIV:
6251    case '%':
6252    case TOK_UMOD:
6253    case TOK_UMULL:
6254        /* first operand must be in eax */
6255        /* XXX: need better constraint for second operand */
6256        gv2(RC_EAX, RC_ECX);
6257        r = vtop[-1].r;
6258        fr = vtop[0].r;
6259        vtop--;
6260        save_reg(TREG_EDX);
6261        if (op == TOK_UMULL) {
6262            o(0xf7); /* mul fr */
6263            o(0xe0 + fr);
6264            vtop->r2 = TREG_EDX;
6265            r = TREG_EAX;
6266        } else {
6267            if (op == TOK_UDIV || op == TOK_UMOD) {
6268                o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
6269                o(0xf0 + fr);
6270            } else {
6271                o(0xf799); /* cltd, idiv fr, %eax */
6272                o(0xf8 + fr);
6273            }
6274            if (op == '%' || op == TOK_UMOD)
6275                r = TREG_EDX;
6276            else
6277                r = TREG_EAX;
6278        }
6279        vtop->r = r;
6280        break;
6281    default:
6282        opc = 7;
6283        goto gen_op8;
6284    }
6285}
6286
6287/* generate a floating point operation 'v = t1 op t2' instruction. The
6288   two operands are guaranted to have the same floating point type */
6289/* XXX: need to use ST1 too */
6290void gen_opf(int op)
6291{
6292    int a, ft, fc, swapped, r;
6293
6294    /* convert constants to memory references */
6295    if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
6296        vswap();
6297        gv(RC_FLOAT);
6298        vswap();
6299    }
6300    if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
6301        gv(RC_FLOAT);
6302
6303    /* must put at least one value in the floating point register */
6304    if ((vtop[-1].r & VT_LVAL) &&
6305        (vtop[0].r & VT_LVAL)) {
6306        vswap();
6307        gv(RC_FLOAT);
6308        vswap();
6309    }
6310    swapped = 0;
6311    /* swap the stack if needed so that t1 is the register and t2 is
6312       the memory reference */
6313    if (vtop[-1].r & VT_LVAL) {
6314        vswap();
6315        swapped = 1;
6316    }
6317    if (op >= TOK_ULT && op <= TOK_GT) {
6318        /* load on stack second operand */
6319        load(TREG_ST0, vtop);
6320        save_reg(TREG_EAX); /* eax is used by FP comparison code */
6321        if (op == TOK_GE || op == TOK_GT)
6322            swapped = !swapped;
6323        else if (op == TOK_EQ || op == TOK_NE)
6324            swapped = 0;
6325        if (swapped)
6326            o(0xc9d9); /* fxch %st(1) */
6327        o(0xe9da); /* fucompp */
6328        o(0xe0df); /* fnstsw %ax */
6329        if (op == TOK_EQ) {
6330            o(0x45e480); /* and $0x45, %ah */
6331            o(0x40fC80); /* cmp $0x40, %ah */
6332        } else if (op == TOK_NE) {
6333            o(0x45e480); /* and $0x45, %ah */
6334            o(0x40f480); /* xor $0x40, %ah */
6335            op = TOK_NE;
6336        } else if (op == TOK_GE || op == TOK_LE) {
6337            o(0x05c4f6); /* test $0x05, %ah */
6338            op = TOK_EQ;
6339        } else {
6340            o(0x45c4f6); /* test $0x45, %ah */
6341            op = TOK_EQ;
6342        }
6343        vtop--;
6344        vtop->r = VT_CMP;
6345        vtop->c.i = op;
6346    } else {
6347        /* no memory reference possible for long double operations */
6348        if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
6349            load(TREG_ST0, vtop);
6350            swapped = !swapped;
6351        }
6352
6353        switch(op) {
6354        default:
6355        case '+':
6356            a = 0;
6357            break;
6358        case '-':
6359            a = 4;
6360            if (swapped)
6361                a++;
6362            break;
6363        case '*':
6364            a = 1;
6365            break;
6366        case '/':
6367            a = 6;
6368            if (swapped)
6369                a++;
6370            break;
6371        }
6372        ft = vtop->type.t;
6373        fc = vtop->c.ul;
6374        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
6375            o(0xde); /* fxxxp %st, %st(1) */
6376            o(0xc1 + (a << 3));
6377        } else {
6378            /* if saved lvalue, then we must reload it */
6379            r = vtop->r;
6380            if ((r & VT_VALMASK) == VT_LLOCAL) {
6381                SValue v1;
6382                r = get_reg(RC_INT);
6383                v1.type.t = VT_INT;
6384                v1.r = VT_LOCAL | VT_LVAL;
6385                v1.c.ul = fc;
6386                load(r, &v1);
6387                fc = 0;
6388            }
6389
6390            if ((ft & VT_BTYPE) == VT_DOUBLE)
6391                o(0xdc);
6392            else
6393                o(0xd8);
6394            gen_modrm(a, r, vtop->sym, fc);
6395        }
6396        vtop--;
6397    }
6398}
6399
6400/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
6401   and 'long long' cases. */
6402void gen_cvt_itof(int t)
6403{
6404    save_reg(TREG_ST0);
6405    gv(RC_INT);
6406    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
6407        /* signed long long to float/double/long double (unsigned case
6408           is handled generically) */
6409        o(0x50 + vtop->r2); /* push r2 */
6410        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6411        o(0x242cdf); /* fildll (%esp) */
6412        o(0x08c483); /* add $8, %esp */
6413    } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
6414               (VT_INT | VT_UNSIGNED)) {
6415        /* unsigned int to float/double/long double */
6416        o(0x6a); /* push $0 */
6417        g(0x00);
6418        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6419        o(0x242cdf); /* fildll (%esp) */
6420        o(0x08c483); /* add $8, %esp */
6421    } else {
6422        /* int to float/double/long double */
6423        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
6424        o(0x2404db); /* fildl (%esp) */
6425        o(0x04c483); /* add $4, %esp */
6426    }
6427    vtop->r = TREG_ST0;
6428}
6429
6430/* convert fp to int 't' type */
6431/* XXX: handle long long case */
6432void gen_cvt_ftoi(int t)
6433{
6434    int r, r2, size;
6435    Sym *sym;
6436    CType ushort_type;
6437
6438    ushort_type.t = VT_SHORT | VT_UNSIGNED;
6439
6440    gv(RC_FLOAT);
6441    if (t != VT_INT)
6442        size = 8;
6443    else
6444        size = 4;
6445
6446    o(0x2dd9); /* ldcw xxx */
6447    sym = external_global_sym(TOK___tcc_int_fpu_control,
6448                              &ushort_type, VT_LVAL);
6449    greloc(cur_text_section, sym,
6450           ind, R_386_32);
6451    gen_le32(0);
6452
6453    oad(0xec81, size); /* sub $xxx, %esp */
6454    if (size == 4)
6455        o(0x1cdb); /* fistpl */
6456    else
6457        o(0x3cdf); /* fistpll */
6458    o(0x24);
6459    o(0x2dd9); /* ldcw xxx */
6460    sym = external_global_sym(TOK___tcc_fpu_control,
6461                              &ushort_type, VT_LVAL);
6462    greloc(cur_text_section, sym,
6463           ind, R_386_32);
6464    gen_le32(0);
6465
6466    r = get_reg(RC_INT);
6467    o(0x58 + r); /* pop r */
6468    if (size == 8) {
6469        if (t == VT_LLONG) {
6470            vtop->r = r; /* mark reg as used */
6471            r2 = get_reg(RC_INT);
6472            o(0x58 + r2); /* pop r2 */
6473            vtop->r2 = r2;
6474        } else {
6475            o(0x04c483); /* add $4, %esp */
6476        }
6477    }
6478    vtop->r = r;
6479}
6480
6481/* convert from one floating point type to another */
6482void gen_cvt_ftof(int t)
6483{
6484    /* all we have to do on i386 is to put the float in a register */
6485    gv(RC_FLOAT);
6486}
6487
6488/* computed goto support */
6489void ggoto(void)
6490{
6491    gcall_or_jmp(1);
6492    vtop--;
6493}
6494
6495/* bound check support functions */
6496#ifdef CONFIG_TCC_BCHECK
6497
6498/* generate a bounded pointer addition */
6499void gen_bounded_ptr_add(void)
6500{
6501    Sym *sym;
6502
6503    /* prepare fast i386 function call (args in eax and edx) */
6504    gv2(RC_EAX, RC_EDX);
6505    /* save all temporary registers */
6506    vtop -= 2;
6507    save_regs(0);
6508    /* do a fast function call */
6509    sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
6510    greloc(cur_text_section, sym,
6511           ind + 1, R_386_PC32);
6512    oad(0xe8, -4);
6513    /* returned pointer is in eax */
6514    vtop++;
6515    vtop->r = TREG_EAX | VT_BOUNDED;
6516    /* address of bounding function call point */
6517    vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
6518}
6519
6520/* patch pointer addition in vtop so that pointer dereferencing is
6521   also tested */
6522void gen_bounded_ptr_deref(void)
6523{
6524    int func;
6525    int size, align;
6526    Elf32_Rel *rel;
6527    Sym *sym;
6528
6529    size = 0;
6530    /* XXX: put that code in generic part of tcc */
6531    if (!is_float(vtop->type.t)) {
6532        if (vtop->r & VT_LVAL_BYTE)
6533            size = 1;
6534        else if (vtop->r & VT_LVAL_SHORT)
6535            size = 2;
6536    }
6537    if (!size)
6538        size = type_size(&vtop->type, &align);
6539    switch(size) {
6540    case  1: func = TOK___bound_ptr_indir1; break;
6541    case  2: func = TOK___bound_ptr_indir2; break;
6542    case  4: func = TOK___bound_ptr_indir4; break;
6543    case  8: func = TOK___bound_ptr_indir8; break;
6544    case 12: func = TOK___bound_ptr_indir12; break;
6545    case 16: func = TOK___bound_ptr_indir16; break;
6546    default:
6547        error("unhandled size when derefencing bounded pointer");
6548        func = 0;
6549        break;
6550    }
6551
6552    /* patch relocation */
6553    /* XXX: find a better solution ? */
6554    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
6555    sym = external_global_sym(func, &func_old_type, 0);
6556    if (!sym->c)
6557        put_extern_sym(sym, NULL, 0, 0);
6558    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
6559}
6560#endif
6561
6562/* end of X86 code generator */
6563/*************************************************************/
6564
6565//---------------------------------------------------------------------------
6566#endif
6567
6568// njn: commented these out
6569//#ifdef TCC_TARGET_ARM
6570//#include "arm-gen.c"
6571//#endif
6572//
6573//#ifdef TCC_TARGET_C67
6574//#include "c67-gen.c"
6575//#endif
6576
6577#ifdef CONFIG_TCC_STATIC
6578
6579#define RTLD_LAZY       0x001
6580#define RTLD_NOW        0x002
6581#define RTLD_GLOBAL     0x100
6582#define RTLD_DEFAULT    NULL
6583
6584/* dummy function for profiling */
6585void *dlopen(const char *filename, int flag)
6586{
6587    return NULL;
6588}
6589
6590const char *dlerror(void)
6591{
6592    return "error";
6593}
6594
6595typedef struct TCCSyms {
6596    char *str;
6597    void *ptr;
6598} TCCSyms;
6599
6600#define TCCSYM(a) { #a, &a, },
6601
6602/* add the symbol you want here if no dynamic linking is done */
6603static TCCSyms tcc_syms[] = {
6604#if !defined(CONFIG_TCCBOOT)
6605    TCCSYM(printf)
6606    TCCSYM(fprintf)
6607    TCCSYM(fopen)
6608    TCCSYM(fclose)
6609#endif
6610    { NULL, NULL },
6611};
6612
6613void *resolve_sym(TCCState *s1, const char *symbol, int type)
6614{
6615    TCCSyms *p;
6616    p = tcc_syms;
6617    while (p->str != NULL) {
6618        if (!strcmp(p->str, symbol))
6619            return p->ptr;
6620        p++;
6621    }
6622    return NULL;
6623}
6624
6625#elif !defined(WIN32)
6626
6627#include <dlfcn.h>
6628
6629void *resolve_sym(TCCState *s1, const char *sym, int type)
6630{
6631  assert(0);
6632  return 0; //dlsym(RTLD_DEFAULT, sym);
6633  // jrs: remove need for dlsym
6634}
6635
6636#endif
6637
6638/********************************************************/
6639
6640/* we use our own 'finite' function to avoid potential problems with
6641   non standard math libs */
6642/* XXX: endianness dependent */
6643int ieee_finite(double d)
6644{
6645    int *p = (int *)&d;
6646    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
6647}
6648
6649/* copy a string and truncate it. */
6650static char *pstrcpy(char *buf, int buf_size, const char *s)
6651{
6652    char *q, *q_end;
6653    int c;
6654
6655    if (buf_size > 0) {
6656        q = buf;
6657        q_end = buf + buf_size - 1;
6658        while (q < q_end) {
6659            c = *s++;
6660            if (c == '\0')
6661                break;
6662            *q++ = c;
6663        }
6664        *q = '\0';
6665    }
6666    return buf;
6667}
6668
6669/* strcat and truncate. */
6670static char *pstrcat(char *buf, int buf_size, const char *s)
6671{
6672    int len;
6673    len = strlen(buf);
6674    if (len < buf_size)
6675        pstrcpy(buf + len, buf_size - len, s);
6676    return buf;
6677}
6678
6679static int strstart(const char *str, const char *val, const char **ptr)
6680{
6681    const char *p, *q;
6682    p = str;
6683    q = val;
6684    while (*q != '\0') {
6685        if (*p != *q)
6686            return 0;
6687        p++;
6688        q++;
6689    }
6690    if (ptr)
6691        *ptr = p;
6692    return 1;
6693}
6694
6695/* memory management */
6696#ifdef MEM_DEBUG
6697int mem_cur_size;
6698int mem_max_size;
6699#endif
6700
6701static inline void tcc_free(void *ptr)
6702{
6703#ifdef MEM_DEBUG
6704    mem_cur_size -= malloc_usable_size(ptr);
6705#endif
6706    free(ptr);
6707}
6708
6709static void *tcc_malloc(unsigned long size)
6710{
6711    void *ptr;
6712    ptr = malloc(size);
6713    if (!ptr && size)
6714        error("memory full");
6715#ifdef MEM_DEBUG
6716    mem_cur_size += malloc_usable_size(ptr);
6717    if (mem_cur_size > mem_max_size)
6718        mem_max_size = mem_cur_size;
6719#endif
6720    return ptr;
6721}
6722
6723static void *tcc_mallocz(unsigned long size)
6724{
6725    void *ptr;
6726    ptr = tcc_malloc(size);
6727    memset(ptr, 0, size);
6728    return ptr;
6729}
6730
6731static inline void *tcc_realloc(void *ptr, unsigned long size)
6732{
6733    void *ptr1;
6734#ifdef MEM_DEBUG
6735    mem_cur_size -= malloc_usable_size(ptr);
6736#endif
6737    ptr1 = realloc(ptr, size);
6738#ifdef MEM_DEBUG
6739    /* NOTE: count not correct if alloc error, but not critical */
6740    mem_cur_size += malloc_usable_size(ptr1);
6741    if (mem_cur_size > mem_max_size)
6742        mem_max_size = mem_cur_size;
6743#endif
6744    return ptr1;
6745}
6746
6747static char *tcc_strdup(const char *str)
6748{
6749    char *ptr;
6750    ptr = tcc_malloc(strlen(str) + 1);
6751    strcpy(ptr, str);
6752    return ptr;
6753}
6754
6755#define free(p) use_tcc_free(p)
6756#define malloc(s) use_tcc_malloc(s)
6757#define realloc(p, s) use_tcc_realloc(p, s)
6758
6759static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
6760{
6761    int nb, nb_alloc;
6762    void **pp;
6763
6764    nb = *nb_ptr;
6765    pp = *ptab;
6766    /* every power of two we double array size */
6767    if ((nb & (nb - 1)) == 0) {
6768        if (!nb)
6769            nb_alloc = 1;
6770        else
6771            nb_alloc = nb * 2;
6772        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
6773        if (!pp)
6774            error("memory full");
6775        *ptab = pp;
6776    }
6777    pp[nb++] = data;
6778    *nb_ptr = nb;
6779}
6780
6781/* symbol allocator */
6782static Sym *__sym_malloc(void)
6783{
6784    Sym *sym_pool, *sym, *last_sym;
6785    int i;
6786
6787    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
6788
6789    last_sym = sym_free_first;
6790    sym = sym_pool;
6791    for(i = 0; i < SYM_POOL_NB; i++) {
6792        sym->next = last_sym;
6793        last_sym = sym;
6794        sym++;
6795    }
6796    sym_free_first = last_sym;
6797    return last_sym;
6798}
6799
6800static inline Sym *sym_malloc(void)
6801{
6802    Sym *sym;
6803    sym = sym_free_first;
6804    if (!sym)
6805        sym = __sym_malloc();
6806    sym_free_first = sym->next;
6807    return sym;
6808}
6809
6810static inline void sym_free(Sym *sym)
6811{
6812    sym->next = sym_free_first;
6813    sym_free_first = sym;
6814}
6815
6816Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
6817{
6818    Section *sec;
6819
6820    sec = tcc_mallocz(sizeof(Section) + strlen(name));
6821    strcpy(sec->name, name);
6822    sec->sh_type = sh_type;
6823    sec->sh_flags = sh_flags;
6824    switch(sh_type) {
6825    case SHT_HASH:
6826    case SHT_REL:
6827    case SHT_DYNSYM:
6828    case SHT_SYMTAB:
6829    case SHT_DYNAMIC:
6830        sec->sh_addralign = 4;
6831        break;
6832    case SHT_STRTAB:
6833        sec->sh_addralign = 1;
6834        break;
6835    default:
6836        sec->sh_addralign = 32; /* default conservative alignment */
6837        break;
6838    }
6839
6840    /* only add section if not private */
6841    if (!(sh_flags & SHF_PRIVATE)) {
6842        sec->sh_num = s1->nb_sections;
6843        dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
6844    }
6845    return sec;
6846}
6847
6848static void free_section(Section *s)
6849{
6850    tcc_free(s->data);
6851    tcc_free(s);
6852}
6853
6854/* realloc section and set its content to zero */
6855static void section_realloc(Section *sec, unsigned long new_size)
6856{
6857    unsigned long size;
6858    unsigned char *data;
6859
6860    size = sec->data_allocated;
6861    if (size == 0)
6862        size = 1;
6863    while (size < new_size)
6864        size = size * 2;
6865    data = tcc_realloc(sec->data, size);
6866    if (!data)
6867        error("memory full");
6868    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
6869    sec->data = data;
6870    sec->data_allocated = size;
6871}
6872
6873/* reserve at least 'size' bytes in section 'sec' from
6874   sec->data_offset. */
6875static void *section_ptr_add(Section *sec, unsigned long size)
6876{
6877    unsigned long offset, offset1;
6878
6879    offset = sec->data_offset;
6880    offset1 = offset + size;
6881    if (offset1 > sec->data_allocated)
6882        section_realloc(sec, offset1);
6883    sec->data_offset = offset1;
6884    return sec->data + offset;
6885}
6886
6887/* return a reference to a section, and create it if it does not
6888   exists */
6889Section *find_section(TCCState *s1, const char *name)
6890{
6891    Section *sec;
6892    int i;
6893    for(i = 1; i < s1->nb_sections; i++) {
6894        sec = s1->sections[i];
6895        if (!strcmp(name, sec->name))
6896            return sec;
6897    }
6898    /* sections are created as PROGBITS */
6899    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
6900}
6901
6902#define SECTION_ABS ((void *)1)
6903
6904/* update sym->c so that it points to an external symbol in section
6905   'section' with value 'value' */
6906static void put_extern_sym2(Sym *sym, Section *section,
6907                            unsigned long value, unsigned long size,
6908                            int can_add_underscore)
6909{
6910    int sym_type, sym_bind, sh_num, info;
6911    Elf32_Sym *esym;
6912    const char *name;
6913    char buf1[256];
6914
6915    if (section == NULL)
6916        sh_num = SHN_UNDEF;
6917    else if (section == SECTION_ABS)
6918        sh_num = SHN_ABS;
6919    else
6920        sh_num = section->sh_num;
6921    if (!sym->c) {
6922        if ((sym->type.t & VT_BTYPE) == VT_FUNC)
6923            sym_type = STT_FUNC;
6924        else
6925            sym_type = STT_OBJECT;
6926        if (sym->type.t & VT_STATIC)
6927            sym_bind = STB_LOCAL;
6928        else
6929            sym_bind = STB_GLOBAL;
6930
6931        name = get_tok_str(sym->v, NULL);
6932#ifdef CONFIG_TCC_BCHECK
6933        if (do_bounds_check) {
6934            char buf[32];
6935
6936            /* XXX: avoid doing that for statics ? */
6937            /* if bound checking is activated, we change some function
6938               names by adding the "__bound" prefix */
6939            switch(sym->v) {
6940#if 0
6941            /* XXX: we rely only on malloc hooks */
6942            case TOK_malloc:
6943            case TOK_free:
6944            case TOK_realloc:
6945            case TOK_memalign:
6946            case TOK_calloc:
6947#endif
6948            case TOK_memcpy:
6949            case TOK_memmove:
6950            case TOK_memset:
6951            case TOK_strlen:
6952            case TOK_strcpy:
6953                strcpy(buf, "__bound_");
6954                strcat(buf, name);
6955                name = buf;
6956                break;
6957            }
6958        }
6959#endif
6960        if (tcc_state->leading_underscore && can_add_underscore) {
6961            buf1[0] = '_';
6962            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
6963            name = buf1;
6964        }
6965        info = ELF32_ST_INFO(sym_bind, sym_type);
6966        sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
6967    } else {
6968        esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
6969        esym->st_value = value;
6970        esym->st_size = size;
6971        esym->st_shndx = sh_num;
6972    }
6973}
6974
6975static void put_extern_sym(Sym *sym, Section *section,
6976                           unsigned long value, unsigned long size)
6977{
6978    put_extern_sym2(sym, section, value, size, 1);
6979}
6980
6981/* add a new relocation entry to symbol 'sym' in section 's' */
6982static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
6983{
6984    if (!sym->c)
6985        put_extern_sym(sym, NULL, 0, 0);
6986    /* now we can add ELF relocation info */
6987    put_elf_reloc(symtab_section, s, offset, type, sym->c);
6988}
6989
6990static inline int isid(int c)
6991{
6992    return (c >= 'a' && c <= 'z') ||
6993        (c >= 'A' && c <= 'Z') ||
6994        c == '_';
6995}
6996
6997static inline int isnum(int c)
6998{
6999    return c >= '0' && c <= '9';
7000}
7001
7002static inline int isoct(int c)
7003{
7004    return c >= '0' && c <= '7';
7005}
7006
7007static inline int toup(int c)
7008{
7009    if (c >= 'a' && c <= 'z')
7010        return c - 'a' + 'A';
7011    else
7012        return c;
7013}
7014
7015static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
7016{
7017    int len;
7018    len = strlen(buf);
7019    vsnprintf(buf + len, buf_size - len, fmt, ap);
7020}
7021
7022static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
7023{
7024    va_list ap;
7025    va_start(ap, fmt);
7026    strcat_vprintf(buf, buf_size, fmt, ap);
7027    va_end(ap);
7028}
7029
7030void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
7031{
7032    char buf[2048];
7033    BufferedFile **f;
7034
7035    buf[0] = '\0';
7036    if (file) {
7037        for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
7038            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
7039                          (*f)->filename, (*f)->line_num);
7040        if (file->line_num > 0) {
7041            strcat_printf(buf, sizeof(buf),
7042                          "%s:%d: ", file->filename, file->line_num);
7043        } else {
7044            strcat_printf(buf, sizeof(buf),
7045                          "%s: ", file->filename);
7046        }
7047    } else {
7048        strcat_printf(buf, sizeof(buf),
7049                      "tcc: ");
7050    }
7051    if (is_warning)
7052        strcat_printf(buf, sizeof(buf), "warning: ");
7053    strcat_vprintf(buf, sizeof(buf), fmt, ap);
7054
7055    if (!s1->error_func) {
7056        /* default case: stderr */
7057        fprintf(stderr, "%s\n", buf);
7058    } else {
7059        s1->error_func(s1->error_opaque, buf);
7060    }
7061    if (!is_warning || s1->warn_error)
7062        s1->nb_errors++;
7063}
7064
7065#ifdef LIBTCC
7066void tcc_set_error_func(TCCState *s, void *error_opaque,
7067                        void (*error_func)(void *opaque, const char *msg))
7068{
7069    s->error_opaque = error_opaque;
7070    s->error_func = error_func;
7071}
7072#endif
7073
7074/* error without aborting current compilation */
7075void error_noabort(const char *fmt, ...)
7076{
7077    TCCState *s1 = tcc_state;
7078    va_list ap;
7079
7080    va_start(ap, fmt);
7081    error1(s1, 0, fmt, ap);
7082    va_end(ap);
7083}
7084
7085void error(const char *fmt, ...)
7086{
7087    TCCState *s1 = tcc_state;
7088    va_list ap;
7089
7090    va_start(ap, fmt);
7091    error1(s1, 0, fmt, ap);
7092    va_end(ap);
7093    /* better than nothing: in some cases, we accept to handle errors */
7094    if (s1->error_set_jmp_enabled) {
7095        longjmp(s1->error_jmp_buf, 1);
7096    } else {
7097        /* XXX: eliminate this someday */
7098        exit(1);
7099    }
7100}
7101
7102void expect(const char *msg)
7103{
7104    error("%s expected", msg);
7105}
7106
7107void warning(const char *fmt, ...)
7108{
7109    TCCState *s1 = tcc_state;
7110    va_list ap;
7111
7112    if (s1->warn_none)
7113        return;
7114
7115    va_start(ap, fmt);
7116    error1(s1, 1, fmt, ap);
7117    va_end(ap);
7118}
7119
7120void skip(int c)
7121{
7122    if (tok != c)
7123        error("'%c' expected", c);
7124    next();
7125}
7126
7127static void test_lvalue(void)
7128{
7129    if (!(vtop->r & VT_LVAL))
7130        expect("lvalue");
7131}
7132
7133/* allocate a new token */
7134static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
7135{
7136    TokenSym *ts, **ptable;
7137    int i;
7138
7139    if (tok_ident >= SYM_FIRST_ANOM)
7140        error("memory full");
7141
7142    /* expand token table if needed */
7143    i = tok_ident - TOK_IDENT;
7144    if ((i % TOK_ALLOC_INCR) == 0) {
7145        ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
7146        if (!ptable)
7147            error("memory full");
7148        table_ident = ptable;
7149    }
7150
7151    ts = tcc_malloc(sizeof(TokenSym) + len);
7152    table_ident[i] = ts;
7153    ts->tok = tok_ident++;
7154    ts->sym_define = NULL;
7155    ts->sym_label = NULL;
7156    ts->sym_struct = NULL;
7157    ts->sym_identifier = NULL;
7158    ts->len = len;
7159    ts->hash_next = NULL;
7160    memcpy(ts->str, str, len);
7161    ts->str[len] = '\0';
7162    *pts = ts;
7163    return ts;
7164}
7165
7166#define TOK_HASH_INIT 1
7167#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
7168
7169/* find a token and add it if not found */
7170static TokenSym *tok_alloc(const char *str, int len)
7171{
7172    TokenSym *ts, **pts;
7173    int i;
7174    unsigned int h;
7175
7176    h = TOK_HASH_INIT;
7177    for(i=0;i<len;i++)
7178        h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
7179    h &= (TOK_HASH_SIZE - 1);
7180
7181    pts = &hash_ident[h];
7182    for(;;) {
7183        ts = *pts;
7184        if (!ts)
7185            break;
7186        if (ts->len == len && !memcmp(ts->str, str, len))
7187            return ts;
7188        pts = &(ts->hash_next);
7189    }
7190    return tok_alloc_new(pts, str, len);
7191}
7192
7193/* CString handling */
7194
7195static void cstr_realloc(CString *cstr, int new_size)
7196{
7197    int size;
7198    void *data;
7199
7200    size = cstr->size_allocated;
7201    if (size == 0)
7202        size = 8; /* no need to allocate a too small first string */
7203    while (size < new_size)
7204        size = size * 2;
7205    data = tcc_realloc(cstr->data_allocated, size);
7206    if (!data)
7207        error("memory full");
7208    cstr->data_allocated = data;
7209    cstr->size_allocated = size;
7210    cstr->data = data;
7211}
7212
7213/* add a byte */
7214static inline void cstr_ccat(CString *cstr, int ch)
7215{
7216    int size;
7217    size = cstr->size + 1;
7218    if (size > cstr->size_allocated)
7219        cstr_realloc(cstr, size);
7220    ((unsigned char *)cstr->data)[size - 1] = ch;
7221    cstr->size = size;
7222}
7223
7224static void cstr_cat(CString *cstr, const char *str)
7225{
7226    int c;
7227    for(;;) {
7228        c = *str;
7229        if (c == '\0')
7230            break;
7231        cstr_ccat(cstr, c);
7232        str++;
7233    }
7234}
7235
7236/* add a wide char */
7237static void cstr_wccat(CString *cstr, int ch)
7238{
7239    int size;
7240    size = cstr->size + sizeof(int);
7241    if (size > cstr->size_allocated)
7242        cstr_realloc(cstr, size);
7243    *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch;
7244    cstr->size = size;
7245}
7246
7247static void cstr_new(CString *cstr)
7248{
7249    memset(cstr, 0, sizeof(CString));
7250}
7251
7252/* free string and reset it to NULL */
7253static void cstr_free(CString *cstr)
7254{
7255    tcc_free(cstr->data_allocated);
7256    cstr_new(cstr);
7257}
7258
7259#define cstr_reset(cstr) cstr_free(cstr)
7260
7261/* XXX: unicode ? */
7262static void add_char(CString *cstr, int c)
7263{
7264    if (c == '\'' || c == '\"' || c == '\\') {
7265        /* XXX: could be more precise if char or string */
7266        cstr_ccat(cstr, '\\');
7267    }
7268    if (c >= 32 && c <= 126) {
7269        cstr_ccat(cstr, c);
7270    } else {
7271        cstr_ccat(cstr, '\\');
7272        if (c == '\n') {
7273            cstr_ccat(cstr, 'n');
7274        } else {
7275            cstr_ccat(cstr, '0' + ((c >> 6) & 7));
7276            cstr_ccat(cstr, '0' + ((c >> 3) & 7));
7277            cstr_ccat(cstr, '0' + (c & 7));
7278        }
7279    }
7280}
7281
7282/* XXX: buffer overflow */
7283/* XXX: float tokens */
7284char *get_tok_str(int v, CValue *cv)
7285{
7286    static char buf[STRING_MAX_SIZE + 1];
7287    static CString cstr_buf;
7288    CString *cstr;
7289    unsigned char *q;
7290    char *p;
7291    int i, len;
7292
7293    /* NOTE: to go faster, we give a fixed buffer for small strings */
7294    cstr_reset(&cstr_buf);
7295    cstr_buf.data = buf;
7296    cstr_buf.size_allocated = sizeof(buf);
7297    p = buf;
7298
7299    switch(v) {
7300    case TOK_CINT:
7301    case TOK_CUINT:
7302        /* XXX: not quite exact, but only useful for testing */
7303        sprintf(p, "%u", cv->ui);
7304        break;
7305    case TOK_CLLONG:
7306    case TOK_CULLONG:
7307        /* XXX: not quite exact, but only useful for testing  */
7308        sprintf(p, "%llu", cv->ull);
7309        break;
7310    case TOK_CCHAR:
7311    case TOK_LCHAR:
7312        cstr_ccat(&cstr_buf, '\'');
7313        add_char(&cstr_buf, cv->i);
7314        cstr_ccat(&cstr_buf, '\'');
7315        cstr_ccat(&cstr_buf, '\0');
7316        break;
7317    case TOK_PPNUM:
7318        cstr = cv->cstr;
7319        len = cstr->size - 1;
7320        for(i=0;i<len;i++)
7321            add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7322        cstr_ccat(&cstr_buf, '\0');
7323        break;
7324    case TOK_STR:
7325    case TOK_LSTR:
7326        cstr = cv->cstr;
7327        cstr_ccat(&cstr_buf, '\"');
7328        if (v == TOK_STR) {
7329            len = cstr->size - 1;
7330            for(i=0;i<len;i++)
7331                add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
7332        } else {
7333            len = (cstr->size / sizeof(int)) - 1;
7334            for(i=0;i<len;i++)
7335                add_char(&cstr_buf, ((int *)cstr->data)[i]);
7336        }
7337        cstr_ccat(&cstr_buf, '\"');
7338        cstr_ccat(&cstr_buf, '\0');
7339        break;
7340    case TOK_LT:
7341        v = '<';
7342        goto addv;
7343    case TOK_GT:
7344        v = '>';
7345        goto addv;
7346    case TOK_A_SHL:
7347        return strcpy(p, "<<=");
7348    case TOK_A_SAR:
7349        return strcpy(p, ">>=");
7350    default:
7351        if (v < TOK_IDENT) {
7352            /* search in two bytes table */
7353            q = tok_two_chars;
7354            while (*q) {
7355                if (q[2] == v) {
7356                    *p++ = q[0];
7357                    *p++ = q[1];
7358                    *p = '\0';
7359                    return buf;
7360                }
7361                q += 3;
7362            }
7363        addv:
7364            *p++ = v;
7365            *p = '\0';
7366        } else if (v < tok_ident) {
7367            return table_ident[v - TOK_IDENT]->str;
7368        } else if (v >= SYM_FIRST_ANOM) {
7369            /* special name for anonymous symbol */
7370            sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
7371        } else {
7372            /* should never happen */
7373            return NULL;
7374        }
7375        break;
7376    }
7377    return cstr_buf.data;
7378}
7379
7380/* push, without hashing */
7381static Sym *sym_push2(Sym **ps, long v, long t, long c)
7382{
7383    Sym *s;
7384    s = sym_malloc();
7385    s->v = v;
7386    s->type.t = t;
7387    s->c = c;
7388    s->next = NULL;
7389    /* add in stack */
7390    s->prev = *ps;
7391    *ps = s;
7392    return s;
7393}
7394
7395/* find a symbol and return its associated structure. 's' is the top
7396   of the symbol stack */
7397static Sym *sym_find2(Sym *s, int v)
7398{
7399    while (s) {
7400        if (s->v == v)
7401            return s;
7402        s = s->prev;
7403    }
7404    return NULL;
7405}
7406
7407/* structure lookup */
7408static inline Sym *struct_find(int v)
7409{
7410    v -= TOK_IDENT;
7411    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7412        return NULL;
7413    return table_ident[v]->sym_struct;
7414}
7415
7416/* find an identifier */
7417static inline Sym *sym_find(int v)
7418{
7419    v -= TOK_IDENT;
7420    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
7421        return NULL;
7422    return table_ident[v]->sym_identifier;
7423}
7424
7425/* push a given symbol on the symbol stack */
7426static Sym *sym_push(int v, CType *type, int r, int c)
7427{
7428    Sym *s, **ps;
7429    TokenSym *ts;
7430
7431    if (local_stack)
7432        ps = &local_stack;
7433    else
7434        ps = &global_stack;
7435    s = sym_push2(ps, v, type->t, c);
7436    s->type.ref = type->ref;
7437    s->r = r;
7438    /* don't record fields or anonymous symbols */
7439    /* XXX: simplify */
7440    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7441        /* record symbol in token array */
7442        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7443        if (v & SYM_STRUCT)
7444            ps = &ts->sym_struct;
7445        else
7446            ps = &ts->sym_identifier;
7447        s->prev_tok = *ps;
7448        *ps = s;
7449    }
7450    return s;
7451}
7452
7453/* push a global identifier */
7454static Sym *global_identifier_push(int v, int t, int c)
7455{
7456    Sym *s, **ps;
7457    s = sym_push2(&global_stack, v, t, c);
7458    /* don't record anonymous symbol */
7459    if (v < SYM_FIRST_ANOM) {
7460        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
7461        /* modify the top most local identifier, so that
7462           sym_identifier will point to 's' when popped */
7463        while (*ps != NULL)
7464            ps = &(*ps)->prev_tok;
7465        s->prev_tok = NULL;
7466        *ps = s;
7467    }
7468    return s;
7469}
7470
7471/* pop symbols until top reaches 'b' */
7472static void sym_pop(Sym **ptop, Sym *b)
7473{
7474    Sym *s, *ss, **ps;
7475    TokenSym *ts;
7476    int v;
7477
7478    s = *ptop;
7479    while(s != b) {
7480        ss = s->prev;
7481        v = s->v;
7482        /* remove symbol in token array */
7483        /* XXX: simplify */
7484        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
7485            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
7486            if (v & SYM_STRUCT)
7487                ps = &ts->sym_struct;
7488            else
7489                ps = &ts->sym_identifier;
7490            *ps = s->prev_tok;
7491        }
7492        sym_free(s);
7493        s = ss;
7494    }
7495    *ptop = b;
7496}
7497
7498/* I/O layer */
7499
7500BufferedFile *tcc_open(TCCState *s1, const char *filename)
7501{
7502    int fd;
7503    BufferedFile *bf;
7504
7505    fd = open(filename, O_RDONLY | O_BINARY);
7506    if (fd < 0)
7507        return NULL;
7508    bf = tcc_malloc(sizeof(BufferedFile));
7509    if (!bf) {
7510        close(fd);
7511        return NULL;
7512    }
7513    bf->fd = fd;
7514    bf->buf_ptr = bf->buffer;
7515    bf->buf_end = bf->buffer;
7516    bf->buffer[0] = CH_EOB; /* put eob symbol */
7517    pstrcpy(bf->filename, sizeof(bf->filename), filename);
7518    bf->line_num = 1;
7519    bf->ifndef_macro = 0;
7520    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
7521    //    printf("opening '%s'\n", filename);
7522    return bf;
7523}
7524
7525void tcc_close(BufferedFile *bf)
7526{
7527    total_lines += bf->line_num;
7528    close(bf->fd);
7529    tcc_free(bf);
7530}
7531
7532/* fill input buffer and peek next char */
7533static int tcc_peekc_slow(BufferedFile *bf)
7534{
7535    int len;
7536    /* only tries to read if really end of buffer */
7537    if (bf->buf_ptr >= bf->buf_end) {
7538        if (bf->fd != -1) {
7539#if defined(PARSE_DEBUG)
7540            len = 8;
7541#else
7542            len = IO_BUF_SIZE;
7543#endif
7544            len = read(bf->fd, bf->buffer, len);
7545            if (len < 0)
7546                len = 0;
7547        } else {
7548            len = 0;
7549        }
7550        total_bytes += len;
7551        bf->buf_ptr = bf->buffer;
7552        bf->buf_end = bf->buffer + len;
7553        *bf->buf_end = CH_EOB;
7554    }
7555    if (bf->buf_ptr < bf->buf_end) {
7556        return bf->buf_ptr[0];
7557    } else {
7558        bf->buf_ptr = bf->buf_end;
7559        return CH_EOF;
7560    }
7561}
7562
7563/* return the current character, handling end of block if necessary
7564   (but not stray) */
7565static int handle_eob(void)
7566{
7567    return tcc_peekc_slow(file);
7568}
7569
7570/* read next char from current input file and handle end of input buffer */
7571static inline void inp(void)
7572{
7573    ch = *(++(file->buf_ptr));
7574    /* end of buffer/file handling */
7575    if (ch == CH_EOB)
7576        ch = handle_eob();
7577}
7578
7579/* handle '\[\r]\n' */
7580static void handle_stray(void)
7581{
7582    while (ch == '\\') {
7583        inp();
7584        if (ch == '\n') {
7585            file->line_num++;
7586            inp();
7587        } else if (ch == '\r') {
7588            inp();
7589            if (ch != '\n')
7590                goto fail;
7591            file->line_num++;
7592            inp();
7593        } else {
7594        fail:
7595            error("stray '\\' in program");
7596        }
7597    }
7598}
7599
7600/* skip the stray and handle the \\n case. Output an error if
7601   incorrect char after the stray */
7602static int handle_stray1(uint8_t *p)
7603{
7604    int c;
7605
7606    if (p >= file->buf_end) {
7607        file->buf_ptr = p;
7608        c = handle_eob();
7609        p = file->buf_ptr;
7610        if (c == '\\')
7611            goto parse_stray;
7612    } else {
7613    parse_stray:
7614        file->buf_ptr = p;
7615        ch = *p;
7616        handle_stray();
7617        p = file->buf_ptr;
7618        c = *p;
7619    }
7620    return c;
7621}
7622
7623/* handle just the EOB case, but not stray */
7624#define PEEKC_EOB(c, p)\
7625{\
7626    p++;\
7627    c = *p;\
7628    if (c == '\\') {\
7629        file->buf_ptr = p;\
7630        c = handle_eob();\
7631        p = file->buf_ptr;\
7632    }\
7633}
7634
7635/* handle the complicated stray case */
7636#define PEEKC(c, p)\
7637{\
7638    p++;\
7639    c = *p;\
7640    if (c == '\\') {\
7641        c = handle_stray1(p);\
7642        p = file->buf_ptr;\
7643    }\
7644}
7645
7646/* input with '\[\r]\n' handling. Note that this function cannot
7647   handle other characters after '\', so you cannot call it inside
7648   strings or comments */
7649static void minp(void)
7650{
7651    inp();
7652    if (ch == '\\')
7653        handle_stray();
7654}
7655
7656
7657/* single line C++ comments */
7658static uint8_t *parse_line_comment(uint8_t *p)
7659{
7660    int c;
7661
7662    p++;
7663    for(;;) {
7664        c = *p;
7665    redo:
7666        if (c == '\n' || c == CH_EOF) {
7667            break;
7668        } else if (c == '\\') {
7669            file->buf_ptr = p;
7670            c = handle_eob();
7671            p = file->buf_ptr;
7672            if (c == '\\') {
7673                PEEKC_EOB(c, p);
7674                if (c == '\n') {
7675                    file->line_num++;
7676                    PEEKC_EOB(c, p);
7677                } else if (c == '\r') {
7678                    PEEKC_EOB(c, p);
7679                    if (c == '\n') {
7680                        file->line_num++;
7681                        PEEKC_EOB(c, p);
7682                    }
7683                }
7684            } else {
7685                goto redo;
7686            }
7687        } else {
7688            p++;
7689        }
7690    }
7691    return p;
7692}
7693
7694/* C comments */
7695static uint8_t *parse_comment(uint8_t *p)
7696{
7697    int c;
7698
7699    p++;
7700    for(;;) {
7701        /* fast skip loop */
7702        for(;;) {
7703            c = *p;
7704            if (c == '\n' || c == '*' || c == '\\')
7705                break;
7706            p++;
7707            c = *p;
7708            if (c == '\n' || c == '*' || c == '\\')
7709                break;
7710            p++;
7711        }
7712        /* now we can handle all the cases */
7713        if (c == '\n') {
7714            file->line_num++;
7715            p++;
7716        } else if (c == '*') {
7717            p++;
7718            for(;;) {
7719                c = *p;
7720                if (c == '*') {
7721                    p++;
7722                } else if (c == '/') {
7723                    goto end_of_comment;
7724                } else if (c == '\\') {
7725                    file->buf_ptr = p;
7726                    c = handle_eob();
7727                    p = file->buf_ptr;
7728                    if (c == '\\') {
7729                        /* skip '\[\r]\n', otherwise just skip the stray */
7730                        while (c == '\\') {
7731                            PEEKC_EOB(c, p);
7732                            if (c == '\n') {
7733                                file->line_num++;
7734                                PEEKC_EOB(c, p);
7735                            } else if (c == '\r') {
7736                                PEEKC_EOB(c, p);
7737                                if (c == '\n') {
7738                                    file->line_num++;
7739                                    PEEKC_EOB(c, p);
7740                                }
7741                            } else {
7742                                goto after_star;
7743                            }
7744                        }
7745                    }
7746                } else {
7747                    break;
7748                }
7749            }
7750        after_star: ;
7751        } else {
7752            /* stray, eob or eof */
7753            file->buf_ptr = p;
7754            c = handle_eob();
7755            p = file->buf_ptr;
7756            if (c == CH_EOF) {
7757                error("unexpected end of file in comment");
7758            } else if (c == '\\') {
7759                p++;
7760            }
7761        }
7762    }
7763 end_of_comment:
7764    p++;
7765    return p;
7766}
7767
7768#define cinp minp
7769
7770/* space exlcuding newline */
7771static inline int is_space(int ch)
7772{
7773    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
7774}
7775
7776static inline void skip_spaces(void)
7777{
7778    while (is_space(ch))
7779        cinp();
7780}
7781
7782/* parse a string without interpreting escapes */
7783static uint8_t *parse_pp_string(uint8_t *p,
7784                                int sep, CString *str)
7785{
7786    int c;
7787    p++;
7788    for(;;) {
7789        c = *p;
7790        if (c == sep) {
7791            break;
7792        } else if (c == '\\') {
7793            file->buf_ptr = p;
7794            c = handle_eob();
7795            p = file->buf_ptr;
7796            if (c == CH_EOF) {
7797            unterminated_string:
7798                /* XXX: indicate line number of start of string */
7799                error("missing terminating %c character", sep);
7800            } else if (c == '\\') {
7801                /* escape : just skip \[\r]\n */
7802                PEEKC_EOB(c, p);
7803                if (c == '\n') {
7804                    file->line_num++;
7805                    p++;
7806                } else if (c == '\r') {
7807                    PEEKC_EOB(c, p);
7808                    if (c != '\n')
7809                        expect("'\n' after '\r'");
7810                    file->line_num++;
7811                    p++;
7812                } else if (c == CH_EOF) {
7813                    goto unterminated_string;
7814                } else {
7815                    if (str) {
7816                        cstr_ccat(str, '\\');
7817                        cstr_ccat(str, c);
7818                    }
7819                    p++;
7820                }
7821            }
7822        } else if (c == '\n') {
7823            file->line_num++;
7824            goto add_char;
7825        } else if (c == '\r') {
7826            PEEKC_EOB(c, p);
7827            if (c != '\n') {
7828                if (str)
7829                    cstr_ccat(str, '\r');
7830            } else {
7831                file->line_num++;
7832                goto add_char;
7833            }
7834        } else {
7835        add_char:
7836            if (str)
7837                cstr_ccat(str, c);
7838            p++;
7839        }
7840    }
7841    p++;
7842    return p;
7843}
7844
7845/* skip block of text until #else, #elif or #endif. skip also pairs of
7846   #if/#endif */
7847void preprocess_skip(void)
7848{
7849    int a, start_of_line, c;
7850    uint8_t *p;
7851
7852    p = file->buf_ptr;
7853    start_of_line = 1;
7854    a = 0;
7855    for(;;) {
7856    redo_no_start:
7857        c = *p;
7858        switch(c) {
7859        case ' ':
7860        case '\t':
7861        case '\f':
7862        case '\v':
7863        case '\r':
7864            p++;
7865            goto redo_no_start;
7866        case '\n':
7867            start_of_line = 1;
7868            file->line_num++;
7869            p++;
7870            goto redo_no_start;
7871        case '\\':
7872            file->buf_ptr = p;
7873            c = handle_eob();
7874            if (c == CH_EOF) {
7875                expect("#endif");
7876            } else if (c == '\\') {
7877                /* XXX: incorrect: should not give an error */
7878                ch = file->buf_ptr[0];
7879                handle_stray();
7880            }
7881            p = file->buf_ptr;
7882            goto redo_no_start;
7883            /* skip strings */
7884        case '\"':
7885        case '\'':
7886            p = parse_pp_string(p, c, NULL);
7887            break;
7888            /* skip comments */
7889        case '/':
7890            file->buf_ptr = p;
7891            ch = *p;
7892            minp();
7893            p = file->buf_ptr;
7894            if (ch == '*') {
7895                p = parse_comment(p);
7896            } else if (ch == '/') {
7897                p = parse_line_comment(p);
7898            }
7899            break;
7900
7901        case '#':
7902            p++;
7903            if (start_of_line) {
7904                file->buf_ptr = p;
7905                next_nomacro();
7906                p = file->buf_ptr;
7907                if (a == 0 &&
7908                    (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
7909                    goto the_end;
7910                if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
7911                    a++;
7912                else if (tok == TOK_ENDIF)
7913                    a--;
7914            }
7915            break;
7916        default:
7917            p++;
7918            break;
7919        }
7920        start_of_line = 0;
7921    }
7922 the_end: ;
7923    file->buf_ptr = p;
7924}
7925
7926/* ParseState handling */
7927
7928/* XXX: currently, no include file info is stored. Thus, we cannot display
7929   accurate messages if the function or data definition spans multiple
7930   files */
7931
7932/* save current parse state in 's' */
7933void save_parse_state(ParseState *s)
7934{
7935    s->line_num = file->line_num;
7936    s->macro_ptr = macro_ptr;
7937    s->tok = tok;
7938    s->tokc = tokc;
7939}
7940
7941/* restore parse state from 's' */
7942void restore_parse_state(ParseState *s)
7943{
7944    file->line_num = s->line_num;
7945    macro_ptr = s->macro_ptr;
7946    tok = s->tok;
7947    tokc = s->tokc;
7948}
7949
7950/* return the number of additional 'ints' necessary to store the
7951   token */
7952static inline int tok_ext_size(int t)
7953{
7954    switch(t) {
7955        /* 4 bytes */
7956    case TOK_CINT:
7957    case TOK_CUINT:
7958    case TOK_CCHAR:
7959    case TOK_LCHAR:
7960    case TOK_CFLOAT:
7961    case TOK_LINENUM:
7962        return 1;
7963    case TOK_STR:
7964    case TOK_LSTR:
7965    case TOK_PPNUM:
7966        error("unsupported token");
7967        return 1;
7968    case TOK_CDOUBLE:
7969    case TOK_CLLONG:
7970    case TOK_CULLONG:
7971        return 2;
7972    case TOK_CLDOUBLE:
7973        return LDOUBLE_SIZE / 4;
7974    default:
7975        return 0;
7976    }
7977}
7978
7979/* token string handling */
7980
7981static inline void tok_str_new(TokenString *s)
7982{
7983    s->str = NULL;
7984    s->len = 0;
7985    s->allocated_len = 0;
7986    s->last_line_num = -1;
7987}
7988
7989static void tok_str_free(int *str)
7990{
7991    tcc_free(str);
7992}
7993
7994static int *tok_str_realloc(TokenString *s)
7995{
7996    int *str, len;
7997
7998    if (s->allocated_len == 0) {
7999        len = 8;
8000    } else {
8001        len = s->allocated_len * 2;
8002    }
8003    str = tcc_realloc(s->str, len * sizeof(int));
8004    if (!str)
8005        error("memory full");
8006    s->allocated_len = len;
8007    s->str = str;
8008    return str;
8009}
8010
8011static void tok_str_add(TokenString *s, int t)
8012{
8013    int len, *str;
8014
8015    len = s->len;
8016    str = s->str;
8017    if (len >= s->allocated_len)
8018        str = tok_str_realloc(s);
8019    str[len++] = t;
8020    s->len = len;
8021}
8022
8023static void tok_str_add2(TokenString *s, int t, CValue *cv)
8024{
8025    int len, *str;
8026
8027    len = s->len;
8028    str = s->str;
8029
8030    /* allocate space for worst case */
8031    if (len + TOK_MAX_SIZE > s->allocated_len)
8032        str = tok_str_realloc(s);
8033    str[len++] = t;
8034    switch(t) {
8035    case TOK_CINT:
8036    case TOK_CUINT:
8037    case TOK_CCHAR:
8038    case TOK_LCHAR:
8039    case TOK_CFLOAT:
8040    case TOK_LINENUM:
8041        str[len++] = cv->tab[0];
8042        break;
8043    case TOK_PPNUM:
8044    case TOK_STR:
8045    case TOK_LSTR:
8046        {
8047            int nb_words;
8048            CString *cstr;
8049
8050            nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
8051            while ((len + nb_words) > s->allocated_len)
8052                str = tok_str_realloc(s);
8053            cstr = (CString *)(str + len);
8054            cstr->data = NULL;
8055            cstr->size = cv->cstr->size;
8056            cstr->data_allocated = NULL;
8057            cstr->size_allocated = cstr->size;
8058            memcpy((char *)cstr + sizeof(CString),
8059                   cv->cstr->data, cstr->size);
8060            len += nb_words;
8061        }
8062        break;
8063    case TOK_CDOUBLE:
8064    case TOK_CLLONG:
8065    case TOK_CULLONG:
8066#if LDOUBLE_SIZE == 8
8067    case TOK_CLDOUBLE:
8068#endif
8069        str[len++] = cv->tab[0];
8070        str[len++] = cv->tab[1];
8071        break;
8072#if LDOUBLE_SIZE == 12
8073    case TOK_CLDOUBLE:
8074        str[len++] = cv->tab[0];
8075        str[len++] = cv->tab[1];
8076        str[len++] = cv->tab[2];
8077#elif LDOUBLE_SIZE != 8
8078#error add long double size support
8079#endif
8080        break;
8081    default:
8082        break;
8083    }
8084    s->len = len;
8085}
8086
8087/* add the current parse token in token string 's' */
8088static void tok_str_add_tok(TokenString *s)
8089{
8090    CValue cval;
8091
8092    /* save line number info */
8093    if (file->line_num != s->last_line_num) {
8094        s->last_line_num = file->line_num;
8095        cval.i = s->last_line_num;
8096        tok_str_add2(s, TOK_LINENUM, &cval);
8097    }
8098    tok_str_add2(s, tok, &tokc);
8099}
8100
8101#if LDOUBLE_SIZE == 12
8102#define LDOUBLE_GET(p, cv)                      \
8103        cv.tab[0] = p[0];                       \
8104        cv.tab[1] = p[1];                       \
8105        cv.tab[2] = p[2];
8106#elif LDOUBLE_SIZE == 8
8107#define LDOUBLE_GET(p, cv)                      \
8108        cv.tab[0] = p[0];                       \
8109        cv.tab[1] = p[1];
8110#else
8111#error add long double size support
8112#endif
8113
8114
8115/* get a token from an integer array and increment pointer
8116   accordingly. we code it as a macro to avoid pointer aliasing. */
8117#define TOK_GET(t, p, cv)                       \
8118{                                               \
8119    t = *p++;                                   \
8120    switch(t) {                                 \
8121    case TOK_CINT:                              \
8122    case TOK_CUINT:                             \
8123    case TOK_CCHAR:                             \
8124    case TOK_LCHAR:                             \
8125    case TOK_CFLOAT:                            \
8126    case TOK_LINENUM:                           \
8127        cv.tab[0] = *p++;                       \
8128        break;                                  \
8129    case TOK_STR:                               \
8130    case TOK_LSTR:                              \
8131    case TOK_PPNUM:                             \
8132        cv.cstr = (CString *)p;                 \
8133        cv.cstr->data = (char *)p + sizeof(CString);\
8134        p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
8135        break;                                  \
8136    case TOK_CDOUBLE:                           \
8137    case TOK_CLLONG:                            \
8138    case TOK_CULLONG:                           \
8139        cv.tab[0] = p[0];                       \
8140        cv.tab[1] = p[1];                       \
8141        p += 2;                                 \
8142        break;                                  \
8143    case TOK_CLDOUBLE:                          \
8144        LDOUBLE_GET(p, cv);                     \
8145        p += LDOUBLE_SIZE / 4;                  \
8146        break;                                  \
8147    default:                                    \
8148        break;                                  \
8149    }                                           \
8150}
8151
8152/* defines handling */
8153static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
8154{
8155    Sym *s;
8156
8157    s = sym_push2(&define_stack, v, macro_type, (long)str);
8158    s->next = first_arg;
8159    table_ident[v - TOK_IDENT]->sym_define = s;
8160}
8161
8162/* undefined a define symbol. Its name is just set to zero */
8163static void define_undef(Sym *s)
8164{
8165    int v;
8166    v = s->v;
8167    if (v >= TOK_IDENT && v < tok_ident)
8168        table_ident[v - TOK_IDENT]->sym_define = NULL;
8169    s->v = 0;
8170}
8171
8172static inline Sym *define_find(int v)
8173{
8174    v -= TOK_IDENT;
8175    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8176        return NULL;
8177    return table_ident[v]->sym_define;
8178}
8179
8180/* free define stack until top reaches 'b' */
8181static void free_defines(Sym *b)
8182{
8183    Sym *top, *top1;
8184    int v;
8185
8186    top = define_stack;
8187    while (top != b) {
8188        top1 = top->prev;
8189        /* do not free args or predefined defines */
8190        if (top->c)
8191            tok_str_free((int *)top->c);
8192        v = top->v;
8193        if (v >= TOK_IDENT && v < tok_ident)
8194            table_ident[v - TOK_IDENT]->sym_define = NULL;
8195        sym_free(top);
8196        top = top1;
8197    }
8198    define_stack = b;
8199}
8200
8201/* label lookup */
8202static Sym *label_find(int v)
8203{
8204    v -= TOK_IDENT;
8205    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
8206        return NULL;
8207    return table_ident[v]->sym_label;
8208}
8209
8210static Sym *label_push(Sym **ptop, int v, int flags)
8211{
8212    Sym *s, **ps;
8213    s = sym_push2(ptop, v, 0, 0);
8214    s->r = flags;
8215    ps = &table_ident[v - TOK_IDENT]->sym_label;
8216    if (ptop == &global_label_stack) {
8217        /* modify the top most local identifier, so that
8218           sym_identifier will point to 's' when popped */
8219        while (*ps != NULL)
8220            ps = &(*ps)->prev_tok;
8221    }
8222    s->prev_tok = *ps;
8223    *ps = s;
8224    return s;
8225}
8226
8227/* pop labels until element last is reached. Look if any labels are
8228   undefined. Define symbols if '&&label' was used. */
8229static void label_pop(Sym **ptop, Sym *slast)
8230{
8231    Sym *s, *s1;
8232    for(s = *ptop; s != slast; s = s1) {
8233        s1 = s->prev;
8234        if (s->r == LABEL_DECLARED) {
8235            warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
8236        } else if (s->r == LABEL_FORWARD) {
8237                error("label '%s' used but not defined",
8238                      get_tok_str(s->v, NULL));
8239        } else {
8240            if (s->c) {
8241                /* define corresponding symbol. A size of
8242                   1 is put. */
8243                put_extern_sym(s, cur_text_section, (long)s->next, 1);
8244            }
8245        }
8246        /* remove label */
8247        table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
8248        sym_free(s);
8249    }
8250    *ptop = slast;
8251}
8252
8253/* eval an expression for #if/#elif */
8254static int expr_preprocess(void)
8255{
8256    int c, t;
8257    TokenString str;
8258
8259    tok_str_new(&str);
8260    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8261        next(); /* do macro subst */
8262        if (tok == TOK_DEFINED) {
8263            next_nomacro();
8264            t = tok;
8265            if (t == '(')
8266                next_nomacro();
8267            c = define_find(tok) != 0;
8268            if (t == '(')
8269                next_nomacro();
8270            tok = TOK_CINT;
8271            tokc.i = c;
8272        } else if (tok >= TOK_IDENT) {
8273            /* if undefined macro */
8274            tok = TOK_CINT;
8275            tokc.i = 0;
8276        }
8277        tok_str_add_tok(&str);
8278    }
8279    tok_str_add(&str, -1); /* simulate end of file */
8280    tok_str_add(&str, 0);
8281    /* now evaluate C constant expression */
8282    macro_ptr = str.str;
8283    next();
8284    c = expr_const();
8285    macro_ptr = NULL;
8286    tok_str_free(str.str);
8287    return c != 0;
8288}
8289
8290#if defined(PARSE_DEBUG) || defined(PP_DEBUG)
8291static void tok_print(int *str)
8292{
8293    int t;
8294    CValue cval;
8295
8296    while (1) {
8297        TOK_GET(t, str, cval);
8298        if (!t)
8299            break;
8300        printf(" %s", get_tok_str(t, &cval));
8301    }
8302    printf("\n");
8303}
8304#endif
8305
8306/* parse after #define */
8307static void parse_define(void)
8308{
8309    Sym *s, *first, **ps;
8310    int v, t, varg, is_vaargs, c;
8311    TokenString str;
8312
8313    v = tok;
8314    if (v < TOK_IDENT)
8315        error("invalid macro name '%s'", get_tok_str(tok, &tokc));
8316    /* XXX: should check if same macro (ANSI) */
8317    first = NULL;
8318    t = MACRO_OBJ;
8319    /* '(' must be just after macro definition for MACRO_FUNC */
8320    c = file->buf_ptr[0];
8321    if (c == '\\')
8322        c = handle_stray1(file->buf_ptr);
8323    if (c == '(') {
8324        next_nomacro();
8325        next_nomacro();
8326        ps = &first;
8327        while (tok != ')') {
8328            varg = tok;
8329            next_nomacro();
8330            is_vaargs = 0;
8331            if (varg == TOK_DOTS) {
8332                varg = TOK___VA_ARGS__;
8333                is_vaargs = 1;
8334            } else if (tok == TOK_DOTS && gnu_ext) {
8335                is_vaargs = 1;
8336                next_nomacro();
8337            }
8338            if (varg < TOK_IDENT)
8339                error("badly punctuated parameter list");
8340            s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
8341            *ps = s;
8342            ps = &s->next;
8343            if (tok != ',')
8344                break;
8345            next_nomacro();
8346        }
8347        t = MACRO_FUNC;
8348    }
8349    tok_str_new(&str);
8350    next_nomacro();
8351    /* EOF testing necessary for '-D' handling */
8352    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
8353        tok_str_add2(&str, tok, &tokc);
8354        next_nomacro();
8355    }
8356    tok_str_add(&str, 0);
8357#ifdef PP_DEBUG
8358    printf("define %s %d: ", get_tok_str(v, NULL), t);
8359    tok_print(str.str);
8360#endif
8361    define_push(v, t, str.str, first);
8362}
8363
8364static inline int hash_cached_include(int type, const char *filename)
8365{
8366    const unsigned char *s;
8367    unsigned int h;
8368
8369    h = TOK_HASH_INIT;
8370    h = TOK_HASH_FUNC(h, type);
8371    s = filename;
8372    while (*s) {
8373        h = TOK_HASH_FUNC(h, *s);
8374        s++;
8375    }
8376    h &= (CACHED_INCLUDES_HASH_SIZE - 1);
8377    return h;
8378}
8379
8380/* XXX: use a token or a hash table to accelerate matching ? */
8381static CachedInclude *search_cached_include(TCCState *s1,
8382                                            int type, const char *filename)
8383{
8384    CachedInclude *e;
8385    int i, h;
8386    h = hash_cached_include(type, filename);
8387    i = s1->cached_includes_hash[h];
8388    for(;;) {
8389        if (i == 0)
8390            break;
8391        e = s1->cached_includes[i - 1];
8392        if (e->type == type && !strcmp(e->filename, filename))
8393            return e;
8394        i = e->hash_next;
8395    }
8396    return NULL;
8397}
8398
8399static inline void add_cached_include(TCCState *s1, int type,
8400                                      const char *filename, int ifndef_macro)
8401{
8402    CachedInclude *e;
8403    int h;
8404
8405    if (search_cached_include(s1, type, filename))
8406        return;
8407#ifdef INC_DEBUG
8408    printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
8409#endif
8410    e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
8411    if (!e)
8412        return;
8413    e->type = type;
8414    strcpy(e->filename, filename);
8415    e->ifndef_macro = ifndef_macro;
8416    dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
8417    /* add in hash table */
8418    h = hash_cached_include(type, filename);
8419    e->hash_next = s1->cached_includes_hash[h];
8420    s1->cached_includes_hash[h] = s1->nb_cached_includes;
8421}
8422
8423static void pragma_parse(TCCState *s1)
8424{
8425    int val;
8426
8427    next();
8428    if (tok == TOK_pack) {
8429        /*
8430          This may be:
8431          #pragma pack(1) // set
8432          #pragma pack() // reset to default
8433          #pragma pack(push,1) // push & set
8434          #pragma pack(pop) // restore previous
8435        */
8436        next();
8437        skip('(');
8438        if (tok == TOK_ASM_pop) {
8439            next();
8440            if (s1->pack_stack_ptr <= s1->pack_stack) {
8441            stk_error:
8442                error("out of pack stack");
8443            }
8444            s1->pack_stack_ptr--;
8445        } else {
8446            val = 0;
8447            if (tok != ')') {
8448                if (tok == TOK_ASM_push) {
8449                    next();
8450                    if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
8451                        goto stk_error;
8452                    s1->pack_stack_ptr++;
8453                    skip(',');
8454                }
8455                if (tok != TOK_CINT) {
8456                pack_error:
8457                    error("invalid pack pragma");
8458                }
8459                val = tokc.i;
8460                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
8461                    goto pack_error;
8462                next();
8463            }
8464            *s1->pack_stack_ptr = val;
8465            skip(')');
8466        }
8467    }
8468}
8469
8470/* is_bof is true if first non space token at beginning of file */
8471static void preprocess(int is_bof)
8472{
8473    TCCState *s1 = tcc_state;
8474    int size, i, c, n, saved_parse_flags;
8475    char buf[1024], *q, *p;
8476    char buf1[1024];
8477    BufferedFile *f;
8478    Sym *s;
8479    CachedInclude *e;
8480
8481    saved_parse_flags = parse_flags;
8482    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
8483        PARSE_FLAG_LINEFEED;
8484    next_nomacro();
8485 redo:
8486    switch(tok) {
8487    case TOK_DEFINE:
8488        next_nomacro();
8489        parse_define();
8490        break;
8491    case TOK_UNDEF:
8492        next_nomacro();
8493        s = define_find(tok);
8494        /* undefine symbol by putting an invalid name */
8495        if (s)
8496            define_undef(s);
8497        break;
8498    case TOK_INCLUDE:
8499    case TOK_INCLUDE_NEXT:
8500        ch = file->buf_ptr[0];
8501        /* XXX: incorrect if comments : use next_nomacro with a special mode */
8502        skip_spaces();
8503        if (ch == '<') {
8504            c = '>';
8505            goto read_name;
8506        } else if (ch == '\"') {
8507            c = ch;
8508        read_name:
8509            /* XXX: better stray handling */
8510            minp();
8511            q = buf;
8512            while (ch != c && ch != '\n' && ch != CH_EOF) {
8513                if ((q - buf) < sizeof(buf) - 1)
8514                    *q++ = ch;
8515                minp();
8516            }
8517            *q = '\0';
8518            minp();
8519#if 0
8520            /* eat all spaces and comments after include */
8521            /* XXX: slightly incorrect */
8522            while (ch1 != '\n' && ch1 != CH_EOF)
8523                inp();
8524#endif
8525        } else {
8526            /* computed #include : either we have only strings or
8527               we have anything enclosed in '<>' */
8528            next();
8529            buf[0] = '\0';
8530            if (tok == TOK_STR) {
8531                while (tok != TOK_LINEFEED) {
8532                    if (tok != TOK_STR) {
8533                    include_syntax:
8534                        error("'#include' expects \"FILENAME\" or <FILENAME>");
8535                    }
8536                    pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
8537                    next();
8538                }
8539                c = '\"';
8540            } else {
8541                int len;
8542                while (tok != TOK_LINEFEED) {
8543                    pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
8544                    next();
8545                }
8546                len = strlen(buf);
8547                /* check syntax and remove '<>' */
8548                if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
8549                    goto include_syntax;
8550                memmove(buf, buf + 1, len - 2);
8551                buf[len - 2] = '\0';
8552                c = '>';
8553            }
8554        }
8555
8556        e = search_cached_include(s1, c, buf);
8557        if (e && define_find(e->ifndef_macro)) {
8558            /* no need to parse the include because the 'ifndef macro'
8559               is defined */
8560#ifdef INC_DEBUG
8561            printf("%s: skipping %s\n", file->filename, buf);
8562#endif
8563        } else {
8564            if (c == '\"') {
8565                /* first search in current dir if "header.h" */
8566                size = 0;
8567                p = strrchr(file->filename, '/');
8568                if (p)
8569                    size = p + 1 - file->filename;
8570                if (size > sizeof(buf1) - 1)
8571                    size = sizeof(buf1) - 1;
8572                memcpy(buf1, file->filename, size);
8573                buf1[size] = '\0';
8574                pstrcat(buf1, sizeof(buf1), buf);
8575                f = tcc_open(s1, buf1);
8576                if (f) {
8577                    if (tok == TOK_INCLUDE_NEXT)
8578                        tok = TOK_INCLUDE;
8579                    else
8580                        goto found;
8581                }
8582            }
8583            if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
8584                error("#include recursion too deep");
8585            /* now search in all the include paths */
8586            n = s1->nb_include_paths + s1->nb_sysinclude_paths;
8587            for(i = 0; i < n; i++) {
8588                const char *path;
8589                if (i < s1->nb_include_paths)
8590                    path = s1->include_paths[i];
8591                else
8592                    path = s1->sysinclude_paths[i - s1->nb_include_paths];
8593                pstrcpy(buf1, sizeof(buf1), path);
8594                pstrcat(buf1, sizeof(buf1), "/");
8595                pstrcat(buf1, sizeof(buf1), buf);
8596                f = tcc_open(s1, buf1);
8597                if (f) {
8598                    if (tok == TOK_INCLUDE_NEXT)
8599                        tok = TOK_INCLUDE;
8600                    else
8601                        goto found;
8602                }
8603            }
8604            error("include file '%s' not found", buf);
8605            f = NULL;
8606        found:
8607#ifdef INC_DEBUG
8608            printf("%s: including %s\n", file->filename, buf1);
8609#endif
8610            f->inc_type = c;
8611            pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf);
8612            /* push current file in stack */
8613            /* XXX: fix current line init */
8614            *s1->include_stack_ptr++ = file;
8615            file = f;
8616            /* add include file debug info */
8617            if (do_debug) {
8618                put_stabs(file->filename, N_BINCL, 0, 0, 0);
8619            }
8620            tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
8621            ch = file->buf_ptr[0];
8622            goto the_end;
8623        }
8624        break;
8625    case TOK_IFNDEF:
8626        c = 1;
8627        goto do_ifdef;
8628    case TOK_IF:
8629        c = expr_preprocess();
8630        goto do_if;
8631    case TOK_IFDEF:
8632        c = 0;
8633    do_ifdef:
8634        next_nomacro();
8635        if (tok < TOK_IDENT)
8636            error("invalid argument for '#if%sdef'", c ? "n" : "");
8637        if (is_bof) {
8638            if (c) {
8639#ifdef INC_DEBUG
8640                printf("#ifndef %s\n", get_tok_str(tok, NULL));
8641#endif
8642                file->ifndef_macro = tok;
8643            }
8644        }
8645        c = (define_find(tok) != 0) ^ c;
8646    do_if:
8647        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
8648            error("memory full");
8649        *s1->ifdef_stack_ptr++ = c;
8650        goto test_skip;
8651    case TOK_ELSE:
8652        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8653            error("#else without matching #if");
8654        if (s1->ifdef_stack_ptr[-1] & 2)
8655            error("#else after #else");
8656        c = (s1->ifdef_stack_ptr[-1] ^= 3);
8657        goto test_skip;
8658    case TOK_ELIF:
8659        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
8660            error("#elif without matching #if");
8661        c = s1->ifdef_stack_ptr[-1];
8662        if (c > 1)
8663            error("#elif after #else");
8664        /* last #if/#elif expression was true: we skip */
8665        if (c == 1)
8666            goto skip;
8667        c = expr_preprocess();
8668        s1->ifdef_stack_ptr[-1] = c;
8669    test_skip:
8670        if (!(c & 1)) {
8671        skip:
8672            preprocess_skip();
8673            is_bof = 0;
8674            goto redo;
8675        }
8676        break;
8677    case TOK_ENDIF:
8678        if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
8679            error("#endif without matching #if");
8680        s1->ifdef_stack_ptr--;
8681        /* '#ifndef macro' was at the start of file. Now we check if
8682           an '#endif' is exactly at the end of file */
8683        if (file->ifndef_macro &&
8684            s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
8685            file->ifndef_macro_saved = file->ifndef_macro;
8686            /* need to set to zero to avoid false matches if another
8687               #ifndef at middle of file */
8688            file->ifndef_macro = 0;
8689            while (tok != TOK_LINEFEED)
8690                next_nomacro();
8691            tok_flags |= TOK_FLAG_ENDIF;
8692            goto the_end;
8693        }
8694        break;
8695    case TOK_LINE:
8696        next();
8697        if (tok != TOK_CINT)
8698            error("#line");
8699        file->line_num = tokc.i - 1; /* the line number will be incremented after */
8700        next();
8701        if (tok != TOK_LINEFEED) {
8702            if (tok != TOK_STR)
8703                error("#line");
8704            pstrcpy(file->filename, sizeof(file->filename),
8705                    (char *)tokc.cstr->data);
8706        }
8707        break;
8708    case TOK_ERROR:
8709    case TOK_WARNING:
8710        c = tok;
8711        ch = file->buf_ptr[0];
8712        skip_spaces();
8713        q = buf;
8714        while (ch != '\n' && ch != CH_EOF) {
8715            if ((q - buf) < sizeof(buf) - 1)
8716                *q++ = ch;
8717            minp();
8718        }
8719        *q = '\0';
8720        if (c == TOK_ERROR)
8721            error("#error %s", buf);
8722        else
8723            warning("#warning %s", buf);
8724        break;
8725    case TOK_PRAGMA:
8726        pragma_parse(s1);
8727        break;
8728    default:
8729        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
8730            /* '!' is ignored to allow C scripts. numbers are ignored
8731               to emulate cpp behaviour */
8732        } else {
8733            if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
8734                error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc));
8735        }
8736        break;
8737    }
8738    /* ignore other preprocess commands or #! for C scripts */
8739    while (tok != TOK_LINEFEED)
8740        next_nomacro();
8741 the_end:
8742    parse_flags = saved_parse_flags;
8743}
8744
8745/* evaluate escape codes in a string. */
8746static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
8747{
8748    int c, n;
8749    const uint8_t *p;
8750
8751    p = buf;
8752    for(;;) {
8753        c = *p;
8754        if (c == '\0')
8755            break;
8756        if (c == '\\') {
8757            p++;
8758            /* escape */
8759            c = *p;
8760            switch(c) {
8761            case '0': case '1': case '2': case '3':
8762            case '4': case '5': case '6': case '7':
8763                /* at most three octal digits */
8764                n = c - '0';
8765                p++;
8766                c = *p;
8767                if (isoct(c)) {
8768                    n = n * 8 + c - '0';
8769                    p++;
8770                    c = *p;
8771                    if (isoct(c)) {
8772                        n = n * 8 + c - '0';
8773                        p++;
8774                    }
8775                }
8776                c = n;
8777                goto add_char_nonext;
8778            case 'x':
8779                p++;
8780                n = 0;
8781                for(;;) {
8782                    c = *p;
8783                    if (c >= 'a' && c <= 'f')
8784                        c = c - 'a' + 10;
8785                    else if (c >= 'A' && c <= 'F')
8786                        c = c - 'A' + 10;
8787                    else if (isnum(c))
8788                        c = c - '0';
8789                    else
8790                        break;
8791                    n = n * 16 + c;
8792                    p++;
8793                }
8794                c = n;
8795                goto add_char_nonext;
8796            case 'a':
8797                c = '\a';
8798                break;
8799            case 'b':
8800                c = '\b';
8801                break;
8802            case 'f':
8803                c = '\f';
8804                break;
8805            case 'n':
8806                c = '\n';
8807                break;
8808            case 'r':
8809                c = '\r';
8810                break;
8811            case 't':
8812                c = '\t';
8813                break;
8814            case 'v':
8815                c = '\v';
8816                break;
8817            case 'e':
8818                if (!gnu_ext)
8819                    goto invalid_escape;
8820                c = 27;
8821                break;
8822            case '\'':
8823            case '\"':
8824            case '\\':
8825            case '?':
8826                break;
8827            default:
8828            invalid_escape:
8829                if (c >= '!' && c <= '~')
8830                    warning("unknown escape sequence: \'\\%c\'", c);
8831                else
8832                    warning("unknown escape sequence: \'\\x%x\'", c);
8833                break;
8834            }
8835        }
8836        p++;
8837    add_char_nonext:
8838        if (!is_long)
8839            cstr_ccat(outstr, c);
8840        else
8841            cstr_wccat(outstr, c);
8842    }
8843    /* add a trailing '\0' */
8844    if (!is_long)
8845        cstr_ccat(outstr, '\0');
8846    else
8847        cstr_wccat(outstr, '\0');
8848}
8849
8850/* we use 64 bit numbers */
8851#define BN_SIZE 2
8852
8853/* bn = (bn << shift) | or_val */
8854void bn_lshift(unsigned int *bn, int shift, int or_val)
8855{
8856    int i;
8857    unsigned int v;
8858    for(i=0;i<BN_SIZE;i++) {
8859        v = bn[i];
8860        bn[i] = (v << shift) | or_val;
8861        or_val = v >> (32 - shift);
8862    }
8863}
8864
8865void bn_zero(unsigned int *bn)
8866{
8867    int i;
8868    for(i=0;i<BN_SIZE;i++) {
8869        bn[i] = 0;
8870    }
8871}
8872
8873/* parse number in null terminated string 'p' and return it in the
8874   current token */
8875void parse_number(const char *p)
8876{
8877    int b, t, shift, frac_bits, s, exp_val, ch;
8878    char *q;
8879    unsigned int bn[BN_SIZE];
8880    double d;
8881
8882    /* number */
8883    q = token_buf;
8884    ch = *p++;
8885    t = ch;
8886    ch = *p++;
8887    *q++ = t;
8888    b = 10;
8889    if (t == '.') {
8890        goto float_frac_parse;
8891    } else if (t == '0') {
8892        if (ch == 'x' || ch == 'X') {
8893            q--;
8894            ch = *p++;
8895            b = 16;
8896        } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
8897            q--;
8898            ch = *p++;
8899            b = 2;
8900        }
8901    }
8902    /* parse all digits. cannot check octal numbers at this stage
8903       because of floating point constants */
8904    while (1) {
8905        if (ch >= 'a' && ch <= 'f')
8906            t = ch - 'a' + 10;
8907        else if (ch >= 'A' && ch <= 'F')
8908            t = ch - 'A' + 10;
8909        else if (isnum(ch))
8910            t = ch - '0';
8911        else
8912            break;
8913        if (t >= b)
8914            break;
8915        if (q >= token_buf + STRING_MAX_SIZE) {
8916        num_too_long:
8917            error("number too long");
8918        }
8919        *q++ = ch;
8920        ch = *p++;
8921    }
8922    if (ch == '.' ||
8923        ((ch == 'e' || ch == 'E') && b == 10) ||
8924        ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
8925        if (b != 10) {
8926            /* NOTE: strtox should support that for hexa numbers, but
8927               non ISOC99 libcs do not support it, so we prefer to do
8928               it by hand */
8929            /* hexadecimal or binary floats */
8930            /* XXX: handle overflows */
8931            *q = '\0';
8932            if (b == 16)
8933                shift = 4;
8934            else
8935                shift = 2;
8936            bn_zero(bn);
8937            q = token_buf;
8938            while (1) {
8939                t = *q++;
8940                if (t == '\0') {
8941                    break;
8942                } else if (t >= 'a') {
8943                    t = t - 'a' + 10;
8944                } else if (t >= 'A') {
8945                    t = t - 'A' + 10;
8946                } else {
8947                    t = t - '0';
8948                }
8949                bn_lshift(bn, shift, t);
8950            }
8951            frac_bits = 0;
8952            if (ch == '.') {
8953                ch = *p++;
8954                while (1) {
8955                    t = ch;
8956                    if (t >= 'a' && t <= 'f') {
8957                        t = t - 'a' + 10;
8958                    } else if (t >= 'A' && t <= 'F') {
8959                        t = t - 'A' + 10;
8960                    } else if (t >= '0' && t <= '9') {
8961                        t = t - '0';
8962                    } else {
8963                        break;
8964                    }
8965                    if (t >= b)
8966                        error("invalid digit");
8967                    bn_lshift(bn, shift, t);
8968                    frac_bits += shift;
8969                    ch = *p++;
8970                }
8971            }
8972            if (ch != 'p' && ch != 'P')
8973                expect("exponent");
8974            ch = *p++;
8975            s = 1;
8976            exp_val = 0;
8977            if (ch == '+') {
8978                ch = *p++;
8979            } else if (ch == '-') {
8980                s = -1;
8981                ch = *p++;
8982            }
8983            if (ch < '0' || ch > '9')
8984                expect("exponent digits");
8985            while (ch >= '0' && ch <= '9') {
8986                exp_val = exp_val * 10 + ch - '0';
8987                ch = *p++;
8988            }
8989            exp_val = exp_val * s;
8990
8991            /* now we can generate the number */
8992            /* XXX: should patch directly float number */
8993            d = (double)bn[1] * 4294967296.0 + (double)bn[0];
8994            d = ldexp(d, exp_val - frac_bits);
8995            t = toup(ch);
8996            if (t == 'F') {
8997                ch = *p++;
8998                tok = TOK_CFLOAT;
8999                /* float : should handle overflow */
9000                tokc.f = (float)d;
9001            } else if (t == 'L') {
9002                ch = *p++;
9003                tok = TOK_CLDOUBLE;
9004                /* XXX: not large enough */
9005                tokc.ld = (long double)d;
9006            } else {
9007                tok = TOK_CDOUBLE;
9008                tokc.d = d;
9009            }
9010        } else {
9011            /* decimal floats */
9012            if (ch == '.') {
9013                if (q >= token_buf + STRING_MAX_SIZE)
9014                    goto num_too_long;
9015                *q++ = ch;
9016                ch = *p++;
9017            float_frac_parse:
9018                while (ch >= '0' && ch <= '9') {
9019                    if (q >= token_buf + STRING_MAX_SIZE)
9020                        goto num_too_long;
9021                    *q++ = ch;
9022                    ch = *p++;
9023                }
9024            }
9025            if (ch == 'e' || ch == 'E') {
9026                if (q >= token_buf + STRING_MAX_SIZE)
9027                    goto num_too_long;
9028                *q++ = ch;
9029                ch = *p++;
9030                if (ch == '-' || ch == '+') {
9031                    if (q >= token_buf + STRING_MAX_SIZE)
9032                        goto num_too_long;
9033                    *q++ = ch;
9034                    ch = *p++;
9035                }
9036                if (ch < '0' || ch > '9')
9037                    expect("exponent digits");
9038                while (ch >= '0' && ch <= '9') {
9039                    if (q >= token_buf + STRING_MAX_SIZE)
9040                        goto num_too_long;
9041                    *q++ = ch;
9042                    ch = *p++;
9043                }
9044            }
9045            *q = '\0';
9046            t = toup(ch);
9047            errno = 0;
9048            if (t == 'F') {
9049                ch = *p++;
9050                tok = TOK_CFLOAT;
9051                tokc.f = strtof(token_buf, NULL);
9052            } else if (t == 'L') {
9053                ch = *p++;
9054                tok = TOK_CLDOUBLE;
9055                tokc.ld = strtold(token_buf, NULL);
9056            } else {
9057                tok = TOK_CDOUBLE;
9058                tokc.d = strtod(token_buf, NULL);
9059            }
9060        }
9061    } else {
9062        unsigned long long n, n1;
9063        int lcount, ucount;
9064
9065        /* integer number */
9066        *q = '\0';
9067        q = token_buf;
9068        if (b == 10 && *q == '0') {
9069            b = 8;
9070            q++;
9071        }
9072        n = 0;
9073        while(1) {
9074            t = *q++;
9075            /* no need for checks except for base 10 / 8 errors */
9076            if (t == '\0') {
9077                break;
9078            } else if (t >= 'a') {
9079                t = t - 'a' + 10;
9080            } else if (t >= 'A') {
9081                t = t - 'A' + 10;
9082            } else {
9083                t = t - '0';
9084                if (t >= b)
9085                    error("invalid digit");
9086            }
9087            n1 = n;
9088            n = n * b + t;
9089            /* detect overflow */
9090            /* XXX: this test is not reliable */
9091            if (n < n1)
9092                error("integer constant overflow");
9093        }
9094
9095        /* XXX: not exactly ANSI compliant */
9096        if ((n & 0xffffffff00000000LL) != 0) {
9097            if ((n >> 63) != 0)
9098                tok = TOK_CULLONG;
9099            else
9100                tok = TOK_CLLONG;
9101        } else if (n > 0x7fffffff) {
9102            tok = TOK_CUINT;
9103        } else {
9104            tok = TOK_CINT;
9105        }
9106        lcount = 0;
9107        ucount = 0;
9108        for(;;) {
9109            t = toup(ch);
9110            if (t == 'L') {
9111                if (lcount >= 2)
9112                    error("three 'l's in integer constant");
9113                lcount++;
9114                if (lcount == 2) {
9115                    if (tok == TOK_CINT)
9116                        tok = TOK_CLLONG;
9117                    else if (tok == TOK_CUINT)
9118                        tok = TOK_CULLONG;
9119                }
9120                ch = *p++;
9121            } else if (t == 'U') {
9122                if (ucount >= 1)
9123                    error("two 'u's in integer constant");
9124                ucount++;
9125                if (tok == TOK_CINT)
9126                    tok = TOK_CUINT;
9127                else if (tok == TOK_CLLONG)
9128                    tok = TOK_CULLONG;
9129                ch = *p++;
9130            } else {
9131                break;
9132            }
9133        }
9134        if (tok == TOK_CINT || tok == TOK_CUINT)
9135            tokc.ui = n;
9136        else
9137            tokc.ull = n;
9138    }
9139}
9140
9141
9142#define PARSE2(c1, tok1, c2, tok2)              \
9143    case c1:                                    \
9144        PEEKC(c, p);                            \
9145        if (c == c2) {                          \
9146            p++;                                \
9147            tok = tok2;                         \
9148        } else {                                \
9149            tok = tok1;                         \
9150        }                                       \
9151        break;
9152
9153/* return next token without macro substitution */
9154static /*inline*/ void next_nomacro1(void)
9155{
9156    int t, c, is_long;
9157    TokenSym *ts;
9158    uint8_t *p, *p1;
9159    unsigned int h;
9160
9161    p = file->buf_ptr;
9162 redo_no_start:
9163    c = *p;
9164    switch(c) {
9165    case ' ':
9166    case '\t':
9167    case '\f':
9168    case '\v':
9169    case '\r':
9170        p++;
9171        goto redo_no_start;
9172
9173    case '\\':
9174        /* first look if it is in fact an end of buffer */
9175        if (p >= file->buf_end) {
9176            file->buf_ptr = p;
9177            handle_eob();
9178            p = file->buf_ptr;
9179            if (p >= file->buf_end)
9180                goto parse_eof;
9181            else
9182                goto redo_no_start;
9183        } else {
9184            file->buf_ptr = p;
9185            ch = *p;
9186            handle_stray();
9187            p = file->buf_ptr;
9188            goto redo_no_start;
9189        }
9190    parse_eof:
9191        {
9192            TCCState *s1 = tcc_state;
9193            if (parse_flags & PARSE_FLAG_LINEFEED) {
9194                tok = TOK_LINEFEED;
9195            } else if (s1->include_stack_ptr == s1->include_stack ||
9196                       !(parse_flags & PARSE_FLAG_PREPROCESS)) {
9197                /* no include left : end of file. */
9198                tok = TOK_EOF;
9199            } else {
9200                /* pop include file */
9201
9202                /* test if previous '#endif' was after a #ifdef at
9203                   start of file */
9204                if (tok_flags & TOK_FLAG_ENDIF) {
9205#ifdef INC_DEBUG
9206                    printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
9207#endif
9208                    add_cached_include(s1, file->inc_type, file->inc_filename,
9209                                       file->ifndef_macro_saved);
9210                }
9211
9212                /* add end of include file debug info */
9213                if (do_debug) {
9214                    put_stabd(N_EINCL, 0, 0);
9215                }
9216                /* pop include stack */
9217                tcc_close(file);
9218                s1->include_stack_ptr--;
9219                file = *s1->include_stack_ptr;
9220                p = file->buf_ptr;
9221                goto redo_no_start;
9222            }
9223        }
9224        break;
9225
9226    case '\n':
9227        if (parse_flags & PARSE_FLAG_LINEFEED) {
9228            tok = TOK_LINEFEED;
9229        } else {
9230            file->line_num++;
9231            tok_flags |= TOK_FLAG_BOL;
9232            p++;
9233            goto redo_no_start;
9234        }
9235        break;
9236
9237    case '#':
9238        /* XXX: simplify */
9239        PEEKC(c, p);
9240        if ((tok_flags & TOK_FLAG_BOL) &&
9241            (parse_flags & PARSE_FLAG_PREPROCESS)) {
9242            file->buf_ptr = p;
9243            preprocess(tok_flags & TOK_FLAG_BOF);
9244            p = file->buf_ptr;
9245            goto redo_no_start;
9246        } else {
9247            if (c == '#') {
9248                p++;
9249                tok = TOK_TWOSHARPS;
9250            } else {
9251                if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
9252                    p = parse_line_comment(p - 1);
9253                    goto redo_no_start;
9254                } else {
9255                    tok = '#';
9256                }
9257            }
9258        }
9259        break;
9260
9261    case 'a': case 'b': case 'c': case 'd':
9262    case 'e': case 'f': case 'g': case 'h':
9263    case 'i': case 'j': case 'k': case 'l':
9264    case 'm': case 'n': case 'o': case 'p':
9265    case 'q': case 'r': case 's': case 't':
9266    case 'u': case 'v': case 'w': case 'x':
9267    case 'y': case 'z':
9268    case 'A': case 'B': case 'C': case 'D':
9269    case 'E': case 'F': case 'G': case 'H':
9270    case 'I': case 'J': case 'K':
9271    case 'M': case 'N': case 'O': case 'P':
9272    case 'Q': case 'R': case 'S': case 'T':
9273    case 'U': case 'V': case 'W': case 'X':
9274    case 'Y': case 'Z':
9275    case '_':
9276    parse_ident_fast:
9277        p1 = p;
9278        h = TOK_HASH_INIT;
9279        h = TOK_HASH_FUNC(h, c);
9280        p++;
9281        for(;;) {
9282            c = *p;
9283            if (!isidnum_table[c])
9284                break;
9285            h = TOK_HASH_FUNC(h, c);
9286            p++;
9287        }
9288        if (c != '\\') {
9289            TokenSym **pts;
9290            int len;
9291
9292            /* fast case : no stray found, so we have the full token
9293               and we have already hashed it */
9294            len = p - p1;
9295            h &= (TOK_HASH_SIZE - 1);
9296            pts = &hash_ident[h];
9297            for(;;) {
9298                ts = *pts;
9299                if (!ts)
9300                    break;
9301                if (ts->len == len && !memcmp(ts->str, p1, len))
9302                    goto token_found;
9303                pts = &(ts->hash_next);
9304            }
9305            ts = tok_alloc_new(pts, p1, len);
9306        token_found: ;
9307        } else {
9308            /* slower case */
9309            cstr_reset(&tokcstr);
9310
9311            while (p1 < p) {
9312                cstr_ccat(&tokcstr, *p1);
9313                p1++;
9314            }
9315            p--;
9316            PEEKC(c, p);
9317        parse_ident_slow:
9318            while (isidnum_table[c]) {
9319                cstr_ccat(&tokcstr, c);
9320                PEEKC(c, p);
9321            }
9322            ts = tok_alloc(tokcstr.data, tokcstr.size);
9323        }
9324        tok = ts->tok;
9325        break;
9326    case 'L':
9327        t = p[1];
9328        if (t != '\\' && t != '\'' && t != '\"') {
9329            /* fast case */
9330            goto parse_ident_fast;
9331        } else {
9332            PEEKC(c, p);
9333            if (c == '\'' || c == '\"') {
9334                is_long = 1;
9335                goto str_const;
9336            } else {
9337                cstr_reset(&tokcstr);
9338                cstr_ccat(&tokcstr, 'L');
9339                goto parse_ident_slow;
9340            }
9341        }
9342        break;
9343    case '0': case '1': case '2': case '3':
9344    case '4': case '5': case '6': case '7':
9345    case '8': case '9':
9346
9347        cstr_reset(&tokcstr);
9348        /* after the first digit, accept digits, alpha, '.' or sign if
9349           prefixed by 'eEpP' */
9350    parse_num:
9351        for(;;) {
9352            t = c;
9353            cstr_ccat(&tokcstr, c);
9354            PEEKC(c, p);
9355            if (!(isnum(c) || isid(c) || c == '.' ||
9356                  ((c == '+' || c == '-') &&
9357                   (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
9358                break;
9359        }
9360        /* We add a trailing '\0' to ease parsing */
9361        cstr_ccat(&tokcstr, '\0');
9362        tokc.cstr = &tokcstr;
9363        tok = TOK_PPNUM;
9364        break;
9365    case '.':
9366        /* special dot handling because it can also start a number */
9367        PEEKC(c, p);
9368        if (isnum(c)) {
9369            cstr_reset(&tokcstr);
9370            cstr_ccat(&tokcstr, '.');
9371            goto parse_num;
9372        } else if (c == '.') {
9373            PEEKC(c, p);
9374            if (c != '.')
9375                expect("'.'");
9376            PEEKC(c, p);
9377            tok = TOK_DOTS;
9378        } else {
9379            tok = '.';
9380        }
9381        break;
9382    case '\'':
9383    case '\"':
9384        is_long = 0;
9385    str_const:
9386        {
9387            CString str;
9388            int sep;
9389
9390            sep = c;
9391
9392            /* parse the string */
9393            cstr_new(&str);
9394            p = parse_pp_string(p, sep, &str);
9395            cstr_ccat(&str, '\0');
9396
9397            /* eval the escape (should be done as TOK_PPNUM) */
9398            cstr_reset(&tokcstr);
9399            parse_escape_string(&tokcstr, str.data, is_long);
9400            cstr_free(&str);
9401
9402            if (sep == '\'') {
9403                int char_size;
9404                /* XXX: make it portable */
9405                if (!is_long)
9406                    char_size = 1;
9407                else
9408                    char_size = sizeof(int);
9409                if (tokcstr.size <= char_size)
9410                    error("empty character constant");
9411                if (tokcstr.size > 2 * char_size)
9412                    warning("multi-character character constant");
9413                if (!is_long) {
9414                    tokc.i = *(int8_t *)tokcstr.data;
9415                    tok = TOK_CCHAR;
9416                } else {
9417                    tokc.i = *(int *)tokcstr.data;
9418                    tok = TOK_LCHAR;
9419                }
9420            } else {
9421                tokc.cstr = &tokcstr;
9422                if (!is_long)
9423                    tok = TOK_STR;
9424                else
9425                    tok = TOK_LSTR;
9426            }
9427        }
9428        break;
9429
9430    case '<':
9431        PEEKC(c, p);
9432        if (c == '=') {
9433            p++;
9434            tok = TOK_LE;
9435        } else if (c == '<') {
9436            PEEKC(c, p);
9437            if (c == '=') {
9438                p++;
9439                tok = TOK_A_SHL;
9440            } else {
9441                tok = TOK_SHL;
9442            }
9443        } else {
9444            tok = TOK_LT;
9445        }
9446        break;
9447
9448    case '>':
9449        PEEKC(c, p);
9450        if (c == '=') {
9451            p++;
9452            tok = TOK_GE;
9453        } else if (c == '>') {
9454            PEEKC(c, p);
9455            if (c == '=') {
9456                p++;
9457                tok = TOK_A_SAR;
9458            } else {
9459                tok = TOK_SAR;
9460            }
9461        } else {
9462            tok = TOK_GT;
9463        }
9464        break;
9465
9466    case '&':
9467        PEEKC(c, p);
9468        if (c == '&') {
9469            p++;
9470            tok = TOK_LAND;
9471        } else if (c == '=') {
9472            p++;
9473            tok = TOK_A_AND;
9474        } else {
9475            tok = '&';
9476        }
9477        break;
9478
9479    case '|':
9480        PEEKC(c, p);
9481        if (c == '|') {
9482            p++;
9483            tok = TOK_LOR;
9484        } else if (c == '=') {
9485            p++;
9486            tok = TOK_A_OR;
9487        } else {
9488            tok = '|';
9489        }
9490        break;
9491
9492    case '+':
9493        PEEKC(c, p);
9494        if (c == '+') {
9495            p++;
9496            tok = TOK_INC;
9497        } else if (c == '=') {
9498            p++;
9499            tok = TOK_A_ADD;
9500        } else {
9501            tok = '+';
9502        }
9503        break;
9504
9505    case '-':
9506        PEEKC(c, p);
9507        if (c == '-') {
9508            p++;
9509            tok = TOK_DEC;
9510        } else if (c == '=') {
9511            p++;
9512            tok = TOK_A_SUB;
9513        } else if (c == '>') {
9514            p++;
9515            tok = TOK_ARROW;
9516        } else {
9517            tok = '-';
9518        }
9519        break;
9520
9521    PARSE2('!', '!', '=', TOK_NE)
9522    PARSE2('=', '=', '=', TOK_EQ)
9523    PARSE2('*', '*', '=', TOK_A_MUL)
9524    PARSE2('%', '%', '=', TOK_A_MOD)
9525    PARSE2('^', '^', '=', TOK_A_XOR)
9526
9527        /* comments or operator */
9528    case '/':
9529        PEEKC(c, p);
9530        if (c == '*') {
9531            p = parse_comment(p);
9532            goto redo_no_start;
9533        } else if (c == '/') {
9534            p = parse_line_comment(p);
9535            goto redo_no_start;
9536        } else if (c == '=') {
9537            p++;
9538            tok = TOK_A_DIV;
9539        } else {
9540            tok = '/';
9541        }
9542        break;
9543
9544        /* simple tokens */
9545    case '(':
9546    case ')':
9547    case '[':
9548    case ']':
9549    case '{':
9550    case '}':
9551    case ',':
9552    case ';':
9553    case ':':
9554    case '?':
9555    case '~':
9556    case '$': /* only used in assembler */
9557    case '@': /* dito */
9558        tok = c;
9559        p++;
9560        break;
9561    default:
9562        error("unrecognized character \\x%02x", c);
9563        break;
9564    }
9565    file->buf_ptr = p;
9566    tok_flags = 0;
9567#if defined(PARSE_DEBUG)
9568    printf("token = %s\n", get_tok_str(tok, &tokc));
9569#endif
9570}
9571
9572/* return next token without macro substitution. Can read input from
9573   macro_ptr buffer */
9574static void next_nomacro(void)
9575{
9576    if (macro_ptr) {
9577    redo:
9578        tok = *macro_ptr;
9579        if (tok) {
9580            TOK_GET(tok, macro_ptr, tokc);
9581            if (tok == TOK_LINENUM) {
9582                file->line_num = tokc.i;
9583                goto redo;
9584            }
9585        }
9586    } else {
9587        next_nomacro1();
9588    }
9589}
9590
9591/* substitute args in macro_str and return allocated string */
9592static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
9593{
9594    int *st, last_tok, t, notfirst;
9595    Sym *s;
9596    CValue cval;
9597    TokenString str;
9598    CString cstr;
9599
9600    tok_str_new(&str);
9601    last_tok = 0;
9602    while(1) {
9603        TOK_GET(t, macro_str, cval);
9604        if (!t)
9605            break;
9606        if (t == '#') {
9607            /* stringize */
9608            TOK_GET(t, macro_str, cval);
9609            if (!t)
9610                break;
9611            s = sym_find2(args, t);
9612            if (s) {
9613                cstr_new(&cstr);
9614                st = (int *)s->c;
9615                notfirst = 0;
9616                while (*st) {
9617                    if (notfirst)
9618                        cstr_ccat(&cstr, ' ');
9619                    TOK_GET(t, st, cval);
9620                    cstr_cat(&cstr, get_tok_str(t, &cval));
9621                    notfirst = 1;
9622                }
9623                cstr_ccat(&cstr, '\0');
9624#ifdef PP_DEBUG
9625                printf("stringize: %s\n", (char *)cstr.data);
9626#endif
9627                /* add string */
9628                cval.cstr = &cstr;
9629                tok_str_add2(&str, TOK_STR, &cval);
9630                cstr_free(&cstr);
9631            } else {
9632                tok_str_add2(&str, t, &cval);
9633            }
9634        } else if (t >= TOK_IDENT) {
9635            s = sym_find2(args, t);
9636            if (s) {
9637                st = (int *)s->c;
9638                /* if '##' is present before or after, no arg substitution */
9639                if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
9640                    /* special case for var arg macros : ## eats the
9641                       ',' if empty VA_ARGS variable. */
9642                    /* XXX: test of the ',' is not 100%
9643                       reliable. should fix it to avoid security
9644                       problems */
9645                    if (gnu_ext && s->type.t &&
9646                        last_tok == TOK_TWOSHARPS &&
9647                        str.len >= 2 && str.str[str.len - 2] == ',') {
9648                        if (*st == 0) {
9649                            /* suppress ',' '##' */
9650                            str.len -= 2;
9651                        } else {
9652                            /* suppress '##' and add variable */
9653                            str.len--;
9654                            goto add_var;
9655                        }
9656                    } else {
9657                        int t1;
9658                    add_var:
9659                        for(;;) {
9660                            TOK_GET(t1, st, cval);
9661                            if (!t1)
9662                                break;
9663                            tok_str_add2(&str, t1, &cval);
9664                        }
9665                    }
9666                } else {
9667                    /* NOTE: the stream cannot be read when macro
9668                       substituing an argument */
9669                    macro_subst(&str, nested_list, st, NULL);
9670                }
9671            } else {
9672                tok_str_add(&str, t);
9673            }
9674        } else {
9675            tok_str_add2(&str, t, &cval);
9676        }
9677        last_tok = t;
9678    }
9679    tok_str_add(&str, 0);
9680    return str.str;
9681}
9682
9683static char const ab_month_name[12][4] =
9684{
9685    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
9686    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
9687};
9688
9689/* do macro substitution of current token with macro 's' and add
9690   result to (tok_str,tok_len). 'nested_list' is the list of all
9691   macros we got inside to avoid recursing. Return non zero if no
9692   substitution needs to be done */
9693static int macro_subst_tok(TokenString *tok_str,
9694                           Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
9695{
9696    Sym *args, *sa, *sa1;
9697    int mstr_allocated, parlevel, *mstr, t, t1;
9698    TokenString str;
9699    char *cstrval;
9700    CValue cval;
9701    CString cstr;
9702    char buf[32];
9703
9704    /* if symbol is a macro, prepare substitution */
9705    /* special macros */
9706    if (tok == TOK___LINE__) {
9707        snprintf(buf, sizeof(buf), "%d", file->line_num);
9708        cstrval = buf;
9709        t1 = TOK_PPNUM;
9710        goto add_cstr1;
9711    } else if (tok == TOK___FILE__) {
9712        cstrval = file->filename;
9713        goto add_cstr;
9714    } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
9715        time_t ti;
9716        struct tm *tm;
9717
9718        time(&ti);
9719        tm = localtime(&ti);
9720        if (tok == TOK___DATE__) {
9721            snprintf(buf, sizeof(buf), "%s %2d %d",
9722                     ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
9723        } else {
9724            snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
9725                     tm->tm_hour, tm->tm_min, tm->tm_sec);
9726        }
9727        cstrval = buf;
9728    add_cstr:
9729        t1 = TOK_STR;
9730    add_cstr1:
9731        cstr_new(&cstr);
9732        cstr_cat(&cstr, cstrval);
9733        cstr_ccat(&cstr, '\0');
9734        cval.cstr = &cstr;
9735        tok_str_add2(tok_str, t1, &cval);
9736        cstr_free(&cstr);
9737    } else {
9738        mstr = (int *)s->c;
9739        mstr_allocated = 0;
9740        if (s->type.t == MACRO_FUNC) {
9741            /* NOTE: we do not use next_nomacro to avoid eating the
9742               next token. XXX: find better solution */
9743        redo:
9744            if (macro_ptr) {
9745                t = *macro_ptr;
9746                if (t == 0 && can_read_stream) {
9747                    /* end of macro stream: we must look at the token
9748                       after in the file */
9749                    struct macro_level *ml = *can_read_stream;
9750                    macro_ptr = NULL;
9751                    if (ml)
9752                    {
9753                        macro_ptr = ml->p;
9754                        ml->p = NULL;
9755                        *can_read_stream = ml -> prev;
9756                    }
9757                    goto redo;
9758                }
9759            } else {
9760                /* XXX: incorrect with comments */
9761                ch = file->buf_ptr[0];
9762                while (is_space(ch) || ch == '\n')
9763                    cinp();
9764                t = ch;
9765            }
9766            if (t != '(') /* no macro subst */
9767                return -1;
9768
9769            /* argument macro */
9770            next_nomacro();
9771            next_nomacro();
9772            args = NULL;
9773            sa = s->next;
9774            /* NOTE: empty args are allowed, except if no args */
9775            for(;;) {
9776                /* handle '()' case */
9777                if (!args && !sa && tok == ')')
9778                    break;
9779                if (!sa)
9780                    error("macro '%s' used with too many args",
9781                          get_tok_str(s->v, 0));
9782                tok_str_new(&str);
9783                parlevel = 0;
9784                /* NOTE: non zero sa->t indicates VA_ARGS */
9785                while ((parlevel > 0 ||
9786                        (tok != ')' &&
9787                         (tok != ',' || sa->type.t))) &&
9788                       tok != -1) {
9789                    if (tok == '(')
9790                        parlevel++;
9791                    else if (tok == ')')
9792                        parlevel--;
9793                    tok_str_add2(&str, tok, &tokc);
9794                    next_nomacro();
9795                }
9796                tok_str_add(&str, 0);
9797                sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
9798                sa = sa->next;
9799                if (tok == ')') {
9800                    /* special case for gcc var args: add an empty
9801                       var arg argument if it is omitted */
9802                    if (sa && sa->type.t && gnu_ext)
9803                        continue;
9804                    else
9805                        break;
9806                }
9807                if (tok != ',')
9808                    expect(",");
9809                next_nomacro();
9810            }
9811            if (sa) {
9812                error("macro '%s' used with too few args",
9813                      get_tok_str(s->v, 0));
9814            }
9815
9816            /* now subst each arg */
9817            mstr = macro_arg_subst(nested_list, mstr, args);
9818            /* free memory */
9819            sa = args;
9820            while (sa) {
9821                sa1 = sa->prev;
9822                tok_str_free((int *)sa->c);
9823                sym_free(sa);
9824                sa = sa1;
9825            }
9826            mstr_allocated = 1;
9827        }
9828        sym_push2(nested_list, s->v, 0, 0);
9829        macro_subst(tok_str, nested_list, mstr, can_read_stream);
9830        /* pop nested defined symbol */
9831        sa1 = *nested_list;
9832        *nested_list = sa1->prev;
9833        sym_free(sa1);
9834        if (mstr_allocated)
9835            tok_str_free(mstr);
9836    }
9837    return 0;
9838}
9839
9840/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
9841   return the resulting string (which must be freed). */
9842static /*inline*/ int *macro_twosharps(const int *macro_str)
9843{
9844    TokenSym *ts;
9845    const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr;
9846    int t;
9847    const char *p1, *p2;
9848    CValue cval;
9849    TokenString macro_str1;
9850    CString cstr;
9851    memset(&cval, 0, sizeof(cval));
9852    start_macro_ptr = macro_str;
9853    /* we search the first '##' */
9854    for(;;) {
9855        macro_ptr1 = macro_str;
9856        TOK_GET(t, macro_str, cval);
9857        /* nothing more to do if end of string */
9858        if (t == 0)
9859            return NULL;
9860        if (*macro_str == TOK_TWOSHARPS)
9861            break;
9862    }
9863
9864    /* we saw '##', so we need more processing to handle it */
9865    cstr_new(&cstr);
9866    tok_str_new(&macro_str1);
9867    tok = t;
9868    tokc = cval;
9869
9870    /* add all tokens seen so far */
9871    for(ptr = start_macro_ptr; ptr < macro_ptr1;) {
9872        TOK_GET(t, ptr, cval);
9873        tok_str_add2(&macro_str1, t, &cval);
9874    }
9875    saved_macro_ptr = macro_ptr;
9876    /* XXX: get rid of the use of macro_ptr here */
9877    macro_ptr = (int *)macro_str;
9878    for(;;) {
9879        while (*macro_ptr == TOK_TWOSHARPS) {
9880            macro_ptr++;
9881            macro_ptr1 = macro_ptr;
9882            t = *macro_ptr;
9883            if (t) {
9884                TOK_GET(t, macro_ptr, cval);
9885                /* We concatenate the two tokens if we have an
9886                   identifier or a preprocessing number */
9887                cstr_reset(&cstr);
9888                p1 = get_tok_str(tok, &tokc);
9889                cstr_cat(&cstr, p1);
9890                p2 = get_tok_str(t, &cval);
9891                cstr_cat(&cstr, p2);
9892                cstr_ccat(&cstr, '\0');
9893
9894                if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
9895                    (t >= TOK_IDENT || t == TOK_PPNUM)) {
9896                    if (tok == TOK_PPNUM) {
9897                        /* if number, then create a number token */
9898                        /* NOTE: no need to allocate because
9899                           tok_str_add2() does it */
9900                        tokc.cstr = &cstr;
9901                    } else {
9902                        /* if identifier, we must do a test to
9903                           validate we have a correct identifier */
9904                        if (t == TOK_PPNUM) {
9905                            const char *p;
9906                            int c;
9907
9908                            p = p2;
9909                            for(;;) {
9910                                c = *p;
9911                                if (c == '\0')
9912                                    break;
9913                                p++;
9914                                if (!isnum(c) && !isid(c))
9915                                    goto error_pasting;
9916                            }
9917                        }
9918                        ts = tok_alloc(cstr.data, strlen(cstr.data));
9919                        tok = ts->tok; /* modify current token */
9920                    }
9921                } else {
9922                    const char *str = cstr.data;
9923                    const unsigned char *q;
9924
9925                    /* we look for a valid token */
9926                    /* XXX: do more extensive checks */
9927                    if (!strcmp(str, ">>=")) {
9928                        tok = TOK_A_SAR;
9929                    } else if (!strcmp(str, "<<=")) {
9930                        tok = TOK_A_SHL;
9931                    } else if (strlen(str) == 2) {
9932                        /* search in two bytes table */
9933                        q = tok_two_chars;
9934                        for(;;) {
9935                            if (!*q)
9936                                goto error_pasting;
9937                            if (q[0] == str[0] && q[1] == str[1])
9938                                break;
9939                            q += 3;
9940                        }
9941                        tok = q[2];
9942                    } else {
9943                    error_pasting:
9944                        /* NOTE: because get_tok_str use a static buffer,
9945                           we must save it */
9946                        cstr_reset(&cstr);
9947                        p1 = get_tok_str(tok, &tokc);
9948                        cstr_cat(&cstr, p1);
9949                        cstr_ccat(&cstr, '\0');
9950                        p2 = get_tok_str(t, &cval);
9951                        warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
9952                        /* cannot merge tokens: just add them separately */
9953                        tok_str_add2(&macro_str1, tok, &tokc);
9954                        /* XXX: free associated memory ? */
9955                        tok = t;
9956                        tokc = cval;
9957                    }
9958                }
9959            }
9960        }
9961        tok_str_add2(&macro_str1, tok, &tokc);
9962        next_nomacro();
9963        if (tok == 0)
9964            break;
9965    }
9966    macro_ptr = (int *)saved_macro_ptr;
9967    cstr_free(&cstr);
9968    tok_str_add(&macro_str1, 0);
9969    return macro_str1.str;
9970}
9971
9972
9973/* do macro substitution of macro_str and add result to
9974   (tok_str,tok_len). 'nested_list' is the list of all macros we got
9975   inside to avoid recursing. */
9976static void macro_subst(TokenString *tok_str, Sym **nested_list,
9977                        const int *macro_str, struct macro_level ** can_read_stream)
9978{
9979    Sym *s;
9980    int *macro_str1;
9981    const int *ptr;
9982    int t, ret;
9983    CValue cval;
9984    struct macro_level ml;
9985
9986    /* first scan for '##' operator handling */
9987    ptr = macro_str;
9988    macro_str1 = macro_twosharps(ptr);
9989    if (macro_str1)
9990        ptr = macro_str1;
9991    while (1) {
9992        /* NOTE: ptr == NULL can only happen if tokens are read from
9993           file stream due to a macro function call */
9994        if (ptr == NULL)
9995            break;
9996        TOK_GET(t, ptr, cval);
9997        if (t == 0)
9998            break;
9999        s = define_find(t);
10000        if (s != NULL) {
10001            /* if nested substitution, do nothing */
10002            if (sym_find2(*nested_list, t))
10003                goto no_subst;
10004            ml.p = macro_ptr;
10005            if (can_read_stream)
10006                ml.prev = *can_read_stream, *can_read_stream = &ml;
10007            macro_ptr = (int *)ptr;
10008            tok = t;
10009            ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
10010            ptr = (int *)macro_ptr;
10011            macro_ptr = ml.p;
10012            if (can_read_stream && *can_read_stream == &ml)
10013                    *can_read_stream = ml.prev;
10014            if (ret != 0)
10015                goto no_subst;
10016        } else {
10017        no_subst:
10018            tok_str_add2(tok_str, t, &cval);
10019        }
10020    }
10021    if (macro_str1)
10022        tok_str_free(macro_str1);
10023}
10024
10025/* return next token with macro substitution */
10026static void next(void)
10027{
10028    Sym *nested_list, *s;
10029    TokenString str;
10030    struct macro_level *ml;
10031
10032 redo:
10033    next_nomacro();
10034    if (!macro_ptr) {
10035        /* if not reading from macro substituted string, then try
10036           to substitute macros */
10037        if (tok >= TOK_IDENT &&
10038            (parse_flags & PARSE_FLAG_PREPROCESS)) {
10039            s = define_find(tok);
10040            if (s) {
10041                /* we have a macro: we try to substitute */
10042                tok_str_new(&str);
10043                nested_list = NULL;
10044                ml = NULL;
10045                if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
10046                    /* substitution done, NOTE: maybe empty */
10047                    tok_str_add(&str, 0);
10048                    macro_ptr = str.str;
10049                    macro_ptr_allocated = str.str;
10050                    goto redo;
10051                }
10052            }
10053        }
10054    } else {
10055        if (tok == 0) {
10056            /* end of macro or end of unget buffer */
10057            if (unget_buffer_enabled) {
10058                macro_ptr = unget_saved_macro_ptr;
10059                unget_buffer_enabled = 0;
10060            } else {
10061                /* end of macro string: free it */
10062                tok_str_free(macro_ptr_allocated);
10063                macro_ptr = NULL;
10064            }
10065            goto redo;
10066        }
10067    }
10068
10069    /* convert preprocessor tokens into C tokens */
10070    if (tok == TOK_PPNUM &&
10071        (parse_flags & PARSE_FLAG_TOK_NUM)) {
10072        parse_number((char *)tokc.cstr->data);
10073    }
10074}
10075
10076/* push back current token and set current token to 'last_tok'. Only
10077   identifier case handled for labels. */
10078static inline void unget_tok(int last_tok)
10079{
10080    int i, n;
10081    int *q;
10082    unget_saved_macro_ptr = macro_ptr;
10083    unget_buffer_enabled = 1;
10084    q = unget_saved_buffer;
10085    macro_ptr = q;
10086    *q++ = tok;
10087    n = tok_ext_size(tok) - 1;
10088    for(i=0;i<n;i++)
10089        *q++ = tokc.tab[i];
10090    *q = 0; /* end of token string */
10091    tok = last_tok;
10092}
10093
10094
10095void swap(int *p, int *q)
10096{
10097    int t;
10098    t = *p;
10099    *p = *q;
10100    *q = t;
10101}
10102
10103void vsetc(CType *type, int r, CValue *vc)
10104{
10105    int v;
10106
10107    if (vtop >= vstack + (VSTACK_SIZE - 1))
10108        error("memory full");
10109    /* cannot let cpu flags if other instruction are generated. Also
10110       avoid leaving VT_JMP anywhere except on the top of the stack
10111       because it would complicate the code generator. */
10112    if (vtop >= vstack) {
10113        v = vtop->r & VT_VALMASK;
10114        if (v == VT_CMP || (v & ~1) == VT_JMP)
10115            gv(RC_INT);
10116    }
10117    vtop++;
10118    vtop->type = *type;
10119    vtop->r = r;
10120    vtop->r2 = VT_CONST;
10121    vtop->c = *vc;
10122}
10123
10124/* push integer constant */
10125void vpushi(int v)
10126{
10127    CValue cval;
10128    cval.i = v;
10129    vsetc(&int_type, VT_CONST, &cval);
10130}
10131
10132/* Return a static symbol pointing to a section */
10133static Sym *get_sym_ref(CType *type, Section *sec,
10134                        unsigned long offset, unsigned long size)
10135{
10136    int v;
10137    Sym *sym;
10138
10139    v = anon_sym++;
10140    sym = global_identifier_push(v, type->t | VT_STATIC, 0);
10141    sym->type.ref = type->ref;
10142    sym->r = VT_CONST | VT_SYM;
10143    put_extern_sym(sym, sec, offset, size);
10144    return sym;
10145}
10146
10147/* push a reference to a section offset by adding a dummy symbol */
10148static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
10149{
10150    CValue cval;
10151
10152    cval.ul = 0;
10153    vsetc(type, VT_CONST | VT_SYM, &cval);
10154    vtop->sym = get_sym_ref(type, sec, offset, size);
10155}
10156
10157/* define a new external reference to a symbol 'v' of type 'u' */
10158static Sym *external_global_sym(int v, CType *type, int r)
10159{
10160    Sym *s;
10161
10162    s = sym_find(v);
10163    if (!s) {
10164        /* push forward reference */
10165        s = global_identifier_push(v, type->t | VT_EXTERN, 0);
10166        s->type.ref = type->ref;
10167        s->r = r | VT_CONST | VT_SYM;
10168    }
10169    return s;
10170}
10171
10172/* define a new external reference to a symbol 'v' of type 'u' */
10173static Sym *external_sym(int v, CType *type, int r)
10174{
10175    Sym *s;
10176
10177    s = sym_find(v);
10178    if (!s) {
10179        /* push forward reference */
10180        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
10181        s->type.t |= VT_EXTERN;
10182    } else {
10183        if (!is_compatible_types(&s->type, type))
10184            error("incompatible types for redefinition of '%s'",
10185                  get_tok_str(v, NULL));
10186    }
10187    return s;
10188}
10189
10190/* push a reference to global symbol v */
10191static void vpush_global_sym(CType *type, int v)
10192{
10193    Sym *sym;
10194    CValue cval;
10195
10196    sym = external_global_sym(v, type, 0);
10197    cval.ul = 0;
10198    vsetc(type, VT_CONST | VT_SYM, &cval);
10199    vtop->sym = sym;
10200}
10201
10202void vset(CType *type, int r, int v)
10203{
10204    CValue cval;
10205
10206    cval.i = v;
10207    vsetc(type, r, &cval);
10208}
10209
10210void vseti(int r, int v)
10211{
10212    CType type;
10213    type.t = VT_INT;
10214    vset(&type, r, v);
10215}
10216
10217void vswap(void)
10218{
10219    SValue tmp;
10220
10221    tmp = vtop[0];
10222    vtop[0] = vtop[-1];
10223    vtop[-1] = tmp;
10224}
10225
10226void vpushv(SValue *v)
10227{
10228    if (vtop >= vstack + (VSTACK_SIZE - 1))
10229        error("memory full");
10230    vtop++;
10231    *vtop = *v;
10232}
10233
10234void vdup(void)
10235{
10236    vpushv(vtop);
10237}
10238
10239/* save r to the memory stack, and mark it as being free */
10240void save_reg(int r)
10241{
10242    int l, saved, size, align;
10243    SValue *p, sv;
10244    CType *type;
10245
10246    /* modify all stack values */
10247    saved = 0;
10248    l = 0;
10249    for(p=vstack;p<=vtop;p++) {
10250        if ((p->r & VT_VALMASK) == r ||
10251            (p->r2 & VT_VALMASK) == r) {
10252            /* must save value on stack if not already done */
10253            if (!saved) {
10254                /* NOTE: must reload 'r' because r might be equal to r2 */
10255                r = p->r & VT_VALMASK;
10256                /* store register in the stack */
10257                type = &p->type;
10258                if ((p->r & VT_LVAL) ||
10259                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
10260                    type = &int_type;
10261                size = type_size(type, &align);
10262                loc = (loc - size) & -align;
10263                sv.type.t = type->t;
10264                sv.r = VT_LOCAL | VT_LVAL;
10265                sv.c.ul = loc;
10266                store(r, &sv);
10267#ifdef TCC_TARGET_I386
10268                /* x86 specific: need to pop fp register ST0 if saved */
10269                if (r == TREG_ST0) {
10270                    o(0xd9dd); /* fstp %st(1) */
10271                }
10272#endif
10273                /* special long long case */
10274                if ((type->t & VT_BTYPE) == VT_LLONG) {
10275                    sv.c.ul += 4;
10276                    store(p->r2, &sv);
10277                }
10278                l = loc;
10279                saved = 1;
10280            }
10281            /* mark that stack entry as being saved on the stack */
10282            if (p->r & VT_LVAL) {
10283                /* also clear the bounded flag because the
10284                   relocation address of the function was stored in
10285                   p->c.ul */
10286                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
10287            } else {
10288                p->r = lvalue_type(p->type.t) | VT_LOCAL;
10289            }
10290            p->r2 = VT_CONST;
10291            p->c.ul = l;
10292        }
10293    }
10294}
10295
10296/* find a register of class 'rc2' with at most one reference on stack.
10297 * If none, call get_reg(rc) */
10298int get_reg_ex(int rc, int rc2)
10299{
10300    int r;
10301    SValue *p;
10302
10303    for(r=0;r<NB_REGS;r++) {
10304        if (reg_classes[r] & rc2) {
10305            int n;
10306            n=0;
10307            for(p = vstack; p <= vtop; p++) {
10308                if ((p->r & VT_VALMASK) == r ||
10309                    (p->r2 & VT_VALMASK) == r)
10310                    n++;
10311            }
10312            if (n <= 1)
10313                return r;
10314        }
10315    }
10316    return get_reg(rc);
10317}
10318
10319/* find a free register of class 'rc'. If none, save one register */
10320int get_reg(int rc)
10321{
10322    int r;
10323    SValue *p;
10324
10325    /* find a free register */
10326    for(r=0;r<NB_REGS;r++) {
10327        if (reg_classes[r] & rc) {
10328            for(p=vstack;p<=vtop;p++) {
10329                if ((p->r & VT_VALMASK) == r ||
10330                    (p->r2 & VT_VALMASK) == r)
10331                    goto notfound;
10332            }
10333            return r;
10334        }
10335    notfound: ;
10336    }
10337
10338    /* no register left : free the first one on the stack (VERY
10339       IMPORTANT to start from the bottom to ensure that we don't
10340       spill registers used in gen_opi()) */
10341    for(p=vstack;p<=vtop;p++) {
10342        r = p->r & VT_VALMASK;
10343        if (r < VT_CONST && (reg_classes[r] & rc))
10344            goto save_found;
10345        /* also look at second register (if long long) */
10346        r = p->r2 & VT_VALMASK;
10347        if (r < VT_CONST && (reg_classes[r] & rc)) {
10348        save_found:
10349            save_reg(r);
10350            return r;
10351        }
10352    }
10353    /* Should never comes here */
10354    return -1;
10355}
10356
10357/* save registers up to (vtop - n) stack entry */
10358void save_regs(int n)
10359{
10360    int r;
10361    SValue *p, *p1;
10362    p1 = vtop - n;
10363    for(p = vstack;p <= p1; p++) {
10364        r = p->r & VT_VALMASK;
10365        if (r < VT_CONST) {
10366            save_reg(r);
10367        }
10368    }
10369}
10370
10371/* move register 's' to 'r', and flush previous value of r to memory
10372   if needed */
10373void move_reg(int r, int s)
10374{
10375    SValue sv;
10376
10377    if (r != s) {
10378        save_reg(r);
10379        sv.type.t = VT_INT;
10380        sv.r = s;
10381        sv.c.ul = 0;
10382        load(r, &sv);
10383    }
10384}
10385
10386/* get address of vtop (vtop MUST BE an lvalue) */
10387void gaddrof(void)
10388{
10389    vtop->r &= ~VT_LVAL;
10390    /* tricky: if saved lvalue, then we can go back to lvalue */
10391    if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
10392        vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
10393}
10394
10395#ifdef CONFIG_TCC_BCHECK
10396/* generate lvalue bound code */
10397void gbound(void)
10398{
10399    int lval_type;
10400    CType type1;
10401
10402    vtop->r &= ~VT_MUSTBOUND;
10403    /* if lvalue, then use checking code before dereferencing */
10404    if (vtop->r & VT_LVAL) {
10405        /* if not VT_BOUNDED value, then make one */
10406        if (!(vtop->r & VT_BOUNDED)) {
10407            lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
10408            /* must save type because we must set it to int to get pointer */
10409            type1 = vtop->type;
10410            vtop->type.t = VT_INT;
10411            gaddrof();
10412            vpushi(0);
10413            gen_bounded_ptr_add();
10414            vtop->r |= lval_type;
10415            vtop->type = type1;
10416        }
10417        /* then check for dereferencing */
10418        gen_bounded_ptr_deref();
10419    }
10420}
10421#endif
10422
10423/* store vtop a register belonging to class 'rc'. lvalues are
10424   converted to values. Cannot be used if cannot be converted to
10425   register value (such as structures). */
10426int gv(int rc)
10427{
10428    int r, r2, rc2, bit_pos, bit_size, size, align, i;
10429    unsigned long long ll;
10430
10431    /* NOTE: get_reg can modify vstack[] */
10432    if (vtop->type.t & VT_BITFIELD) {
10433        bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
10434        bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
10435        /* remove bit field info to avoid loops */
10436        vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
10437        /* generate shifts */
10438        vpushi(32 - (bit_pos + bit_size));
10439        gen_op(TOK_SHL);
10440        vpushi(32 - bit_size);
10441        /* NOTE: transformed to SHR if unsigned */
10442        gen_op(TOK_SAR);
10443        r = gv(rc);
10444    } else {
10445        if (is_float(vtop->type.t) &&
10446            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10447            Sym *sym;
10448            int *ptr;
10449            unsigned long offset;
10450
10451            /* XXX: unify with initializers handling ? */
10452            /* CPUs usually cannot use float constants, so we store them
10453               generically in data segment */
10454            size = type_size(&vtop->type, &align);
10455            offset = (data_section->data_offset + align - 1) & -align;
10456            data_section->data_offset = offset;
10457            /* XXX: not portable yet */
10458            ptr = section_ptr_add(data_section, size);
10459            size = size >> 2;
10460            for(i=0;i<size;i++)
10461                ptr[i] = vtop->c.tab[i];
10462            sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
10463            vtop->r |= VT_LVAL | VT_SYM;
10464            vtop->sym = sym;
10465            vtop->c.ul = 0;
10466        }
10467#ifdef CONFIG_TCC_BCHECK
10468        if (vtop->r & VT_MUSTBOUND)
10469            gbound();
10470#endif
10471
10472        r = vtop->r & VT_VALMASK;
10473        /* need to reload if:
10474           - constant
10475           - lvalue (need to dereference pointer)
10476           - already a register, but not in the right class */
10477        if (r >= VT_CONST ||
10478            (vtop->r & VT_LVAL) ||
10479            !(reg_classes[r] & rc) ||
10480            ((vtop->type.t & VT_BTYPE) == VT_LLONG &&
10481             !(reg_classes[vtop->r2] & rc))) {
10482            r = get_reg(rc);
10483            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
10484                /* two register type load : expand to two words
10485                   temporarily */
10486                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
10487                    /* load constant */
10488                    ll = vtop->c.ull;
10489                    vtop->c.ui = ll; /* first word */
10490                    load(r, vtop);
10491                    vtop->r = r; /* save register value */
10492                    vpushi(ll >> 32); /* second word */
10493                } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
10494                           (vtop->r & VT_LVAL)) {
10495                    /* We do not want to modifier the long long
10496                       pointer here, so the safest (and less
10497                       efficient) is to save all the other registers
10498                       in the stack. XXX: totally inefficient. */
10499                    save_regs(1);
10500                    /* load from memory */
10501                    load(r, vtop);
10502                    vdup();
10503                    vtop[-1].r = r; /* save register value */
10504                    /* increment pointer to get second word */
10505                    vtop->type.t = VT_INT;
10506                    gaddrof();
10507                    vpushi(4);
10508                    gen_op('+');
10509                    vtop->r |= VT_LVAL;
10510                } else {
10511                    /* move registers */
10512                    load(r, vtop);
10513                    vdup();
10514                    vtop[-1].r = r; /* save register value */
10515                    vtop->r = vtop[-1].r2;
10516                }
10517                /* allocate second register */
10518                rc2 = RC_INT;
10519                if (rc == RC_IRET)
10520                    rc2 = RC_LRET;
10521                r2 = get_reg(rc2);
10522                load(r2, vtop);
10523                vpop();
10524                /* write second register */
10525                vtop->r2 = r2;
10526            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
10527                int t1, t;
10528                /* lvalue of scalar type : need to use lvalue type
10529                   because of possible cast */
10530                t = vtop->type.t;
10531                t1 = t;
10532                /* compute memory access type */
10533                if (vtop->r & VT_LVAL_BYTE)
10534                    t = VT_BYTE;
10535                else if (vtop->r & VT_LVAL_SHORT)
10536                    t = VT_SHORT;
10537                if (vtop->r & VT_LVAL_UNSIGNED)
10538                    t |= VT_UNSIGNED;
10539                vtop->type.t = t;
10540                load(r, vtop);
10541                /* restore wanted type */
10542                vtop->type.t = t1;
10543            } else {
10544                /* one register type load */
10545                load(r, vtop);
10546            }
10547        }
10548        vtop->r = r;
10549#ifdef TCC_TARGET_C67
10550        /* uses register pairs for doubles */
10551        if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
10552            vtop->r2 = r+1;
10553#endif
10554    }
10555    return r;
10556}
10557
10558/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
10559void gv2(int rc1, int rc2)
10560{
10561    int v;
10562
10563    /* generate more generic register first. But VT_JMP or VT_CMP
10564       values must be generated first in all cases to avoid possible
10565       reload errors */
10566    v = vtop[0].r & VT_VALMASK;
10567    if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
10568        vswap();
10569        gv(rc1);
10570        vswap();
10571        gv(rc2);
10572        /* test if reload is needed for first register */
10573        if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
10574            vswap();
10575            gv(rc1);
10576            vswap();
10577        }
10578    } else {
10579        gv(rc2);
10580        vswap();
10581        gv(rc1);
10582        vswap();
10583        /* test if reload is needed for first register */
10584        if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
10585            gv(rc2);
10586        }
10587    }
10588}
10589
10590/* expand long long on stack in two int registers */
10591void lexpand(void)
10592{
10593    int u;
10594
10595    u = vtop->type.t & VT_UNSIGNED;
10596    gv(RC_INT);
10597    vdup();
10598    vtop[0].r = vtop[-1].r2;
10599    vtop[0].r2 = VT_CONST;
10600    vtop[-1].r2 = VT_CONST;
10601    vtop[0].type.t = VT_INT | u;
10602    vtop[-1].type.t = VT_INT | u;
10603}
10604
10605#ifdef TCC_TARGET_ARM
10606/* expand long long on stack */
10607void lexpand_nr(void)
10608{
10609    int u,v;
10610
10611    u = vtop->type.t & VT_UNSIGNED;
10612    vdup();
10613    vtop->r2 = VT_CONST;
10614    vtop->type.t = VT_INT | u;
10615    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
10616    if (v == VT_CONST) {
10617      vtop[-1].c.ui = vtop->c.ull;
10618      vtop->c.ui = vtop->c.ull >> 32;
10619      vtop->r = VT_CONST;
10620    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
10621      vtop->c.ui += 4;
10622      vtop->r = vtop[-1].r;
10623    } else if (v > VT_CONST) {
10624      vtop--;
10625      lexpand();
10626    } else
10627      vtop->r = vtop[-1].r2;
10628    vtop[-1].r2 = VT_CONST;
10629    vtop[-1].type.t = VT_INT | u;
10630}
10631#endif
10632
10633/* build a long long from two ints */
10634void lbuild(int t)
10635{
10636    gv2(RC_INT, RC_INT);
10637    vtop[-1].r2 = vtop[0].r;
10638    vtop[-1].type.t = t;
10639    vpop();
10640}
10641
10642/* rotate n first stack elements to the bottom
10643   I1 ... In -> I2 ... In I1 [top is right]
10644*/
10645void vrotb(int n)
10646{
10647    int i;
10648    SValue tmp;
10649
10650    tmp = vtop[-n + 1];
10651    for(i=-n+1;i!=0;i++)
10652        vtop[i] = vtop[i+1];
10653    vtop[0] = tmp;
10654}
10655
10656/* rotate n first stack elements to the top
10657   I1 ... In -> In I1 ... I(n-1)  [top is right]
10658 */
10659void vrott(int n)
10660{
10661    int i;
10662    SValue tmp;
10663
10664    tmp = vtop[0];
10665    for(i = 0;i < n - 1; i++)
10666        vtop[-i] = vtop[-i - 1];
10667    vtop[-n + 1] = tmp;
10668}
10669
10670#ifdef TCC_TARGET_ARM
10671/* like vrott but in other direction
10672   In ... I1 -> I(n-1) ... I1 In  [top is right]
10673 */
10674void vnrott(int n)
10675{
10676    int i;
10677    SValue tmp;
10678
10679    tmp = vtop[-n + 1];
10680    for(i = n - 1; i > 0; i--)
10681        vtop[-i] = vtop[-i + 1];
10682    vtop[0] = tmp;
10683}
10684#endif
10685
10686/* pop stack value */
10687void vpop(void)
10688{
10689    int v;
10690    v = vtop->r & VT_VALMASK;
10691#ifdef TCC_TARGET_I386
10692    /* for x86, we need to pop the FP stack */
10693    if (v == TREG_ST0 && !nocode_wanted) {
10694        o(0xd9dd); /* fstp %st(1) */
10695    } else
10696#endif
10697    if (v == VT_JMP || v == VT_JMPI) {
10698        /* need to put correct jump if && or || without test */
10699        gsym(vtop->c.ul);
10700    }
10701    vtop--;
10702}
10703
10704/* convert stack entry to register and duplicate its value in another
10705   register */
10706void gv_dup(void)
10707{
10708    int rc, t, r, r1;
10709    SValue sv;
10710
10711    t = vtop->type.t;
10712    if ((t & VT_BTYPE) == VT_LLONG) {
10713        lexpand();
10714        gv_dup();
10715        vswap();
10716        vrotb(3);
10717        gv_dup();
10718        vrotb(4);
10719        /* stack: H L L1 H1 */
10720        lbuild(t);
10721        vrotb(3);
10722        vrotb(3);
10723        vswap();
10724        lbuild(t);
10725        vswap();
10726    } else {
10727        /* duplicate value */
10728        rc = RC_INT;
10729        sv.type.t = VT_INT;
10730        if (is_float(t)) {
10731            rc = RC_FLOAT;
10732            sv.type.t = t;
10733        }
10734        r = gv(rc);
10735        r1 = get_reg(rc);
10736        sv.r = r;
10737        sv.c.ul = 0;
10738        load(r1, &sv); /* move r to r1 */
10739        vdup();
10740        /* duplicates value */
10741        vtop->r = r1;
10742    }
10743}
10744
10745/* generate CPU independent (unsigned) long long operations */
10746void gen_opl(int op)
10747{
10748    int t, a, b, op1, c, i;
10749    int func;
10750    SValue tmp;
10751
10752    switch(op) {
10753    case '/':
10754    case TOK_PDIV:
10755        func = TOK___divdi3;
10756        goto gen_func;
10757    case TOK_UDIV:
10758        func = TOK___udivdi3;
10759        goto gen_func;
10760    case '%':
10761        func = TOK___moddi3;
10762        goto gen_func;
10763    case TOK_UMOD:
10764        func = TOK___umoddi3;
10765    gen_func:
10766        /* call generic long long function */
10767        vpush_global_sym(&func_old_type, func);
10768        vrott(3);
10769        gfunc_call(2);
10770        vpushi(0);
10771        vtop->r = REG_IRET;
10772        vtop->r2 = REG_LRET;
10773        break;
10774    case '^':
10775    case '&':
10776    case '|':
10777    case '*':
10778    case '+':
10779    case '-':
10780        t = vtop->type.t;
10781        vswap();
10782        lexpand();
10783        vrotb(3);
10784        lexpand();
10785        /* stack: L1 H1 L2 H2 */
10786        tmp = vtop[0];
10787        vtop[0] = vtop[-3];
10788        vtop[-3] = tmp;
10789        tmp = vtop[-2];
10790        vtop[-2] = vtop[-3];
10791        vtop[-3] = tmp;
10792        vswap();
10793        /* stack: H1 H2 L1 L2 */
10794        if (op == '*') {
10795            vpushv(vtop - 1);
10796            vpushv(vtop - 1);
10797            gen_op(TOK_UMULL);
10798            lexpand();
10799            /* stack: H1 H2 L1 L2 ML MH */
10800            for(i=0;i<4;i++)
10801                vrotb(6);
10802            /* stack: ML MH H1 H2 L1 L2 */
10803            tmp = vtop[0];
10804            vtop[0] = vtop[-2];
10805            vtop[-2] = tmp;
10806            /* stack: ML MH H1 L2 H2 L1 */
10807            gen_op('*');
10808            vrotb(3);
10809            vrotb(3);
10810            gen_op('*');
10811            /* stack: ML MH M1 M2 */
10812            gen_op('+');
10813            gen_op('+');
10814        } else if (op == '+' || op == '-') {
10815            /* XXX: add non carry method too (for MIPS or alpha) */
10816            if (op == '+')
10817                op1 = TOK_ADDC1;
10818            else
10819                op1 = TOK_SUBC1;
10820            gen_op(op1);
10821            /* stack: H1 H2 (L1 op L2) */
10822            vrotb(3);
10823            vrotb(3);
10824            gen_op(op1 + 1); /* TOK_xxxC2 */
10825        } else {
10826            gen_op(op);
10827            /* stack: H1 H2 (L1 op L2) */
10828            vrotb(3);
10829            vrotb(3);
10830            /* stack: (L1 op L2) H1 H2 */
10831            gen_op(op);
10832            /* stack: (L1 op L2) (H1 op H2) */
10833        }
10834        /* stack: L H */
10835        lbuild(t);
10836        break;
10837    case TOK_SAR:
10838    case TOK_SHR:
10839    case TOK_SHL:
10840        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
10841            t = vtop[-1].type.t;
10842            vswap();
10843            lexpand();
10844            vrotb(3);
10845            /* stack: L H shift */
10846            c = (int)vtop->c.i;
10847            /* constant: simpler */
10848            /* NOTE: all comments are for SHL. the other cases are
10849               done by swaping words */
10850            vpop();
10851            if (op != TOK_SHL)
10852                vswap();
10853            if (c >= 32) {
10854                /* stack: L H */
10855                vpop();
10856                if (c > 32) {
10857                    vpushi(c - 32);
10858                    gen_op(op);
10859                }
10860                if (op != TOK_SAR) {
10861                    vpushi(0);
10862                } else {
10863                    gv_dup();
10864                    vpushi(31);
10865                    gen_op(TOK_SAR);
10866                }
10867                vswap();
10868            } else {
10869                vswap();
10870                gv_dup();
10871                /* stack: H L L */
10872                vpushi(c);
10873                gen_op(op);
10874                vswap();
10875                vpushi(32 - c);
10876                if (op == TOK_SHL)
10877                    gen_op(TOK_SHR);
10878                else
10879                    gen_op(TOK_SHL);
10880                vrotb(3);
10881                /* stack: L L H */
10882                vpushi(c);
10883                if (op == TOK_SHL)
10884                    gen_op(TOK_SHL);
10885                else
10886                    gen_op(TOK_SHR);
10887                gen_op('|');
10888            }
10889            if (op != TOK_SHL)
10890                vswap();
10891            lbuild(t);
10892        } else {
10893            /* XXX: should provide a faster fallback on x86 ? */
10894            switch(op) {
10895            case TOK_SAR:
10896                func = TOK___sardi3;
10897                goto gen_func;
10898            case TOK_SHR:
10899                func = TOK___shrdi3;
10900                goto gen_func;
10901            case TOK_SHL:
10902                func = TOK___shldi3;
10903                goto gen_func;
10904            }
10905        }
10906        break;
10907    default:
10908        /* compare operations */
10909        t = vtop->type.t;
10910        vswap();
10911        lexpand();
10912        vrotb(3);
10913        lexpand();
10914        /* stack: L1 H1 L2 H2 */
10915        tmp = vtop[-1];
10916        vtop[-1] = vtop[-2];
10917        vtop[-2] = tmp;
10918        /* stack: L1 L2 H1 H2 */
10919        /* compare high */
10920        op1 = op;
10921        /* when values are equal, we need to compare low words. since
10922           the jump is inverted, we invert the test too. */
10923        if (op1 == TOK_LT)
10924            op1 = TOK_LE;
10925        else if (op1 == TOK_GT)
10926            op1 = TOK_GE;
10927        else if (op1 == TOK_ULT)
10928            op1 = TOK_ULE;
10929        else if (op1 == TOK_UGT)
10930            op1 = TOK_UGE;
10931        a = 0;
10932        b = 0;
10933        gen_op(op1);
10934        if (op1 != TOK_NE) {
10935            a = gtst(1, 0);
10936        }
10937        if (op != TOK_EQ) {
10938            /* generate non equal test */
10939            /* XXX: NOT PORTABLE yet */
10940            if (a == 0) {
10941                b = gtst(0, 0);
10942            } else {
10943#if defined(TCC_TARGET_I386)
10944                b = psym(0x850f, 0);
10945#elif defined(TCC_TARGET_ARM)
10946		b = ind;
10947		o(0x1A000000 | encbranch(ind, 0, 1));
10948#elif defined(TCC_TARGET_C67)
10949                error("not implemented");
10950#else
10951#error not supported
10952#endif
10953            }
10954        }
10955        /* compare low. Always unsigned */
10956        op1 = op;
10957        if (op1 == TOK_LT)
10958            op1 = TOK_ULT;
10959        else if (op1 == TOK_LE)
10960            op1 = TOK_ULE;
10961        else if (op1 == TOK_GT)
10962            op1 = TOK_UGT;
10963        else if (op1 == TOK_GE)
10964            op1 = TOK_UGE;
10965        gen_op(op1);
10966        a = gtst(1, a);
10967        gsym(b);
10968        vseti(VT_JMPI, a);
10969        break;
10970    }
10971}
10972
10973/* handle integer constant optimizations and various machine
10974   independent opt */
10975void gen_opic(int op)
10976{
10977    int fc, c1, c2, n;
10978    SValue *v1, *v2;
10979
10980    v1 = vtop - 1;
10981    v2 = vtop;
10982    /* currently, we cannot do computations with forward symbols */
10983    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10984    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
10985    if (c1 && c2) {
10986        fc = v2->c.i;
10987        switch(op) {
10988        case '+': v1->c.i += fc; break;
10989        case '-': v1->c.i -= fc; break;
10990        case '&': v1->c.i &= fc; break;
10991        case '^': v1->c.i ^= fc; break;
10992        case '|': v1->c.i |= fc; break;
10993        case '*': v1->c.i *= fc; break;
10994
10995        case TOK_PDIV:
10996        case '/':
10997        case '%':
10998        case TOK_UDIV:
10999        case TOK_UMOD:
11000            /* if division by zero, generate explicit division */
11001            if (fc == 0) {
11002                if (const_wanted)
11003                    error("division by zero in constant");
11004                goto general_case;
11005            }
11006            switch(op) {
11007            default: v1->c.i /= fc; break;
11008            case '%': v1->c.i %= fc; break;
11009            case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break;
11010            case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break;
11011            }
11012            break;
11013        case TOK_SHL: v1->c.i <<= fc; break;
11014        case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break;
11015        case TOK_SAR: v1->c.i >>= fc; break;
11016            /* tests */
11017        case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break;
11018        case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break;
11019        case TOK_EQ: v1->c.i = v1->c.i == fc; break;
11020        case TOK_NE: v1->c.i = v1->c.i != fc; break;
11021        case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break;
11022        case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break;
11023        case TOK_LT: v1->c.i = v1->c.i < fc; break;
11024        case TOK_GE: v1->c.i = v1->c.i >= fc; break;
11025        case TOK_LE: v1->c.i = v1->c.i <= fc; break;
11026        case TOK_GT: v1->c.i = v1->c.i > fc; break;
11027            /* logical */
11028        case TOK_LAND: v1->c.i = v1->c.i && fc; break;
11029        case TOK_LOR: v1->c.i = v1->c.i || fc; break;
11030        default:
11031            goto general_case;
11032        }
11033        vtop--;
11034    } else {
11035        /* if commutative ops, put c2 as constant */
11036        if (c1 && (op == '+' || op == '&' || op == '^' ||
11037                   op == '|' || op == '*')) {
11038            vswap();
11039            swap(&c1, &c2);
11040        }
11041        fc = vtop->c.i;
11042        if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
11043                     op == TOK_PDIV) &&
11044                    fc == 1) ||
11045                   ((op == '+' || op == '-' || op == '|' || op == '^' ||
11046                     op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
11047                    fc == 0) ||
11048                   (op == '&' &&
11049                    fc == -1))) {
11050            /* nothing to do */
11051            vtop--;
11052        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
11053            /* try to use shifts instead of muls or divs */
11054            if (fc > 0 && (fc & (fc - 1)) == 0) {
11055                n = -1;
11056                while (fc) {
11057                    fc >>= 1;
11058                    n++;
11059                }
11060                vtop->c.i = n;
11061                if (op == '*')
11062                    op = TOK_SHL;
11063                else if (op == TOK_PDIV)
11064                    op = TOK_SAR;
11065                else
11066                    op = TOK_SHR;
11067            }
11068            goto general_case;
11069        } else if (c2 && (op == '+' || op == '-') &&
11070                   (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
11071                   (VT_CONST | VT_SYM)) {
11072            /* symbol + constant case */
11073            if (op == '-')
11074                fc = -fc;
11075            vtop--;
11076            vtop->c.i += fc;
11077        } else {
11078        general_case:
11079            if (!nocode_wanted) {
11080                /* call low level op generator */
11081                gen_opi(op);
11082            } else {
11083                vtop--;
11084            }
11085        }
11086    }
11087}
11088
11089/* generate a floating point operation with constant propagation */
11090void gen_opif(int op)
11091{
11092    int c1, c2;
11093    SValue *v1, *v2;
11094    long double f1, f2;
11095
11096    v1 = vtop - 1;
11097    v2 = vtop;
11098    /* currently, we cannot do computations with forward symbols */
11099    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11100    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11101    if (c1 && c2) {
11102        if (v1->type.t == VT_FLOAT) {
11103            f1 = v1->c.f;
11104            f2 = v2->c.f;
11105        } else if (v1->type.t == VT_DOUBLE) {
11106            f1 = v1->c.d;
11107            f2 = v2->c.d;
11108        } else {
11109            f1 = v1->c.ld;
11110            f2 = v2->c.ld;
11111        }
11112
11113        /* NOTE: we only do constant propagation if finite number (not
11114           NaN or infinity) (ANSI spec) */
11115        if (!ieee_finite(f1) || !ieee_finite(f2))
11116            goto general_case;
11117
11118        switch(op) {
11119        case '+': f1 += f2; break;
11120        case '-': f1 -= f2; break;
11121        case '*': f1 *= f2; break;
11122        case '/':
11123            if (f2 == 0.0) {
11124                if (const_wanted)
11125                    error("division by zero in constant");
11126                goto general_case;
11127            }
11128            f1 /= f2;
11129            break;
11130            /* XXX: also handles tests ? */
11131        default:
11132            goto general_case;
11133        }
11134        /* XXX: overflow test ? */
11135        if (v1->type.t == VT_FLOAT) {
11136            v1->c.f = f1;
11137        } else if (v1->type.t == VT_DOUBLE) {
11138            v1->c.d = f1;
11139        } else {
11140            v1->c.ld = f1;
11141        }
11142        vtop--;
11143    } else {
11144    general_case:
11145        if (!nocode_wanted) {
11146            gen_opf(op);
11147        } else {
11148            vtop--;
11149        }
11150    }
11151}
11152
11153/* return the pointed type of t */
11154static inline CType *pointed_type(CType *type)
11155{
11156    return &type->ref->type;
11157}
11158
11159static int pointed_size(CType *type)
11160{
11161    int align;
11162    return type_size(pointed_type(type), &align);
11163}
11164
11165static inline int is_null_pointer(SValue *p)
11166{
11167    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
11168        return 0;
11169    return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
11170        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
11171}
11172
11173static inline int is_integer_btype(int bt)
11174{
11175    return (bt == VT_BYTE || bt == VT_SHORT ||
11176            bt == VT_INT || bt == VT_LLONG);
11177}
11178
11179/* check types for comparison or substraction of pointers */
11180static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
11181{
11182    CType *type1, *type2, tmp_type1, tmp_type2;
11183    int bt1, bt2;
11184
11185    /* null pointers are accepted for all comparisons as gcc */
11186    if (is_null_pointer(p1) || is_null_pointer(p2))
11187        return;
11188    type1 = &p1->type;
11189    type2 = &p2->type;
11190    bt1 = type1->t & VT_BTYPE;
11191    bt2 = type2->t & VT_BTYPE;
11192    /* accept comparison between pointer and integer with a warning */
11193    if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
11194        warning("comparison between pointer and integer");
11195        return;
11196    }
11197
11198    /* both must be pointers or implicit function pointers */
11199    if (bt1 == VT_PTR) {
11200        type1 = pointed_type(type1);
11201    } else if (bt1 != VT_FUNC)
11202        goto invalid_operands;
11203
11204    if (bt2 == VT_PTR) {
11205        type2 = pointed_type(type2);
11206    } else if (bt2 != VT_FUNC) {
11207    invalid_operands:
11208        error("invalid operands to binary %s", get_tok_str(op, NULL));
11209    }
11210    if ((type1->t & VT_BTYPE) == VT_VOID ||
11211        (type2->t & VT_BTYPE) == VT_VOID)
11212        return;
11213    tmp_type1 = *type1;
11214    tmp_type2 = *type2;
11215    tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11216    tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11217    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11218        /* gcc-like error if '-' is used */
11219        if (op == '-')
11220            goto invalid_operands;
11221        else
11222            warning("comparison of distinct pointer types lacks a cast");
11223    }
11224}
11225
11226/* generic gen_op: handles types problems */
11227void gen_op(int op)
11228{
11229    int u, t1, t2, bt1, bt2, t;
11230    CType type1;
11231
11232    t1 = vtop[-1].type.t;
11233    t2 = vtop[0].type.t;
11234    bt1 = t1 & VT_BTYPE;
11235    bt2 = t2 & VT_BTYPE;
11236
11237    if (bt1 == VT_PTR || bt2 == VT_PTR) {
11238        /* at least one operand is a pointer */
11239        /* relationnal op: must be both pointers */
11240        if (op >= TOK_ULT && op <= TOK_GT) {
11241            check_comparison_pointer_types(vtop - 1, vtop, op);
11242            /* pointers are handled are unsigned */
11243            t = VT_INT | VT_UNSIGNED;
11244            goto std_op;
11245        }
11246        /* if both pointers, then it must be the '-' op */
11247        if (bt1 == VT_PTR && bt2 == VT_PTR) {
11248            if (op != '-')
11249                error("cannot use pointers here");
11250            check_comparison_pointer_types(vtop - 1, vtop, op);
11251            /* XXX: check that types are compatible */
11252            u = pointed_size(&vtop[-1].type);
11253            gen_opic(op);
11254            /* set to integer type */
11255            vtop->type.t = VT_INT;
11256            vpushi(u);
11257            gen_op(TOK_PDIV);
11258        } else {
11259            /* exactly one pointer : must be '+' or '-'. */
11260            if (op != '-' && op != '+')
11261                error("cannot use pointers here");
11262            /* Put pointer as first operand */
11263            if (bt2 == VT_PTR) {
11264                vswap();
11265                swap(&t1, &t2);
11266            }
11267            type1 = vtop[-1].type;
11268            /* XXX: cast to int ? (long long case) */
11269            vpushi(pointed_size(&vtop[-1].type));
11270            gen_op('*');
11271#ifdef CONFIG_TCC_BCHECK
11272            /* if evaluating constant expression, no code should be
11273               generated, so no bound check */
11274            if (do_bounds_check && !const_wanted) {
11275                /* if bounded pointers, we generate a special code to
11276                   test bounds */
11277                if (op == '-') {
11278                    vpushi(0);
11279                    vswap();
11280                    gen_op('-');
11281                }
11282                gen_bounded_ptr_add();
11283            } else
11284#endif
11285            {
11286                gen_opic(op);
11287            }
11288            /* put again type if gen_opic() swaped operands */
11289            vtop->type = type1;
11290        }
11291    } else if (is_float(bt1) || is_float(bt2)) {
11292        /* compute bigger type and do implicit casts */
11293        if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
11294            t = VT_LDOUBLE;
11295        } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
11296            t = VT_DOUBLE;
11297        } else {
11298            t = VT_FLOAT;
11299        }
11300        /* floats can only be used for a few operations */
11301        if (op != '+' && op != '-' && op != '*' && op != '/' &&
11302            (op < TOK_ULT || op > TOK_GT))
11303            error("invalid operands for binary operation");
11304        goto std_op;
11305    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
11306        /* cast to biggest op */
11307        t = VT_LLONG;
11308        /* convert to unsigned if it does not fit in a long long */
11309        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
11310            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
11311            t |= VT_UNSIGNED;
11312        goto std_op;
11313    } else {
11314        /* integer operations */
11315        t = VT_INT;
11316        /* convert to unsigned if it does not fit in an integer */
11317        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
11318            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
11319            t |= VT_UNSIGNED;
11320    std_op:
11321        /* XXX: currently, some unsigned operations are explicit, so
11322           we modify them here */
11323        if (t & VT_UNSIGNED) {
11324            if (op == TOK_SAR)
11325                op = TOK_SHR;
11326            else if (op == '/')
11327                op = TOK_UDIV;
11328            else if (op == '%')
11329                op = TOK_UMOD;
11330            else if (op == TOK_LT)
11331                op = TOK_ULT;
11332            else if (op == TOK_GT)
11333                op = TOK_UGT;
11334            else if (op == TOK_LE)
11335                op = TOK_ULE;
11336            else if (op == TOK_GE)
11337                op = TOK_UGE;
11338        }
11339        vswap();
11340        type1.t = t;
11341        gen_cast(&type1);
11342        vswap();
11343        /* special case for shifts and long long: we keep the shift as
11344           an integer */
11345        if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
11346            type1.t = VT_INT;
11347        gen_cast(&type1);
11348        if (is_float(t))
11349            gen_opif(op);
11350        else if ((t & VT_BTYPE) == VT_LLONG)
11351            gen_opl(op);
11352        else
11353            gen_opic(op);
11354        if (op >= TOK_ULT && op <= TOK_GT) {
11355            /* relationnal op: the result is an int */
11356            vtop->type.t = VT_INT;
11357        } else {
11358            vtop->type.t = t;
11359        }
11360    }
11361}
11362
11363/* generic itof for unsigned long long case */
11364void gen_cvt_itof1(int t)
11365{
11366    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
11367        (VT_LLONG | VT_UNSIGNED)) {
11368
11369        if (t == VT_FLOAT)
11370            vpush_global_sym(&func_old_type, TOK___ulltof);
11371        else if (t == VT_DOUBLE)
11372            vpush_global_sym(&func_old_type, TOK___ulltod);
11373        else
11374            vpush_global_sym(&func_old_type, TOK___ulltold);
11375        vrott(2);
11376        gfunc_call(1);
11377        vpushi(0);
11378        vtop->r = REG_FRET;
11379    } else {
11380        gen_cvt_itof(t);
11381    }
11382}
11383
11384/* generic ftoi for unsigned long long case */
11385void gen_cvt_ftoi1(int t)
11386{
11387    int st;
11388
11389    if (t == (VT_LLONG | VT_UNSIGNED)) {
11390        /* not handled natively */
11391        st = vtop->type.t & VT_BTYPE;
11392        if (st == VT_FLOAT)
11393            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
11394        else if (st == VT_DOUBLE)
11395            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
11396        else
11397            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
11398        vrott(2);
11399        gfunc_call(1);
11400        vpushi(0);
11401        vtop->r = REG_IRET;
11402        vtop->r2 = REG_LRET;
11403    } else {
11404        gen_cvt_ftoi(t);
11405    }
11406}
11407
11408/* force char or short cast */
11409void force_charshort_cast(int t)
11410{
11411    int bits, dbt;
11412    dbt = t & VT_BTYPE;
11413    /* XXX: add optimization if lvalue : just change type and offset */
11414    if (dbt == VT_BYTE)
11415        bits = 8;
11416    else
11417        bits = 16;
11418    if (t & VT_UNSIGNED) {
11419        vpushi((1 << bits) - 1);
11420        gen_op('&');
11421    } else {
11422        bits = 32 - bits;
11423        vpushi(bits);
11424        gen_op(TOK_SHL);
11425        vpushi(bits);
11426        gen_op(TOK_SAR);
11427    }
11428}
11429
11430/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
11431static void gen_cast(CType *type)
11432{
11433    int sbt, dbt, sf, df, c;
11434
11435    /* special delayed cast for char/short */
11436    /* XXX: in some cases (multiple cascaded casts), it may still
11437       be incorrect */
11438    if (vtop->r & VT_MUSTCAST) {
11439        vtop->r &= ~VT_MUSTCAST;
11440        force_charshort_cast(vtop->type.t);
11441    }
11442
11443    /* bitfields first get cast to ints */
11444    if (vtop->type.t & VT_BITFIELD) {
11445        gv(RC_INT);
11446    }
11447
11448    dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
11449    sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
11450
11451    if (sbt != dbt && !nocode_wanted) {
11452        sf = is_float(sbt);
11453        df = is_float(dbt);
11454        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
11455        if (sf && df) {
11456            /* convert from fp to fp */
11457            if (c) {
11458                /* constant case: we can do it now */
11459                /* XXX: in ISOC, cannot do it if error in convert */
11460                if (dbt == VT_FLOAT && sbt == VT_DOUBLE)
11461                    vtop->c.f = (float)vtop->c.d;
11462                else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE)
11463                    vtop->c.f = (float)vtop->c.ld;
11464                else if (dbt == VT_DOUBLE && sbt == VT_FLOAT)
11465                    vtop->c.d = (double)vtop->c.f;
11466                else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE)
11467                    vtop->c.d = (double)vtop->c.ld;
11468                else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT)
11469                    vtop->c.ld = (long double)vtop->c.f;
11470                else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE)
11471                    vtop->c.ld = (long double)vtop->c.d;
11472            } else {
11473                /* non constant case: generate code */
11474                gen_cvt_ftof(dbt);
11475            }
11476        } else if (df) {
11477            /* convert int to fp */
11478            if (c) {
11479                switch(sbt) {
11480                case VT_LLONG | VT_UNSIGNED:
11481                case VT_LLONG:
11482                    /* XXX: add const cases for long long */
11483                    goto do_itof;
11484                case VT_INT | VT_UNSIGNED:
11485                    switch(dbt) {
11486                    case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break;
11487                    case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break;
11488                    case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break;
11489                    }
11490                    break;
11491                default:
11492                    switch(dbt) {
11493                    case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break;
11494                    case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break;
11495                    case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break;
11496                    }
11497                    break;
11498                }
11499            } else {
11500            do_itof:
11501#if !defined(TCC_TARGET_ARM)
11502                gen_cvt_itof1(dbt);
11503#else
11504                gen_cvt_itof(dbt);
11505#endif
11506            }
11507        } else if (sf) {
11508            /* convert fp to int */
11509            /* we handle char/short/etc... with generic code */
11510            if (dbt != (VT_INT | VT_UNSIGNED) &&
11511                dbt != (VT_LLONG | VT_UNSIGNED) &&
11512                dbt != VT_LLONG)
11513                dbt = VT_INT;
11514            if (c) {
11515                switch(dbt) {
11516                case VT_LLONG | VT_UNSIGNED:
11517                case VT_LLONG:
11518                    /* XXX: add const cases for long long */
11519                    goto do_ftoi;
11520                case VT_INT | VT_UNSIGNED:
11521                    switch(sbt) {
11522                    case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break;
11523                    case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11524                    case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break;
11525                    }
11526                    break;
11527                default:
11528                    /* int case */
11529                    switch(sbt) {
11530                    case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break;
11531                    case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break;
11532                    case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break;
11533                    }
11534                    break;
11535                }
11536            } else {
11537            do_ftoi:
11538                gen_cvt_ftoi1(dbt);
11539            }
11540            if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
11541                /* additional cast for char/short/bool... */
11542                vtop->type.t = dbt;
11543                gen_cast(type);
11544            }
11545        } else if ((dbt & VT_BTYPE) == VT_LLONG) {
11546            if ((sbt & VT_BTYPE) != VT_LLONG) {
11547                /* scalar to long long */
11548                if (c) {
11549                    if (sbt == (VT_INT | VT_UNSIGNED))
11550                        vtop->c.ll = vtop->c.ui;
11551                    else
11552                        vtop->c.ll = vtop->c.i;
11553                } else {
11554                    /* machine independent conversion */
11555                    gv(RC_INT);
11556                    /* generate high word */
11557                    if (sbt == (VT_INT | VT_UNSIGNED)) {
11558                        vpushi(0);
11559                        gv(RC_INT);
11560                    } else {
11561                        gv_dup();
11562                        vpushi(31);
11563                        gen_op(TOK_SAR);
11564                    }
11565                    /* patch second register */
11566                    vtop[-1].r2 = vtop->r;
11567                    vpop();
11568                }
11569            }
11570        } else if (dbt == VT_BOOL) {
11571            /* scalar to bool */
11572            vpushi(0);
11573            gen_op(TOK_NE);
11574        } else if ((dbt & VT_BTYPE) == VT_BYTE ||
11575                   (dbt & VT_BTYPE) == VT_SHORT) {
11576            force_charshort_cast(dbt);
11577        } else if ((dbt & VT_BTYPE) == VT_INT) {
11578            /* scalar to int */
11579            if (sbt == VT_LLONG) {
11580                /* from long long: just take low order word */
11581                lexpand();
11582                vpop();
11583            }
11584            /* if lvalue and single word type, nothing to do because
11585               the lvalue already contains the real type size (see
11586               VT_LVAL_xxx constants) */
11587        }
11588    }
11589    vtop->type = *type;
11590}
11591
11592/* return type size. Put alignment at 'a' */
11593static int type_size(CType *type, int *a)
11594{
11595    Sym *s;
11596    int bt;
11597
11598    bt = type->t & VT_BTYPE;
11599    if (bt == VT_STRUCT) {
11600        /* struct/union */
11601        s = type->ref;
11602        *a = s->r;
11603        return s->c;
11604    } else if (bt == VT_PTR) {
11605        if (type->t & VT_ARRAY) {
11606            s = type->ref;
11607            return type_size(&s->type, a) * s->c;
11608        } else {
11609            *a = PTR_SIZE;
11610            return PTR_SIZE;
11611        }
11612    } else if (bt == VT_LDOUBLE) {
11613        *a = LDOUBLE_ALIGN;
11614        return LDOUBLE_SIZE;
11615    } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
11616#ifdef TCC_TARGET_I386
11617        *a = 4;
11618#else
11619        *a = 8;
11620#endif
11621        return 8;
11622    } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
11623        *a = 4;
11624        return 4;
11625    } else if (bt == VT_SHORT) {
11626        *a = 2;
11627        return 2;
11628    } else {
11629        /* char, void, function, _Bool */
11630        *a = 1;
11631        return 1;
11632    }
11633}
11634
11635/* modify type so that its it is a pointer to type. */
11636static void mk_pointer(CType *type)
11637{
11638    Sym *s;
11639    s = sym_push(SYM_FIELD, type, 0, -1);
11640    type->t = VT_PTR | (type->t & ~VT_TYPE);
11641    type->ref = s;
11642}
11643
11644/* compare function types. OLD functions match any new functions */
11645static int is_compatible_func(CType *type1, CType *type2)
11646{
11647    Sym *s1, *s2;
11648
11649    s1 = type1->ref;
11650    s2 = type2->ref;
11651    if (!is_compatible_types(&s1->type, &s2->type))
11652        return 0;
11653    /* check func_call */
11654    if (s1->r != s2->r)
11655        return 0;
11656    /* XXX: not complete */
11657    if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
11658        return 1;
11659    if (s1->c != s2->c)
11660        return 0;
11661    while (s1 != NULL) {
11662        if (s2 == NULL)
11663            return 0;
11664        if (!is_compatible_types(&s1->type, &s2->type))
11665            return 0;
11666        s1 = s1->next;
11667        s2 = s2->next;
11668    }
11669    if (s2)
11670        return 0;
11671    return 1;
11672}
11673
11674/* return true if type1 and type2 are exactly the same (including
11675   qualifiers).
11676
11677   - enums are not checked as gcc __builtin_types_compatible_p ()
11678 */
11679static int is_compatible_types(CType *type1, CType *type2)
11680{
11681    int bt1, t1, t2;
11682
11683    t1 = type1->t & VT_TYPE;
11684    t2 = type2->t & VT_TYPE;
11685    /* XXX: bitfields ? */
11686    if (t1 != t2)
11687        return 0;
11688    /* test more complicated cases */
11689    bt1 = t1 & VT_BTYPE;
11690    if (bt1 == VT_PTR) {
11691        type1 = pointed_type(type1);
11692        type2 = pointed_type(type2);
11693        return is_compatible_types(type1, type2);
11694    } else if (bt1 == VT_STRUCT) {
11695        return (type1->ref == type2->ref);
11696    } else if (bt1 == VT_FUNC) {
11697        return is_compatible_func(type1, type2);
11698    } else {
11699        return 1;
11700    }
11701}
11702
11703/* print a type. If 'varstr' is not NULL, then the variable is also
11704   printed in the type */
11705/* XXX: union */
11706/* XXX: add array and function pointers */
11707void type_to_str(char *buf, int buf_size,
11708                 CType *type, const char *varstr)
11709{
11710    int bt, v, t;
11711    Sym *s, *sa;
11712    char buf1[256];
11713    const char *tstr;
11714
11715    t = type->t & VT_TYPE;
11716    bt = t & VT_BTYPE;
11717    buf[0] = '\0';
11718    if (t & VT_CONSTANT)
11719        pstrcat(buf, buf_size, "const ");
11720    if (t & VT_VOLATILE)
11721        pstrcat(buf, buf_size, "volatile ");
11722    if (t & VT_UNSIGNED)
11723        pstrcat(buf, buf_size, "unsigned ");
11724    switch(bt) {
11725    case VT_VOID:
11726        tstr = "void";
11727        goto add_tstr;
11728    case VT_BOOL:
11729        tstr = "_Bool";
11730        goto add_tstr;
11731    case VT_BYTE:
11732        tstr = "char";
11733        goto add_tstr;
11734    case VT_SHORT:
11735        tstr = "short";
11736        goto add_tstr;
11737    case VT_INT:
11738        tstr = "int";
11739        goto add_tstr;
11740    case VT_LONG:
11741        tstr = "long";
11742        goto add_tstr;
11743    case VT_LLONG:
11744        tstr = "long long";
11745        goto add_tstr;
11746    case VT_FLOAT:
11747        tstr = "float";
11748        goto add_tstr;
11749    case VT_DOUBLE:
11750        tstr = "double";
11751        goto add_tstr;
11752    case VT_LDOUBLE:
11753        tstr = "long double";
11754    add_tstr:
11755        pstrcat(buf, buf_size, tstr);
11756        break;
11757    case VT_ENUM:
11758    case VT_STRUCT:
11759        if (bt == VT_STRUCT)
11760            tstr = "struct ";
11761        else
11762            tstr = "enum ";
11763        pstrcat(buf, buf_size, tstr);
11764        v = type->ref->v & ~SYM_STRUCT;
11765        if (v >= SYM_FIRST_ANOM)
11766            pstrcat(buf, buf_size, "<anonymous>");
11767        else
11768            pstrcat(buf, buf_size, get_tok_str(v, NULL));
11769        break;
11770    case VT_FUNC:
11771        s = type->ref;
11772        type_to_str(buf, buf_size, &s->type, varstr);
11773        pstrcat(buf, buf_size, "(");
11774        sa = s->next;
11775        while (sa != NULL) {
11776            type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
11777            pstrcat(buf, buf_size, buf1);
11778            sa = sa->next;
11779            if (sa)
11780                pstrcat(buf, buf_size, ", ");
11781        }
11782        pstrcat(buf, buf_size, ")");
11783        goto no_var;
11784    case VT_PTR:
11785        s = type->ref;
11786        pstrcpy(buf1, sizeof(buf1), "*");
11787        if (varstr)
11788            pstrcat(buf1, sizeof(buf1), varstr);
11789        type_to_str(buf, buf_size, &s->type, buf1);
11790        goto no_var;
11791    }
11792    if (varstr) {
11793        pstrcat(buf, buf_size, " ");
11794        pstrcat(buf, buf_size, varstr);
11795    }
11796 no_var: ;
11797}
11798
11799/* verify type compatibility to store vtop in 'dt' type, and generate
11800   casts if needed. */
11801static void gen_assign_cast(CType *dt)
11802{
11803    CType *st, *type1, *type2, tmp_type1, tmp_type2;
11804    char buf1[256], buf2[256];
11805    int dbt, sbt;
11806
11807    st = &vtop->type; /* source type */
11808    dbt = dt->t & VT_BTYPE;
11809    sbt = st->t & VT_BTYPE;
11810    if (dt->t & VT_CONSTANT)
11811        warning("assignment of read-only location");
11812    switch(dbt) {
11813    case VT_PTR:
11814        /* special cases for pointers */
11815        /* '0' can also be a pointer */
11816        if (is_null_pointer(vtop))
11817            goto type_ok;
11818        /* accept implicit pointer to integer cast with warning */
11819        if (is_integer_btype(sbt)) {
11820            warning("assignment makes pointer from integer without a cast");
11821            goto type_ok;
11822        }
11823        type1 = pointed_type(dt);
11824        /* a function is implicitely a function pointer */
11825        if (sbt == VT_FUNC) {
11826            if ((type1->t & VT_BTYPE) != VT_VOID &&
11827                !is_compatible_types(pointed_type(dt), st))
11828                goto error;
11829            else
11830                goto type_ok;
11831        }
11832        if (sbt != VT_PTR)
11833            goto error;
11834        type2 = pointed_type(st);
11835        if ((type1->t & VT_BTYPE) == VT_VOID ||
11836            (type2->t & VT_BTYPE) == VT_VOID) {
11837            /* void * can match anything */
11838        } else {
11839            /* exact type match, except for unsigned */
11840            tmp_type1 = *type1;
11841            tmp_type2 = *type2;
11842            tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11843            tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
11844            if (!is_compatible_types(&tmp_type1, &tmp_type2))
11845                goto error;
11846        }
11847        /* check const and volatile */
11848        if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
11849            (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
11850            warning("assignment discards qualifiers from pointer target type");
11851        break;
11852    case VT_BYTE:
11853    case VT_SHORT:
11854    case VT_INT:
11855    case VT_LLONG:
11856        if (sbt == VT_PTR || sbt == VT_FUNC) {
11857            warning("assignment makes integer from pointer without a cast");
11858        }
11859        /* XXX: more tests */
11860        break;
11861    case VT_STRUCT:
11862        tmp_type1 = *dt;
11863        tmp_type2 = *st;
11864        tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
11865        tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
11866        if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
11867        error:
11868            type_to_str(buf1, sizeof(buf1), st, NULL);
11869            type_to_str(buf2, sizeof(buf2), dt, NULL);
11870            error("cannot cast '%s' to '%s'", buf1, buf2);
11871        }
11872        break;
11873    }
11874 type_ok:
11875    gen_cast(dt);
11876}
11877
11878/* store vtop in lvalue pushed on stack */
11879void vstore(void)
11880{
11881    int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
11882
11883    ft = vtop[-1].type.t;
11884    sbt = vtop->type.t & VT_BTYPE;
11885    dbt = ft & VT_BTYPE;
11886    if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
11887        (sbt == VT_INT && dbt == VT_SHORT)) {
11888        /* optimize char/short casts */
11889        delayed_cast = VT_MUSTCAST;
11890        vtop->type.t = ft & VT_TYPE;
11891        /* XXX: factorize */
11892        if (ft & VT_CONSTANT)
11893            warning("assignment of read-only location");
11894    } else {
11895        delayed_cast = 0;
11896        if (!(ft & VT_BITFIELD))
11897            gen_assign_cast(&vtop[-1].type);
11898    }
11899
11900    if (sbt == VT_STRUCT) {
11901        /* if structure, only generate pointer */
11902        /* structure assignment : generate memcpy */
11903        /* XXX: optimize if small size */
11904        if (!nocode_wanted) {
11905            size = type_size(&vtop->type, &align);
11906
11907            vpush_global_sym(&func_old_type, TOK_memcpy);
11908
11909            /* destination */
11910            vpushv(vtop - 2);
11911            vtop->type.t = VT_INT;
11912            gaddrof();
11913            /* source */
11914            vpushv(vtop - 2);
11915            vtop->type.t = VT_INT;
11916            gaddrof();
11917            /* type size */
11918            vpushi(size);
11919            gfunc_call(3);
11920
11921            vswap();
11922            vpop();
11923        } else {
11924            vswap();
11925            vpop();
11926        }
11927        /* leave source on stack */
11928    } else if (ft & VT_BITFIELD) {
11929        /* bitfield store handling */
11930        bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
11931        bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
11932        /* remove bit field info to avoid loops */
11933        vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
11934
11935        /* duplicate destination */
11936        vdup();
11937        vtop[-1] = vtop[-2];
11938
11939        /* mask and shift source */
11940        vpushi((1 << bit_size) - 1);
11941        gen_op('&');
11942        vpushi(bit_pos);
11943        gen_op(TOK_SHL);
11944        /* load destination, mask and or with source */
11945        vswap();
11946        vpushi(~(((1 << bit_size) - 1) << bit_pos));
11947        gen_op('&');
11948        gen_op('|');
11949        /* store result */
11950        vstore();
11951    } else {
11952#ifdef CONFIG_TCC_BCHECK
11953        /* bound check case */
11954        if (vtop[-1].r & VT_MUSTBOUND) {
11955            vswap();
11956            gbound();
11957            vswap();
11958        }
11959#endif
11960        if (!nocode_wanted) {
11961            rc = RC_INT;
11962            if (is_float(ft))
11963                rc = RC_FLOAT;
11964            r = gv(rc);  /* generate value */
11965            /* if lvalue was saved on stack, must read it */
11966            if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
11967                SValue sv;
11968                t = get_reg(RC_INT);
11969                sv.type.t = VT_INT;
11970                sv.r = VT_LOCAL | VT_LVAL;
11971                sv.c.ul = vtop[-1].c.ul;
11972                load(t, &sv);
11973                vtop[-1].r = t | VT_LVAL;
11974            }
11975            store(r, vtop - 1);
11976            /* two word case handling : store second register at word + 4 */
11977            if ((ft & VT_BTYPE) == VT_LLONG) {
11978                vswap();
11979                /* convert to int to increment easily */
11980                vtop->type.t = VT_INT;
11981                gaddrof();
11982                vpushi(4);
11983                gen_op('+');
11984                vtop->r |= VT_LVAL;
11985                vswap();
11986                /* XXX: it works because r2 is spilled last ! */
11987                store(vtop->r2, vtop - 1);
11988            }
11989        }
11990        vswap();
11991        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
11992        vtop->r |= delayed_cast;
11993    }
11994}
11995
11996/* post defines POST/PRE add. c is the token ++ or -- */
11997void inc(int post, int c)
11998{
11999    test_lvalue();
12000    vdup(); /* save lvalue */
12001    if (post) {
12002        gv_dup(); /* duplicate value */
12003        vrotb(3);
12004        vrotb(3);
12005    }
12006    /* add constant */
12007    vpushi(c - TOK_MID);
12008    gen_op('+');
12009    vstore(); /* store value */
12010    if (post)
12011        vpop(); /* if post op, return saved value */
12012}
12013
12014/* Parse GNUC __attribute__ extension. Currently, the following
12015   extensions are recognized:
12016   - aligned(n) : set data/function alignment.
12017   - packed : force data alignment to 1
12018   - section(x) : generate data/code in this section.
12019   - unused : currently ignored, but may be used someday.
12020   - regparm(n) : pass function parameters in registers (i386 only)
12021 */
12022static void parse_attribute(AttributeDef *ad)
12023{
12024    int t, n;
12025
12026    while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
12027    next();
12028    skip('(');
12029    skip('(');
12030    while (tok != ')') {
12031        if (tok < TOK_IDENT)
12032            expect("attribute name");
12033        t = tok;
12034        next();
12035        switch(t) {
12036        case TOK_SECTION1:
12037        case TOK_SECTION2:
12038            skip('(');
12039            if (tok != TOK_STR)
12040                expect("section name");
12041            ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
12042            next();
12043            skip(')');
12044            break;
12045        case TOK_ALIGNED1:
12046        case TOK_ALIGNED2:
12047            if (tok == '(') {
12048                next();
12049                n = expr_const();
12050                if (n <= 0 || (n & (n - 1)) != 0)
12051                    error("alignment must be a positive power of two");
12052                skip(')');
12053            } else {
12054                n = MAX_ALIGN;
12055            }
12056            ad->aligned = n;
12057            break;
12058        case TOK_PACKED1:
12059        case TOK_PACKED2:
12060            ad->packed = 1;
12061            break;
12062        case TOK_UNUSED1:
12063        case TOK_UNUSED2:
12064            /* currently, no need to handle it because tcc does not
12065               track unused objects */
12066            break;
12067        case TOK_NORETURN1:
12068        case TOK_NORETURN2:
12069            /* currently, no need to handle it because tcc does not
12070               track unused objects */
12071            break;
12072        case TOK_CDECL1:
12073        case TOK_CDECL2:
12074        case TOK_CDECL3:
12075            ad->func_call = FUNC_CDECL;
12076            break;
12077        case TOK_STDCALL1:
12078        case TOK_STDCALL2:
12079        case TOK_STDCALL3:
12080            ad->func_call = FUNC_STDCALL;
12081            break;
12082#ifdef TCC_TARGET_I386
12083        case TOK_REGPARM1:
12084        case TOK_REGPARM2:
12085            skip('(');
12086            n = expr_const();
12087            if (n > 3)
12088                n = 3;
12089            else if (n < 0)
12090                n = 0;
12091            if (n > 0)
12092                ad->func_call = FUNC_FASTCALL1 + n - 1;
12093            skip(')');
12094            break;
12095#endif
12096        case TOK_DLLEXPORT:
12097            ad->dllexport = 1;
12098            break;
12099        default:
12100            if (tcc_state->warn_unsupported)
12101                warning("'%s' attribute ignored", get_tok_str(t, NULL));
12102            /* skip parameters */
12103            /* XXX: skip parenthesis too */
12104            if (tok == '(') {
12105                next();
12106                while (tok != ')' && tok != -1)
12107                    next();
12108                next();
12109            }
12110            break;
12111        }
12112        if (tok != ',')
12113            break;
12114        next();
12115    }
12116    skip(')');
12117    skip(')');
12118    }
12119}
12120
12121/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
12122static void struct_decl(CType *type, int u)
12123{
12124    int a, v, size, align, maxalign, c, offset;
12125    int bit_size, bit_pos, bsize, bt, lbit_pos;
12126    Sym *s, *ss, **ps;
12127    AttributeDef ad;
12128    CType type1, btype;
12129
12130    a = tok; /* save decl type */
12131    next();
12132    if (tok != '{') {
12133        v = tok;
12134        next();
12135        /* struct already defined ? return it */
12136        if (v < TOK_IDENT)
12137            expect("struct/union/enum name");
12138        s = struct_find(v);
12139        if (s) {
12140            if (s->type.t != a)
12141                error("invalid type");
12142            goto do_decl;
12143        }
12144    } else {
12145        v = anon_sym++;
12146    }
12147    type1.t = a;
12148    /* we put an undefined size for struct/union */
12149    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
12150    s->r = 0; /* default alignment is zero as gcc */
12151    /* put struct/union/enum name in type */
12152 do_decl:
12153    type->t = u;
12154    type->ref = s;
12155
12156    if (tok == '{') {
12157        next();
12158        if (s->c != -1)
12159            error("struct/union/enum already defined");
12160        /* cannot be empty */
12161        c = 0;
12162        /* non empty enums are not allowed */
12163        if (a == TOK_ENUM) {
12164            for(;;) {
12165                v = tok;
12166                if (v < TOK_UIDENT)
12167                    expect("identifier");
12168                next();
12169                if (tok == '=') {
12170                    next();
12171                    c = expr_const();
12172                }
12173                /* enum symbols have static storage */
12174                ss = sym_push(v, &int_type, VT_CONST, c);
12175                ss->type.t |= VT_STATIC;
12176                if (tok != ',')
12177                    break;
12178                next();
12179                c++;
12180                /* NOTE: we accept a trailing comma */
12181                if (tok == '}')
12182                    break;
12183            }
12184            skip('}');
12185        } else {
12186            maxalign = 1;
12187            ps = &s->next;
12188            bit_pos = 0;
12189            offset = 0;
12190            while (tok != '}') {
12191                parse_btype(&btype, &ad);
12192                while (1) {
12193                    bit_size = -1;
12194                    v = 0;
12195                    type1 = btype;
12196                    if (tok != ':') {
12197                        type_decl(&type1, &ad, &v, TYPE_DIRECT);
12198                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
12199                            (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
12200                            error("invalid type for '%s'",
12201                                  get_tok_str(v, NULL));
12202                    }
12203                    if (tok == ':') {
12204                        next();
12205                        bit_size = expr_const();
12206                        /* XXX: handle v = 0 case for messages */
12207                        if (bit_size < 0)
12208                            error("negative width in bit-field '%s'",
12209                                  get_tok_str(v, NULL));
12210                        if (v && bit_size == 0)
12211                            error("zero width for bit-field '%s'",
12212                                  get_tok_str(v, NULL));
12213                    }
12214                    size = type_size(&type1, &align);
12215                    if (ad.aligned) {
12216                        if (align < ad.aligned)
12217                            align = ad.aligned;
12218                    } else if (ad.packed) {
12219                        align = 1;
12220                    } else if (*tcc_state->pack_stack_ptr) {
12221                        if (align > *tcc_state->pack_stack_ptr)
12222                            align = *tcc_state->pack_stack_ptr;
12223                    }
12224                    lbit_pos = 0;
12225                    if (bit_size >= 0) {
12226                        bt = type1.t & VT_BTYPE;
12227                        if (bt != VT_INT &&
12228                            bt != VT_BYTE &&
12229                            bt != VT_SHORT &&
12230                            bt != VT_BOOL &&
12231                            bt != VT_ENUM)
12232                            error("bitfields must have scalar type");
12233                        bsize = size * 8;
12234                        if (bit_size > bsize) {
12235                            error("width of '%s' exceeds its type",
12236                                  get_tok_str(v, NULL));
12237                        } else if (bit_size == bsize) {
12238                            /* no need for bit fields */
12239                            bit_pos = 0;
12240                        } else if (bit_size == 0) {
12241                            /* XXX: what to do if only padding in a
12242                               structure ? */
12243                            /* zero size: means to pad */
12244                            if (bit_pos > 0)
12245                                bit_pos = bsize;
12246                        } else {
12247                            /* we do not have enough room ? */
12248                            if ((bit_pos + bit_size) > bsize)
12249                                bit_pos = 0;
12250                            lbit_pos = bit_pos;
12251                            /* XXX: handle LSB first */
12252                            type1.t |= VT_BITFIELD |
12253                                (bit_pos << VT_STRUCT_SHIFT) |
12254                                (bit_size << (VT_STRUCT_SHIFT + 6));
12255                            bit_pos += bit_size;
12256                        }
12257                    } else {
12258                        bit_pos = 0;
12259                    }
12260                    if (v) {
12261                        /* add new memory data only if starting
12262                           bit field */
12263                        if (lbit_pos == 0) {
12264                            if (a == TOK_STRUCT) {
12265                                c = (c + align - 1) & -align;
12266                                offset = c;
12267                                c += size;
12268                            } else {
12269                                offset = 0;
12270                                if (size > c)
12271                                    c = size;
12272                            }
12273                            if (align > maxalign)
12274                                maxalign = align;
12275                        }
12276#if 0
12277                        printf("add field %s offset=%d",
12278                               get_tok_str(v, NULL), offset);
12279                        if (type1.t & VT_BITFIELD) {
12280                            printf(" pos=%d size=%d",
12281                                   (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
12282                                   (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
12283                        }
12284                        printf("\n");
12285#endif
12286                        ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
12287                        *ps = ss;
12288                        ps = &ss->next;
12289                    }
12290                    if (tok == ';' || tok == TOK_EOF)
12291                        break;
12292                    skip(',');
12293                }
12294                skip(';');
12295            }
12296            skip('}');
12297            /* store size and alignment */
12298            s->c = (c + maxalign - 1) & -maxalign;
12299            s->r = maxalign;
12300        }
12301    }
12302}
12303
12304/* return 0 if no type declaration. otherwise, return the basic type
12305   and skip it.
12306 */
12307static int parse_btype(CType *type, AttributeDef *ad)
12308{
12309    int t, u, type_found, typespec_found;
12310    Sym *s;
12311    CType type1;
12312
12313    memset(ad, 0, sizeof(AttributeDef));
12314    type_found = 0;
12315    typespec_found = 0;
12316    t = 0;
12317    while(1) {
12318        switch(tok) {
12319        case TOK_EXTENSION:
12320            /* currently, we really ignore extension */
12321            next();
12322            continue;
12323
12324            /* basic types */
12325        case TOK_CHAR:
12326            u = VT_BYTE;
12327        basic_type:
12328            next();
12329        basic_type1:
12330            if ((t & VT_BTYPE) != 0)
12331                error("too many basic types");
12332            t |= u;
12333            typespec_found = 1;
12334            break;
12335        case TOK_VOID:
12336            u = VT_VOID;
12337            goto basic_type;
12338        case TOK_SHORT:
12339            u = VT_SHORT;
12340            goto basic_type;
12341        case TOK_INT:
12342            next();
12343            typespec_found = 1;
12344            break;
12345        case TOK_LONG:
12346            next();
12347            if ((t & VT_BTYPE) == VT_DOUBLE) {
12348                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12349            } else if ((t & VT_BTYPE) == VT_LONG) {
12350                t = (t & ~VT_BTYPE) | VT_LLONG;
12351            } else {
12352                u = VT_LONG;
12353                goto basic_type1;
12354            }
12355            break;
12356        case TOK_BOOL:
12357            u = VT_BOOL;
12358            goto basic_type;
12359        case TOK_FLOAT:
12360            u = VT_FLOAT;
12361            goto basic_type;
12362        case TOK_DOUBLE:
12363            next();
12364            if ((t & VT_BTYPE) == VT_LONG) {
12365                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
12366            } else {
12367                u = VT_DOUBLE;
12368                goto basic_type1;
12369            }
12370            break;
12371        case TOK_ENUM:
12372            struct_decl(&type1, VT_ENUM);
12373        basic_type2:
12374            u = type1.t;
12375            type->ref = type1.ref;
12376            goto basic_type1;
12377        case TOK_STRUCT:
12378        case TOK_UNION:
12379            struct_decl(&type1, VT_STRUCT);
12380            goto basic_type2;
12381
12382            /* type modifiers */
12383        case TOK_CONST1:
12384        case TOK_CONST2:
12385        case TOK_CONST3:
12386            t |= VT_CONSTANT;
12387            next();
12388            break;
12389        case TOK_VOLATILE1:
12390        case TOK_VOLATILE2:
12391        case TOK_VOLATILE3:
12392            t |= VT_VOLATILE;
12393            next();
12394            break;
12395        case TOK_SIGNED1:
12396        case TOK_SIGNED2:
12397        case TOK_SIGNED3:
12398            typespec_found = 1;
12399	    t |= VT_SIGNED;
12400	    next();
12401	    break;
12402        case TOK_REGISTER:
12403        case TOK_AUTO:
12404        case TOK_RESTRICT1:
12405        case TOK_RESTRICT2:
12406        case TOK_RESTRICT3:
12407            next();
12408            break;
12409        case TOK_UNSIGNED:
12410            t |= VT_UNSIGNED;
12411            next();
12412            typespec_found = 1;
12413            break;
12414
12415            /* storage */
12416        case TOK_EXTERN:
12417            t |= VT_EXTERN;
12418            next();
12419            break;
12420        case TOK_STATIC:
12421            t |= VT_STATIC;
12422            next();
12423            break;
12424        case TOK_TYPEDEF:
12425            t |= VT_TYPEDEF;
12426            next();
12427            break;
12428        case TOK_INLINE1:
12429        case TOK_INLINE2:
12430        case TOK_INLINE3:
12431            t |= VT_INLINE;
12432            next();
12433            break;
12434
12435            /* GNUC attribute */
12436        case TOK_ATTRIBUTE1:
12437        case TOK_ATTRIBUTE2:
12438            parse_attribute(ad);
12439            break;
12440            /* GNUC typeof */
12441        case TOK_TYPEOF1:
12442        case TOK_TYPEOF2:
12443        case TOK_TYPEOF3:
12444            next();
12445            parse_expr_type(&type1);
12446            goto basic_type2;
12447        default:
12448            if (typespec_found)
12449                goto the_end;
12450            s = sym_find(tok);
12451            if (!s || !(s->type.t & VT_TYPEDEF))
12452                goto the_end;
12453            t |= (s->type.t & ~VT_TYPEDEF);
12454            type->ref = s->type.ref;
12455            next();
12456            break;
12457        }
12458        type_found = 1;
12459    }
12460the_end:
12461    if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
12462      error("signed and unsigned modifier");
12463    if (tcc_state->char_is_unsigned) {
12464        if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
12465            t |= VT_UNSIGNED;
12466    }
12467    t &= ~VT_SIGNED;
12468
12469    /* long is never used as type */
12470    if ((t & VT_BTYPE) == VT_LONG)
12471        t = (t & ~VT_BTYPE) | VT_INT;
12472    type->t = t;
12473    return type_found;
12474}
12475
12476/* convert a function parameter type (array to pointer and function to
12477   function pointer) */
12478static inline void convert_parameter_type(CType *pt)
12479{
12480    /* remove const and volatile qualifiers (XXX: const could be used
12481       to indicate a const function parameter */
12482    pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
12483    /* array must be transformed to pointer according to ANSI C */
12484    pt->t &= ~VT_ARRAY;
12485    if ((pt->t & VT_BTYPE) == VT_FUNC) {
12486        mk_pointer(pt);
12487    }
12488}
12489
12490static void post_type(CType *type, AttributeDef *ad)
12491{
12492    int n, l, t1;
12493    Sym **plast, *s, *first;
12494    AttributeDef ad1;
12495    CType pt;
12496
12497    if (tok == '(') {
12498        /* function declaration */
12499        next();
12500        l = 0;
12501        first = NULL;
12502        plast = &first;
12503        while (tok != ')') {
12504            /* read param name and compute offset */
12505            if (l != FUNC_OLD) {
12506                if (!parse_btype(&pt, &ad1)) {
12507                    if (l) {
12508                        error("invalid type");
12509                    } else {
12510                        l = FUNC_OLD;
12511                        goto old_proto;
12512                    }
12513                }
12514                l = FUNC_NEW;
12515                if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
12516                    break;
12517                type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
12518                if ((pt.t & VT_BTYPE) == VT_VOID)
12519                    error("parameter declared as void");
12520            } else {
12521            old_proto:
12522                n = tok;
12523                pt.t = VT_INT;
12524                next();
12525            }
12526            convert_parameter_type(&pt);
12527            s = sym_push(n | SYM_FIELD, &pt, 0, 0);
12528            *plast = s;
12529            plast = &s->next;
12530            if (tok == ',') {
12531                next();
12532                if (l == FUNC_NEW && tok == TOK_DOTS) {
12533                    l = FUNC_ELLIPSIS;
12534                    next();
12535                    break;
12536                }
12537            }
12538        }
12539        /* if no parameters, then old type prototype */
12540        if (l == 0)
12541            l = FUNC_OLD;
12542        skip(')');
12543        t1 = type->t & VT_STORAGE;
12544        /* NOTE: const is ignored in returned type as it has a special
12545           meaning in gcc / C++ */
12546        type->t &= ~(VT_STORAGE | VT_CONSTANT);
12547        post_type(type, ad);
12548        /* we push a anonymous symbol which will contain the function prototype */
12549        s = sym_push(SYM_FIELD, type, ad->func_call, l);
12550        s->next = first;
12551        type->t = t1 | VT_FUNC;
12552        type->ref = s;
12553    } else if (tok == '[') {
12554        /* array definition */
12555        next();
12556        n = -1;
12557        if (tok != ']') {
12558            n = expr_const();
12559            if (n < 0)
12560                error("invalid array size");
12561        }
12562        skip(']');
12563        /* parse next post type */
12564        t1 = type->t & VT_STORAGE;
12565        type->t &= ~VT_STORAGE;
12566        post_type(type, ad);
12567
12568        /* we push a anonymous symbol which will contain the array
12569           element type */
12570        s = sym_push(SYM_FIELD, type, 0, n);
12571        type->t = t1 | VT_ARRAY | VT_PTR;
12572        type->ref = s;
12573    }
12574}
12575
12576/* Parse a type declaration (except basic type), and return the type
12577   in 'type'. 'td' is a bitmask indicating which kind of type decl is
12578   expected. 'type' should contain the basic type. 'ad' is the
12579   attribute definition of the basic type. It can be modified by
12580   type_decl().
12581 */
12582static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
12583{
12584    Sym *s;
12585    CType type1, *type2;
12586    int qualifiers;
12587
12588    while (tok == '*') {
12589        qualifiers = 0;
12590    redo:
12591        next();
12592        switch(tok) {
12593        case TOK_CONST1:
12594        case TOK_CONST2:
12595        case TOK_CONST3:
12596            qualifiers |= VT_CONSTANT;
12597            goto redo;
12598        case TOK_VOLATILE1:
12599        case TOK_VOLATILE2:
12600        case TOK_VOLATILE3:
12601            qualifiers |= VT_VOLATILE;
12602            goto redo;
12603        case TOK_RESTRICT1:
12604        case TOK_RESTRICT2:
12605        case TOK_RESTRICT3:
12606            goto redo;
12607        }
12608        mk_pointer(type);
12609        type->t |= qualifiers;
12610    }
12611
12612    /* XXX: clarify attribute handling */
12613    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12614        parse_attribute(ad);
12615
12616    /* recursive type */
12617    /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
12618    type1.t = 0; /* XXX: same as int */
12619    if (tok == '(') {
12620        next();
12621        /* XXX: this is not correct to modify 'ad' at this point, but
12622           the syntax is not clear */
12623        if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12624            parse_attribute(ad);
12625        type_decl(&type1, ad, v, td);
12626        skip(')');
12627    } else {
12628        /* type identifier */
12629        if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
12630            *v = tok;
12631            next();
12632        } else {
12633            if (!(td & TYPE_ABSTRACT))
12634                expect("identifier");
12635            *v = 0;
12636        }
12637    }
12638    post_type(type, ad);
12639    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
12640        parse_attribute(ad);
12641    if (!type1.t)
12642        return;
12643    /* append type at the end of type1 */
12644    type2 = &type1;
12645    for(;;) {
12646        s = type2->ref;
12647        type2 = &s->type;
12648        if (!type2->t) {
12649            *type2 = *type;
12650            break;
12651        }
12652    }
12653    *type = type1;
12654}
12655
12656/* compute the lvalue VT_LVAL_xxx needed to match type t. */
12657static int lvalue_type(int t)
12658{
12659    int bt, r;
12660    r = VT_LVAL;
12661    bt = t & VT_BTYPE;
12662    if (bt == VT_BYTE || bt == VT_BOOL)
12663        r |= VT_LVAL_BYTE;
12664    else if (bt == VT_SHORT)
12665        r |= VT_LVAL_SHORT;
12666    else
12667        return r;
12668    if (t & VT_UNSIGNED)
12669        r |= VT_LVAL_UNSIGNED;
12670    return r;
12671}
12672
12673/* indirection with full error checking and bound check */
12674static void indir(void)
12675{
12676    if ((vtop->type.t & VT_BTYPE) != VT_PTR)
12677        expect("pointer");
12678    if ((vtop->r & VT_LVAL) && !nocode_wanted)
12679        gv(RC_INT);
12680    vtop->type = *pointed_type(&vtop->type);
12681    /* an array is never an lvalue */
12682    if (!(vtop->type.t & VT_ARRAY)) {
12683        vtop->r |= lvalue_type(vtop->type.t);
12684        /* if bound checking, the referenced pointer must be checked */
12685        if (do_bounds_check)
12686            vtop->r |= VT_MUSTBOUND;
12687    }
12688}
12689
12690/* pass a parameter to a function and do type checking and casting */
12691static void gfunc_param_typed(Sym *func, Sym *arg)
12692{
12693    int func_type;
12694    CType type;
12695
12696    func_type = func->c;
12697    if (func_type == FUNC_OLD ||
12698        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
12699        /* default casting : only need to convert float to double */
12700        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
12701            type.t = VT_DOUBLE;
12702            gen_cast(&type);
12703        }
12704    } else if (arg == NULL) {
12705        error("too many arguments to function");
12706    } else {
12707        type = arg->type;
12708        type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
12709        gen_assign_cast(&type);
12710    }
12711}
12712
12713/* parse an expression of the form '(type)' or '(expr)' and return its
12714   type */
12715static void parse_expr_type(CType *type)
12716{
12717    int n;
12718    AttributeDef ad;
12719
12720    skip('(');
12721    if (parse_btype(type, &ad)) {
12722        type_decl(type, &ad, &n, TYPE_ABSTRACT);
12723    } else {
12724        expr_type(type);
12725    }
12726    skip(')');
12727}
12728
12729static void parse_type(CType *type)
12730{
12731    AttributeDef ad;
12732    int n;
12733
12734    if (!parse_btype(type, &ad)) {
12735        expect("type");
12736    }
12737    type_decl(type, &ad, &n, TYPE_ABSTRACT);
12738}
12739
12740static void vpush_tokc(int t)
12741{
12742    CType type;
12743    type.t = t;
12744    vsetc(&type, VT_CONST, &tokc);
12745}
12746
12747static void unary(void)
12748{
12749    int n, t, align, size, r;
12750    CType type;
12751    Sym *s;
12752    AttributeDef ad;
12753
12754    /* XXX: GCC 2.95.3 does not generate a table although it should be
12755       better here */
12756 tok_next:
12757    switch(tok) {
12758    case TOK_EXTENSION:
12759        next();
12760        goto tok_next;
12761    case TOK_CINT:
12762    case TOK_CCHAR:
12763    case TOK_LCHAR:
12764        vpushi(tokc.i);
12765        next();
12766        break;
12767    case TOK_CUINT:
12768        vpush_tokc(VT_INT | VT_UNSIGNED);
12769        next();
12770        break;
12771    case TOK_CLLONG:
12772        vpush_tokc(VT_LLONG);
12773        next();
12774        break;
12775    case TOK_CULLONG:
12776        vpush_tokc(VT_LLONG | VT_UNSIGNED);
12777        next();
12778        break;
12779    case TOK_CFLOAT:
12780        vpush_tokc(VT_FLOAT);
12781        next();
12782        break;
12783    case TOK_CDOUBLE:
12784        vpush_tokc(VT_DOUBLE);
12785        next();
12786        break;
12787    case TOK_CLDOUBLE:
12788        vpush_tokc(VT_LDOUBLE);
12789        next();
12790        break;
12791    case TOK___FUNCTION__:
12792        if (!gnu_ext)
12793            goto tok_identifier;
12794        /* fall thru */
12795    case TOK___FUNC__:
12796        {
12797            void *ptr;
12798            int len;
12799            /* special function name identifier */
12800            len = strlen(funcname) + 1;
12801            /* generate char[len] type */
12802            type.t = VT_BYTE;
12803            mk_pointer(&type);
12804            type.t |= VT_ARRAY;
12805            type.ref->c = len;
12806            vpush_ref(&type, data_section, data_section->data_offset, len);
12807            ptr = section_ptr_add(data_section, len);
12808            memcpy(ptr, funcname, len);
12809            next();
12810        }
12811        break;
12812    case TOK_LSTR:
12813        t = VT_INT;
12814        goto str_init;
12815    case TOK_STR:
12816        /* string parsing */
12817        t = VT_BYTE;
12818    str_init:
12819        if (tcc_state->warn_write_strings)
12820            t |= VT_CONSTANT;
12821        type.t = t;
12822        mk_pointer(&type);
12823        type.t |= VT_ARRAY;
12824        memset(&ad, 0, sizeof(AttributeDef));
12825        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
12826        break;
12827    case '(':
12828        next();
12829        /* cast ? */
12830        if (parse_btype(&type, &ad)) {
12831            type_decl(&type, &ad, &n, TYPE_ABSTRACT);
12832            skip(')');
12833            /* check ISOC99 compound literal */
12834            if (tok == '{') {
12835                    /* data is allocated locally by default */
12836                if (global_expr)
12837                    r = VT_CONST;
12838                else
12839                    r = VT_LOCAL;
12840                /* all except arrays are lvalues */
12841                if (!(type.t & VT_ARRAY))
12842                    r |= lvalue_type(type.t);
12843                memset(&ad, 0, sizeof(AttributeDef));
12844                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
12845            } else {
12846                unary();
12847                gen_cast(&type);
12848            }
12849        } else if (tok == '{') {
12850            /* save all registers */
12851            save_regs(0);
12852            /* statement expression : we do not accept break/continue
12853               inside as GCC does */
12854            block(NULL, NULL, NULL, NULL, 0, 1);
12855            skip(')');
12856        } else {
12857            gexpr();
12858            skip(')');
12859        }
12860        break;
12861    case '*':
12862        next();
12863        unary();
12864        indir();
12865        break;
12866    case '&':
12867        next();
12868        unary();
12869        /* functions names must be treated as function pointers,
12870           except for unary '&' and sizeof. Since we consider that
12871           functions are not lvalues, we only have to handle it
12872           there and in function calls. */
12873        /* arrays can also be used although they are not lvalues */
12874        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
12875            !(vtop->type.t & VT_ARRAY))
12876            test_lvalue();
12877        mk_pointer(&vtop->type);
12878        gaddrof();
12879        break;
12880    case '!':
12881        next();
12882        unary();
12883        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)
12884            vtop->c.i = !vtop->c.i;
12885        else if ((vtop->r & VT_VALMASK) == VT_CMP)
12886            vtop->c.i = vtop->c.i ^ 1;
12887        else
12888            vseti(VT_JMP, gtst(1, 0));
12889        break;
12890    case '~':
12891        next();
12892        unary();
12893        vpushi(-1);
12894        gen_op('^');
12895        break;
12896    case '+':
12897        next();
12898        /* in order to force cast, we add zero */
12899        unary();
12900        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
12901            error("pointer not accepted for unary plus");
12902        vpushi(0);
12903        gen_op('+');
12904        break;
12905    case TOK_SIZEOF:
12906    case TOK_ALIGNOF1:
12907    case TOK_ALIGNOF2:
12908        t = tok;
12909        next();
12910        if (tok == '(') {
12911            parse_expr_type(&type);
12912        } else {
12913            unary_type(&type);
12914        }
12915        size = type_size(&type, &align);
12916        if (t == TOK_SIZEOF) {
12917            if (size < 0)
12918                error("sizeof applied to an incomplete type");
12919            vpushi(size);
12920        } else {
12921            vpushi(align);
12922        }
12923        break;
12924
12925    case TOK_builtin_types_compatible_p:
12926        {
12927            CType type1, type2;
12928            next();
12929            skip('(');
12930            parse_type(&type1);
12931            skip(',');
12932            parse_type(&type2);
12933            skip(')');
12934            type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
12935            type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
12936            vpushi(is_compatible_types(&type1, &type2));
12937        }
12938        break;
12939    case TOK_builtin_constant_p:
12940        {
12941            int saved_nocode_wanted, res;
12942            next();
12943            skip('(');
12944            saved_nocode_wanted = nocode_wanted;
12945            nocode_wanted = 1;
12946            gexpr();
12947            res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
12948            vpop();
12949            nocode_wanted = saved_nocode_wanted;
12950            skip(')');
12951            vpushi(res);
12952        }
12953        break;
12954    case TOK_INC:
12955    case TOK_DEC:
12956        t = tok;
12957        next();
12958        unary();
12959        inc(0, t);
12960        break;
12961    case '-':
12962        next();
12963        vpushi(0);
12964        unary();
12965        gen_op('-');
12966        break;
12967    case TOK_LAND:
12968        if (!gnu_ext)
12969            goto tok_identifier;
12970        next();
12971        /* allow to take the address of a label */
12972        if (tok < TOK_UIDENT)
12973            expect("label identifier");
12974        s = label_find(tok);
12975        if (!s) {
12976            s = label_push(&global_label_stack, tok, LABEL_FORWARD);
12977        } else {
12978            if (s->r == LABEL_DECLARED)
12979                s->r = LABEL_FORWARD;
12980        }
12981        if (!s->type.t) {
12982            s->type.t = VT_VOID;
12983            mk_pointer(&s->type);
12984            s->type.t |= VT_STATIC;
12985        }
12986        vset(&s->type, VT_CONST | VT_SYM, 0);
12987        vtop->sym = s;
12988        next();
12989        break;
12990    default:
12991    tok_identifier:
12992        t = tok;
12993        next();
12994        if (t < TOK_UIDENT)
12995            expect("identifier");
12996        s = sym_find(t);
12997        if (!s) {
12998            if (tok != '(')
12999                error("'%s' undeclared", get_tok_str(t, NULL));
13000            /* for simple function calls, we tolerate undeclared
13001               external reference to int() function */
13002            if (tcc_state->warn_implicit_function_declaration)
13003                warning("implicit declaration of function '%s'",
13004                        get_tok_str(t, NULL));
13005            s = external_global_sym(t, &func_old_type, 0);
13006        }
13007        if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
13008            (VT_STATIC | VT_INLINE | VT_FUNC)) {
13009            /* if referencing an inline function, then we generate a
13010               symbol to it if not already done. It will have the
13011               effect to generate code for it at the end of the
13012               compilation unit. Inline function as always
13013               generated in the text section. */
13014            if (!s->c)
13015                put_extern_sym(s, text_section, 0, 0);
13016            r = VT_SYM | VT_CONST;
13017        } else {
13018            r = s->r;
13019        }
13020        vset(&s->type, r, s->c);
13021        /* if forward reference, we must point to s */
13022        if (vtop->r & VT_SYM) {
13023            vtop->sym = s;
13024            vtop->c.ul = 0;
13025        }
13026        break;
13027    }
13028
13029    /* post operations */
13030    while (1) {
13031        if (tok == TOK_INC || tok == TOK_DEC) {
13032            inc(1, tok);
13033            next();
13034        } else if (tok == '.' || tok == TOK_ARROW) {
13035            /* field */
13036            if (tok == TOK_ARROW)
13037                indir();
13038            test_lvalue();
13039            gaddrof();
13040            next();
13041            /* expect pointer on structure */
13042            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
13043                expect("struct or union");
13044            s = vtop->type.ref;
13045            /* find field */
13046            tok |= SYM_FIELD;
13047            while ((s = s->next) != NULL) {
13048                if (s->v == tok)
13049                    break;
13050            }
13051            if (!s)
13052                error("field not found");
13053            /* add field offset to pointer */
13054            vtop->type = char_pointer_type; /* change type to 'char *' */
13055            vpushi(s->c);
13056            gen_op('+');
13057            /* change type to field type, and set to lvalue */
13058            vtop->type = s->type;
13059            /* an array is never an lvalue */
13060            if (!(vtop->type.t & VT_ARRAY)) {
13061                vtop->r |= lvalue_type(vtop->type.t);
13062                /* if bound checking, the referenced pointer must be checked */
13063                if (do_bounds_check)
13064                    vtop->r |= VT_MUSTBOUND;
13065            }
13066            next();
13067        } else if (tok == '[') {
13068            next();
13069            gexpr();
13070            gen_op('+');
13071            indir();
13072            skip(']');
13073        } else if (tok == '(') {
13074            SValue ret;
13075            Sym *sa;
13076            int nb_args;
13077
13078            /* function call  */
13079            if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
13080                /* pointer test (no array accepted) */
13081                if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
13082                    vtop->type = *pointed_type(&vtop->type);
13083                    if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
13084                        goto error_func;
13085                } else {
13086                error_func:
13087                    expect("function pointer");
13088                }
13089            } else {
13090                vtop->r &= ~VT_LVAL; /* no lvalue */
13091            }
13092            /* get return type */
13093            s = vtop->type.ref;
13094            next();
13095            sa = s->next; /* first parameter */
13096            nb_args = 0;
13097            /* compute first implicit argument if a structure is returned */
13098            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
13099                /* get some space for the returned structure */
13100                size = type_size(&s->type, &align);
13101                loc = (loc - size) & -align;
13102                ret.type = s->type;
13103                ret.r = VT_LOCAL | VT_LVAL;
13104                /* pass it as 'int' to avoid structure arg passing
13105                   problems */
13106                vseti(VT_LOCAL, loc);
13107                ret.c = vtop->c;
13108                nb_args++;
13109            } else {
13110                ret.type = s->type;
13111                ret.r2 = VT_CONST;
13112                /* return in register */
13113                if (is_float(ret.type.t)) {
13114                    ret.r = REG_FRET;
13115                } else {
13116                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
13117                        ret.r2 = REG_LRET;
13118                    ret.r = REG_IRET;
13119                }
13120                ret.c.i = 0;
13121            }
13122            if (tok != ')') {
13123                for(;;) {
13124                    expr_eq();
13125                    gfunc_param_typed(s, sa);
13126                    nb_args++;
13127                    if (sa)
13128                        sa = sa->next;
13129                    if (tok == ')')
13130                        break;
13131                    skip(',');
13132                }
13133            }
13134            if (sa)
13135                error("too few arguments to function");
13136            skip(')');
13137            if (!nocode_wanted) {
13138                gfunc_call(nb_args);
13139            } else {
13140                vtop -= (nb_args + 1);
13141            }
13142            /* return value */
13143            vsetc(&ret.type, ret.r, &ret.c);
13144            vtop->r2 = ret.r2;
13145        } else {
13146            break;
13147        }
13148    }
13149}
13150
13151static void uneq(void)
13152{
13153    int t;
13154
13155    unary();
13156    if (tok == '=' ||
13157        (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
13158        tok == TOK_A_XOR || tok == TOK_A_OR ||
13159        tok == TOK_A_SHL || tok == TOK_A_SAR) {
13160        test_lvalue();
13161        t = tok;
13162        next();
13163        if (t == '=') {
13164            expr_eq();
13165        } else {
13166            vdup();
13167            expr_eq();
13168            gen_op(t & 0x7f);
13169        }
13170        vstore();
13171    }
13172}
13173
13174static void expr_prod(void)
13175{
13176    int t;
13177
13178    uneq();
13179    while (tok == '*' || tok == '/' || tok == '%') {
13180        t = tok;
13181        next();
13182        uneq();
13183        gen_op(t);
13184    }
13185}
13186
13187static void expr_sum(void)
13188{
13189    int t;
13190
13191    expr_prod();
13192    while (tok == '+' || tok == '-') {
13193        t = tok;
13194        next();
13195        expr_prod();
13196        gen_op(t);
13197    }
13198}
13199
13200static void expr_shift(void)
13201{
13202    int t;
13203
13204    expr_sum();
13205    while (tok == TOK_SHL || tok == TOK_SAR) {
13206        t = tok;
13207        next();
13208        expr_sum();
13209        gen_op(t);
13210    }
13211}
13212
13213static void expr_cmp(void)
13214{
13215    int t;
13216
13217    expr_shift();
13218    while ((tok >= TOK_ULE && tok <= TOK_GT) ||
13219           tok == TOK_ULT || tok == TOK_UGE) {
13220        t = tok;
13221        next();
13222        expr_shift();
13223        gen_op(t);
13224    }
13225}
13226
13227static void expr_cmpeq(void)
13228{
13229    int t;
13230
13231    expr_cmp();
13232    while (tok == TOK_EQ || tok == TOK_NE) {
13233        t = tok;
13234        next();
13235        expr_cmp();
13236        gen_op(t);
13237    }
13238}
13239
13240static void expr_and(void)
13241{
13242    expr_cmpeq();
13243    while (tok == '&') {
13244        next();
13245        expr_cmpeq();
13246        gen_op('&');
13247    }
13248}
13249
13250static void expr_xor(void)
13251{
13252    expr_and();
13253    while (tok == '^') {
13254        next();
13255        expr_and();
13256        gen_op('^');
13257    }
13258}
13259
13260static void expr_or(void)
13261{
13262    expr_xor();
13263    while (tok == '|') {
13264        next();
13265        expr_xor();
13266        gen_op('|');
13267    }
13268}
13269
13270/* XXX: fix this mess */
13271static void expr_land_const(void)
13272{
13273    expr_or();
13274    while (tok == TOK_LAND) {
13275        next();
13276        expr_or();
13277        gen_op(TOK_LAND);
13278    }
13279}
13280
13281/* XXX: fix this mess */
13282static void expr_lor_const(void)
13283{
13284    expr_land_const();
13285    while (tok == TOK_LOR) {
13286        next();
13287        expr_land_const();
13288        gen_op(TOK_LOR);
13289    }
13290}
13291
13292/* only used if non constant */
13293static void expr_land(void)
13294{
13295    int t;
13296
13297    expr_or();
13298    if (tok == TOK_LAND) {
13299        t = 0;
13300        for(;;) {
13301            t = gtst(1, t);
13302            if (tok != TOK_LAND) {
13303                vseti(VT_JMPI, t);
13304                break;
13305            }
13306            next();
13307            expr_or();
13308        }
13309    }
13310}
13311
13312static void expr_lor(void)
13313{
13314    int t;
13315
13316    expr_land();
13317    if (tok == TOK_LOR) {
13318        t = 0;
13319        for(;;) {
13320            t = gtst(0, t);
13321            if (tok != TOK_LOR) {
13322                vseti(VT_JMP, t);
13323                break;
13324            }
13325            next();
13326            expr_land();
13327        }
13328    }
13329}
13330
13331/* XXX: better constant handling */
13332static void expr_eq(void)
13333{
13334    int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
13335    SValue sv;
13336    CType type, type1, type2;
13337
13338    if (const_wanted) {
13339        int c1, c;
13340        expr_lor_const();
13341        if (tok == '?') {
13342            c = vtop->c.i;
13343            vpop();
13344            next();
13345            if (tok == ':' && gnu_ext) {
13346                c1 = c;
13347            } else {
13348                gexpr();
13349                c1 = vtop->c.i;
13350                vpop();
13351            }
13352            skip(':');
13353            expr_eq();
13354            if (c)
13355                vtop->c.i = c1;
13356        }
13357    } else {
13358        expr_lor();
13359        if (tok == '?') {
13360            next();
13361            if (vtop != vstack) {
13362                /* needed to avoid having different registers saved in
13363                   each branch */
13364                if (is_float(vtop->type.t))
13365                    rc = RC_FLOAT;
13366                else
13367                    rc = RC_INT;
13368                    gv(rc);
13369                    save_regs(1);
13370            }
13371            if (tok == ':' && gnu_ext) {
13372                gv_dup();
13373                tt = gtst(1, 0);
13374            } else {
13375                tt = gtst(1, 0);
13376                gexpr();
13377            }
13378            type1 = vtop->type;
13379            sv = *vtop; /* save value to handle it later */
13380            vtop--; /* no vpop so that FP stack is not flushed */
13381            skip(':');
13382            u = gjmp(0);
13383            gsym(tt);
13384            expr_eq();
13385            type2 = vtop->type;
13386
13387            t1 = type1.t;
13388            bt1 = t1 & VT_BTYPE;
13389            t2 = type2.t;
13390            bt2 = t2 & VT_BTYPE;
13391            /* cast operands to correct type according to ISOC rules */
13392            if (is_float(bt1) || is_float(bt2)) {
13393                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
13394                    type.t = VT_LDOUBLE;
13395                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
13396                    type.t = VT_DOUBLE;
13397                } else {
13398                    type.t = VT_FLOAT;
13399                }
13400            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
13401                /* cast to biggest op */
13402                type.t = VT_LLONG;
13403                /* convert to unsigned if it does not fit in a long long */
13404                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
13405                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
13406                    type.t |= VT_UNSIGNED;
13407            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
13408                /* XXX: test pointer compatibility */
13409                type = type1;
13410            } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
13411                /* XXX: test structure compatibility */
13412                type = type1;
13413            } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
13414                /* NOTE: as an extension, we accept void on only one side */
13415                type.t = VT_VOID;
13416            } else {
13417                /* integer operations */
13418                type.t = VT_INT;
13419                /* convert to unsigned if it does not fit in an integer */
13420                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
13421                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
13422                    type.t |= VT_UNSIGNED;
13423            }
13424
13425            /* now we convert second operand */
13426            gen_cast(&type);
13427            rc = RC_INT;
13428            if (is_float(type.t)) {
13429                rc = RC_FLOAT;
13430            } else if ((type.t & VT_BTYPE) == VT_LLONG) {
13431                /* for long longs, we use fixed registers to avoid having
13432                   to handle a complicated move */
13433                rc = RC_IRET;
13434            }
13435
13436            r2 = gv(rc);
13437            /* this is horrible, but we must also convert first
13438               operand */
13439            tt = gjmp(0);
13440            gsym(u);
13441            /* put again first value and cast it */
13442            *vtop = sv;
13443            gen_cast(&type);
13444            r1 = gv(rc);
13445            move_reg(r2, r1);
13446            vtop->r = r2;
13447            gsym(tt);
13448        }
13449    }
13450}
13451
13452static void gexpr(void)
13453{
13454    while (1) {
13455        expr_eq();
13456        if (tok != ',')
13457            break;
13458        vpop();
13459        next();
13460    }
13461}
13462
13463/* parse an expression and return its type without any side effect. */
13464static void expr_type(CType *type)
13465{
13466    int saved_nocode_wanted;
13467
13468    saved_nocode_wanted = nocode_wanted;
13469    nocode_wanted = 1;
13470    gexpr();
13471    *type = vtop->type;
13472    vpop();
13473    nocode_wanted = saved_nocode_wanted;
13474}
13475
13476/* parse a unary expression and return its type without any side
13477   effect. */
13478static void unary_type(CType *type)
13479{
13480    int a;
13481
13482    a = nocode_wanted;
13483    nocode_wanted = 1;
13484    unary();
13485    *type = vtop->type;
13486    vpop();
13487    nocode_wanted = a;
13488}
13489
13490/* parse a constant expression and return value in vtop.  */
13491static void expr_const1(void)
13492{
13493    int a;
13494    a = const_wanted;
13495    const_wanted = 1;
13496    expr_eq();
13497    const_wanted = a;
13498}
13499
13500/* parse an integer constant and return its value. */
13501static int expr_const(void)
13502{
13503    int c;
13504    expr_const1();
13505    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
13506        expect("constant expression");
13507    c = vtop->c.i;
13508    vpop();
13509    return c;
13510}
13511
13512/* return the label token if current token is a label, otherwise
13513   return zero */
13514static int is_label(void)
13515{
13516    int last_tok;
13517
13518    /* fast test first */
13519    if (tok < TOK_UIDENT)
13520        return 0;
13521    /* no need to save tokc because tok is an identifier */
13522    last_tok = tok;
13523    next();
13524    if (tok == ':') {
13525        next();
13526        return last_tok;
13527    } else {
13528        unget_tok(last_tok);
13529        return 0;
13530    }
13531}
13532
13533static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
13534                  int case_reg, int is_expr)
13535{
13536    int a, b, c, d;
13537    Sym *s;
13538
13539    /* generate line number info */
13540    if (do_debug &&
13541        (last_line_num != file->line_num || last_ind != ind)) {
13542        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
13543        last_ind = ind;
13544        last_line_num = file->line_num;
13545    }
13546
13547    if (is_expr) {
13548        /* default return value is (void) */
13549        vpushi(0);
13550        vtop->type.t = VT_VOID;
13551    }
13552
13553    if (tok == TOK_IF) {
13554        /* if test */
13555        next();
13556        skip('(');
13557        gexpr();
13558        skip(')');
13559        a = gtst(1, 0);
13560        block(bsym, csym, case_sym, def_sym, case_reg, 0);
13561        c = tok;
13562        if (c == TOK_ELSE) {
13563            next();
13564            d = gjmp(0);
13565            gsym(a);
13566            block(bsym, csym, case_sym, def_sym, case_reg, 0);
13567            gsym(d); /* patch else jmp */
13568        } else
13569            gsym(a);
13570    } else if (tok == TOK_WHILE) {
13571        next();
13572        d = ind;
13573        skip('(');
13574        gexpr();
13575        skip(')');
13576        a = gtst(1, 0);
13577        b = 0;
13578        block(&a, &b, case_sym, def_sym, case_reg, 0);
13579        gjmp_addr(d);
13580        gsym(a);
13581        gsym_addr(b, d);
13582    } else if (tok == '{') {
13583        Sym *llabel;
13584
13585        next();
13586        /* record local declaration stack position */
13587        s = local_stack;
13588        llabel = local_label_stack;
13589        /* handle local labels declarations */
13590        if (tok == TOK_LABEL) {
13591            next();
13592            for(;;) {
13593                if (tok < TOK_UIDENT)
13594                    expect("label identifier");
13595                label_push(&local_label_stack, tok, LABEL_DECLARED);
13596                next();
13597                if (tok == ',') {
13598                    next();
13599                } else {
13600                    skip(';');
13601                    break;
13602                }
13603            }
13604        }
13605        while (tok != '}') {
13606            decl(VT_LOCAL);
13607            if (tok != '}') {
13608                if (is_expr)
13609                    vpop();
13610                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13611            }
13612        }
13613        /* pop locally defined labels */
13614        label_pop(&local_label_stack, llabel);
13615        /* pop locally defined symbols */
13616        sym_pop(&local_stack, s);
13617        next();
13618    } else if (tok == TOK_RETURN) {
13619        next();
13620        if (tok != ';') {
13621            gexpr();
13622            gen_assign_cast(&func_vt);
13623            if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
13624                CType type;
13625                /* if returning structure, must copy it to implicit
13626                   first pointer arg location */
13627                type = func_vt;
13628                mk_pointer(&type);
13629                vset(&type, VT_LOCAL | VT_LVAL, func_vc);
13630                indir();
13631                vswap();
13632                /* copy structure value to pointer */
13633                vstore();
13634            } else if (is_float(func_vt.t)) {
13635                gv(RC_FRET);
13636            } else {
13637                gv(RC_IRET);
13638            }
13639            vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
13640        }
13641        skip(';');
13642        rsym = gjmp(rsym); /* jmp */
13643    } else if (tok == TOK_BREAK) {
13644        /* compute jump */
13645        if (!bsym)
13646            error("cannot break");
13647        *bsym = gjmp(*bsym);
13648        next();
13649        skip(';');
13650    } else if (tok == TOK_CONTINUE) {
13651        /* compute jump */
13652        if (!csym)
13653            error("cannot continue");
13654        *csym = gjmp(*csym);
13655        next();
13656        skip(';');
13657    } else if (tok == TOK_FOR) {
13658        int e;
13659        next();
13660        skip('(');
13661        if (tok != ';') {
13662            gexpr();
13663            vpop();
13664        }
13665        skip(';');
13666        d = ind;
13667        c = ind;
13668        a = 0;
13669        b = 0;
13670        if (tok != ';') {
13671            gexpr();
13672            a = gtst(1, 0);
13673        }
13674        skip(';');
13675        if (tok != ')') {
13676            e = gjmp(0);
13677            c = ind;
13678            gexpr();
13679            vpop();
13680            gjmp_addr(d);
13681            gsym(e);
13682        }
13683        skip(')');
13684        block(&a, &b, case_sym, def_sym, case_reg, 0);
13685        gjmp_addr(c);
13686        gsym(a);
13687        gsym_addr(b, c);
13688    } else
13689    if (tok == TOK_DO) {
13690        next();
13691        a = 0;
13692        b = 0;
13693        d = ind;
13694        block(&a, &b, case_sym, def_sym, case_reg, 0);
13695        skip(TOK_WHILE);
13696        skip('(');
13697        gsym(b);
13698        gexpr();
13699        c = gtst(0, 0);
13700        gsym_addr(c, d);
13701        skip(')');
13702        gsym(a);
13703        skip(';');
13704    } else
13705    if (tok == TOK_SWITCH) {
13706        next();
13707        skip('(');
13708        gexpr();
13709        /* XXX: other types than integer */
13710        case_reg = gv(RC_INT);
13711        vpop();
13712        skip(')');
13713        a = 0;
13714        b = gjmp(0); /* jump to first case */
13715        c = 0;
13716        block(&a, csym, &b, &c, case_reg, 0);
13717        /* if no default, jmp after switch */
13718        if (c == 0)
13719            c = ind;
13720        /* default label */
13721        gsym_addr(b, c);
13722        /* break label */
13723        gsym(a);
13724    } else
13725    if (tok == TOK_CASE) {
13726        int v1, v2;
13727        if (!case_sym)
13728            expect("switch");
13729        next();
13730        v1 = expr_const();
13731        v2 = v1;
13732        if (gnu_ext && tok == TOK_DOTS) {
13733            next();
13734            v2 = expr_const();
13735            if (v2 < v1)
13736                warning("empty case range");
13737        }
13738        /* since a case is like a label, we must skip it with a jmp */
13739        b = gjmp(0);
13740        gsym(*case_sym);
13741        vseti(case_reg, 0);
13742        vpushi(v1);
13743        if (v1 == v2) {
13744            gen_op(TOK_EQ);
13745            *case_sym = gtst(1, 0);
13746        } else {
13747            gen_op(TOK_GE);
13748            *case_sym = gtst(1, 0);
13749            vseti(case_reg, 0);
13750            vpushi(v2);
13751            gen_op(TOK_LE);
13752            *case_sym = gtst(1, *case_sym);
13753        }
13754        gsym(b);
13755        skip(':');
13756        is_expr = 0;
13757        goto block_after_label;
13758    } else
13759    if (tok == TOK_DEFAULT) {
13760        next();
13761        skip(':');
13762        if (!def_sym)
13763            expect("switch");
13764        if (*def_sym)
13765            error("too many 'default'");
13766        *def_sym = ind;
13767        is_expr = 0;
13768        goto block_after_label;
13769    } else
13770    if (tok == TOK_GOTO) {
13771        next();
13772        if (tok == '*' && gnu_ext) {
13773            /* computed goto */
13774            next();
13775            gexpr();
13776            if ((vtop->type.t & VT_BTYPE) != VT_PTR)
13777                expect("pointer");
13778            ggoto();
13779        } else if (tok >= TOK_UIDENT) {
13780            s = label_find(tok);
13781            /* put forward definition if needed */
13782            if (!s) {
13783                s = label_push(&global_label_stack, tok, LABEL_FORWARD);
13784            } else {
13785                if (s->r == LABEL_DECLARED)
13786                    s->r = LABEL_FORWARD;
13787            }
13788            /* label already defined */
13789            if (s->r & LABEL_FORWARD)
13790                s->next = (void *)gjmp((long)s->next);
13791            else
13792                gjmp_addr((long)s->next);
13793            next();
13794        } else {
13795            expect("label identifier");
13796        }
13797        skip(';');
13798    } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
13799        asm_instr();
13800    } else {
13801        b = is_label();
13802        if (b) {
13803            /* label case */
13804            s = label_find(b);
13805            if (s) {
13806                if (s->r == LABEL_DEFINED)
13807                    error("duplicate label '%s'", get_tok_str(s->v, NULL));
13808                gsym((long)s->next);
13809                s->r = LABEL_DEFINED;
13810            } else {
13811                s = label_push(&global_label_stack, b, LABEL_DEFINED);
13812            }
13813            s->next = (void *)ind;
13814            /* we accept this, but it is a mistake */
13815        block_after_label:
13816            if (tok == '}') {
13817                warning("deprecated use of label at end of compound statement");
13818            } else {
13819                if (is_expr)
13820                    vpop();
13821                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
13822            }
13823        } else {
13824            /* expression case */
13825            if (tok != ';') {
13826                if (is_expr) {
13827                    vpop();
13828                    gexpr();
13829                } else {
13830                    gexpr();
13831                    vpop();
13832                }
13833            }
13834            skip(';');
13835        }
13836    }
13837}
13838
13839/* t is the array or struct type. c is the array or struct
13840   address. cur_index/cur_field is the pointer to the current
13841   value. 'size_only' is true if only size info is needed (only used
13842   in arrays) */
13843static void decl_designator(CType *type, Section *sec, unsigned long c,
13844                            int *cur_index, Sym **cur_field,
13845                            int size_only)
13846{
13847    Sym *s, *f;
13848    int notfirst, index, index_last, align, l, nb_elems, elem_size;
13849    CType type1;
13850
13851    notfirst = 0;
13852    elem_size = 0;
13853    nb_elems = 1;
13854    if (gnu_ext && (l = is_label()) != 0)
13855        goto struct_field;
13856    while (tok == '[' || tok == '.') {
13857        if (tok == '[') {
13858            if (!(type->t & VT_ARRAY))
13859                expect("array type");
13860            s = type->ref;
13861            next();
13862            index = expr_const();
13863            if (index < 0 || (s->c >= 0 && index >= s->c))
13864                expect("invalid index");
13865            if (tok == TOK_DOTS && gnu_ext) {
13866                next();
13867                index_last = expr_const();
13868                if (index_last < 0 ||
13869                    (s->c >= 0 && index_last >= s->c) ||
13870                    index_last < index)
13871                    expect("invalid index");
13872            } else {
13873                index_last = index;
13874            }
13875            skip(']');
13876            if (!notfirst)
13877                *cur_index = index_last;
13878            type = pointed_type(type);
13879            elem_size = type_size(type, &align);
13880            c += index * elem_size;
13881            /* NOTE: we only support ranges for last designator */
13882            nb_elems = index_last - index + 1;
13883            if (nb_elems != 1) {
13884                notfirst = 1;
13885                break;
13886            }
13887        } else {
13888            next();
13889            l = tok;
13890            next();
13891        struct_field:
13892            if ((type->t & VT_BTYPE) != VT_STRUCT)
13893                expect("struct/union type");
13894            s = type->ref;
13895            l |= SYM_FIELD;
13896            f = s->next;
13897            while (f) {
13898                if (f->v == l)
13899                    break;
13900                f = f->next;
13901            }
13902            if (!f)
13903                expect("field");
13904            if (!notfirst)
13905                *cur_field = f;
13906            /* XXX: fix this mess by using explicit storage field */
13907            type1 = f->type;
13908            type1.t |= (type->t & ~VT_TYPE);
13909            type = &type1;
13910            c += f->c;
13911        }
13912        notfirst = 1;
13913    }
13914    if (notfirst) {
13915        if (tok == '=') {
13916            next();
13917        } else {
13918            if (!gnu_ext)
13919                expect("=");
13920        }
13921    } else {
13922        if (type->t & VT_ARRAY) {
13923            index = *cur_index;
13924            type = pointed_type(type);
13925            c += index * type_size(type, &align);
13926        } else {
13927            f = *cur_field;
13928            if (!f)
13929                error("too many field init");
13930            /* XXX: fix this mess by using explicit storage field */
13931            type1 = f->type;
13932            type1.t |= (type->t & ~VT_TYPE);
13933            type = &type1;
13934            c += f->c;
13935        }
13936    }
13937    decl_initializer(type, sec, c, 0, size_only);
13938
13939    /* XXX: make it more general */
13940    if (!size_only && nb_elems > 1) {
13941        unsigned long c_end;
13942        uint8_t *src, *dst;
13943        int i;
13944
13945        if (!sec)
13946            error("range init not supported yet for dynamic storage");
13947        c_end = c + nb_elems * elem_size;
13948        if (c_end > sec->data_allocated)
13949            section_realloc(sec, c_end);
13950        src = sec->data + c;
13951        dst = src;
13952        for(i = 1; i < nb_elems; i++) {
13953            dst += elem_size;
13954            memcpy(dst, src, elem_size);
13955        }
13956    }
13957}
13958
13959#define EXPR_VAL   0
13960#define EXPR_CONST 1
13961#define EXPR_ANY   2
13962
13963/* store a value or an expression directly in global data or in local array */
13964static void init_putv(CType *type, Section *sec, unsigned long c,
13965                      int v, int expr_type)
13966{
13967    int saved_global_expr, bt, bit_pos, bit_size;
13968    void *ptr;
13969    unsigned long long bit_mask;
13970    CType dtype;
13971
13972    switch(expr_type) {
13973    case EXPR_VAL:
13974        vpushi(v);
13975        break;
13976    case EXPR_CONST:
13977        /* compound literals must be allocated globally in this case */
13978        saved_global_expr = global_expr;
13979        global_expr = 1;
13980        expr_const1();
13981        global_expr = saved_global_expr;
13982        /* NOTE: symbols are accepted */
13983        if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
13984            error("initializer element is not constant");
13985        break;
13986    case EXPR_ANY:
13987        expr_eq();
13988        break;
13989    }
13990
13991    dtype = *type;
13992    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
13993
13994    if (sec) {
13995        /* XXX: not portable */
13996        /* XXX: generate error if incorrect relocation */
13997        gen_assign_cast(&dtype);
13998        bt = type->t & VT_BTYPE;
13999        ptr = sec->data + c;
14000        /* XXX: make code faster ? */
14001        if (!(type->t & VT_BITFIELD)) {
14002            bit_pos = 0;
14003            bit_size = 32;
14004            bit_mask = -1LL;
14005        } else {
14006            bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
14007            bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
14008            bit_mask = (1LL << bit_size) - 1;
14009        }
14010        if ((vtop->r & VT_SYM) &&
14011            (bt == VT_BYTE ||
14012             bt == VT_SHORT ||
14013             bt == VT_DOUBLE ||
14014             bt == VT_LDOUBLE ||
14015             bt == VT_LLONG ||
14016             (bt == VT_INT && bit_size != 32)))
14017            error("initializer element is not computable at load time");
14018        switch(bt) {
14019        case VT_BYTE:
14020            *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14021            break;
14022        case VT_SHORT:
14023            *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14024            break;
14025        case VT_DOUBLE:
14026            *(double *)ptr = vtop->c.d;
14027            break;
14028        case VT_LDOUBLE:
14029            *(long double *)ptr = vtop->c.ld;
14030            break;
14031        case VT_LLONG:
14032            *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
14033            break;
14034        default:
14035            if (vtop->r & VT_SYM) {
14036                greloc(sec, vtop->sym, c, R_DATA_32);
14037            }
14038            *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
14039            break;
14040        }
14041        vtop--;
14042    } else {
14043        vset(&dtype, VT_LOCAL, c);
14044        vswap();
14045        vstore();
14046        vpop();
14047    }
14048}
14049
14050/* put zeros for variable based init */
14051static void init_putz(CType *t, Section *sec, unsigned long c, int size)
14052{
14053    if (sec) {
14054        /* nothing to do because globals are already set to zero */
14055    } else {
14056        vpush_global_sym(&func_old_type, TOK_memset);
14057        vseti(VT_LOCAL, c);
14058        vpushi(0);
14059        vpushi(size);
14060        gfunc_call(3);
14061    }
14062}
14063
14064/* 't' contains the type and storage info. 'c' is the offset of the
14065   object in section 'sec'. If 'sec' is NULL, it means stack based
14066   allocation. 'first' is true if array '{' must be read (multi
14067   dimension implicit array init handling). 'size_only' is true if
14068   size only evaluation is wanted (only for arrays). */
14069static void decl_initializer(CType *type, Section *sec, unsigned long c,
14070                             int first, int size_only)
14071{
14072    int index, array_length, n, no_oblock, nb, parlevel, i;
14073    int size1, align1, expr_type;
14074    Sym *s, *f;
14075    CType *t1;
14076
14077    if (type->t & VT_ARRAY) {
14078        s = type->ref;
14079        n = s->c;
14080        array_length = 0;
14081        t1 = pointed_type(type);
14082        size1 = type_size(t1, &align1);
14083
14084        no_oblock = 1;
14085        if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
14086            tok == '{') {
14087            skip('{');
14088            no_oblock = 0;
14089        }
14090
14091        /* only parse strings here if correct type (otherwise: handle
14092           them as ((w)char *) expressions */
14093        if ((tok == TOK_LSTR &&
14094             (t1->t & VT_BTYPE) == VT_INT) ||
14095            (tok == TOK_STR &&
14096             (t1->t & VT_BTYPE) == VT_BYTE)) {
14097            while (tok == TOK_STR || tok == TOK_LSTR) {
14098                int cstr_len, ch;
14099                CString *cstr;
14100
14101                cstr = tokc.cstr;
14102                /* compute maximum number of chars wanted */
14103                if (tok == TOK_STR)
14104                    cstr_len = cstr->size;
14105                else
14106                    cstr_len = cstr->size / sizeof(int);
14107                cstr_len--;
14108                nb = cstr_len;
14109                if (n >= 0 && nb > (n - array_length))
14110                    nb = n - array_length;
14111                if (!size_only) {
14112                    if (cstr_len > nb)
14113                        warning("initializer-string for array is too long");
14114                    /* in order to go faster for common case (char
14115                       string in global variable, we handle it
14116                       specifically */
14117                    if (sec && tok == TOK_STR && size1 == 1) {
14118                        memcpy(sec->data + c + array_length, cstr->data, nb);
14119                    } else {
14120                        for(i=0;i<nb;i++) {
14121                            if (tok == TOK_STR)
14122                                ch = ((unsigned char *)cstr->data)[i];
14123                            else
14124                                ch = ((int *)cstr->data)[i];
14125                            init_putv(t1, sec, c + (array_length + i) * size1,
14126                                      ch, EXPR_VAL);
14127                        }
14128                    }
14129                }
14130                array_length += nb;
14131                next();
14132            }
14133            /* only add trailing zero if enough storage (no
14134               warning in this case since it is standard) */
14135            if (n < 0 || array_length < n) {
14136                if (!size_only) {
14137                    init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
14138                }
14139                array_length++;
14140            }
14141        } else {
14142            index = 0;
14143            while (tok != '}') {
14144                decl_designator(type, sec, c, &index, NULL, size_only);
14145                if (n >= 0 && index >= n)
14146                    error("index too large");
14147                /* must put zero in holes (note that doing it that way
14148                   ensures that it even works with designators) */
14149                if (!size_only && array_length < index) {
14150                    init_putz(t1, sec, c + array_length * size1,
14151                              (index - array_length) * size1);
14152                }
14153                index++;
14154                if (index > array_length)
14155                    array_length = index;
14156                /* special test for multi dimensional arrays (may not
14157                   be strictly correct if designators are used at the
14158                   same time) */
14159                if (index >= n && no_oblock)
14160                    break;
14161                if (tok == '}')
14162                    break;
14163                skip(',');
14164            }
14165        }
14166        if (!no_oblock)
14167            skip('}');
14168        /* put zeros at the end */
14169        if (!size_only && n >= 0 && array_length < n) {
14170            init_putz(t1, sec, c + array_length * size1,
14171                      (n - array_length) * size1);
14172        }
14173        /* patch type size if needed */
14174        if (n < 0)
14175            s->c = array_length;
14176    } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
14177               (sec || !first || tok == '{')) {
14178        int par_count;
14179
14180        /* NOTE: the previous test is a specific case for automatic
14181           struct/union init */
14182        /* XXX: union needs only one init */
14183
14184        /* XXX: this test is incorrect for local initializers
14185           beginning with ( without {. It would be much more difficult
14186           to do it correctly (ideally, the expression parser should
14187           be used in all cases) */
14188        par_count = 0;
14189        if (tok == '(') {
14190            AttributeDef ad1;
14191            CType type1;
14192            next();
14193            while (tok == '(') {
14194                par_count++;
14195                next();
14196            }
14197            if (!parse_btype(&type1, &ad1))
14198                expect("cast");
14199            type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
14200#if 0
14201            if (!is_assignable_types(type, &type1))
14202                error("invalid type for cast");
14203#endif
14204            skip(')');
14205        }
14206        no_oblock = 1;
14207        if (first || tok == '{') {
14208            skip('{');
14209            no_oblock = 0;
14210        }
14211        s = type->ref;
14212        f = s->next;
14213        array_length = 0;
14214        index = 0;
14215        n = s->c;
14216        while (tok != '}') {
14217            decl_designator(type, sec, c, NULL, &f, size_only);
14218            index = f->c;
14219            if (!size_only && array_length < index) {
14220                init_putz(type, sec, c + array_length,
14221                          index - array_length);
14222            }
14223            index = index + type_size(&f->type, &align1);
14224            if (index > array_length)
14225                array_length = index;
14226            f = f->next;
14227            if (no_oblock && f == NULL)
14228                break;
14229            if (tok == '}')
14230                break;
14231            skip(',');
14232        }
14233        /* put zeros at the end */
14234        if (!size_only && array_length < n) {
14235            init_putz(type, sec, c + array_length,
14236                      n - array_length);
14237        }
14238        if (!no_oblock)
14239            skip('}');
14240        while (par_count) {
14241            skip(')');
14242            par_count--;
14243        }
14244    } else if (tok == '{') {
14245        next();
14246        decl_initializer(type, sec, c, first, size_only);
14247        skip('}');
14248    } else if (size_only) {
14249        /* just skip expression */
14250        parlevel = 0;
14251        while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
14252               tok != -1) {
14253            if (tok == '(')
14254                parlevel++;
14255            else if (tok == ')')
14256                parlevel--;
14257            next();
14258        }
14259    } else {
14260        /* currently, we always use constant expression for globals
14261           (may change for scripting case) */
14262        expr_type = EXPR_CONST;
14263        if (!sec)
14264            expr_type = EXPR_ANY;
14265        init_putv(type, sec, c, 0, expr_type);
14266    }
14267}
14268
14269/* parse an initializer for type 't' if 'has_init' is non zero, and
14270   allocate space in local or global data space ('r' is either
14271   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
14272   variable 'v' of scope 'scope' is declared before initializers are
14273   parsed. If 'v' is zero, then a reference to the new object is put
14274   in the value stack. If 'has_init' is 2, a special parsing is done
14275   to handle string constants. */
14276static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
14277                                   int has_init, int v, int scope)
14278{
14279    int size, align, addr, data_offset;
14280    int level;
14281    ParseState saved_parse_state;
14282    TokenString init_str;
14283    Section *sec;
14284
14285    size = type_size(type, &align);
14286    /* If unknown size, we must evaluate it before
14287       evaluating initializers because
14288       initializers can generate global data too
14289       (e.g. string pointers or ISOC99 compound
14290       literals). It also simplifies local
14291       initializers handling */
14292    tok_str_new(&init_str);
14293    if (size < 0) {
14294        if (!has_init)
14295            error("unknown type size");
14296        /* get all init string */
14297        if (has_init == 2) {
14298            /* only get strings */
14299            while (tok == TOK_STR || tok == TOK_LSTR) {
14300                tok_str_add_tok(&init_str);
14301                next();
14302            }
14303        } else {
14304            level = 0;
14305            while (level > 0 || (tok != ',' && tok != ';')) {
14306                if (tok < 0)
14307                    error("unexpected end of file in initializer");
14308                tok_str_add_tok(&init_str);
14309                if (tok == '{')
14310                    level++;
14311                else if (tok == '}') {
14312                    if (level == 0)
14313                        break;
14314                    level--;
14315                }
14316                next();
14317            }
14318        }
14319        tok_str_add(&init_str, -1);
14320        tok_str_add(&init_str, 0);
14321
14322        /* compute size */
14323        save_parse_state(&saved_parse_state);
14324
14325        macro_ptr = init_str.str;
14326        next();
14327        decl_initializer(type, NULL, 0, 1, 1);
14328        /* prepare second initializer parsing */
14329        macro_ptr = init_str.str;
14330        next();
14331
14332        /* if still unknown size, error */
14333        size = type_size(type, &align);
14334        if (size < 0)
14335            error("unknown type size");
14336    }
14337    /* take into account specified alignment if bigger */
14338    if (ad->aligned) {
14339        if (ad->aligned > align)
14340            align = ad->aligned;
14341    } else if (ad->packed) {
14342        align = 1;
14343    }
14344    if ((r & VT_VALMASK) == VT_LOCAL) {
14345        sec = NULL;
14346        if (do_bounds_check && (type->t & VT_ARRAY))
14347            loc--;
14348        loc = (loc - size) & -align;
14349        addr = loc;
14350        /* handles bounds */
14351        /* XXX: currently, since we do only one pass, we cannot track
14352           '&' operators, so we add only arrays */
14353        if (do_bounds_check && (type->t & VT_ARRAY)) {
14354            unsigned long *bounds_ptr;
14355            /* add padding between regions */
14356            loc--;
14357            /* then add local bound info */
14358            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
14359            bounds_ptr[0] = addr;
14360            bounds_ptr[1] = size;
14361        }
14362        if (v) {
14363            /* local variable */
14364            sym_push(v, type, r, addr);
14365        } else {
14366            /* push local reference */
14367            vset(type, r, addr);
14368        }
14369    } else {
14370        Sym *sym;
14371
14372        sym = NULL;
14373        if (v && scope == VT_CONST) {
14374            /* see if the symbol was already defined */
14375            sym = sym_find(v);
14376            if (sym) {
14377                if (!is_compatible_types(&sym->type, type))
14378                    error("incompatible types for redefinition of '%s'",
14379                          get_tok_str(v, NULL));
14380                if (sym->type.t & VT_EXTERN) {
14381                    /* if the variable is extern, it was not allocated */
14382                    sym->type.t &= ~VT_EXTERN;
14383                    /* set array size if it was ommited in extern
14384                       declaration */
14385                    if ((sym->type.t & VT_ARRAY) &&
14386                        sym->type.ref->c < 0 &&
14387                        type->ref->c >= 0)
14388                        sym->type.ref->c = type->ref->c;
14389                } else {
14390                    /* we accept several definitions of the same
14391                       global variable. this is tricky, because we
14392                       must play with the SHN_COMMON type of the symbol */
14393                    /* XXX: should check if the variable was already
14394                       initialized. It is incorrect to initialized it
14395                       twice */
14396                    /* no init data, we won't add more to the symbol */
14397                    if (!has_init)
14398                        goto no_alloc;
14399                }
14400            }
14401        }
14402
14403        /* allocate symbol in corresponding section */
14404        sec = ad->section;
14405        if (!sec) {
14406            if (has_init)
14407                sec = data_section;
14408            else if (tcc_state->nocommon)
14409                sec = bss_section;
14410        }
14411        if (sec) {
14412            data_offset = sec->data_offset;
14413            data_offset = (data_offset + align - 1) & -align;
14414            addr = data_offset;
14415            /* very important to increment global pointer at this time
14416               because initializers themselves can create new initializers */
14417            data_offset += size;
14418            /* add padding if bound check */
14419            if (do_bounds_check)
14420                data_offset++;
14421            sec->data_offset = data_offset;
14422            /* allocate section space to put the data */
14423            if (sec->sh_type != SHT_NOBITS &&
14424                data_offset > sec->data_allocated)
14425                section_realloc(sec, data_offset);
14426            /* align section if needed */
14427            if (align > sec->sh_addralign)
14428                sec->sh_addralign = align;
14429        } else {
14430            addr = 0; /* avoid warning */
14431        }
14432
14433        if (v) {
14434            if (scope == VT_CONST) {
14435                if (!sym)
14436                    goto do_def;
14437            } else {
14438            do_def:
14439                sym = sym_push(v, type, r | VT_SYM, 0);
14440            }
14441            /* update symbol definition */
14442            if (sec) {
14443                put_extern_sym(sym, sec, addr, size);
14444            } else {
14445                Elf32_Sym *esym;
14446                /* put a common area */
14447                put_extern_sym(sym, NULL, align, size);
14448                /* XXX: find a nicer way */
14449                esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
14450                esym->st_shndx = SHN_COMMON;
14451            }
14452        } else {
14453            CValue cval;
14454
14455            /* push global reference */
14456            sym = get_sym_ref(type, sec, addr, size);
14457            cval.ul = 0;
14458            vsetc(type, VT_CONST | VT_SYM, &cval);
14459            vtop->sym = sym;
14460        }
14461
14462        /* handles bounds now because the symbol must be defined
14463           before for the relocation */
14464        if (do_bounds_check) {
14465            unsigned long *bounds_ptr;
14466
14467            greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
14468            /* then add global bound info */
14469            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
14470            bounds_ptr[0] = 0; /* relocated */
14471            bounds_ptr[1] = size;
14472        }
14473    }
14474    if (has_init) {
14475        decl_initializer(type, sec, addr, 1, 0);
14476        /* restore parse state if needed */
14477        if (init_str.str) {
14478            tok_str_free(init_str.str);
14479            restore_parse_state(&saved_parse_state);
14480        }
14481    }
14482 no_alloc: ;
14483}
14484
14485void put_func_debug(Sym *sym)
14486{
14487    char buf[512];
14488
14489    /* stabs info */
14490    /* XXX: we put here a dummy type */
14491    snprintf(buf, sizeof(buf), "%s:%c1",
14492             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
14493    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
14494                cur_text_section, sym->c);
14495    last_ind = 0;
14496    last_line_num = 0;
14497}
14498
14499/* parse an old style function declaration list */
14500/* XXX: check multiple parameter */
14501static void func_decl_list(Sym *func_sym)
14502{
14503    AttributeDef ad;
14504    int v;
14505    Sym *s;
14506    CType btype, type;
14507
14508    /* parse each declaration */
14509    while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
14510        if (!parse_btype(&btype, &ad))
14511            expect("declaration list");
14512        if (((btype.t & VT_BTYPE) == VT_ENUM ||
14513             (btype.t & VT_BTYPE) == VT_STRUCT) &&
14514            tok == ';') {
14515            /* we accept no variable after */
14516        } else {
14517            for(;;) {
14518                type = btype;
14519                type_decl(&type, &ad, &v, TYPE_DIRECT);
14520                /* find parameter in function parameter list */
14521                s = func_sym->next;
14522                while (s != NULL) {
14523                    if ((s->v & ~SYM_FIELD) == v)
14524                        goto found;
14525                    s = s->next;
14526                }
14527                error("declaration for parameter '%s' but no such parameter",
14528                      get_tok_str(v, NULL));
14529            found:
14530                /* check that no storage specifier except 'register' was given */
14531                if (type.t & VT_STORAGE)
14532                    error("storage class specified for '%s'", get_tok_str(v, NULL));
14533                convert_parameter_type(&type);
14534                /* we can add the type (NOTE: it could be local to the function) */
14535                s->type = type;
14536                /* accept other parameters */
14537                if (tok == ',')
14538                    next();
14539                else
14540                    break;
14541            }
14542        }
14543        skip(';');
14544    }
14545}
14546
14547/* parse a function defined by symbol 'sym' and generate its code in
14548   'cur_text_section' */
14549static void gen_function(Sym *sym)
14550{
14551    ind = cur_text_section->data_offset;
14552    /* NOTE: we patch the symbol size later */
14553    put_extern_sym(sym, cur_text_section, ind, 0);
14554    funcname = get_tok_str(sym->v, NULL);
14555    func_ind = ind;
14556    /* put debug symbol */
14557    if (do_debug)
14558        put_func_debug(sym);
14559    /* push a dummy symbol to enable local sym storage */
14560    sym_push2(&local_stack, SYM_FIELD, 0, 0);
14561    gfunc_prolog(&sym->type);
14562    rsym = 0;
14563    block(NULL, NULL, NULL, NULL, 0, 0);
14564    gsym(rsym);
14565    gfunc_epilog();
14566    cur_text_section->data_offset = ind;
14567    label_pop(&global_label_stack, NULL);
14568    sym_pop(&local_stack, NULL); /* reset local stack */
14569    /* end of function */
14570    /* patch symbol size */
14571    ((Elf32_Sym *)symtab_section->data)[sym->c].st_size =
14572        ind - func_ind;
14573    if (do_debug) {
14574        put_stabn(N_FUN, 0, 0, ind - func_ind);
14575    }
14576    funcname = ""; /* for safety */
14577    func_vt.t = VT_VOID; /* for safety */
14578    ind = 0; /* for safety */
14579}
14580
14581static void gen_inline_functions(void)
14582{
14583    Sym *sym;
14584    CType *type;
14585    int *str, inline_generated;
14586
14587    /* iterate while inline function are referenced */
14588    for(;;) {
14589        inline_generated = 0;
14590        for(sym = global_stack; sym != NULL; sym = sym->prev) {
14591            type = &sym->type;
14592            if (((type->t & VT_BTYPE) == VT_FUNC) &&
14593                (type->t & (VT_STATIC | VT_INLINE)) ==
14594                (VT_STATIC | VT_INLINE) &&
14595                sym->c != 0) {
14596                /* the function was used: generate its code and
14597                   convert it to a normal function */
14598                str = (int *)sym->r;
14599                sym->r = VT_SYM | VT_CONST;
14600                type->t &= ~VT_INLINE;
14601
14602                macro_ptr = str;
14603                next();
14604                cur_text_section = text_section;
14605                gen_function(sym);
14606                macro_ptr = NULL; /* fail safe */
14607
14608                tok_str_free(str);
14609                inline_generated = 1;
14610            }
14611        }
14612        if (!inline_generated)
14613            break;
14614    }
14615
14616    /* free all remaining inline function tokens */
14617    for(sym = global_stack; sym != NULL; sym = sym->prev) {
14618        type = &sym->type;
14619        if (((type->t & VT_BTYPE) == VT_FUNC) &&
14620            (type->t & (VT_STATIC | VT_INLINE)) ==
14621            (VT_STATIC | VT_INLINE)) {
14622            str = (int *)sym->r;
14623            tok_str_free(str);
14624            sym->r = 0; /* fail safe */
14625        }
14626    }
14627}
14628
14629/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
14630static void decl(int l)
14631{
14632    int v, has_init, r;
14633    CType type, btype;
14634    Sym *sym;
14635    AttributeDef ad;
14636
14637    while (1) {
14638        if (!parse_btype(&btype, &ad)) {
14639            /* skip redundant ';' */
14640            /* XXX: find more elegant solution */
14641            if (tok == ';') {
14642                next();
14643                continue;
14644            }
14645            if (l == VT_CONST &&
14646                (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
14647                /* global asm block */
14648                asm_global_instr();
14649                continue;
14650            }
14651            /* special test for old K&R protos without explicit int
14652               type. Only accepted when defining global data */
14653            if (l == VT_LOCAL || tok < TOK_DEFINE)
14654                break;
14655            btype.t = VT_INT;
14656        }
14657        if (((btype.t & VT_BTYPE) == VT_ENUM ||
14658             (btype.t & VT_BTYPE) == VT_STRUCT) &&
14659            tok == ';') {
14660            /* we accept no variable after */
14661            next();
14662            continue;
14663        }
14664        while (1) { /* iterate thru each declaration */
14665            type = btype;
14666            type_decl(&type, &ad, &v, TYPE_DIRECT);
14667#if 0
14668            {
14669                char buf[500];
14670                type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
14671                printf("type = '%s'\n", buf);
14672            }
14673#endif
14674            if ((type.t & VT_BTYPE) == VT_FUNC) {
14675                /* if old style function prototype, we accept a
14676                   declaration list */
14677                sym = type.ref;
14678                if (sym->c == FUNC_OLD)
14679                    func_decl_list(sym);
14680            }
14681
14682            if (tok == '{') {
14683                if (l == VT_LOCAL)
14684                    error("cannot use local functions");
14685                if (!(type.t & VT_FUNC))
14686                    expect("function definition");
14687
14688                /* reject abstract declarators in function definition */
14689                sym = type.ref;
14690                while ((sym = sym->next) != NULL)
14691                    if (!(sym->v & ~SYM_FIELD))
14692                       expect("identifier");
14693
14694                /* XXX: cannot do better now: convert extern line to static inline */
14695                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
14696                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
14697
14698                sym = sym_find(v);
14699                if (sym) {
14700                    if ((sym->type.t & VT_BTYPE) != VT_FUNC)
14701                        goto func_error1;
14702                    /* specific case: if not func_call defined, we put
14703                       the one of the prototype */
14704                    /* XXX: should have default value */
14705                    if (sym->type.ref->r != FUNC_CDECL &&
14706                        type.ref->r == FUNC_CDECL)
14707                        type.ref->r = sym->type.ref->r;
14708                    if (!is_compatible_types(&sym->type, &type)) {
14709                    func_error1:
14710                        error("incompatible types for redefinition of '%s'",
14711                              get_tok_str(v, NULL));
14712                    }
14713                    /* if symbol is already defined, then put complete type */
14714                    sym->type = type;
14715                } else {
14716                    /* put function symbol */
14717                    sym = global_identifier_push(v, type.t, 0);
14718                    sym->type.ref = type.ref;
14719                }
14720
14721                /* static inline functions are just recorded as a kind
14722                   of macro. Their code will be emitted at the end of
14723                   the compilation unit only if they are used */
14724                if ((type.t & (VT_INLINE | VT_STATIC)) ==
14725                    (VT_INLINE | VT_STATIC)) {
14726                    TokenString func_str;
14727                    int block_level;
14728
14729                    tok_str_new(&func_str);
14730
14731                    block_level = 0;
14732                    for(;;) {
14733                        int t;
14734                        if (tok == TOK_EOF)
14735                            error("unexpected end of file");
14736                        tok_str_add_tok(&func_str);
14737                        t = tok;
14738                        next();
14739                        if (t == '{') {
14740                            block_level++;
14741                        } else if (t == '}') {
14742                            block_level--;
14743                            if (block_level == 0)
14744                                break;
14745                        }
14746                    }
14747                    tok_str_add(&func_str, -1);
14748                    tok_str_add(&func_str, 0);
14749                    sym->r = (long)func_str.str;
14750                } else {
14751                    /* compute text section */
14752                    cur_text_section = ad.section;
14753                    if (!cur_text_section)
14754                        cur_text_section = text_section;
14755                    sym->r = VT_SYM | VT_CONST;
14756                    gen_function(sym);
14757#ifdef TCC_TARGET_PE
14758                    if (ad.dllexport) {
14759                        ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
14760                    }
14761#endif
14762                }
14763                break;
14764            } else {
14765                if (btype.t & VT_TYPEDEF) {
14766                    /* save typedefed type  */
14767                    /* XXX: test storage specifiers ? */
14768                    sym = sym_push(v, &type, 0, 0);
14769                    sym->type.t |= VT_TYPEDEF;
14770                } else if ((type.t & VT_BTYPE) == VT_FUNC) {
14771                    /* external function definition */
14772                    /* specific case for func_call attribute */
14773                    if (ad.func_call)
14774                        type.ref->r = ad.func_call;
14775                    external_sym(v, &type, 0);
14776                } else {
14777                    /* not lvalue if array */
14778                    r = 0;
14779                    if (!(type.t & VT_ARRAY))
14780                        r |= lvalue_type(type.t);
14781                    has_init = (tok == '=');
14782                    if ((btype.t & VT_EXTERN) ||
14783                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
14784                         !has_init && l == VT_CONST && type.ref->c < 0)) {
14785                        /* external variable */
14786                        /* NOTE: as GCC, uninitialized global static
14787                           arrays of null size are considered as
14788                           extern */
14789                        external_sym(v, &type, r);
14790                    } else {
14791                        if (type.t & VT_STATIC)
14792                            r |= VT_CONST;
14793                        else
14794                            r |= l;
14795                        if (has_init)
14796                            next();
14797                        decl_initializer_alloc(&type, &ad, r,
14798                                               has_init, v, l);
14799                    }
14800                }
14801                if (tok != ',') {
14802                    skip(';');
14803                    break;
14804                }
14805                next();
14806            }
14807        }
14808    }
14809}
14810
14811/* better than nothing, but needs extension to handle '-E' option
14812   correctly too */
14813static void preprocess_init(TCCState *s1)
14814{
14815    s1->include_stack_ptr = s1->include_stack;
14816    /* XXX: move that before to avoid having to initialize
14817       file->ifdef_stack_ptr ? */
14818    s1->ifdef_stack_ptr = s1->ifdef_stack;
14819    file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
14820
14821    /* XXX: not ANSI compliant: bound checking says error */
14822    vtop = vstack - 1;
14823    s1->pack_stack[0] = 0;
14824    s1->pack_stack_ptr = s1->pack_stack;
14825}
14826
14827/* compile the C file opened in 'file'. Return non zero if errors. */
14828static int tcc_compile(TCCState *s1)
14829{
14830    Sym *define_start;
14831    char buf[512];
14832    volatile int section_sym;
14833
14834#ifdef INC_DEBUG
14835    printf("%s: **** new file\n", file->filename);
14836#endif
14837    preprocess_init(s1);
14838
14839    funcname = "";
14840    anon_sym = SYM_FIRST_ANOM;
14841
14842    /* file info: full path + filename */
14843    section_sym = 0; /* avoid warning */
14844    if (do_debug) {
14845        section_sym = put_elf_sym(symtab_section, 0, 0,
14846                                  ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0,
14847                                  text_section->sh_num, NULL);
14848        dummy_char_star = getcwd(buf, sizeof(buf));
14849        pstrcat(buf, sizeof(buf), "/");
14850        put_stabs_r(buf, N_SO, 0, 0,
14851                    text_section->data_offset, text_section, section_sym);
14852        put_stabs_r(file->filename, N_SO, 0, 0,
14853                    text_section->data_offset, text_section, section_sym);
14854    }
14855    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
14856       symbols can be safely used */
14857    put_elf_sym(symtab_section, 0, 0,
14858                ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0,
14859                SHN_ABS, file->filename);
14860
14861    /* define some often used types */
14862    int_type.t = VT_INT;
14863
14864    char_pointer_type.t = VT_BYTE;
14865    mk_pointer(&char_pointer_type);
14866
14867    func_old_type.t = VT_FUNC;
14868    func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
14869
14870#if 0
14871    /* define 'void *alloca(unsigned int)' builtin function */
14872    {
14873        Sym *s1;
14874
14875        p = anon_sym++;
14876        sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
14877        s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
14878        s1->next = NULL;
14879        sym->next = s1;
14880        sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
14881    }
14882#endif
14883
14884    define_start = define_stack;
14885
14886    if (setjmp(s1->error_jmp_buf) == 0) {
14887        s1->nb_errors = 0;
14888        s1->error_set_jmp_enabled = 1;
14889
14890        ch = file->buf_ptr[0];
14891        tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
14892        parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
14893        next();
14894        decl(VT_CONST);
14895        if (tok != TOK_EOF)
14896            expect("declaration");
14897
14898        /* end of translation unit info */
14899        if (do_debug) {
14900            put_stabs_r(NULL, N_SO, 0, 0,
14901                        text_section->data_offset, text_section, section_sym);
14902        }
14903    }
14904    s1->error_set_jmp_enabled = 0;
14905
14906    /* reset define stack, but leave -Dsymbols (may be incorrect if
14907       they are undefined) */
14908    free_defines(define_start);
14909
14910    gen_inline_functions();
14911
14912    sym_pop(&global_stack, NULL);
14913
14914    return s1->nb_errors != 0 ? -1 : 0;
14915}
14916
14917#ifdef LIBTCC
14918int tcc_compile_string(TCCState *s, const char *str)
14919{
14920    BufferedFile bf1, *bf = &bf1;
14921    int ret, len;
14922    char *buf;
14923
14924    /* init file structure */
14925    bf->fd = -1;
14926    /* XXX: avoid copying */
14927    len = strlen(str);
14928    buf = tcc_malloc(len + 1);
14929    if (!buf)
14930        return -1;
14931    memcpy(buf, str, len);
14932    buf[len] = CH_EOB;
14933    bf->buf_ptr = buf;
14934    bf->buf_end = buf + len;
14935    pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
14936    bf->line_num = 1;
14937    file = bf;
14938
14939    ret = tcc_compile(s);
14940
14941    tcc_free(buf);
14942
14943    /* currently, no need to close */
14944    return ret;
14945}
14946#endif
14947
14948/* define a preprocessor symbol. A value can also be provided with the '=' operator */
14949void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
14950{
14951    BufferedFile bf1, *bf = &bf1;
14952
14953    pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
14954    pstrcat(bf->buffer, IO_BUF_SIZE, " ");
14955    /* default value */
14956    if (!value)
14957        value = "1";
14958    pstrcat(bf->buffer, IO_BUF_SIZE, value);
14959
14960    /* init file structure */
14961    bf->fd = -1;
14962    bf->buf_ptr = bf->buffer;
14963    bf->buf_end = bf->buffer + strlen(bf->buffer);
14964    *bf->buf_end = CH_EOB;
14965    bf->filename[0] = '\0';
14966    bf->line_num = 1;
14967    file = bf;
14968
14969    s1->include_stack_ptr = s1->include_stack;
14970
14971    /* parse with define parser */
14972    ch = file->buf_ptr[0];
14973    next_nomacro();
14974    parse_define();
14975    file = NULL;
14976}
14977
14978/* undefine a preprocessor symbol */
14979void tcc_undefine_symbol(TCCState *s1, const char *sym)
14980{
14981    TokenSym *ts;
14982    Sym *s;
14983    ts = tok_alloc(sym, strlen(sym));
14984    s = define_find(ts->tok);
14985    /* undefine symbol by putting an invalid name */
14986    if (s)
14987        define_undef(s);
14988}
14989
14990#ifdef CONFIG_TCC_ASM
14991
14992#ifdef TCC_TARGET_I386
14993// njn: inlined i386-asm.c
14994//#include "i386-asm.c"
14995//---------------------------------------------------------------------------
14996/*
14997 *  i386 specific functions for TCC assembler
14998 *
14999 *  Copyright (c) 2001, 2002 Fabrice Bellard
15000 *
15001 * This library is free software; you can redistribute it and/or
15002 * modify it under the terms of the GNU Lesser General Public
15003 * License as published by the Free Software Foundation; either
15004 * version 2 of the License, or (at your option) any later version.
15005 *
15006 * This library is distributed in the hope that it will be useful,
15007 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15008 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15009 * Lesser General Public License for more details.
15010 *
15011 * You should have received a copy of the GNU Lesser General Public
15012 * License along with this library; if not, write to the Free Software
15013 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15014 */
15015
15016#define MAX_OPERANDS 3
15017
15018typedef struct ASMInstr {
15019    uint16_t sym;
15020    uint16_t opcode;
15021    uint16_t instr_type;
15022#define OPC_JMP       0x01  /* jmp operand */
15023#define OPC_B         0x02  /* only used zith OPC_WL */
15024#define OPC_WL        0x04  /* accepts w, l or no suffix */
15025#define OPC_BWL       (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
15026#define OPC_REG       0x08 /* register is added to opcode */
15027#define OPC_MODRM     0x10 /* modrm encoding */
15028#define OPC_FWAIT     0x20 /* add fwait opcode */
15029#define OPC_TEST      0x40 /* test opcodes */
15030#define OPC_SHIFT     0x80 /* shift opcodes */
15031#define OPC_D16      0x0100 /* generate data16 prefix */
15032#define OPC_ARITH    0x0200 /* arithmetic opcodes */
15033#define OPC_SHORTJMP 0x0400 /* short jmp operand */
15034#define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
15035#define OPC_GROUP_SHIFT 13
15036
15037/* in order to compress the operand type, we use specific operands and
15038   we or only with EA  */
15039#define OPT_REG8  0 /* warning: value is hardcoded from TOK_ASM_xxx */
15040#define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */
15041#define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */
15042#define OPT_MMX   3 /* warning: value is hardcoded from TOK_ASM_xxx */
15043#define OPT_SSE   4 /* warning: value is hardcoded from TOK_ASM_xxx */
15044#define OPT_CR    5 /* warning: value is hardcoded from TOK_ASM_xxx */
15045#define OPT_TR    6 /* warning: value is hardcoded from TOK_ASM_xxx */
15046#define OPT_DB    7 /* warning: value is hardcoded from TOK_ASM_xxx */
15047#define OPT_SEG   8
15048#define OPT_ST    9
15049#define OPT_IM8   10
15050#define OPT_IM8S  11
15051#define OPT_IM16  12
15052#define OPT_IM32  13
15053#define OPT_EAX   14 /* %al, %ax or %eax register */
15054#define OPT_ST0   15 /* %st(0) register */
15055#define OPT_CL    16 /* %cl register */
15056#define OPT_DX    17 /* %dx register */
15057#define OPT_ADDR  18 /* OP_EA with only offset */
15058#define OPT_INDIR 19 /* *(expr) */
15059
15060/* composite types */
15061#define OPT_COMPOSITE_FIRST   20
15062#define OPT_IM       20 /* IM8 | IM16 | IM32 */
15063#define OPT_REG      21 /* REG8 | REG16 | REG32 */
15064#define OPT_REGW     22 /* REG16 | REG32 */
15065#define OPT_IMW      23 /* IM16 | IM32 */
15066
15067/* can be ored with any OPT_xxx */
15068#define OPT_EA    0x80
15069
15070    uint8_t nb_ops;
15071    uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
15072} ASMInstr;
15073
15074typedef struct Operand {
15075    uint32_t type;
15076#define OP_REG8   (1 << OPT_REG8)
15077#define OP_REG16  (1 << OPT_REG16)
15078#define OP_REG32  (1 << OPT_REG32)
15079#define OP_MMX    (1 << OPT_MMX)
15080#define OP_SSE    (1 << OPT_SSE)
15081#define OP_CR     (1 << OPT_CR)
15082#define OP_TR     (1 << OPT_TR)
15083#define OP_DB     (1 << OPT_DB)
15084#define OP_SEG    (1 << OPT_SEG)
15085#define OP_ST     (1 << OPT_ST)
15086#define OP_IM8    (1 << OPT_IM8)
15087#define OP_IM8S   (1 << OPT_IM8S)
15088#define OP_IM16   (1 << OPT_IM16)
15089#define OP_IM32   (1 << OPT_IM32)
15090#define OP_EAX    (1 << OPT_EAX)
15091#define OP_ST0    (1 << OPT_ST0)
15092#define OP_CL     (1 << OPT_CL)
15093#define OP_DX     (1 << OPT_DX)
15094#define OP_ADDR   (1 << OPT_ADDR)
15095#define OP_INDIR  (1 << OPT_INDIR)
15096
15097#define OP_EA     0x40000000
15098#define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32)
15099#define OP_IM     OP_IM32
15100    int8_t  reg; /* register, -1 if none */
15101    int8_t  reg2; /* second register, -1 if none */
15102    uint8_t shift;
15103    ExprValue e;
15104} Operand;
15105
15106static const uint8_t reg_to_size[5] = {
15107    [OP_REG8] = 0,
15108    [OP_REG16] = 1,
15109    [OP_REG32] = 2,
15110};
15111
15112#define WORD_PREFIX_OPCODE 0x66
15113
15114#define NB_TEST_OPCODES 30
15115
15116static const uint8_t test_bits[NB_TEST_OPCODES] = {
15117 0x00, /* o */
15118 0x01, /* no */
15119 0x02, /* b */
15120 0x02, /* c */
15121 0x02, /* nae */
15122 0x03, /* nb */
15123 0x03, /* nc */
15124 0x03, /* ae */
15125 0x04, /* e */
15126 0x04, /* z */
15127 0x05, /* ne */
15128 0x05, /* nz */
15129 0x06, /* be */
15130 0x06, /* na */
15131 0x07, /* nbe */
15132 0x07, /* a */
15133 0x08, /* s */
15134 0x09, /* ns */
15135 0x0a, /* p */
15136 0x0a, /* pe */
15137 0x0b, /* np */
15138 0x0b, /* po */
15139 0x0c, /* l */
15140 0x0c, /* nge */
15141 0x0d, /* nl */
15142 0x0d, /* ge */
15143 0x0e, /* le */
15144 0x0e, /* ng */
15145 0x0f, /* nle */
15146 0x0f, /* g */
15147};
15148
15149static const ASMInstr asm_instrs[] = {
15150#define ALT(x) x
15151#define DEF_ASM_OP0(name, opcode)
15152#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
15153#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
15154#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
15155#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
15156// njn: inlined i386-asm.h
15157//#include "i386-asm.h"
15158//---------------------------------------------------------------------------
15159     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
15160     DEF_ASM_OP0(popa, 0x61)
15161     DEF_ASM_OP0(clc, 0xf8)
15162     DEF_ASM_OP0(cld, 0xfc)
15163     DEF_ASM_OP0(cli, 0xfa)
15164     DEF_ASM_OP0(clts, 0x0f06)
15165     DEF_ASM_OP0(cmc, 0xf5)
15166     DEF_ASM_OP0(lahf, 0x9f)
15167     DEF_ASM_OP0(sahf, 0x9e)
15168     DEF_ASM_OP0(pushfl, 0x9c)
15169     DEF_ASM_OP0(popfl, 0x9d)
15170     DEF_ASM_OP0(pushf, 0x9c)
15171     DEF_ASM_OP0(popf, 0x9d)
15172     DEF_ASM_OP0(stc, 0xf9)
15173     DEF_ASM_OP0(std, 0xfd)
15174     DEF_ASM_OP0(sti, 0xfb)
15175     DEF_ASM_OP0(aaa, 0x37)
15176     DEF_ASM_OP0(aas, 0x3f)
15177     DEF_ASM_OP0(daa, 0x27)
15178     DEF_ASM_OP0(das, 0x2f)
15179     DEF_ASM_OP0(aad, 0xd50a)
15180     DEF_ASM_OP0(aam, 0xd40a)
15181     DEF_ASM_OP0(cbw, 0x6698)
15182     DEF_ASM_OP0(cwd, 0x6699)
15183     DEF_ASM_OP0(cwde, 0x98)
15184     DEF_ASM_OP0(cdq, 0x99)
15185     DEF_ASM_OP0(cbtw, 0x6698)
15186     DEF_ASM_OP0(cwtl, 0x98)
15187     DEF_ASM_OP0(cwtd, 0x6699)
15188     DEF_ASM_OP0(cltd, 0x99)
15189     DEF_ASM_OP0(int3, 0xcc)
15190     DEF_ASM_OP0(into, 0xce)
15191     DEF_ASM_OP0(iret, 0xcf)
15192     DEF_ASM_OP0(rsm, 0x0faa)
15193     DEF_ASM_OP0(hlt, 0xf4)
15194     DEF_ASM_OP0(wait, 0x9b)
15195     DEF_ASM_OP0(nop, 0x90)
15196     DEF_ASM_OP0(xlat, 0xd7)
15197
15198     /* strings */
15199ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15200ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15201
15202ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15203ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15204
15205ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15206ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15207
15208ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15209ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15210
15211ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15212ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15213
15214ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15215ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15216
15217     /* bits */
15218
15219ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15220ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15221
15222ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15223ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15224
15225ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15226ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15227
15228ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15229ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15230
15231ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15232ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15233
15234     /* prefixes */
15235     DEF_ASM_OP0(aword, 0x67)
15236     DEF_ASM_OP0(addr16, 0x67)
15237     DEF_ASM_OP0(word, 0x66)
15238     DEF_ASM_OP0(data16, 0x66)
15239     DEF_ASM_OP0(lock, 0xf0)
15240     DEF_ASM_OP0(rep, 0xf3)
15241     DEF_ASM_OP0(repe, 0xf3)
15242     DEF_ASM_OP0(repz, 0xf3)
15243     DEF_ASM_OP0(repne, 0xf2)
15244     DEF_ASM_OP0(repnz, 0xf2)
15245
15246     DEF_ASM_OP0(invd, 0x0f08)
15247     DEF_ASM_OP0(wbinvd, 0x0f09)
15248     DEF_ASM_OP0(cpuid, 0x0fa2)
15249     DEF_ASM_OP0(wrmsr, 0x0f30)
15250     DEF_ASM_OP0(rdtsc, 0x0f31)
15251     DEF_ASM_OP0(rdmsr, 0x0f32)
15252     DEF_ASM_OP0(rdpmc, 0x0f33)
15253     DEF_ASM_OP0(ud2, 0x0f0b)
15254
15255     /* NOTE: we took the same order as gas opcode definition order */
15256ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15257ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15258ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15259ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15260ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15261ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15262
15263ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15264ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15265
15266ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15267ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15268ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15269ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15270ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15271ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15272
15273ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15274ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15275ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15276ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15277ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15278
15279ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15280ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15281ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15282ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15283ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15284
15285ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15286ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15287ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15288
15289ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15290ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15291ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15292ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15293
15294ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15295ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15296ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15297ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15298
15299ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15300ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15301ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15302ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15303
15304ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15305
15306ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15307ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15308ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15309ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15310ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15311
15312     /* arith */
15313ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
15314ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15315ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15316ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15317ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15318
15319ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15320ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15321ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15322ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15323
15324ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15325ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15326ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15327ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15328
15329ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15330ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15331
15332ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15333ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15334
15335ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15336ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15337ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15338ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15339ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15340
15341ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15342ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15343ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15344ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15345
15346     /* shifts */
15347ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15348ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15349ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15350
15351ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15352ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15353ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15354ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15355ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15356ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15357
15358ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15359ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15360ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15361ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15362
15363ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15364ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15365ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15366ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15367
15368ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15369ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15370    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15371    DEF_ASM_OP0(leave, 0xc9)
15372    DEF_ASM_OP0(ret, 0xc3)
15373ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15374    DEF_ASM_OP0(lret, 0xcb)
15375ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15376
15377ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15378    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15379    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15380    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15381    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15382    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15383    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15384
15385     /* float */
15386     /* specific fcomp handling */
15387ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15388
15389ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15390ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15391ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15392ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15393ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15394ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15395ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15396ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15397ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15398ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15399ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15400
15401     DEF_ASM_OP0(fucompp, 0xdae9)
15402     DEF_ASM_OP0(ftst, 0xd9e4)
15403     DEF_ASM_OP0(fxam, 0xd9e5)
15404     DEF_ASM_OP0(fld1, 0xd9e8)
15405     DEF_ASM_OP0(fldl2t, 0xd9e9)
15406     DEF_ASM_OP0(fldl2e, 0xd9ea)
15407     DEF_ASM_OP0(fldpi, 0xd9eb)
15408     DEF_ASM_OP0(fldlg2, 0xd9ec)
15409     DEF_ASM_OP0(fldln2, 0xd9ed)
15410     DEF_ASM_OP0(fldz, 0xd9ee)
15411
15412     DEF_ASM_OP0(f2xm1, 0xd9f0)
15413     DEF_ASM_OP0(fyl2x, 0xd9f1)
15414     DEF_ASM_OP0(fptan, 0xd9f2)
15415     DEF_ASM_OP0(fpatan, 0xd9f3)
15416     DEF_ASM_OP0(fxtract, 0xd9f4)
15417     DEF_ASM_OP0(fprem1, 0xd9f5)
15418     DEF_ASM_OP0(fdecstp, 0xd9f6)
15419     DEF_ASM_OP0(fincstp, 0xd9f7)
15420     DEF_ASM_OP0(fprem, 0xd9f8)
15421     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15422     DEF_ASM_OP0(fsqrt, 0xd9fa)
15423     DEF_ASM_OP0(fsincos, 0xd9fb)
15424     DEF_ASM_OP0(frndint, 0xd9fc)
15425     DEF_ASM_OP0(fscale, 0xd9fd)
15426     DEF_ASM_OP0(fsin, 0xd9fe)
15427     DEF_ASM_OP0(fcos, 0xd9ff)
15428     DEF_ASM_OP0(fchs, 0xd9e0)
15429     DEF_ASM_OP0(fabs, 0xd9e1)
15430     DEF_ASM_OP0(fninit, 0xdbe3)
15431     DEF_ASM_OP0(fnclex, 0xdbe2)
15432     DEF_ASM_OP0(fnop, 0xd9d0)
15433     DEF_ASM_OP0(fwait, 0x9b)
15434
15435    /* fp load */
15436    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15437    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15438    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15439ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15440    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15441    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15442    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15443    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15444    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15445
15446    /* fp store */
15447    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
15448    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15449    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15450    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15451ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15452    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15453    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15454    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15455    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15456    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15457
15458    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15459    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15460    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15461    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15462    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15463
15464    /* exchange */
15465    DEF_ASM_OP0(fxch, 0xd9c9)
15466ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15467
15468    /* misc FPU */
15469    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15470    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15471
15472    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15473    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15474    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15475    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15476    DEF_ASM_OP0(fnstsw, 0xdfe0)
15477ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15478ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15479    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15480ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15481ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15482    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15483    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15484    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15485    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15486    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15487    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15488    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15489    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15490    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15491    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15492    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15493
15494    /* segments */
15495    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15496    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15497    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15498    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15499    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15500    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15501ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15502    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15503    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15504    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15505    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15506    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15507    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15508    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15509    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15510
15511    /* 486 */
15512    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15513ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15514ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15515    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15516
15517    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15518    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15519
15520    /* pentium */
15521    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15522
15523    /* pentium pro */
15524    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15525
15526    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15527    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15528    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15529    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15530    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15531    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15532    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15533    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15534
15535    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15536    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15537    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15538    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15539
15540    /* mmx */
15541    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
15542    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
15543ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
15544    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15545ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
15546    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15547    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15548    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15549    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15550    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15551    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15552    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15553    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15554    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15555    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15556    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15557    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15558    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15559    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15560    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15561    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15562    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15563    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15564    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15565    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15566    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15567    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15568    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15569ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15570    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15571ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15572    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15573ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
15574    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15575ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15576    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15577ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
15578    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15579ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15580    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15581ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15582    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15583ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
15584    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15585    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15586    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15587    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15588    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15589    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15590    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15591    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15592    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15593    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15594    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15595    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15596    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15597    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
15598
15599#undef ALT
15600#undef DEF_ASM_OP0
15601#undef DEF_ASM_OP0L
15602#undef DEF_ASM_OP1
15603#undef DEF_ASM_OP2
15604#undef DEF_ASM_OP3
15605//---------------------------------------------------------------------------
15606
15607    /* last operation */
15608    { 0, },
15609};
15610
15611static const uint16_t op0_codes[] = {
15612#define ALT(x)
15613#define DEF_ASM_OP0(x, opcode) opcode,
15614#define DEF_ASM_OP0L(name, opcode, group, instr_type)
15615#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
15616#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
15617#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
15618// njn: inlined i386-asm.h
15619//#include "i386-asm.h"
15620//---------------------------------------------------------------------------
15621     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
15622     DEF_ASM_OP0(popa, 0x61)
15623     DEF_ASM_OP0(clc, 0xf8)
15624     DEF_ASM_OP0(cld, 0xfc)
15625     DEF_ASM_OP0(cli, 0xfa)
15626     DEF_ASM_OP0(clts, 0x0f06)
15627     DEF_ASM_OP0(cmc, 0xf5)
15628     DEF_ASM_OP0(lahf, 0x9f)
15629     DEF_ASM_OP0(sahf, 0x9e)
15630     DEF_ASM_OP0(pushfl, 0x9c)
15631     DEF_ASM_OP0(popfl, 0x9d)
15632     DEF_ASM_OP0(pushf, 0x9c)
15633     DEF_ASM_OP0(popf, 0x9d)
15634     DEF_ASM_OP0(stc, 0xf9)
15635     DEF_ASM_OP0(std, 0xfd)
15636     DEF_ASM_OP0(sti, 0xfb)
15637     DEF_ASM_OP0(aaa, 0x37)
15638     DEF_ASM_OP0(aas, 0x3f)
15639     DEF_ASM_OP0(daa, 0x27)
15640     DEF_ASM_OP0(das, 0x2f)
15641     DEF_ASM_OP0(aad, 0xd50a)
15642     DEF_ASM_OP0(aam, 0xd40a)
15643     DEF_ASM_OP0(cbw, 0x6698)
15644     DEF_ASM_OP0(cwd, 0x6699)
15645     DEF_ASM_OP0(cwde, 0x98)
15646     DEF_ASM_OP0(cdq, 0x99)
15647     DEF_ASM_OP0(cbtw, 0x6698)
15648     DEF_ASM_OP0(cwtl, 0x98)
15649     DEF_ASM_OP0(cwtd, 0x6699)
15650     DEF_ASM_OP0(cltd, 0x99)
15651     DEF_ASM_OP0(int3, 0xcc)
15652     DEF_ASM_OP0(into, 0xce)
15653     DEF_ASM_OP0(iret, 0xcf)
15654     DEF_ASM_OP0(rsm, 0x0faa)
15655     DEF_ASM_OP0(hlt, 0xf4)
15656     DEF_ASM_OP0(wait, 0x9b)
15657     DEF_ASM_OP0(nop, 0x90)
15658     DEF_ASM_OP0(xlat, 0xd7)
15659
15660     /* strings */
15661ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
15662ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
15663
15664ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
15665ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
15666
15667ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
15668ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
15669
15670ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
15671ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
15672
15673ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
15674ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
15675
15676ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
15677ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
15678
15679     /* bits */
15680
15681ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15682ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
15683
15684ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15685ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15686
15687ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15688ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15689
15690ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15691ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15692
15693ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
15694ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
15695
15696     /* prefixes */
15697     DEF_ASM_OP0(aword, 0x67)
15698     DEF_ASM_OP0(addr16, 0x67)
15699     DEF_ASM_OP0(word, 0x66)
15700     DEF_ASM_OP0(data16, 0x66)
15701     DEF_ASM_OP0(lock, 0xf0)
15702     DEF_ASM_OP0(rep, 0xf3)
15703     DEF_ASM_OP0(repe, 0xf3)
15704     DEF_ASM_OP0(repz, 0xf3)
15705     DEF_ASM_OP0(repne, 0xf2)
15706     DEF_ASM_OP0(repnz, 0xf2)
15707
15708     DEF_ASM_OP0(invd, 0x0f08)
15709     DEF_ASM_OP0(wbinvd, 0x0f09)
15710     DEF_ASM_OP0(cpuid, 0x0fa2)
15711     DEF_ASM_OP0(wrmsr, 0x0f30)
15712     DEF_ASM_OP0(rdtsc, 0x0f31)
15713     DEF_ASM_OP0(rdmsr, 0x0f32)
15714     DEF_ASM_OP0(rdpmc, 0x0f33)
15715     DEF_ASM_OP0(ud2, 0x0f0b)
15716
15717     /* NOTE: we took the same order as gas opcode definition order */
15718ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
15719ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
15720ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15721ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15722ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
15723ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
15724
15725ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
15726ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
15727
15728ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
15729ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
15730ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
15731ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
15732ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
15733ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
15734
15735ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
15736ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
15737ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15738ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
15739ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
15740
15741ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
15742ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15743ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
15744ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
15745ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
15746
15747ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
15748ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
15749ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
15750
15751ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
15752ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
15753ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15754ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15755
15756ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
15757ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
15758ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
15759ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
15760
15761ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
15762ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
15763ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
15764ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
15765
15766ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
15767
15768ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15769ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15770ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15771ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15772ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
15773
15774     /* arith */
15775ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
15776ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15777ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
15778ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15779ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
15780
15781ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
15782ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
15783ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
15784ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
15785
15786ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
15787ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15788ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
15789ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15790
15791ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15792ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15793
15794ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15795ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15796
15797ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
15798ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
15799ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
15800ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
15801ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
15802
15803ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15804ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15805ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
15806ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
15807
15808     /* shifts */
15809ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
15810ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
15811ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
15812
15813ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15814ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15815ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15816ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
15817ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
15818ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
15819
15820ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
15821ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
15822ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
15823ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
15824
15825ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
15826ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
15827ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
15828ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
15829
15830ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
15831ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
15832    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
15833    DEF_ASM_OP0(leave, 0xc9)
15834    DEF_ASM_OP0(ret, 0xc3)
15835ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
15836    DEF_ASM_OP0(lret, 0xcb)
15837ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
15838
15839ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
15840    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15841    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
15842    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15843    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
15844    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
15845    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
15846
15847     /* float */
15848     /* specific fcomp handling */
15849ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
15850
15851ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15852ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15853ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
15854ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
15855ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
15856ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
15857ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
15858ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15859ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15860ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15861ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
15862
15863     DEF_ASM_OP0(fucompp, 0xdae9)
15864     DEF_ASM_OP0(ftst, 0xd9e4)
15865     DEF_ASM_OP0(fxam, 0xd9e5)
15866     DEF_ASM_OP0(fld1, 0xd9e8)
15867     DEF_ASM_OP0(fldl2t, 0xd9e9)
15868     DEF_ASM_OP0(fldl2e, 0xd9ea)
15869     DEF_ASM_OP0(fldpi, 0xd9eb)
15870     DEF_ASM_OP0(fldlg2, 0xd9ec)
15871     DEF_ASM_OP0(fldln2, 0xd9ed)
15872     DEF_ASM_OP0(fldz, 0xd9ee)
15873
15874     DEF_ASM_OP0(f2xm1, 0xd9f0)
15875     DEF_ASM_OP0(fyl2x, 0xd9f1)
15876     DEF_ASM_OP0(fptan, 0xd9f2)
15877     DEF_ASM_OP0(fpatan, 0xd9f3)
15878     DEF_ASM_OP0(fxtract, 0xd9f4)
15879     DEF_ASM_OP0(fprem1, 0xd9f5)
15880     DEF_ASM_OP0(fdecstp, 0xd9f6)
15881     DEF_ASM_OP0(fincstp, 0xd9f7)
15882     DEF_ASM_OP0(fprem, 0xd9f8)
15883     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
15884     DEF_ASM_OP0(fsqrt, 0xd9fa)
15885     DEF_ASM_OP0(fsincos, 0xd9fb)
15886     DEF_ASM_OP0(frndint, 0xd9fc)
15887     DEF_ASM_OP0(fscale, 0xd9fd)
15888     DEF_ASM_OP0(fsin, 0xd9fe)
15889     DEF_ASM_OP0(fcos, 0xd9ff)
15890     DEF_ASM_OP0(fchs, 0xd9e0)
15891     DEF_ASM_OP0(fabs, 0xd9e1)
15892     DEF_ASM_OP0(fninit, 0xdbe3)
15893     DEF_ASM_OP0(fnclex, 0xdbe2)
15894     DEF_ASM_OP0(fnop, 0xd9d0)
15895     DEF_ASM_OP0(fwait, 0x9b)
15896
15897    /* fp load */
15898    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
15899    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
15900    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
15901ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
15902    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
15903    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
15904    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
15905    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
15906    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
15907
15908    /* fp store */
15909    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
15910    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
15911    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
15912    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
15913ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
15914    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
15915    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
15916    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
15917    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
15918    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
15919
15920    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
15921    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
15922    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
15923    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
15924    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
15925
15926    /* exchange */
15927    DEF_ASM_OP0(fxch, 0xd9c9)
15928ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
15929
15930    /* misc FPU */
15931    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
15932    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
15933
15934    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
15935    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
15936    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
15937    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
15938    DEF_ASM_OP0(fnstsw, 0xdfe0)
15939ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
15940ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
15941    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
15942ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
15943ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
15944    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
15945    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
15946    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15947    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
15948    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
15949    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
15950    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
15951    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
15952    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
15953    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
15954    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
15955
15956    /* segments */
15957    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
15958    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
15959    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
15960    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
15961    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
15962    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
15963ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
15964    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
15965    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
15966    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
15967    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
15968    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
15969    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
15970    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
15971    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
15972
15973    /* 486 */
15974    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
15975ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15976ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
15977    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
15978
15979    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
15980    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
15981
15982    /* pentium */
15983    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
15984
15985    /* pentium pro */
15986    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
15987
15988    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15989    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15990    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15991    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15992    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15993    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15994    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15995    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15996
15997    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
15998    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
15999    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
16000    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
16001
16002    /* mmx */
16003    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
16004    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
16005ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
16006    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16007ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
16008    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16009    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16010    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16011    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16012    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16013    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16014    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16015    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16016    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16017    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16018    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16019    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16020    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16021    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16022    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16023    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16024    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16025    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16026    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16027    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16028    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16029    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16030    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16031ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16032    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16033ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16034    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16035ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
16036    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16037ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16038    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16039ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
16040    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16041ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16042    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16043ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16044    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16045ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
16046    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16047    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16048    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16049    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16050    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16051    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16052    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16053    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16054    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16055    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16056    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16057    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16058    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16059    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
16060
16061#undef ALT
16062#undef DEF_ASM_OP0
16063#undef DEF_ASM_OP0L
16064#undef DEF_ASM_OP1
16065#undef DEF_ASM_OP2
16066#undef DEF_ASM_OP3
16067//---------------------------------------------------------------------------
16068};
16069
16070static inline int get_reg_shift(TCCState *s1)
16071{
16072    int shift, v;
16073
16074    v = asm_int_expr(s1);
16075    switch(v) {
16076    case 1:
16077        shift = 0;
16078        break;
16079    case 2:
16080        shift = 1;
16081        break;
16082    case 4:
16083        shift = 2;
16084        break;
16085    case 8:
16086        shift = 3;
16087        break;
16088    default:
16089        expect("1, 2, 4 or 8 constant");
16090        shift = 0;
16091        break;
16092    }
16093    return shift;
16094}
16095
16096static int asm_parse_reg(void)
16097{
16098    int reg;
16099    if (tok != '%')
16100        goto error_32;
16101    next();
16102    if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
16103        reg = tok - TOK_ASM_eax;
16104        next();
16105        return reg;
16106    } else {
16107    error_32:
16108        expect("32 bit register");
16109        return 0;
16110    }
16111}
16112
16113static void parse_operand(TCCState *s1, Operand *op)
16114{
16115    ExprValue e;
16116    int reg, indir;
16117    const char *p;
16118
16119    indir = 0;
16120    if (tok == '*') {
16121        next();
16122        indir = OP_INDIR;
16123    }
16124
16125    if (tok == '%') {
16126        next();
16127        if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
16128            reg = tok - TOK_ASM_al;
16129            op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
16130            op->reg = reg & 7;
16131            if ((op->type & OP_REG) && op->reg == TREG_EAX)
16132                op->type |= OP_EAX;
16133            else if (op->type == OP_REG8 && op->reg == TREG_ECX)
16134                op->type |= OP_CL;
16135            else if (op->type == OP_REG16 && op->reg == TREG_EDX)
16136                op->type |= OP_DX;
16137        } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
16138            op->type = OP_DB;
16139            op->reg = tok - TOK_ASM_dr0;
16140        } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
16141            op->type = OP_SEG;
16142            op->reg = tok - TOK_ASM_es;
16143        } else if (tok == TOK_ASM_st) {
16144            op->type = OP_ST;
16145            op->reg = 0;
16146            next();
16147            if (tok == '(') {
16148                next();
16149                if (tok != TOK_PPNUM)
16150                    goto reg_error;
16151                p = tokc.cstr->data;
16152                reg = p[0] - '0';
16153                if ((unsigned)reg >= 8 || p[1] != '\0')
16154                    goto reg_error;
16155                op->reg = reg;
16156                next();
16157                skip(')');
16158            }
16159            if (op->reg == 0)
16160                op->type |= OP_ST0;
16161            goto no_skip;
16162        } else {
16163        reg_error:
16164            error("unknown register");
16165        }
16166        next();
16167    no_skip: ;
16168    } else if (tok == '$') {
16169        /* constant value */
16170        next();
16171        asm_expr(s1, &e);
16172        op->type = OP_IM32;
16173        op->e.v = e.v;
16174        op->e.sym = e.sym;
16175        if (!op->e.sym) {
16176            if (op->e.v == (uint8_t)op->e.v)
16177                op->type |= OP_IM8;
16178            if (op->e.v == (int8_t)op->e.v)
16179                op->type |= OP_IM8S;
16180            if (op->e.v == (uint16_t)op->e.v)
16181                op->type |= OP_IM16;
16182        }
16183    } else {
16184        /* address(reg,reg2,shift) with all variants */
16185        op->type = OP_EA;
16186        op->reg = -1;
16187        op->reg2 = -1;
16188        op->shift = 0;
16189        if (tok != '(') {
16190            asm_expr(s1, &e);
16191            op->e.v = e.v;
16192            op->e.sym = e.sym;
16193        } else {
16194            op->e.v = 0;
16195            op->e.sym = NULL;
16196        }
16197        if (tok == '(') {
16198            next();
16199            if (tok != ',') {
16200                op->reg = asm_parse_reg();
16201            }
16202            if (tok == ',') {
16203                next();
16204                if (tok != ',') {
16205                    op->reg2 = asm_parse_reg();
16206                }
16207                skip(',');
16208                op->shift = get_reg_shift(s1);
16209            }
16210            skip(')');
16211        }
16212        if (op->reg == -1 && op->reg2 == -1)
16213            op->type |= OP_ADDR;
16214    }
16215    op->type |= indir;
16216}
16217
16218/* XXX: unify with C code output ? */
16219static void gen_expr32(ExprValue *pe)
16220{
16221    if (pe->sym)
16222        greloc(cur_text_section, pe->sym, ind, R_386_32);
16223    gen_le32(pe->v);
16224}
16225
16226/* XXX: unify with C code output ? */
16227static void gen_disp32(ExprValue *pe)
16228{
16229    Sym *sym;
16230    sym = pe->sym;
16231    if (sym) {
16232        if (sym->r == cur_text_section->sh_num) {
16233            /* same section: we can output an absolute value. Note
16234               that the TCC compiler behaves differently here because
16235               it always outputs a relocation to ease (future) code
16236               elimination in the linker */
16237            gen_le32(pe->v + (long)sym->next - ind - 4);
16238        } else {
16239            greloc(cur_text_section, sym, ind, R_386_PC32);
16240            gen_le32(pe->v - 4);
16241        }
16242    } else {
16243        /* put an empty PC32 relocation */
16244        put_elf_reloc(symtab_section, cur_text_section,
16245                      ind, R_386_PC32, 0);
16246        gen_le32(pe->v - 4);
16247    }
16248}
16249
16250
16251static void gen_le16(int v)
16252{
16253    g(v);
16254    g(v >> 8);
16255}
16256
16257/* generate the modrm operand */
16258static inline void asm_modrm(int reg, Operand *op)
16259{
16260    int mod, reg1, reg2, sib_reg1;
16261
16262    if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
16263        g(0xc0 + (reg << 3) + op->reg);
16264    } else if (op->reg == -1 && op->reg2 == -1) {
16265        /* displacement only */
16266        g(0x05 + (reg << 3));
16267        gen_expr32(&op->e);
16268    } else {
16269        sib_reg1 = op->reg;
16270        /* fist compute displacement encoding */
16271        if (sib_reg1 == -1) {
16272            sib_reg1 = 5;
16273            mod = 0x00;
16274        } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
16275            mod = 0x00;
16276        } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
16277            mod = 0x40;
16278        } else {
16279            mod = 0x80;
16280        }
16281        /* compute if sib byte needed */
16282        reg1 = op->reg;
16283        if (op->reg2 != -1)
16284            reg1 = 4;
16285        g(mod + (reg << 3) + reg1);
16286        if (reg1 == 4) {
16287            /* add sib byte */
16288            reg2 = op->reg2;
16289            if (reg2 == -1)
16290                reg2 = 4; /* indicate no index */
16291            g((op->shift << 6) + (reg2 << 3) + sib_reg1);
16292        }
16293
16294        /* add offset */
16295        if (mod == 0x40) {
16296            g(op->e.v);
16297        } else if (mod == 0x80 || op->reg == -1) {
16298            gen_expr32(&op->e);
16299        }
16300    }
16301}
16302
16303static void asm_opcode(TCCState *s1, int opcode)
16304{
16305    const ASMInstr *pa;
16306    int i, modrm_index, reg, v, op1, is_short_jmp;
16307    int nb_ops, s, ss;
16308    Operand ops[MAX_OPERANDS], *pop;
16309    int op_type[3]; /* decoded op type */
16310
16311    /* get operands */
16312    pop = ops;
16313    nb_ops = 0;
16314    for(;;) {
16315        if (tok == ';' || tok == TOK_LINEFEED)
16316            break;
16317        if (nb_ops >= MAX_OPERANDS) {
16318            error("incorrect number of operands");
16319        }
16320        parse_operand(s1, pop);
16321        pop++;
16322        nb_ops++;
16323        if (tok != ',')
16324            break;
16325        next();
16326    }
16327
16328    is_short_jmp = 0;
16329    s = 0; /* avoid warning */
16330
16331    /* optimize matching by using a lookup table (no hashing is needed
16332       !) */
16333    for(pa = asm_instrs; pa->sym != 0; pa++) {
16334        s = 0;
16335        if (pa->instr_type & OPC_FARITH) {
16336            v = opcode - pa->sym;
16337            if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
16338                continue;
16339        } else if (pa->instr_type & OPC_ARITH) {
16340            if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
16341                continue;
16342            goto compute_size;
16343        } else if (pa->instr_type & OPC_SHIFT) {
16344            if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
16345                continue;
16346            goto compute_size;
16347        } else if (pa->instr_type & OPC_TEST) {
16348            if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
16349                continue;
16350        } else if (pa->instr_type & OPC_B) {
16351            if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
16352                continue;
16353        compute_size:
16354            s = (opcode - pa->sym) & 3;
16355        } else if (pa->instr_type & OPC_WL) {
16356            if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
16357                continue;
16358            s = opcode - pa->sym + 1;
16359        } else {
16360            if (pa->sym != opcode)
16361                continue;
16362        }
16363        if (pa->nb_ops != nb_ops)
16364            continue;
16365        /* now decode and check each operand */
16366        for(i = 0; i < nb_ops; i++) {
16367            int op1, op2;
16368            op1 = pa->op_type[i];
16369            op2 = op1 & 0x1f;
16370            switch(op2) {
16371            case OPT_IM:
16372                v = OP_IM8 | OP_IM16 | OP_IM32;
16373                break;
16374            case OPT_REG:
16375                v = OP_REG8 | OP_REG16 | OP_REG32;
16376                break;
16377            case OPT_REGW:
16378                v = OP_REG16 | OP_REG32;
16379                break;
16380            case OPT_IMW:
16381                v = OP_IM16 | OP_IM32;
16382                break;
16383            default:
16384                v = 1 << op2;
16385                break;
16386            }
16387            if (op1 & OPT_EA)
16388                v |= OP_EA;
16389            op_type[i] = v;
16390            if ((ops[i].type & v) == 0)
16391                goto next;
16392        }
16393        /* all is matching ! */
16394        break;
16395    next: ;
16396    }
16397    if (pa->sym == 0) {
16398        if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
16399            int b;
16400            b = op0_codes[opcode - TOK_ASM_pusha];
16401            if (b & 0xff00)
16402                g(b >> 8);
16403            g(b);
16404            return;
16405        } else {
16406            error("unknown opcode '%s'",
16407                  get_tok_str(opcode, NULL));
16408        }
16409    }
16410    /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
16411    if (s == 3) {
16412        for(i = 0; s == 3 && i < nb_ops; i++) {
16413            if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
16414                s = reg_to_size[ops[i].type & OP_REG];
16415        }
16416        if (s == 3) {
16417            if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
16418                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
16419                s = 2;
16420            else
16421                error("cannot infer opcode suffix");
16422        }
16423    }
16424
16425    /* generate data16 prefix if needed */
16426    ss = s;
16427    if (s == 1 || (pa->instr_type & OPC_D16))
16428        g(WORD_PREFIX_OPCODE);
16429    else if (s == 2)
16430        s = 1;
16431    /* now generates the operation */
16432    if (pa->instr_type & OPC_FWAIT)
16433        g(0x9b);
16434
16435    v = pa->opcode;
16436    if (v == 0x69 || v == 0x69) {
16437        /* kludge for imul $im, %reg */
16438        nb_ops = 3;
16439        ops[2] = ops[1];
16440    } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
16441        v--; /* int $3 case */
16442        nb_ops = 0;
16443    } else if ((v == 0x06 || v == 0x07)) {
16444        if (ops[0].reg >= 4) {
16445            /* push/pop %fs or %gs */
16446            v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
16447        } else {
16448            v += ops[0].reg << 3;
16449        }
16450        nb_ops = 0;
16451    } else if (v <= 0x05) {
16452        /* arith case */
16453        v += ((opcode - TOK_ASM_addb) >> 2) << 3;
16454    } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
16455        /* fpu arith case */
16456        v += ((opcode - pa->sym) / 6) << 3;
16457    }
16458    if (pa->instr_type & OPC_REG) {
16459        for(i = 0; i < nb_ops; i++) {
16460            if (op_type[i] & (OP_REG | OP_ST)) {
16461                v += ops[i].reg;
16462                break;
16463            }
16464        }
16465        /* mov $im, %reg case */
16466        if (pa->opcode == 0xb0 && s >= 1)
16467            v += 7;
16468    }
16469    if (pa->instr_type & OPC_B)
16470        v += s;
16471    if (pa->instr_type & OPC_TEST)
16472        v += test_bits[opcode - pa->sym];
16473    if (pa->instr_type & OPC_SHORTJMP) {
16474        Sym *sym;
16475        int jmp_disp;
16476
16477        /* see if we can really generate the jump with a byte offset */
16478        sym = ops[0].e.sym;
16479        if (!sym)
16480            goto no_short_jump;
16481        if (sym->r != cur_text_section->sh_num)
16482            goto no_short_jump;
16483        jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
16484        if (jmp_disp == (int8_t)jmp_disp) {
16485            /* OK to generate jump */
16486            is_short_jmp = 1;
16487            ops[0].e.v = jmp_disp;
16488        } else {
16489        no_short_jump:
16490            if (pa->instr_type & OPC_JMP) {
16491                /* long jump will be allowed. need to modify the
16492                   opcode slightly */
16493                if (v == 0xeb)
16494                    v = 0xe9;
16495                else
16496                    v += 0x0f10;
16497            } else {
16498                error("invalid displacement");
16499            }
16500        }
16501    }
16502    op1 = v >> 8;
16503    if (op1)
16504        g(op1);
16505    g(v);
16506
16507    /* search which operand will used for modrm */
16508    modrm_index = 0;
16509    if (pa->instr_type & OPC_SHIFT) {
16510        reg = (opcode - pa->sym) >> 2;
16511        if (reg == 6)
16512            reg = 7;
16513    } else if (pa->instr_type & OPC_ARITH) {
16514        reg = (opcode - pa->sym) >> 2;
16515    } else if (pa->instr_type & OPC_FARITH) {
16516        reg = (opcode - pa->sym) / 6;
16517    } else {
16518        reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
16519    }
16520    if (pa->instr_type & OPC_MODRM) {
16521        /* first look for an ea operand */
16522        for(i = 0;i < nb_ops; i++) {
16523            if (op_type[i] & OP_EA)
16524                goto modrm_found;
16525        }
16526        /* then if not found, a register or indirection (shift instructions) */
16527        for(i = 0;i < nb_ops; i++) {
16528            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
16529                goto modrm_found;
16530        }
16531#ifdef ASM_DEBUG
16532        error("bad op table");
16533#endif
16534    modrm_found:
16535        modrm_index = i;
16536        /* if a register is used in another operand then it is
16537           used instead of group */
16538        for(i = 0;i < nb_ops; i++) {
16539            v = op_type[i];
16540            if (i != modrm_index &&
16541                (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
16542                reg = ops[i].reg;
16543                break;
16544            }
16545        }
16546
16547        asm_modrm(reg, &ops[modrm_index]);
16548    }
16549
16550    /* emit constants */
16551    if (pa->opcode == 0x9a || pa->opcode == 0xea) {
16552        /* ljmp or lcall kludge */
16553        gen_expr32(&ops[1].e);
16554        if (ops[0].e.sym)
16555            error("cannot relocate");
16556        gen_le16(ops[0].e.v);
16557    } else {
16558        for(i = 0;i < nb_ops; i++) {
16559            v = op_type[i];
16560            if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
16561                /* if multiple sizes are given it means we must look
16562                   at the op size */
16563                if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
16564                    v == (OP_IM16 | OP_IM32)) {
16565                    if (ss == 0)
16566                        v = OP_IM8;
16567                    else if (ss == 1)
16568                        v = OP_IM16;
16569                    else
16570                        v = OP_IM32;
16571                }
16572                if (v & (OP_IM8 | OP_IM8S)) {
16573                    if (ops[i].e.sym)
16574                        goto error_relocate;
16575                    g(ops[i].e.v);
16576                } else if (v & OP_IM16) {
16577                    if (ops[i].e.sym) {
16578                    error_relocate:
16579                        error("cannot relocate");
16580                    }
16581                    gen_le16(ops[i].e.v);
16582                } else {
16583                    if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
16584                        if (is_short_jmp)
16585                            g(ops[i].e.v);
16586                        else
16587                            gen_disp32(&ops[i].e);
16588                    } else {
16589                        gen_expr32(&ops[i].e);
16590                    }
16591                }
16592            }
16593        }
16594    }
16595}
16596
16597#define NB_SAVED_REGS 3
16598#define NB_ASM_REGS 8
16599
16600/* return the constraint priority (we allocate first the lowest
16601   numbered constraints) */
16602static inline int constraint_priority(const char *str)
16603{
16604    int priority, c, pr;
16605
16606    /* we take the lowest priority */
16607    priority = 0;
16608    for(;;) {
16609        c = *str;
16610        if (c == '\0')
16611            break;
16612        str++;
16613        switch(c) {
16614        case 'A':
16615            pr = 0;
16616            break;
16617        case 'a':
16618        case 'b':
16619        case 'c':
16620        case 'd':
16621        case 'S':
16622        case 'D':
16623            pr = 1;
16624            break;
16625        case 'q':
16626            pr = 2;
16627            break;
16628        case 'r':
16629            pr = 3;
16630            break;
16631        case 'N':
16632        case 'M':
16633        case 'I':
16634        case 'i':
16635        case 'm':
16636        case 'g':
16637            pr = 4;
16638            break;
16639        default:
16640            error("unknown constraint '%c'", c);
16641            pr = 0;
16642        }
16643        if (pr > priority)
16644            priority = pr;
16645    }
16646    return priority;
16647}
16648
16649static const char *skip_constraint_modifiers(const char *p)
16650{
16651    while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
16652        p++;
16653    return p;
16654}
16655
16656#define REG_OUT_MASK 0x01
16657#define REG_IN_MASK  0x02
16658
16659#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
16660
16661static void asm_compute_constraints(ASMOperand *operands,
16662                                    int nb_operands, int nb_outputs,
16663                                    const uint8_t *clobber_regs,
16664                                    int *pout_reg)
16665{
16666    ASMOperand *op;
16667    int sorted_op[MAX_ASM_OPERANDS];
16668    int i, j, k, p1, p2, tmp, reg, c, reg_mask;
16669    const char *str;
16670    uint8_t regs_allocated[NB_ASM_REGS];
16671
16672    /* init fields */
16673    for(i=0;i<nb_operands;i++) {
16674        op = &operands[i];
16675        op->input_index = -1;
16676        op->ref_index = -1;
16677        op->reg = -1;
16678        op->is_memory = 0;
16679        op->is_rw = 0;
16680    }
16681    /* compute constraint priority and evaluate references to output
16682       constraints if input constraints */
16683    for(i=0;i<nb_operands;i++) {
16684        op = &operands[i];
16685        str = op->constraint;
16686        str = skip_constraint_modifiers(str);
16687        if (isnum(*str) || *str == '[') {
16688            /* this is a reference to another constraint */
16689            k = find_constraint(operands, nb_operands, str, NULL);
16690            if ((unsigned)k >= i || i < nb_outputs)
16691                error("invalid reference in constraint %d ('%s')",
16692                      i, str);
16693            op->ref_index = k;
16694            if (operands[k].input_index >= 0)
16695                error("cannot reference twice the same operand");
16696            operands[k].input_index = i;
16697            op->priority = 5;
16698        } else {
16699            op->priority = constraint_priority(str);
16700        }
16701    }
16702
16703    /* sort operands according to their priority */
16704    for(i=0;i<nb_operands;i++)
16705        sorted_op[i] = i;
16706    for(i=0;i<nb_operands - 1;i++) {
16707        for(j=i+1;j<nb_operands;j++) {
16708            p1 = operands[sorted_op[i]].priority;
16709            p2 = operands[sorted_op[j]].priority;
16710            if (p2 < p1) {
16711                tmp = sorted_op[i];
16712                sorted_op[i] = sorted_op[j];
16713                sorted_op[j] = tmp;
16714            }
16715        }
16716    }
16717
16718    for(i = 0;i < NB_ASM_REGS; i++) {
16719        if (clobber_regs[i])
16720            regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
16721        else
16722            regs_allocated[i] = 0;
16723    }
16724    /* esp cannot be used */
16725    regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK;
16726    /* ebp cannot be used yet */
16727    regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK;
16728
16729    /* allocate registers and generate corresponding asm moves */
16730    for(i=0;i<nb_operands;i++) {
16731        j = sorted_op[i];
16732        op = &operands[j];
16733        str = op->constraint;
16734        /* no need to allocate references */
16735        if (op->ref_index >= 0)
16736            continue;
16737        /* select if register is used for output, input or both */
16738        if (op->input_index >= 0) {
16739            reg_mask = REG_IN_MASK | REG_OUT_MASK;
16740        } else if (j < nb_outputs) {
16741            reg_mask = REG_OUT_MASK;
16742        } else {
16743            reg_mask = REG_IN_MASK;
16744        }
16745    try_next:
16746        c = *str++;
16747        switch(c) {
16748        case '=':
16749            goto try_next;
16750        case '+':
16751            op->is_rw = 1;
16752            /* FALL THRU */
16753        case '&':
16754            if (j >= nb_outputs)
16755                error("'%c' modifier can only be applied to outputs", c);
16756            reg_mask = REG_IN_MASK | REG_OUT_MASK;
16757            goto try_next;
16758        case 'A':
16759            /* allocate both eax and edx */
16760            if (is_reg_allocated(TREG_EAX) ||
16761                is_reg_allocated(TREG_EDX))
16762                goto try_next;
16763            op->is_llong = 1;
16764            op->reg = TREG_EAX;
16765            regs_allocated[TREG_EAX] |= reg_mask;
16766            regs_allocated[TREG_EDX] |= reg_mask;
16767            break;
16768        case 'a':
16769            reg = TREG_EAX;
16770            goto alloc_reg;
16771        case 'b':
16772            reg = 3;
16773            goto alloc_reg;
16774        case 'c':
16775            reg = TREG_ECX;
16776            goto alloc_reg;
16777        case 'd':
16778            reg = TREG_EDX;
16779            goto alloc_reg;
16780        case 'S':
16781            reg = 6;
16782            goto alloc_reg;
16783        case 'D':
16784            reg = 7;
16785        alloc_reg:
16786            if (is_reg_allocated(reg))
16787                goto try_next;
16788            goto reg_found;
16789        case 'q':
16790            /* eax, ebx, ecx or edx */
16791            for(reg = 0; reg < 4; reg++) {
16792                if (!is_reg_allocated(reg))
16793                    goto reg_found;
16794            }
16795            goto try_next;
16796        case 'r':
16797            /* any general register */
16798            for(reg = 0; reg < 8; reg++) {
16799                if (!is_reg_allocated(reg))
16800                    goto reg_found;
16801            }
16802            goto try_next;
16803        reg_found:
16804            /* now we can reload in the register */
16805            op->is_llong = 0;
16806            op->reg = reg;
16807            regs_allocated[reg] |= reg_mask;
16808            break;
16809        case 'i':
16810            if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
16811                goto try_next;
16812            break;
16813        case 'I':
16814        case 'N':
16815        case 'M':
16816            if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
16817                goto try_next;
16818            break;
16819        case 'm':
16820        case 'g':
16821            /* nothing special to do because the operand is already in
16822               memory, except if the pointer itself is stored in a
16823               memory variable (VT_LLOCAL case) */
16824            /* XXX: fix constant case */
16825            /* if it is a reference to a memory zone, it must lie
16826               in a register, so we reserve the register in the
16827               input registers and a load will be generated
16828               later */
16829            if (j < nb_outputs || c == 'm') {
16830                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
16831                    /* any general register */
16832                    for(reg = 0; reg < 8; reg++) {
16833                        if (!(regs_allocated[reg] & REG_IN_MASK))
16834                            goto reg_found1;
16835                    }
16836                    goto try_next;
16837                reg_found1:
16838                    /* now we can reload in the register */
16839                    regs_allocated[reg] |= REG_IN_MASK;
16840                    op->reg = reg;
16841                    op->is_memory = 1;
16842                }
16843            }
16844            break;
16845        default:
16846            error("asm constraint %d ('%s') could not be satisfied",
16847                  j, op->constraint);
16848            break;
16849        }
16850        /* if a reference is present for that operand, we assign it too */
16851        if (op->input_index >= 0) {
16852            operands[op->input_index].reg = op->reg;
16853            operands[op->input_index].is_llong = op->is_llong;
16854        }
16855    }
16856
16857    /* compute out_reg. It is used to store outputs registers to memory
16858       locations references by pointers (VT_LLOCAL case) */
16859    *pout_reg = -1;
16860    for(i=0;i<nb_operands;i++) {
16861        op = &operands[i];
16862        if (op->reg >= 0 &&
16863            (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
16864            !op->is_memory) {
16865            for(reg = 0; reg < 8; reg++) {
16866                if (!(regs_allocated[reg] & REG_OUT_MASK))
16867                    goto reg_found2;
16868            }
16869            error("could not find free output register for reloading");
16870        reg_found2:
16871            *pout_reg = reg;
16872            break;
16873        }
16874    }
16875
16876    /* print sorted constraints */
16877#ifdef ASM_DEBUG
16878    for(i=0;i<nb_operands;i++) {
16879        j = sorted_op[i];
16880        op = &operands[j];
16881        printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
16882               j,
16883               op->id ? get_tok_str(op->id, NULL) : "",
16884               op->constraint,
16885               op->vt->r,
16886               op->reg);
16887    }
16888    if (*pout_reg >= 0)
16889        printf("out_reg=%d\n", *pout_reg);
16890#endif
16891}
16892
16893static void subst_asm_operand(CString *add_str,
16894                              SValue *sv, int modifier)
16895{
16896    int r, reg, size, val;
16897    char buf[64];
16898
16899    r = sv->r;
16900    if ((r & VT_VALMASK) == VT_CONST) {
16901        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
16902            cstr_ccat(add_str, '$');
16903        if (r & VT_SYM) {
16904            cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
16905            if (sv->c.i != 0) {
16906                cstr_ccat(add_str, '+');
16907            } else {
16908                return;
16909            }
16910        }
16911        val = sv->c.i;
16912        if (modifier == 'n')
16913            val = -val;
16914        snprintf(buf, sizeof(buf), "%d", sv->c.i);
16915        cstr_cat(add_str, buf);
16916    } else if ((r & VT_VALMASK) == VT_LOCAL) {
16917        snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
16918        cstr_cat(add_str, buf);
16919    } else if (r & VT_LVAL) {
16920        reg = r & VT_VALMASK;
16921        if (reg >= VT_CONST)
16922            error("internal compiler error");
16923        snprintf(buf, sizeof(buf), "(%%%s)",
16924                 get_tok_str(TOK_ASM_eax + reg, NULL));
16925        cstr_cat(add_str, buf);
16926    } else {
16927        /* register case */
16928        reg = r & VT_VALMASK;
16929        if (reg >= VT_CONST)
16930            error("internal compiler error");
16931
16932        /* choose register operand size */
16933        if ((sv->type.t & VT_BTYPE) == VT_BYTE)
16934            size = 1;
16935        else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
16936            size = 2;
16937        else
16938            size = 4;
16939        if (size == 1 && reg >= 4)
16940            size = 4;
16941
16942        if (modifier == 'b') {
16943            if (reg >= 4)
16944                error("cannot use byte register");
16945            size = 1;
16946        } else if (modifier == 'h') {
16947            if (reg >= 4)
16948                error("cannot use byte register");
16949            size = -1;
16950        } else if (modifier == 'w') {
16951            size = 2;
16952        }
16953
16954        switch(size) {
16955        case -1:
16956            reg = TOK_ASM_ah + reg;
16957            break;
16958        case 1:
16959            reg = TOK_ASM_al + reg;
16960            break;
16961        case 2:
16962            reg = TOK_ASM_ax + reg;
16963            break;
16964        default:
16965            reg = TOK_ASM_eax + reg;
16966            break;
16967        }
16968        snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
16969        cstr_cat(add_str, buf);
16970    }
16971}
16972
16973/* generate prolog and epilog code for asm statment */
16974static void asm_gen_code(ASMOperand *operands, int nb_operands,
16975                         int nb_outputs, int is_output,
16976                         uint8_t *clobber_regs,
16977                         int out_reg)
16978{
16979    uint8_t regs_allocated[NB_ASM_REGS];
16980    ASMOperand *op;
16981    int i, reg;
16982    static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
16983
16984    /* mark all used registers */
16985    memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
16986    for(i = 0; i < nb_operands;i++) {
16987        op = &operands[i];
16988        if (op->reg >= 0)
16989            regs_allocated[op->reg] = 1;
16990    }
16991    if (!is_output) {
16992        /* generate reg save code */
16993        for(i = 0; i < NB_SAVED_REGS; i++) {
16994            reg = reg_saved[i];
16995            if (regs_allocated[reg])
16996                g(0x50 + reg);
16997        }
16998
16999        /* generate load code */
17000        for(i = 0; i < nb_operands; i++) {
17001            op = &operands[i];
17002            if (op->reg >= 0) {
17003                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
17004                    op->is_memory) {
17005                    /* memory reference case (for both input and
17006                       output cases) */
17007                    SValue sv;
17008                    sv = *op->vt;
17009                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17010                    load(op->reg, &sv);
17011                } else if (i >= nb_outputs || op->is_rw) {
17012                    /* load value in register */
17013                    load(op->reg, op->vt);
17014                    if (op->is_llong) {
17015                        SValue sv;
17016                        sv = *op->vt;
17017                        sv.c.ul += 4;
17018                        load(TREG_EDX, &sv);
17019                    }
17020                }
17021            }
17022        }
17023    } else {
17024        /* generate save code */
17025        for(i = 0 ; i < nb_outputs; i++) {
17026            op = &operands[i];
17027            if (op->reg >= 0) {
17028                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
17029                    if (!op->is_memory) {
17030                        SValue sv;
17031                        sv = *op->vt;
17032                        sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
17033                        load(out_reg, &sv);
17034
17035                        sv.r = (sv.r & ~VT_VALMASK) | out_reg;
17036                        store(op->reg, &sv);
17037                    }
17038                } else {
17039                    store(op->reg, op->vt);
17040                    if (op->is_llong) {
17041                        SValue sv;
17042                        sv = *op->vt;
17043                        sv.c.ul += 4;
17044                        store(TREG_EDX, &sv);
17045                    }
17046                }
17047            }
17048        }
17049        /* generate reg restore code */
17050        for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
17051            reg = reg_saved[i];
17052            if (regs_allocated[reg])
17053                g(0x58 + reg);
17054        }
17055    }
17056}
17057
17058static void asm_clobber(uint8_t *clobber_regs, const char *str)
17059{
17060    int reg;
17061    TokenSym *ts;
17062
17063    if (!strcmp(str, "memory") ||
17064        !strcmp(str, "cc"))
17065        return;
17066    ts = tok_alloc(str, strlen(str));
17067    reg = ts->tok;
17068    if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
17069        reg -= TOK_ASM_eax;
17070    } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
17071        reg -= TOK_ASM_ax;
17072    } else {
17073        error("invalid clobber register '%s'", str);
17074    }
17075    clobber_regs[reg] = 1;
17076}
17077//---------------------------------------------------------------------------
17078#endif
17079// njn: inlined tccasm.c
17080//#include "tccasm.c"
17081//---------------------------------------------------------------------------
17082/*
17083 *  GAS like assembler for TCC
17084 *
17085 *  Copyright (c) 2001-2004 Fabrice Bellard
17086 *
17087 * This library is free software; you can redistribute it and/or
17088 * modify it under the terms of the GNU Lesser General Public
17089 * License as published by the Free Software Foundation; either
17090 * version 2 of the License, or (at your option) any later version.
17091 *
17092 * This library is distributed in the hope that it will be useful,
17093 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17094 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17095 * Lesser General Public License for more details.
17096 *
17097 * You should have received a copy of the GNU Lesser General Public
17098 * License along with this library; if not, write to the Free Software
17099 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17100 */
17101
17102static int asm_get_local_label_name(TCCState *s1, unsigned int n)
17103{
17104    char buf[64];
17105    TokenSym *ts;
17106
17107    snprintf(buf, sizeof(buf), "L..%u", n);
17108    ts = tok_alloc(buf, strlen(buf));
17109    return ts->tok;
17110}
17111
17112static void asm_expr(TCCState *s1, ExprValue *pe);
17113
17114/* We do not use the C expression parser to handle symbols. Maybe the
17115   C expression parser could be tweaked to do so. */
17116
17117static void asm_expr_unary(TCCState *s1, ExprValue *pe)
17118{
17119    Sym *sym;
17120    int op, n, label;
17121    const char *p;
17122
17123    switch(tok) {
17124    case TOK_PPNUM:
17125        p = tokc.cstr->data;
17126        n = strtoul(p, (char **)&p, 0);
17127        if (*p == 'b' || *p == 'f') {
17128            /* backward or forward label */
17129            label = asm_get_local_label_name(s1, n);
17130            sym = label_find(label);
17131            if (*p == 'b') {
17132                /* backward : find the last corresponding defined label */
17133                if (sym && sym->r == 0)
17134                    sym = sym->prev_tok;
17135                if (!sym)
17136                    error("local label '%d' not found backward", n);
17137            } else {
17138                /* forward */
17139                if (!sym || sym->r) {
17140                    /* if the last label is defined, then define a new one */
17141                    sym = label_push(&s1->asm_labels, label, 0);
17142                    sym->type.t = VT_STATIC | VT_VOID;
17143                }
17144            }
17145            pe->v = 0;
17146            pe->sym = sym;
17147        } else if (*p == '\0') {
17148            pe->v = n;
17149            pe->sym = NULL;
17150        } else {
17151            error("invalid number syntax");
17152        }
17153        next();
17154        break;
17155    case '+':
17156        next();
17157        asm_expr_unary(s1, pe);
17158        break;
17159    case '-':
17160    case '~':
17161        op = tok;
17162        next();
17163        asm_expr_unary(s1, pe);
17164        if (pe->sym)
17165            error("invalid operation with label");
17166        if (op == '-')
17167            pe->v = -pe->v;
17168        else
17169            pe->v = ~pe->v;
17170        break;
17171    case TOK_CCHAR:
17172    case TOK_LCHAR:
17173	pe->v = tokc.i;
17174	pe->sym = NULL;
17175	next();
17176	break;
17177    case '(':
17178        next();
17179        asm_expr(s1, pe);
17180        skip(')');
17181        break;
17182    default:
17183        if (tok >= TOK_IDENT) {
17184            /* label case : if the label was not found, add one */
17185            sym = label_find(tok);
17186            if (!sym) {
17187                sym = label_push(&s1->asm_labels, tok, 0);
17188                /* NOTE: by default, the symbol is global */
17189                sym->type.t = VT_VOID;
17190            }
17191            if (sym->r == SHN_ABS) {
17192                /* if absolute symbol, no need to put a symbol value */
17193                pe->v = (long)sym->next;
17194                pe->sym = NULL;
17195            } else {
17196                pe->v = 0;
17197                pe->sym = sym;
17198            }
17199            next();
17200        } else {
17201            error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
17202        }
17203        break;
17204    }
17205}
17206
17207static void asm_expr_prod(TCCState *s1, ExprValue *pe)
17208{
17209    int op;
17210    ExprValue e2;
17211
17212    asm_expr_unary(s1, pe);
17213    for(;;) {
17214        op = tok;
17215        if (op != '*' && op != '/' && op != '%' &&
17216            op != TOK_SHL && op != TOK_SAR)
17217            break;
17218        next();
17219        asm_expr_unary(s1, &e2);
17220        if (pe->sym || e2.sym)
17221            error("invalid operation with label");
17222        switch(op) {
17223        case '*':
17224            pe->v *= e2.v;
17225            break;
17226        case '/':
17227            if (e2.v == 0) {
17228            div_error:
17229                error("division by zero");
17230            }
17231            pe->v /= e2.v;
17232            break;
17233        case '%':
17234            if (e2.v == 0)
17235                goto div_error;
17236            pe->v %= e2.v;
17237            break;
17238        case TOK_SHL:
17239            pe->v <<= e2.v;
17240            break;
17241        default:
17242        case TOK_SAR:
17243            pe->v >>= e2.v;
17244            break;
17245        }
17246    }
17247}
17248
17249static void asm_expr_logic(TCCState *s1, ExprValue *pe)
17250{
17251    int op;
17252    ExprValue e2;
17253
17254    asm_expr_prod(s1, pe);
17255    for(;;) {
17256        op = tok;
17257        if (op != '&' && op != '|' && op != '^')
17258            break;
17259        next();
17260        asm_expr_prod(s1, &e2);
17261        if (pe->sym || e2.sym)
17262            error("invalid operation with label");
17263        switch(op) {
17264        case '&':
17265            pe->v &= e2.v;
17266            break;
17267        case '|':
17268            pe->v |= e2.v;
17269            break;
17270        default:
17271        case '^':
17272            pe->v ^= e2.v;
17273            break;
17274        }
17275    }
17276}
17277
17278static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
17279{
17280    int op;
17281    ExprValue e2;
17282
17283    asm_expr_logic(s1, pe);
17284    for(;;) {
17285        op = tok;
17286        if (op != '+' && op != '-')
17287            break;
17288        next();
17289        asm_expr_logic(s1, &e2);
17290        if (op == '+') {
17291            if (pe->sym != NULL && e2.sym != NULL)
17292                goto cannot_relocate;
17293            pe->v += e2.v;
17294            if (pe->sym == NULL && e2.sym != NULL)
17295                pe->sym = e2.sym;
17296        } else {
17297            pe->v -= e2.v;
17298            /* NOTE: we are less powerful than gas in that case
17299               because we store only one symbol in the expression */
17300            if (!pe->sym && !e2.sym) {
17301                /* OK */
17302            } else if (pe->sym && !e2.sym) {
17303                /* OK */
17304            } else if (pe->sym && e2.sym) {
17305                if (pe->sym == e2.sym) {
17306                    /* OK */
17307                } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
17308                    /* we also accept defined symbols in the same section */
17309                    pe->v += (long)pe->sym->next - (long)e2.sym->next;
17310                } else {
17311                    goto cannot_relocate;
17312                }
17313                pe->sym = NULL; /* same symbols can be substracted to NULL */
17314            } else {
17315            cannot_relocate:
17316                error("invalid operation with label");
17317            }
17318        }
17319    }
17320}
17321
17322static void asm_expr(TCCState *s1, ExprValue *pe)
17323{
17324    asm_expr_sum(s1, pe);
17325}
17326
17327static int asm_int_expr(TCCState *s1)
17328{
17329    ExprValue e;
17330    asm_expr(s1, &e);
17331    if (e.sym)
17332        expect("constant");
17333    return e.v;
17334}
17335
17336/* NOTE: the same name space as C labels is used to avoid using too
17337   much memory when storing labels in TokenStrings */
17338static void asm_new_label1(TCCState *s1, int label, int is_local,
17339                           int sh_num, long value)
17340{
17341    Sym *sym;
17342
17343    sym = label_find(label);
17344    if (sym) {
17345        if (sym->r) {
17346            /* the label is already defined */
17347            if (!is_local) {
17348                error("assembler label '%s' already defined",
17349                      get_tok_str(label, NULL));
17350            } else {
17351                /* redefinition of local labels is possible */
17352                goto new_label;
17353            }
17354        }
17355    } else {
17356    new_label:
17357        sym = label_push(&s1->asm_labels, label, 0);
17358        sym->type.t = VT_STATIC | VT_VOID;
17359    }
17360    sym->r = sh_num;
17361    sym->next = (void *)value;
17362}
17363
17364static void asm_new_label(TCCState *s1, int label, int is_local)
17365{
17366    asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
17367}
17368
17369static void asm_free_labels(TCCState *st)
17370{
17371    Sym *s, *s1;
17372    Section *sec;
17373
17374    for(s = st->asm_labels; s != NULL; s = s1) {
17375        s1 = s->prev;
17376        /* define symbol value in object file */
17377        if (s->r) {
17378            if (s->r == SHN_ABS)
17379                sec = SECTION_ABS;
17380            else
17381                sec = st->sections[s->r];
17382            put_extern_sym2(s, sec, (long)s->next, 0, 0);
17383        }
17384        /* remove label */
17385        table_ident[s->v - TOK_IDENT]->sym_label = NULL;
17386        sym_free(s);
17387    }
17388    st->asm_labels = NULL;
17389}
17390
17391static void use_section1(TCCState *s1, Section *sec)
17392{
17393    cur_text_section->data_offset = ind;
17394    cur_text_section = sec;
17395    ind = cur_text_section->data_offset;
17396}
17397
17398static void use_section(TCCState *s1, const char *name)
17399{
17400    Section *sec;
17401    sec = find_section(s1, name);
17402    use_section1(s1, sec);
17403}
17404
17405static void asm_parse_directive(TCCState *s1)
17406{
17407    int n, offset, v, size, tok1;
17408    Section *sec;
17409    uint8_t *ptr;
17410
17411    /* assembler directive */
17412    next();
17413    sec = cur_text_section;
17414    switch(tok) {
17415    case TOK_ASM_align:
17416    case TOK_ASM_skip:
17417    case TOK_ASM_space:
17418        tok1 = tok;
17419        next();
17420        n = asm_int_expr(s1);
17421        if (tok1 == TOK_ASM_align) {
17422            if (n < 0 || (n & (n-1)) != 0)
17423                error("alignment must be a positive power of two");
17424            offset = (ind + n - 1) & -n;
17425            size = offset - ind;
17426            /* the section must have a compatible alignment */
17427            if (sec->sh_addralign < n)
17428                sec->sh_addralign = n;
17429        } else {
17430            size = n;
17431        }
17432        v = 0;
17433        if (tok == ',') {
17434            next();
17435            v = asm_int_expr(s1);
17436        }
17437    zero_pad:
17438        if (sec->sh_type != SHT_NOBITS) {
17439            sec->data_offset = ind;
17440            ptr = section_ptr_add(sec, size);
17441            memset(ptr, v, size);
17442        }
17443        ind += size;
17444        break;
17445    case TOK_ASM_quad:
17446        next();
17447        for(;;) {
17448            uint64_t vl;
17449            const char *p;
17450
17451            p = tokc.cstr->data;
17452            if (tok != TOK_PPNUM) {
17453            error_constant:
17454                error("64 bit constant");
17455            }
17456            vl = strtoll(p, (char **)&p, 0);
17457            if (*p != '\0')
17458                goto error_constant;
17459            next();
17460            if (sec->sh_type != SHT_NOBITS) {
17461                /* XXX: endianness */
17462                gen_le32(vl);
17463                gen_le32(vl >> 32);
17464            } else {
17465                ind += 8;
17466            }
17467            if (tok != ',')
17468                break;
17469            next();
17470        }
17471        break;
17472    case TOK_ASM_byte:
17473        size = 1;
17474        goto asm_data;
17475    case TOK_ASM_word:
17476    case TOK_SHORT:
17477        size = 2;
17478        goto asm_data;
17479    case TOK_LONG:
17480    case TOK_INT:
17481        size = 4;
17482    asm_data:
17483        next();
17484        for(;;) {
17485            ExprValue e;
17486            asm_expr(s1, &e);
17487            if (sec->sh_type != SHT_NOBITS) {
17488                if (size == 4) {
17489                    gen_expr32(&e);
17490                } else {
17491                    if (e.sym)
17492                        expect("constant");
17493                    if (size == 1)
17494                        g(e.v);
17495                    else
17496                        gen_le16(e.v);
17497                }
17498            } else {
17499                ind += size;
17500            }
17501            if (tok != ',')
17502                break;
17503            next();
17504        }
17505        break;
17506    case TOK_ASM_fill:
17507        {
17508            int repeat, size, val, i, j;
17509            uint8_t repeat_buf[8];
17510            next();
17511            repeat = asm_int_expr(s1);
17512            if (repeat < 0) {
17513                error("repeat < 0; .fill ignored");
17514                break;
17515            }
17516            size = 1;
17517            val = 0;
17518            if (tok == ',') {
17519                next();
17520                size = asm_int_expr(s1);
17521                if (size < 0) {
17522                    error("size < 0; .fill ignored");
17523                    break;
17524                }
17525                if (size > 8)
17526                    size = 8;
17527                if (tok == ',') {
17528                    next();
17529                    val = asm_int_expr(s1);
17530                }
17531            }
17532            /* XXX: endianness */
17533            repeat_buf[0] = val;
17534            repeat_buf[1] = val >> 8;
17535            repeat_buf[2] = val >> 16;
17536            repeat_buf[3] = val >> 24;
17537            repeat_buf[4] = 0;
17538            repeat_buf[5] = 0;
17539            repeat_buf[6] = 0;
17540            repeat_buf[7] = 0;
17541            for(i = 0; i < repeat; i++) {
17542                for(j = 0; j < size; j++) {
17543                    g(repeat_buf[j]);
17544                }
17545            }
17546        }
17547        break;
17548    case TOK_ASM_org:
17549        {
17550            unsigned long n;
17551            next();
17552            /* XXX: handle section symbols too */
17553            n = asm_int_expr(s1);
17554            if (n < ind)
17555                error("attempt to .org backwards");
17556            v = 0;
17557            size = n - ind;
17558            goto zero_pad;
17559        }
17560        break;
17561    case TOK_ASM_globl:
17562    case TOK_ASM_global:
17563	{
17564            Sym *sym;
17565
17566            next();
17567            sym = label_find(tok);
17568            if (!sym) {
17569                sym = label_push(&s1->asm_labels, tok, 0);
17570                sym->type.t = VT_VOID;
17571            }
17572            sym->type.t &= ~VT_STATIC;
17573            next();
17574	}
17575	break;
17576    case TOK_ASM_string:
17577    case TOK_ASM_ascii:
17578    case TOK_ASM_asciz:
17579        {
17580            const uint8_t *p;
17581            int i, size, t;
17582
17583            t = tok;
17584            next();
17585            for(;;) {
17586                if (tok != TOK_STR)
17587                    expect("string constant");
17588                p = tokc.cstr->data;
17589                size = tokc.cstr->size;
17590                if (t == TOK_ASM_ascii && size > 0)
17591                    size--;
17592                for(i = 0; i < size; i++)
17593                    g(p[i]);
17594                next();
17595                if (tok == ',') {
17596                    next();
17597                } else if (tok != TOK_STR) {
17598                    break;
17599                }
17600            }
17601	}
17602	break;
17603    case TOK_ASM_text:
17604    case TOK_ASM_data:
17605    case TOK_ASM_bss:
17606	{
17607            char sname[64];
17608            tok1 = tok;
17609            n = 0;
17610            next();
17611            if (tok != ';' && tok != TOK_LINEFEED) {
17612		n = asm_int_expr(s1);
17613		next();
17614            }
17615            sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
17616            use_section(s1, sname);
17617	}
17618	break;
17619    case TOK_SECTION1:
17620        {
17621            char sname[256];
17622
17623            /* XXX: support more options */
17624            next();
17625            sname[0] = '\0';
17626            while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
17627                if (tok == TOK_STR)
17628                    pstrcat(sname, sizeof(sname), tokc.cstr->data);
17629                else
17630                    pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
17631                next();
17632            }
17633            if (tok == ',') {
17634                /* skip section options */
17635                next();
17636                if (tok != TOK_STR)
17637                    expect("string constant");
17638                next();
17639            }
17640            last_text_section = cur_text_section;
17641            use_section(s1, sname);
17642        }
17643        break;
17644    case TOK_ASM_previous:
17645        {
17646            Section *sec;
17647            next();
17648            if (!last_text_section)
17649                error("no previous section referenced");
17650            sec = cur_text_section;
17651            use_section1(s1, last_text_section);
17652            last_text_section = sec;
17653        }
17654        break;
17655    default:
17656        error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
17657        break;
17658    }
17659}
17660
17661
17662/* assemble a file */
17663static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
17664{
17665    int opcode;
17666
17667#if 0
17668    /* print stats about opcodes */
17669    {
17670        const ASMInstr *pa;
17671        int freq[4];
17672        int op_vals[500];
17673        int nb_op_vals, i, j;
17674
17675        nb_op_vals = 0;
17676        memset(freq, 0, sizeof(freq));
17677        for(pa = asm_instrs; pa->sym != 0; pa++) {
17678            freq[pa->nb_ops]++;
17679            for(i=0;i<pa->nb_ops;i++) {
17680                for(j=0;j<nb_op_vals;j++) {
17681                    if (pa->op_type[i] == op_vals[j])
17682                        goto found;
17683                }
17684                op_vals[nb_op_vals++] = pa->op_type[i];
17685            found: ;
17686            }
17687        }
17688        for(i=0;i<nb_op_vals;i++) {
17689            int v = op_vals[i];
17690            if ((v & (v - 1)) != 0)
17691                printf("%3d: %08x\n", i, v);
17692        }
17693        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
17694               sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
17695               freq[0], freq[1], freq[2], freq[3]);
17696    }
17697#endif
17698
17699    /* XXX: undefine C labels */
17700
17701    ch = file->buf_ptr[0];
17702    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
17703    parse_flags = PARSE_FLAG_ASM_COMMENTS;
17704    if (do_preprocess)
17705        parse_flags |= PARSE_FLAG_PREPROCESS;
17706    next();
17707    for(;;) {
17708        if (tok == TOK_EOF)
17709            break;
17710        parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
17711    redo:
17712        if (tok == '#') {
17713            /* horrible gas comment */
17714            while (tok != TOK_LINEFEED)
17715                next();
17716        } else if (tok == '.') {
17717            asm_parse_directive(s1);
17718        } else if (tok == TOK_PPNUM) {
17719            const char *p;
17720            int n;
17721            p = tokc.cstr->data;
17722            n = strtoul(p, (char **)&p, 10);
17723            if (*p != '\0')
17724                expect("':'");
17725            /* new local label */
17726            asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
17727            next();
17728            skip(':');
17729            goto redo;
17730        } else if (tok >= TOK_IDENT) {
17731            /* instruction or label */
17732            opcode = tok;
17733            next();
17734            if (tok == ':') {
17735                /* new label */
17736                asm_new_label(s1, opcode, 0);
17737                next();
17738                goto redo;
17739            } else if (tok == '=') {
17740                int n;
17741                next();
17742                n = asm_int_expr(s1);
17743                asm_new_label1(s1, opcode, 0, SHN_ABS, n);
17744                goto redo;
17745            } else {
17746                asm_opcode(s1, opcode);
17747            }
17748        }
17749        /* end of line */
17750        if (tok != ';' && tok != TOK_LINEFEED){
17751            expect("end of line");
17752        }
17753        parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
17754        next();
17755    }
17756
17757    asm_free_labels(s1);
17758
17759    return 0;
17760}
17761
17762/* Assemble the current file */
17763static int tcc_assemble(TCCState *s1, int do_preprocess)
17764{
17765    Sym *define_start;
17766    int ret;
17767
17768    preprocess_init(s1);
17769
17770    /* default section is text */
17771    cur_text_section = text_section;
17772    ind = cur_text_section->data_offset;
17773
17774    define_start = define_stack;
17775
17776    ret = tcc_assemble_internal(s1, do_preprocess);
17777
17778    cur_text_section->data_offset = ind;
17779
17780    free_defines(define_start);
17781
17782    return ret;
17783}
17784
17785/********************************************************************/
17786/* GCC inline asm support */
17787
17788/* assemble the string 'str' in the current C compilation unit without
17789   C preprocessing. NOTE: str is modified by modifying the '\0' at the
17790   end */
17791static void tcc_assemble_inline(TCCState *s1, char *str, int len)
17792{
17793    BufferedFile *bf, *saved_file;
17794    int saved_parse_flags, *saved_macro_ptr;
17795
17796    bf = tcc_malloc(sizeof(BufferedFile));
17797    memset(bf, 0, sizeof(BufferedFile));
17798    bf->fd = -1;
17799    bf->buf_ptr = str;
17800    bf->buf_end = str + len;
17801    str[len] = CH_EOB;
17802    /* same name as current file so that errors are correctly
17803       reported */
17804    pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
17805    bf->line_num = file->line_num;
17806    saved_file = file;
17807    file = bf;
17808    saved_parse_flags = parse_flags;
17809    saved_macro_ptr = macro_ptr;
17810    macro_ptr = NULL;
17811
17812    tcc_assemble_internal(s1, 0);
17813
17814    parse_flags = saved_parse_flags;
17815    macro_ptr = saved_macro_ptr;
17816    file = saved_file;
17817    tcc_free(bf);
17818}
17819
17820/* find a constraint by its number or id (gcc 3 extended
17821   syntax). return -1 if not found. Return in *pp in char after the
17822   constraint */
17823static int find_constraint(ASMOperand *operands, int nb_operands,
17824                           const char *name, const char **pp)
17825{
17826    int index;
17827    TokenSym *ts;
17828    const char *p;
17829
17830    if (isnum(*name)) {
17831        index = 0;
17832        while (isnum(*name)) {
17833            index = (index * 10) + (*name) - '0';
17834            name++;
17835        }
17836        if ((unsigned)index >= nb_operands)
17837            index = -1;
17838    } else if (*name == '[') {
17839        name++;
17840        p = strchr(name, ']');
17841        if (p) {
17842            ts = tok_alloc(name, p - name);
17843            for(index = 0; index < nb_operands; index++) {
17844                if (operands[index].id == ts->tok)
17845                    goto found;
17846            }
17847            index = -1;
17848        found:
17849            name = p + 1;
17850        } else {
17851            index = -1;
17852        }
17853    } else {
17854        index = -1;
17855    }
17856    if (pp)
17857        *pp = name;
17858    return index;
17859}
17860
17861static void subst_asm_operands(ASMOperand *operands, int nb_operands,
17862                               int nb_outputs,
17863                               CString *out_str, CString *in_str)
17864{
17865    int c, index, modifier;
17866    const char *str;
17867    ASMOperand *op;
17868    SValue sv;
17869
17870    cstr_new(out_str);
17871    str = in_str->data;
17872    for(;;) {
17873        c = *str++;
17874        if (c == '%') {
17875            if (*str == '%') {
17876                str++;
17877                goto add_char;
17878            }
17879            modifier = 0;
17880            if (*str == 'c' || *str == 'n' ||
17881                *str == 'b' || *str == 'w' || *str == 'h')
17882                modifier = *str++;
17883            index = find_constraint(operands, nb_operands, str, &str);
17884            if (index < 0)
17885                error("invalid operand reference after %%");
17886            op = &operands[index];
17887            sv = *op->vt;
17888            if (op->reg >= 0) {
17889                sv.r = op->reg;
17890                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL)
17891                    sv.r |= VT_LVAL;
17892            }
17893            subst_asm_operand(out_str, &sv, modifier);
17894        } else {
17895        add_char:
17896            cstr_ccat(out_str, c);
17897            if (c == '\0')
17898                break;
17899        }
17900    }
17901}
17902
17903
17904static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
17905                               int is_output)
17906{
17907    ASMOperand *op;
17908    int nb_operands;
17909
17910    if (tok != ':') {
17911        nb_operands = *nb_operands_ptr;
17912        for(;;) {
17913            if (nb_operands >= MAX_ASM_OPERANDS)
17914                error("too many asm operands");
17915            op = &operands[nb_operands++];
17916            op->id = 0;
17917            if (tok == '[') {
17918                next();
17919                if (tok < TOK_IDENT)
17920                    expect("identifier");
17921                op->id = tok;
17922                next();
17923                skip(']');
17924            }
17925            if (tok != TOK_STR)
17926                expect("string constant");
17927            op->constraint = tcc_malloc(tokc.cstr->size);
17928            strcpy(op->constraint, tokc.cstr->data);
17929            next();
17930            skip('(');
17931            gexpr();
17932            if (is_output) {
17933                test_lvalue();
17934            } else {
17935                /* we want to avoid LLOCAL case, except when the 'm'
17936                   constraint is used. Note that it may come from
17937                   register storage, so we need to convert (reg)
17938                   case */
17939                if ((vtop->r & VT_LVAL) &&
17940                    ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
17941                     (vtop->r & VT_VALMASK) < VT_CONST) &&
17942                    !strchr(op->constraint, 'm')) {
17943                    gv(RC_INT);
17944                }
17945            }
17946            op->vt = vtop;
17947            skip(')');
17948            if (tok == ',') {
17949                next();
17950            } else {
17951                break;
17952            }
17953        }
17954        *nb_operands_ptr = nb_operands;
17955    }
17956}
17957
17958static void parse_asm_str(CString *astr)
17959{
17960    skip('(');
17961    /* read the string */
17962    if (tok != TOK_STR)
17963        expect("string constant");
17964    cstr_new(astr);
17965    while (tok == TOK_STR) {
17966        /* XXX: add \0 handling too ? */
17967        cstr_cat(astr, tokc.cstr->data);
17968        next();
17969    }
17970    cstr_ccat(astr, '\0');
17971}
17972
17973/* parse the GCC asm() instruction */
17974static void asm_instr(void)
17975{
17976    CString astr, astr1;
17977    ASMOperand operands[MAX_ASM_OPERANDS];
17978    int nb_inputs __attribute__((unused));
17979    int nb_outputs, nb_operands, i, must_subst, out_reg;
17980    uint8_t clobber_regs[NB_ASM_REGS];
17981
17982    next();
17983    /* since we always generate the asm() instruction, we can ignore
17984       volatile */
17985    if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
17986        next();
17987    }
17988    parse_asm_str(&astr);
17989    nb_operands = 0;
17990    nb_outputs = 0;
17991    must_subst = 0;
17992    memset(clobber_regs, 0, sizeof(clobber_regs));
17993    if (tok == ':') {
17994        next();
17995        must_subst = 1;
17996        /* output args */
17997        parse_asm_operands(operands, &nb_operands, 1);
17998        nb_outputs = nb_operands;
17999        if (tok == ':') {
18000            next();
18001            /* input args */
18002            parse_asm_operands(operands, &nb_operands, 0);
18003            if (tok == ':') {
18004                /* clobber list */
18005                /* XXX: handle registers */
18006                next();
18007                for(;;) {
18008                    if (tok != TOK_STR)
18009                        expect("string constant");
18010                    asm_clobber(clobber_regs, tokc.cstr->data);
18011                    next();
18012                    if (tok == ',') {
18013                        next();
18014                    } else {
18015                        break;
18016                    }
18017                }
18018            }
18019        }
18020    }
18021    skip(')');
18022    /* NOTE: we do not eat the ';' so that we can restore the current
18023       token after the assembler parsing */
18024    if (tok != ';')
18025        expect("';'");
18026    nb_inputs = nb_operands - nb_outputs;
18027
18028    /* save all values in the memory */
18029    save_regs(0);
18030
18031    /* compute constraints */
18032    asm_compute_constraints(operands, nb_operands, nb_outputs,
18033                            clobber_regs, &out_reg);
18034
18035    /* substitute the operands in the asm string. No substitution is
18036       done if no operands (GCC behaviour) */
18037#ifdef ASM_DEBUG
18038    printf("asm: \"%s\"\n", (char *)astr.data);
18039#endif
18040    if (must_subst) {
18041        subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
18042        cstr_free(&astr);
18043    } else {
18044        astr1 = astr;
18045    }
18046#ifdef ASM_DEBUG
18047    printf("subst_asm: \"%s\"\n", (char *)astr1.data);
18048#endif
18049
18050    /* generate loads */
18051    asm_gen_code(operands, nb_operands, nb_outputs, 0,
18052                 clobber_regs, out_reg);
18053
18054    /* assemble the string with tcc internal assembler */
18055    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
18056
18057    /* restore the current C token */
18058    next();
18059
18060    /* store the output values if needed */
18061    asm_gen_code(operands, nb_operands, nb_outputs, 1,
18062                 clobber_regs, out_reg);
18063
18064    /* free everything */
18065    for(i=0;i<nb_operands;i++) {
18066        ASMOperand *op;
18067        op = &operands[i];
18068        tcc_free(op->constraint);
18069        vpop();
18070    }
18071    cstr_free(&astr1);
18072}
18073
18074static void asm_global_instr(void)
18075{
18076    CString astr;
18077
18078    next();
18079    parse_asm_str(&astr);
18080    skip(')');
18081    /* NOTE: we do not eat the ';' so that we can restore the current
18082       token after the assembler parsing */
18083    if (tok != ';')
18084        expect("';'");
18085
18086#ifdef ASM_DEBUG
18087    printf("asm_global: \"%s\"\n", (char *)astr.data);
18088#endif
18089    cur_text_section = text_section;
18090    ind = cur_text_section->data_offset;
18091
18092    /* assemble the string with tcc internal assembler */
18093    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
18094
18095    cur_text_section->data_offset = ind;
18096
18097    /* restore the current C token */
18098    next();
18099
18100    cstr_free(&astr);
18101}
18102//---------------------------------------------------------------------------
18103
18104#else
18105static void asm_instr(void)
18106{
18107    error("inline asm() not supported");
18108}
18109static void asm_global_instr(void)
18110{
18111    error("inline asm() not supported");
18112}
18113#endif
18114
18115// njn: inlined tccelf.c
18116//#include "tccelf.c"
18117//---------------------------------------------------------------------------
18118/*
18119 *  ELF file handling for TCC
18120 *
18121 *  Copyright (c) 2001-2004 Fabrice Bellard
18122 *
18123 * This library is free software; you can redistribute it and/or
18124 * modify it under the terms of the GNU Lesser General Public
18125 * License as published by the Free Software Foundation; either
18126 * version 2 of the License, or (at your option) any later version.
18127 *
18128 * This library is distributed in the hope that it will be useful,
18129 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18130 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18131 * Lesser General Public License for more details.
18132 *
18133 * You should have received a copy of the GNU Lesser General Public
18134 * License along with this library; if not, write to the Free Software
18135 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18136 */
18137
18138static int put_elf_str(Section *s, const char *sym)
18139{
18140    int offset, len;
18141    char *ptr;
18142
18143    len = strlen(sym) + 1;
18144    offset = s->data_offset;
18145    ptr = section_ptr_add(s, len);
18146    memcpy(ptr, sym, len);
18147    return offset;
18148}
18149
18150/* elf symbol hashing function */
18151static unsigned long elf_hash(const unsigned char *name)
18152{
18153    unsigned long h = 0, g;
18154
18155    while (*name) {
18156        h = (h << 4) + *name++;
18157        g = h & 0xf0000000;
18158        if (g)
18159            h ^= g >> 24;
18160        h &= ~g;
18161    }
18162    return h;
18163}
18164
18165/* rebuild hash table of section s */
18166/* NOTE: we do factorize the hash table code to go faster */
18167static void rebuild_hash(Section *s, unsigned int nb_buckets)
18168{
18169    Elf32_Sym *sym;
18170    int *ptr, *hash, nb_syms, sym_index, h;
18171    char *strtab;
18172
18173    strtab = s->link->data;
18174    nb_syms = s->data_offset / sizeof(Elf32_Sym);
18175
18176    s->hash->data_offset = 0;
18177    ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
18178    ptr[0] = nb_buckets;
18179    ptr[1] = nb_syms;
18180    ptr += 2;
18181    hash = ptr;
18182    memset(hash, 0, (nb_buckets + 1) * sizeof(int));
18183    ptr += nb_buckets + 1;
18184
18185    sym = (Elf32_Sym *)s->data + 1;
18186    for(sym_index = 1; sym_index < nb_syms; sym_index++) {
18187        if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
18188            h = elf_hash(strtab + sym->st_name) % nb_buckets;
18189            *ptr = hash[h];
18190            hash[h] = sym_index;
18191        } else {
18192            *ptr = 0;
18193        }
18194        ptr++;
18195        sym++;
18196    }
18197}
18198
18199/* return the symbol number */
18200static int put_elf_sym(Section *s,
18201                       unsigned long value, unsigned long size,
18202                       int info, int other, int shndx, const char *name)
18203{
18204    int name_offset, sym_index;
18205    int nbuckets, h;
18206    Elf32_Sym *sym;
18207    Section *hs;
18208
18209    sym = section_ptr_add(s, sizeof(Elf32_Sym));
18210    if (name)
18211        name_offset = put_elf_str(s->link, name);
18212    else
18213        name_offset = 0;
18214    /* XXX: endianness */
18215    sym->st_name = name_offset;
18216    sym->st_value = value;
18217    sym->st_size = size;
18218    sym->st_info = info;
18219    sym->st_other = other;
18220    sym->st_shndx = shndx;
18221    sym_index = sym - (Elf32_Sym *)s->data;
18222    hs = s->hash;
18223    if (hs) {
18224        int *ptr, *base;
18225        ptr = section_ptr_add(hs, sizeof(int));
18226        base = (int *)hs->data;
18227        /* only add global or weak symbols */
18228        if (ELF32_ST_BIND(info) != STB_LOCAL) {
18229            /* add another hashing entry */
18230            nbuckets = base[0];
18231            h = elf_hash(name) % nbuckets;
18232            *ptr = base[2 + h];
18233            base[2 + h] = sym_index;
18234            base[1]++;
18235            /* we resize the hash table */
18236            hs->nb_hashed_syms++;
18237            if (hs->nb_hashed_syms > 2 * nbuckets) {
18238                rebuild_hash(s, 2 * nbuckets);
18239            }
18240        } else {
18241            *ptr = 0;
18242            base[1]++;
18243        }
18244    }
18245    return sym_index;
18246}
18247
18248/* find global ELF symbol 'name' and return its index. Return 0 if not
18249   found. */
18250static int find_elf_sym(Section *s, const char *name)
18251{
18252    Elf32_Sym *sym;
18253    Section *hs;
18254    int nbuckets, sym_index, h;
18255    const char *name1;
18256
18257    hs = s->hash;
18258    if (!hs)
18259        return 0;
18260    nbuckets = ((int *)hs->data)[0];
18261    h = elf_hash(name) % nbuckets;
18262    sym_index = ((int *)hs->data)[2 + h];
18263    while (sym_index != 0) {
18264        sym = &((Elf32_Sym *)s->data)[sym_index];
18265        name1 = s->link->data + sym->st_name;
18266        if (!strcmp(name, name1))
18267            return sym_index;
18268        sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
18269    }
18270    return 0;
18271}
18272
18273/* return elf symbol value or error */
18274int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
18275{
18276    int sym_index;
18277    Elf32_Sym *sym;
18278
18279    sym_index = find_elf_sym(symtab_section, name);
18280    if (!sym_index)
18281        return -1;
18282    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18283    *pval = sym->st_value;
18284    return 0;
18285}
18286
18287void *tcc_get_symbol_err(TCCState *s, const char *name)
18288{
18289    unsigned long val;
18290    if (tcc_get_symbol(s, &val, name) < 0)
18291        error("%s not defined", name);
18292    return (void *)val;
18293}
18294
18295/* add an elf symbol : check if it is already defined and patch
18296   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
18297static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
18298                       int info, int other, int sh_num, const char *name)
18299{
18300    Elf32_Sym *esym;
18301    int sym_bind, sym_index, sym_type, esym_bind;
18302
18303    sym_bind = ELF32_ST_BIND(info);
18304    sym_type = ELF32_ST_TYPE(info);
18305
18306    if (sym_bind != STB_LOCAL) {
18307        /* we search global or weak symbols */
18308        sym_index = find_elf_sym(s, name);
18309        if (!sym_index)
18310            goto do_def;
18311        esym = &((Elf32_Sym *)s->data)[sym_index];
18312        if (esym->st_shndx != SHN_UNDEF) {
18313            esym_bind = ELF32_ST_BIND(esym->st_info);
18314            if (sh_num == SHN_UNDEF) {
18315                /* ignore adding of undefined symbol if the
18316                   corresponding symbol is already defined */
18317            } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
18318                /* global overrides weak, so patch */
18319                goto do_patch;
18320            } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
18321                /* weak is ignored if already global */
18322            } else {
18323#if 0
18324                printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
18325                       sym_bind, sh_num, esym_bind, esym->st_shndx);
18326#endif
18327                /* NOTE: we accept that two DLL define the same symbol */
18328                if (s != tcc_state->dynsymtab_section)
18329                    error_noabort("'%s' defined twice", name);
18330            }
18331        } else {
18332        do_patch:
18333            esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
18334            esym->st_shndx = sh_num;
18335            esym->st_value = value;
18336            esym->st_size = size;
18337            esym->st_other = other;
18338        }
18339    } else {
18340    do_def:
18341        sym_index = put_elf_sym(s, value, size,
18342                                ELF32_ST_INFO(sym_bind, sym_type), other,
18343                                sh_num, name);
18344    }
18345    return sym_index;
18346}
18347
18348/* put relocation */
18349static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
18350                          int type, int symbol)
18351{
18352    char buf[256];
18353    Section *sr;
18354    Elf32_Rel *rel;
18355
18356    sr = s->reloc;
18357    if (!sr) {
18358        /* if no relocation section, create it */
18359        snprintf(buf, sizeof(buf), ".rel%s", s->name);
18360        /* if the symtab is allocated, then we consider the relocation
18361           are also */
18362        sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
18363        sr->sh_entsize = sizeof(Elf32_Rel);
18364        sr->link = symtab;
18365        sr->sh_info = s->sh_num;
18366        s->reloc = sr;
18367    }
18368    rel = section_ptr_add(sr, sizeof(Elf32_Rel));
18369    rel->r_offset = offset;
18370    rel->r_info = ELF32_R_INFO(symbol, type);
18371}
18372
18373/* put stab debug information */
18374
18375typedef struct {
18376    unsigned long n_strx;         /* index into string table of name */
18377    unsigned char n_type;         /* type of symbol */
18378    unsigned char n_other;        /* misc info (usually empty) */
18379    unsigned short n_desc;        /* description field */
18380    unsigned long n_value;        /* value of symbol */
18381} Stab_Sym;
18382
18383static void put_stabs(const char *str, int type, int other, int desc,
18384                      unsigned long value)
18385{
18386    Stab_Sym *sym;
18387
18388    sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
18389    if (str) {
18390        sym->n_strx = put_elf_str(stabstr_section, str);
18391    } else {
18392        sym->n_strx = 0;
18393    }
18394    sym->n_type = type;
18395    sym->n_other = other;
18396    sym->n_desc = desc;
18397    sym->n_value = value;
18398}
18399
18400static void put_stabs_r(const char *str, int type, int other, int desc,
18401                        unsigned long value, Section *sec, int sym_index)
18402{
18403    put_stabs(str, type, other, desc, value);
18404    put_elf_reloc(symtab_section, stab_section,
18405                  stab_section->data_offset - sizeof(unsigned long),
18406                  R_DATA_32, sym_index);
18407}
18408
18409static void put_stabn(int type, int other, int desc, int value)
18410{
18411    put_stabs(NULL, type, other, desc, value);
18412}
18413
18414static void put_stabd(int type, int other, int desc)
18415{
18416    put_stabs(NULL, type, other, desc, 0);
18417}
18418
18419/* In an ELF file symbol table, the local symbols must appear below
18420   the global and weak ones. Since TCC cannot sort it while generating
18421   the code, we must do it after. All the relocation tables are also
18422   modified to take into account the symbol table sorting */
18423static void sort_syms(TCCState *s1, Section *s)
18424{
18425    int *old_to_new_syms;
18426    Elf32_Sym *new_syms;
18427    int nb_syms, i;
18428    Elf32_Sym *p, *q;
18429    Elf32_Rel *rel, *rel_end;
18430    Section *sr;
18431    int type, sym_index;
18432
18433    nb_syms = s->data_offset / sizeof(Elf32_Sym);
18434    new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
18435    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
18436
18437    /* first pass for local symbols */
18438    p = (Elf32_Sym *)s->data;
18439    q = new_syms;
18440    for(i = 0; i < nb_syms; i++) {
18441        if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
18442            old_to_new_syms[i] = q - new_syms;
18443            *q++ = *p;
18444        }
18445        p++;
18446    }
18447    /* save the number of local symbols in section header */
18448    s->sh_info = q - new_syms;
18449
18450    /* then second pass for non local symbols */
18451    p = (Elf32_Sym *)s->data;
18452    for(i = 0; i < nb_syms; i++) {
18453        if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
18454            old_to_new_syms[i] = q - new_syms;
18455            *q++ = *p;
18456        }
18457        p++;
18458    }
18459
18460    /* we copy the new symbols to the old */
18461    memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
18462    tcc_free(new_syms);
18463
18464    /* now we modify all the relocations */
18465    for(i = 1; i < s1->nb_sections; i++) {
18466        sr = s1->sections[i];
18467        if (sr->sh_type == SHT_REL && sr->link == s) {
18468            rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18469            for(rel = (Elf32_Rel *)sr->data;
18470                rel < rel_end;
18471                rel++) {
18472                sym_index = ELF32_R_SYM(rel->r_info);
18473                type = ELF32_R_TYPE(rel->r_info);
18474                sym_index = old_to_new_syms[sym_index];
18475                rel->r_info = ELF32_R_INFO(sym_index, type);
18476            }
18477        }
18478    }
18479
18480    tcc_free(old_to_new_syms);
18481}
18482
18483/* relocate common symbols in the .bss section */
18484static void relocate_common_syms(void)
18485{
18486    Elf32_Sym *sym, *sym_end;
18487    unsigned long offset, align;
18488
18489    sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18490    for(sym = (Elf32_Sym *)symtab_section->data + 1;
18491        sym < sym_end;
18492        sym++) {
18493        if (sym->st_shndx == SHN_COMMON) {
18494            /* align symbol */
18495            align = sym->st_value;
18496            offset = bss_section->data_offset;
18497            offset = (offset + align - 1) & -align;
18498            sym->st_value = offset;
18499            sym->st_shndx = bss_section->sh_num;
18500            offset += sym->st_size;
18501            bss_section->data_offset = offset;
18502        }
18503    }
18504}
18505
18506/* relocate symbol table, resolve undefined symbols if do_resolve is
18507   true and output error if undefined symbol. */
18508static void relocate_syms(TCCState *s1, int do_resolve)
18509{
18510    Elf32_Sym *sym, *esym, *sym_end;
18511    int sym_bind, sh_num, sym_index;
18512    const char *name;
18513    unsigned long addr;
18514
18515    sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
18516    for(sym = (Elf32_Sym *)symtab_section->data + 1;
18517        sym < sym_end;
18518        sym++) {
18519        sh_num = sym->st_shndx;
18520        if (sh_num == SHN_UNDEF) {
18521            name = strtab_section->data + sym->st_name;
18522            if (do_resolve) {
18523                name = symtab_section->link->data + sym->st_name;
18524                addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
18525                if (addr) {
18526                    sym->st_value = addr;
18527                    goto found;
18528                }
18529            } else if (s1->dynsym) {
18530                /* if dynamic symbol exist, then use it */
18531                sym_index = find_elf_sym(s1->dynsym, name);
18532                if (sym_index) {
18533                    esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
18534                    sym->st_value = esym->st_value;
18535                    goto found;
18536                }
18537            }
18538            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
18539               it */
18540            if (!strcmp(name, "_fp_hw"))
18541                goto found;
18542            /* only weak symbols are accepted to be undefined. Their
18543               value is zero */
18544            sym_bind = ELF32_ST_BIND(sym->st_info);
18545            if (sym_bind == STB_WEAK) {
18546                sym->st_value = 0;
18547            } else {
18548                error_noabort("undefined symbol '%s'", name);
18549            }
18550        } else if (sh_num < SHN_LORESERVE) {
18551            /* add section base */
18552            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
18553        }
18554    found: ;
18555    }
18556}
18557
18558/* relocate a given section (CPU dependent) */
18559static void relocate_section(TCCState *s1, Section *s)
18560{
18561    Section *sr;
18562    Elf32_Rel *rel, *rel_end, *qrel;
18563    Elf32_Sym *sym;
18564    int type, sym_index;
18565    unsigned char *ptr;
18566    unsigned long val, addr;
18567#if defined(TCC_TARGET_I386)
18568    int esym_index;
18569#endif
18570
18571    sr = s->reloc;
18572    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18573    qrel = (Elf32_Rel *)sr->data;
18574    for(rel = qrel;
18575        rel < rel_end;
18576        rel++) {
18577        ptr = s->data + rel->r_offset;
18578
18579        sym_index = ELF32_R_SYM(rel->r_info);
18580        sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18581        val = sym->st_value;
18582        type = ELF32_R_TYPE(rel->r_info);
18583        addr = s->sh_addr + rel->r_offset;
18584
18585        /* CPU specific */
18586        switch(type) {
18587#if defined(TCC_TARGET_I386)
18588        case R_386_32:
18589            if (s1->output_type == TCC_OUTPUT_DLL) {
18590                esym_index = s1->symtab_to_dynsym[sym_index];
18591                qrel->r_offset = rel->r_offset;
18592                if (esym_index) {
18593                    qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
18594                    qrel++;
18595                    break;
18596                } else {
18597                    qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
18598                    qrel++;
18599                }
18600            }
18601            *(int *)ptr += val;
18602            break;
18603        case R_386_PC32:
18604            if (s1->output_type == TCC_OUTPUT_DLL) {
18605                /* DLL relocation */
18606                esym_index = s1->symtab_to_dynsym[sym_index];
18607                if (esym_index) {
18608                    qrel->r_offset = rel->r_offset;
18609                    qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
18610                    qrel++;
18611                    break;
18612                }
18613            }
18614            *(int *)ptr += val - addr;
18615            break;
18616        case R_386_PLT32:
18617            *(int *)ptr += val - addr;
18618            break;
18619        case R_386_GLOB_DAT:
18620        case R_386_JMP_SLOT:
18621            *(int *)ptr = val;
18622            break;
18623        case R_386_GOTPC:
18624            *(int *)ptr += s1->got->sh_addr - addr;
18625            break;
18626        case R_386_GOTOFF:
18627            *(int *)ptr += val - s1->got->sh_addr;
18628            break;
18629        case R_386_GOT32:
18630            /* we load the got offset */
18631            *(int *)ptr += s1->got_offsets[sym_index];
18632            break;
18633#elif defined(TCC_TARGET_ARM)
18634	case R_ARM_PC24:
18635	case R_ARM_PLT32:
18636	    {
18637                int x;
18638                x = (*(int *)ptr)&0xffffff;
18639                (*(int *)ptr) &= 0xff000000;
18640                if (x & 0x800000)
18641                    x -= 0x1000000;
18642                x *= 4;
18643                x += val - addr;
18644                if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
18645                    error("can't relocate value at %x",addr);
18646                x >>= 2;
18647                x &= 0xffffff;
18648                (*(int *)ptr) |= x;
18649	    }
18650	    break;
18651	case R_ARM_ABS32:
18652	    *(int *)ptr += val;
18653	    break;
18654	case R_ARM_GOTPC:
18655	    *(int *)ptr += s1->got->sh_addr - addr;
18656	    break;
18657        case R_ARM_GOT32:
18658            /* we load the got offset */
18659            *(int *)ptr += s1->got_offsets[sym_index];
18660            break;
18661	case R_ARM_COPY:
18662            break;
18663	default:
18664	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18665                    type,addr,(unsigned int )ptr,val);
18666            break;
18667#elif defined(TCC_TARGET_C67)
18668	case R_C60_32:
18669	    *(int *)ptr += val;
18670	    break;
18671        case R_C60LO16:
18672            {
18673                uint32_t orig;
18674
18675                /* put the low 16 bits of the absolute address */
18676                // add to what is already there
18677
18678                orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
18679                orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
18680
18681                //patch both at once - assumes always in pairs Low - High
18682
18683                *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
18684                *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
18685            }
18686            break;
18687        case R_C60HI16:
18688            break;
18689        default:
18690	    fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
18691                    type,addr,(unsigned int )ptr,val);
18692            break;
18693#else
18694#error unsupported processor
18695#endif
18696        }
18697    }
18698    /* if the relocation is allocated, we change its symbol table */
18699    if (sr->sh_flags & SHF_ALLOC)
18700        sr->link = s1->dynsym;
18701}
18702
18703/* relocate relocation table in 'sr' */
18704static void relocate_rel(TCCState *s1, Section *sr)
18705{
18706    Section *s;
18707    Elf32_Rel *rel, *rel_end;
18708
18709    s = s1->sections[sr->sh_info];
18710    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18711    for(rel = (Elf32_Rel *)sr->data;
18712        rel < rel_end;
18713        rel++) {
18714        rel->r_offset += s->sh_addr;
18715    }
18716}
18717
18718/* count the number of dynamic relocations so that we can reserve
18719   their space */
18720static int prepare_dynamic_rel(TCCState *s1, Section *sr)
18721{
18722    Elf32_Rel *rel, *rel_end;
18723    int sym_index, esym_index, type, count;
18724
18725    count = 0;
18726    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
18727    for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
18728        sym_index = ELF32_R_SYM(rel->r_info);
18729        type = ELF32_R_TYPE(rel->r_info);
18730        switch(type) {
18731        case R_386_32:
18732            count++;
18733            break;
18734        case R_386_PC32:
18735            esym_index = s1->symtab_to_dynsym[sym_index];
18736            if (esym_index)
18737                count++;
18738            break;
18739        default:
18740            break;
18741        }
18742    }
18743    if (count) {
18744        /* allocate the section */
18745        sr->sh_flags |= SHF_ALLOC;
18746        sr->sh_size = count * sizeof(Elf32_Rel);
18747    }
18748    return count;
18749}
18750
18751static void put_got_offset(TCCState *s1, int index, unsigned long val)
18752{
18753    int n;
18754    unsigned long *tab;
18755
18756    if (index >= s1->nb_got_offsets) {
18757        /* find immediately bigger power of 2 and reallocate array */
18758        n = 1;
18759        while (index >= n)
18760            n *= 2;
18761        tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
18762        if (!tab)
18763            error("memory full");
18764        s1->got_offsets = tab;
18765        memset(s1->got_offsets + s1->nb_got_offsets, 0,
18766               (n - s1->nb_got_offsets) * sizeof(unsigned long));
18767        s1->nb_got_offsets = n;
18768    }
18769    s1->got_offsets[index] = val;
18770}
18771
18772/* XXX: suppress that */
18773static void put32(unsigned char *p, uint32_t val)
18774{
18775    p[0] = val;
18776    p[1] = val >> 8;
18777    p[2] = val >> 16;
18778    p[3] = val >> 24;
18779}
18780
18781#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
18782static uint32_t get32(unsigned char *p)
18783{
18784    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
18785}
18786#endif
18787
18788static void build_got(TCCState *s1)
18789{
18790    unsigned char *ptr;
18791
18792    /* if no got, then create it */
18793    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
18794    s1->got->sh_entsize = 4;
18795    add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
18796                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
18797    ptr = section_ptr_add(s1->got, 3 * sizeof(int));
18798    /* keep space for _DYNAMIC pointer, if present */
18799    put32(ptr, 0);
18800    /* two dummy got entries */
18801    put32(ptr + 4, 0);
18802    put32(ptr + 8, 0);
18803}
18804
18805/* put a got entry corresponding to a symbol in symtab_section. 'size'
18806   and 'info' can be modifed if more precise info comes from the DLL */
18807static void put_got_entry(TCCState *s1,
18808                          int reloc_type, unsigned long size, int info,
18809                          int sym_index)
18810{
18811    int index;
18812    const char *name;
18813    Elf32_Sym *sym;
18814    unsigned long offset;
18815    int *ptr;
18816
18817    if (!s1->got)
18818        build_got(s1);
18819
18820    /* if a got entry already exists for that symbol, no need to add one */
18821    if (sym_index < s1->nb_got_offsets &&
18822        s1->got_offsets[sym_index] != 0)
18823        return;
18824
18825    put_got_offset(s1, sym_index, s1->got->data_offset);
18826
18827    if (s1->dynsym) {
18828        sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18829        name = symtab_section->link->data + sym->st_name;
18830        offset = sym->st_value;
18831#ifdef TCC_TARGET_I386
18832        if (reloc_type == R_386_JMP_SLOT) {
18833            Section *plt;
18834            uint8_t *p;
18835            int modrm;
18836
18837            /* if we build a DLL, we add a %ebx offset */
18838            if (s1->output_type == TCC_OUTPUT_DLL)
18839                modrm = 0xa3;
18840            else
18841                modrm = 0x25;
18842
18843            /* add a PLT entry */
18844            plt = s1->plt;
18845            if (plt->data_offset == 0) {
18846                /* first plt entry */
18847                p = section_ptr_add(plt, 16);
18848                p[0] = 0xff; /* pushl got + 4 */
18849                p[1] = modrm + 0x10;
18850                put32(p + 2, 4);
18851                p[6] = 0xff; /* jmp *(got + 8) */
18852                p[7] = modrm;
18853                put32(p + 8, 8);
18854            }
18855
18856            p = section_ptr_add(plt, 16);
18857            p[0] = 0xff; /* jmp *(got + x) */
18858            p[1] = modrm;
18859            put32(p + 2, s1->got->data_offset);
18860            p[6] = 0x68; /* push $xxx */
18861            put32(p + 7, (plt->data_offset - 32) >> 1);
18862            p[11] = 0xe9; /* jmp plt_start */
18863            put32(p + 12, -(plt->data_offset));
18864
18865            /* the symbol is modified so that it will be relocated to
18866               the PLT */
18867            if (s1->output_type == TCC_OUTPUT_EXE)
18868                offset = plt->data_offset - 16;
18869        }
18870#elif defined(TCC_TARGET_ARM)
18871	if (reloc_type == R_ARM_JUMP_SLOT) {
18872            Section *plt;
18873            uint8_t *p;
18874
18875            /* if we build a DLL, we add a %ebx offset */
18876            if (s1->output_type == TCC_OUTPUT_DLL)
18877                error("DLLs unimplemented!");
18878
18879            /* add a PLT entry */
18880            plt = s1->plt;
18881            if (plt->data_offset == 0) {
18882                /* first plt entry */
18883                p = section_ptr_add(plt, 16);
18884		put32(p     , 0xe52de004);
18885		put32(p +  4, 0xe59fe010);
18886		put32(p +  8, 0xe08fe00e);
18887		put32(p + 12, 0xe5bef008);
18888            }
18889
18890            p = section_ptr_add(plt, 16);
18891	    put32(p  , 0xe59fc004);
18892	    put32(p+4, 0xe08fc00c);
18893	    put32(p+8, 0xe59cf000);
18894	    put32(p+12, s1->got->data_offset);
18895
18896            /* the symbol is modified so that it will be relocated to
18897               the PLT */
18898            if (s1->output_type == TCC_OUTPUT_EXE)
18899                offset = plt->data_offset - 16;
18900        }
18901#elif defined(TCC_TARGET_C67)
18902        error("C67 got not implemented");
18903#else
18904#error unsupported CPU
18905#endif
18906        index = put_elf_sym(s1->dynsym, offset,
18907                            size, info, 0, sym->st_shndx, name);
18908        /* put a got entry */
18909        put_elf_reloc(s1->dynsym, s1->got,
18910                      s1->got->data_offset,
18911                      reloc_type, index);
18912    }
18913    ptr = section_ptr_add(s1->got, sizeof(int));
18914    *ptr = 0;
18915}
18916
18917/* build GOT and PLT entries */
18918static void build_got_entries(TCCState *s1)
18919{
18920    Section *s, *symtab __attribute__((unused));
18921    Elf32_Rel *rel, *rel_end;
18922    Elf32_Sym *sym;
18923    int i, type, reloc_type, sym_index;
18924
18925    for(i = 1; i < s1->nb_sections; i++) {
18926        s = s1->sections[i];
18927        if (s->sh_type != SHT_REL)
18928            continue;
18929        /* no need to handle got relocations */
18930        if (s->link != symtab_section)
18931            continue;
18932        symtab = s->link;
18933        rel_end = (Elf32_Rel *)(s->data + s->data_offset);
18934        for(rel = (Elf32_Rel *)s->data;
18935            rel < rel_end;
18936            rel++) {
18937            type = ELF32_R_TYPE(rel->r_info);
18938            switch(type) {
18939#if defined(TCC_TARGET_I386)
18940            case R_386_GOT32:
18941            case R_386_GOTOFF:
18942            case R_386_GOTPC:
18943            case R_386_PLT32:
18944                if (!s1->got)
18945                    build_got(s1);
18946                if (type == R_386_GOT32 || type == R_386_PLT32) {
18947                    sym_index = ELF32_R_SYM(rel->r_info);
18948                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18949                    /* look at the symbol got offset. If none, then add one */
18950                    if (type == R_386_GOT32)
18951                        reloc_type = R_386_GLOB_DAT;
18952                    else
18953                        reloc_type = R_386_JMP_SLOT;
18954                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
18955                                  sym_index);
18956                }
18957                break;
18958#elif defined(TCC_TARGET_ARM)
18959	    case R_ARM_GOT32:
18960            case R_ARM_GOTOFF:
18961            case R_ARM_GOTPC:
18962            case R_ARM_PLT32:
18963                if (!s1->got)
18964                    build_got(s1);
18965                if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
18966                    sym_index = ELF32_R_SYM(rel->r_info);
18967                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18968                    /* look at the symbol got offset. If none, then add one */
18969                    if (type == R_ARM_GOT32)
18970                        reloc_type = R_ARM_GLOB_DAT;
18971                    else
18972                        reloc_type = R_ARM_JUMP_SLOT;
18973                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
18974                                  sym_index);
18975                }
18976                break;
18977#elif defined(TCC_TARGET_C67)
18978	    case R_C60_GOT32:
18979            case R_C60_GOTOFF:
18980            case R_C60_GOTPC:
18981            case R_C60_PLT32:
18982                if (!s1->got)
18983                    build_got(s1);
18984                if (type == R_C60_GOT32 || type == R_C60_PLT32) {
18985                    sym_index = ELF32_R_SYM(rel->r_info);
18986                    sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
18987                    /* look at the symbol got offset. If none, then add one */
18988                    if (type == R_C60_GOT32)
18989                        reloc_type = R_C60_GLOB_DAT;
18990                    else
18991                        reloc_type = R_C60_JMP_SLOT;
18992                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
18993                                  sym_index);
18994                }
18995                break;
18996#else
18997#error unsupported CPU
18998#endif
18999            default:
19000                break;
19001            }
19002        }
19003    }
19004}
19005
19006static Section *new_symtab(TCCState *s1,
19007                           const char *symtab_name, int sh_type, int sh_flags,
19008                           const char *strtab_name,
19009                           const char *hash_name, int hash_sh_flags)
19010{
19011    Section *symtab, *strtab, *hash;
19012    int *ptr, nb_buckets;
19013
19014    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
19015    symtab->sh_entsize = sizeof(Elf32_Sym);
19016    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
19017    put_elf_str(strtab, "");
19018    symtab->link = strtab;
19019    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
19020
19021    nb_buckets = 1;
19022
19023    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
19024    hash->sh_entsize = sizeof(int);
19025    symtab->hash = hash;
19026    hash->link = symtab;
19027
19028    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
19029    ptr[0] = nb_buckets;
19030    ptr[1] = 1;
19031    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
19032    return symtab;
19033}
19034
19035/* put dynamic tag */
19036static void put_dt(Section *dynamic, int dt, unsigned long val)
19037{
19038    Elf32_Dyn *dyn;
19039    dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
19040    dyn->d_tag = dt;
19041    dyn->d_un.d_val = val;
19042}
19043
19044static void add_init_array_defines(TCCState *s1, const char *section_name)
19045{
19046    Section *s;
19047    long end_offset;
19048    char sym_start[1024];
19049    char sym_end[1024];
19050
19051    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
19052    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
19053
19054    s = find_section(s1, section_name);
19055    if (!s) {
19056        end_offset = 0;
19057        s = data_section;
19058    } else {
19059        end_offset = s->data_offset;
19060    }
19061
19062    add_elf_sym(symtab_section,
19063                0, 0,
19064                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19065                s->sh_num, sym_start);
19066    add_elf_sym(symtab_section,
19067                end_offset, 0,
19068                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19069                s->sh_num, sym_end);
19070}
19071
19072/* add tcc runtime libraries */
19073static void tcc_add_runtime(TCCState *s1)
19074{
19075    char buf[1024];
19076
19077#ifdef CONFIG_TCC_BCHECK
19078    if (do_bounds_check) {
19079        unsigned long *ptr;
19080        Section *init_section;
19081        unsigned char *pinit;
19082        int sym_index;
19083
19084        /* XXX: add an object file to do that */
19085        ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
19086        *ptr = 0;
19087        add_elf_sym(symtab_section, 0, 0,
19088                    ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19089                    bounds_section->sh_num, "__bounds_start");
19090        /* add bound check code */
19091        snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
19092        tcc_add_file(s1, buf);
19093#ifdef TCC_TARGET_I386
19094        if (s1->output_type != TCC_OUTPUT_MEMORY) {
19095            /* add 'call __bound_init()' in .init section */
19096            init_section = find_section(s1, ".init");
19097            pinit = section_ptr_add(init_section, 5);
19098            pinit[0] = 0xe8;
19099            put32(pinit + 1, -4);
19100            sym_index = find_elf_sym(symtab_section, "__bound_init");
19101            put_elf_reloc(symtab_section, init_section,
19102                          init_section->data_offset - 4, R_386_PC32, sym_index);
19103        }
19104#endif
19105    }
19106#endif
19107    /* add libc */
19108    if (!s1->nostdlib) {
19109        tcc_add_library(s1, "c");
19110
19111        snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
19112        tcc_add_file(s1, buf);
19113    }
19114    /* add crt end if not memory output */
19115    if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
19116        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
19117    }
19118}
19119
19120/* add various standard linker symbols (must be done after the
19121   sections are filled (for example after allocating common
19122   symbols)) */
19123static void tcc_add_linker_symbols(TCCState *s1)
19124{
19125    char buf[1024];
19126    int i;
19127    Section *s;
19128
19129    add_elf_sym(symtab_section,
19130                text_section->data_offset, 0,
19131                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19132                text_section->sh_num, "_etext");
19133    add_elf_sym(symtab_section,
19134                data_section->data_offset, 0,
19135                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19136                data_section->sh_num, "_edata");
19137    add_elf_sym(symtab_section,
19138                bss_section->data_offset, 0,
19139                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19140                bss_section->sh_num, "_end");
19141    /* horrible new standard ldscript defines */
19142    add_init_array_defines(s1, ".preinit_array");
19143    add_init_array_defines(s1, ".init_array");
19144    add_init_array_defines(s1, ".fini_array");
19145
19146    /* add start and stop symbols for sections whose name can be
19147       expressed in C */
19148    for(i = 1; i < s1->nb_sections; i++) {
19149        s = s1->sections[i];
19150        if (s->sh_type == SHT_PROGBITS &&
19151            (s->sh_flags & SHF_ALLOC)) {
19152            const char *p;
19153            int ch;
19154
19155            /* check if section name can be expressed in C */
19156            p = s->name;
19157            for(;;) {
19158                ch = *p;
19159                if (!ch)
19160                    break;
19161                if (!isid(ch) && !isnum(ch))
19162                    goto next_sec;
19163                p++;
19164            }
19165            snprintf(buf, sizeof(buf), "__start_%s", s->name);
19166            add_elf_sym(symtab_section,
19167                        0, 0,
19168                        ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19169                        s->sh_num, buf);
19170            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
19171            add_elf_sym(symtab_section,
19172                        s->data_offset, 0,
19173                        ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
19174                        s->sh_num, buf);
19175        }
19176    next_sec: ;
19177    }
19178}
19179
19180/* name of ELF interpreter */
19181#ifdef __FreeBSD__
19182static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
19183#else
19184static char elf_interp[] = "/lib/ld-linux.so.2";
19185#endif
19186
19187static void tcc_output_binary(TCCState *s1, FILE *f,
19188                              const int *section_order)
19189{
19190    Section *s;
19191    int i, offset, size;
19192
19193    offset = 0;
19194    for(i=1;i<s1->nb_sections;i++) {
19195        s = s1->sections[section_order[i]];
19196        if (s->sh_type != SHT_NOBITS &&
19197            (s->sh_flags & SHF_ALLOC)) {
19198            while (offset < s->sh_offset) {
19199                fputc(0, f);
19200                offset++;
19201            }
19202            size = s->sh_size;
19203            dummy_size_t = fwrite(s->data, 1, size, f);
19204            offset += size;
19205        }
19206    }
19207}
19208
19209/* output an ELF file */
19210/* XXX: suppress unneeded sections */
19211int tcc_output_file(TCCState *s1, const char *filename)
19212{
19213    Elf32_Ehdr ehdr;
19214    FILE *f;
19215    int fd, mode, ret;
19216    int *section_order;
19217    int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
19218    unsigned long addr;
19219    Section *strsec, *s;
19220    Elf32_Shdr shdr, *sh;
19221    Elf32_Phdr *phdr, *ph;
19222    Section *interp, *dynamic, *dynstr;
19223    unsigned long saved_dynamic_data_offset;
19224    Elf32_Sym *sym;
19225    int type, file_type;
19226    unsigned long rel_addr, rel_size;
19227
19228    file_type = s1->output_type;
19229    s1->nb_errors = 0;
19230
19231    if (file_type != TCC_OUTPUT_OBJ) {
19232        tcc_add_runtime(s1);
19233    }
19234
19235    phdr = NULL;
19236    section_order = NULL;
19237    interp = NULL;
19238    dynamic = NULL;
19239    dynstr = NULL; /* avoid warning */
19240    saved_dynamic_data_offset = 0; /* avoid warning */
19241
19242    if (file_type != TCC_OUTPUT_OBJ) {
19243        relocate_common_syms();
19244
19245        tcc_add_linker_symbols(s1);
19246
19247        if (!s1->static_link) {
19248            const char *name;
19249            int sym_index, index;
19250            Elf32_Sym *esym, *sym_end;
19251
19252            if (file_type == TCC_OUTPUT_EXE) {
19253                char *ptr;
19254                /* add interpreter section only if executable */
19255                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
19256                interp->sh_addralign = 1;
19257                ptr = section_ptr_add(interp, sizeof(elf_interp));
19258                strcpy(ptr, elf_interp);
19259            }
19260
19261            /* add dynamic symbol table */
19262            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
19263                                    ".dynstr",
19264                                    ".hash", SHF_ALLOC);
19265            dynstr = s1->dynsym->link;
19266
19267            /* add dynamic section */
19268            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
19269                                  SHF_ALLOC | SHF_WRITE);
19270            dynamic->link = dynstr;
19271            dynamic->sh_entsize = sizeof(Elf32_Dyn);
19272
19273            /* add PLT */
19274            s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
19275                                  SHF_ALLOC | SHF_EXECINSTR);
19276            s1->plt->sh_entsize = 4;
19277
19278            build_got(s1);
19279
19280            /* scan for undefined symbols and see if they are in the
19281               dynamic symbols. If a symbol STT_FUNC is found, then we
19282               add it in the PLT. If a symbol STT_OBJECT is found, we
19283               add it in the .bss section with a suitable relocation */
19284            sym_end = (Elf32_Sym *)(symtab_section->data +
19285                                    symtab_section->data_offset);
19286            if (file_type == TCC_OUTPUT_EXE) {
19287                for(sym = (Elf32_Sym *)symtab_section->data + 1;
19288                    sym < sym_end;
19289                    sym++) {
19290                    if (sym->st_shndx == SHN_UNDEF) {
19291                        name = symtab_section->link->data + sym->st_name;
19292                        sym_index = find_elf_sym(s1->dynsymtab_section, name);
19293                        if (sym_index) {
19294                            esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
19295                            type = ELF32_ST_TYPE(esym->st_info);
19296                            if (type == STT_FUNC) {
19297                                put_got_entry(s1, R_JMP_SLOT, esym->st_size,
19298                                              esym->st_info,
19299                                              sym - (Elf32_Sym *)symtab_section->data);
19300                            } else if (type == STT_OBJECT) {
19301                                unsigned long offset;
19302                                offset = bss_section->data_offset;
19303                                /* XXX: which alignment ? */
19304                                offset = (offset + 16 - 1) & -16;
19305                                index = put_elf_sym(s1->dynsym, offset, esym->st_size,
19306                                                    esym->st_info, 0,
19307                                                    bss_section->sh_num, name);
19308                                put_elf_reloc(s1->dynsym, bss_section,
19309                                              offset, R_COPY, index);
19310                                offset += esym->st_size;
19311                                bss_section->data_offset = offset;
19312                            }
19313                        } else {
19314                                /* STB_WEAK undefined symbols are accepted */
19315                                /* XXX: _fp_hw seems to be part of the ABI, so we ignore
19316                                   it */
19317                            if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
19318                                !strcmp(name, "_fp_hw")) {
19319                            } else {
19320                                error_noabort("undefined symbol '%s'", name);
19321                            }
19322                        }
19323                    } else if (s1->rdynamic &&
19324                               ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19325                        /* if -rdynamic option, then export all non
19326                           local symbols */
19327                        name = symtab_section->link->data + sym->st_name;
19328                        put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
19329                                    sym->st_info, 0,
19330                                    sym->st_shndx, name);
19331                    }
19332                }
19333
19334                if (s1->nb_errors)
19335                    goto fail;
19336
19337                /* now look at unresolved dynamic symbols and export
19338                   corresponding symbol */
19339                sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
19340                                        s1->dynsymtab_section->data_offset);
19341                for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
19342                    esym < sym_end;
19343                    esym++) {
19344                    if (esym->st_shndx == SHN_UNDEF) {
19345                        name = s1->dynsymtab_section->link->data + esym->st_name;
19346                        sym_index = find_elf_sym(symtab_section, name);
19347                        if (sym_index) {
19348                            /* XXX: avoid adding a symbol if already
19349                               present because of -rdynamic ? */
19350                            sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
19351                            put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
19352                                        sym->st_info, 0,
19353                                        sym->st_shndx, name);
19354                        } else {
19355                            if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
19356                                /* weak symbols can stay undefined */
19357                            } else {
19358                                warning("undefined dynamic symbol '%s'", name);
19359                            }
19360                        }
19361                    }
19362                }
19363            } else {
19364                int nb_syms;
19365                /* shared library case : we simply export all the global symbols */
19366                nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
19367                s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
19368                for(sym = (Elf32_Sym *)symtab_section->data + 1;
19369                    sym < sym_end;
19370                    sym++) {
19371                    if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
19372                        name = symtab_section->link->data + sym->st_name;
19373                        index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
19374                                            sym->st_info, 0,
19375                                            sym->st_shndx, name);
19376                        s1->symtab_to_dynsym[sym -
19377                                            (Elf32_Sym *)symtab_section->data] =
19378                            index;
19379                    }
19380                }
19381            }
19382
19383            build_got_entries(s1);
19384
19385            /* add a list of needed dlls */
19386            for(i = 0; i < s1->nb_loaded_dlls; i++) {
19387                DLLReference *dllref = s1->loaded_dlls[i];
19388                if (dllref->level == 0)
19389                    put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
19390            }
19391            /* XXX: currently, since we do not handle PIC code, we
19392               must relocate the readonly segments */
19393            if (file_type == TCC_OUTPUT_DLL)
19394                put_dt(dynamic, DT_TEXTREL, 0);
19395
19396            /* add necessary space for other entries */
19397            saved_dynamic_data_offset = dynamic->data_offset;
19398            dynamic->data_offset += 8 * 9;
19399        } else {
19400            /* still need to build got entries in case of static link */
19401            build_got_entries(s1);
19402        }
19403    }
19404
19405    memset(&ehdr, 0, sizeof(ehdr));
19406
19407    /* we add a section for symbols */
19408    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
19409    put_elf_str(strsec, "");
19410
19411    /* compute number of sections */
19412    shnum = s1->nb_sections;
19413
19414    /* this array is used to reorder sections in the output file */
19415    section_order = tcc_malloc(sizeof(int) * shnum);
19416    section_order[0] = 0;
19417    sh_order_index = 1;
19418
19419    /* compute number of program headers */
19420    switch(file_type) {
19421    default:
19422    case TCC_OUTPUT_OBJ:
19423        phnum = 0;
19424        break;
19425    case TCC_OUTPUT_EXE:
19426        if (!s1->static_link)
19427            phnum = 4;
19428        else
19429            phnum = 2;
19430        break;
19431    case TCC_OUTPUT_DLL:
19432        phnum = 3;
19433        break;
19434    }
19435
19436    /* allocate strings for section names and decide if an unallocated
19437       section should be output */
19438    /* NOTE: the strsec section comes last, so its size is also
19439       correct ! */
19440    for(i = 1; i < s1->nb_sections; i++) {
19441        s = s1->sections[i];
19442        s->sh_name = put_elf_str(strsec, s->name);
19443        /* when generating a DLL, we include relocations but we may
19444           patch them */
19445        if (file_type == TCC_OUTPUT_DLL &&
19446            s->sh_type == SHT_REL &&
19447            !(s->sh_flags & SHF_ALLOC)) {
19448            prepare_dynamic_rel(s1, s);
19449        } else if (do_debug ||
19450            file_type == TCC_OUTPUT_OBJ ||
19451            (s->sh_flags & SHF_ALLOC) ||
19452            i == (s1->nb_sections - 1)) {
19453            /* we output all sections if debug or object file */
19454            s->sh_size = s->data_offset;
19455        }
19456    }
19457
19458    /* allocate program segment headers */
19459    phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
19460
19461    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19462        file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19463    } else {
19464        file_offset = 0;
19465    }
19466    if (phnum > 0) {
19467        /* compute section to program header mapping */
19468        if (s1->has_text_addr) {
19469            int a_offset, p_offset;
19470            addr = s1->text_addr;
19471            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
19472               ELF_PAGE_SIZE */
19473            a_offset = addr & (ELF_PAGE_SIZE - 1);
19474            p_offset = file_offset & (ELF_PAGE_SIZE - 1);
19475            if (a_offset < p_offset)
19476                a_offset += ELF_PAGE_SIZE;
19477            file_offset += (a_offset - p_offset);
19478        } else {
19479            if (file_type == TCC_OUTPUT_DLL)
19480                addr = 0;
19481            else
19482                addr = ELF_START_ADDR;
19483            /* compute address after headers */
19484            addr += (file_offset & (ELF_PAGE_SIZE - 1));
19485        }
19486
19487        /* dynamic relocation table information, for .dynamic section */
19488        rel_size = 0;
19489        rel_addr = 0;
19490
19491        /* leave one program header for the program interpreter */
19492        ph = &phdr[0];
19493        if (interp)
19494            ph++;
19495
19496        for(j = 0; j < 2; j++) {
19497            ph->p_type = PT_LOAD;
19498            if (j == 0)
19499                ph->p_flags = PF_R | PF_X;
19500            else
19501                ph->p_flags = PF_R | PF_W;
19502            ph->p_align = ELF_PAGE_SIZE;
19503
19504            /* we do the following ordering: interp, symbol tables,
19505               relocations, progbits, nobits */
19506            /* XXX: do faster and simpler sorting */
19507            for(k = 0; k < 5; k++) {
19508                for(i = 1; i < s1->nb_sections; i++) {
19509                    s = s1->sections[i];
19510                    /* compute if section should be included */
19511                    if (j == 0) {
19512                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
19513                            SHF_ALLOC)
19514                            continue;
19515                    } else {
19516                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
19517                            (SHF_ALLOC | SHF_WRITE))
19518                            continue;
19519                    }
19520                    if (s == interp) {
19521                        if (k != 0)
19522                            continue;
19523                    } else if (s->sh_type == SHT_DYNSYM ||
19524                               s->sh_type == SHT_STRTAB ||
19525                               s->sh_type == SHT_HASH) {
19526                        if (k != 1)
19527                            continue;
19528                    } else if (s->sh_type == SHT_REL) {
19529                        if (k != 2)
19530                            continue;
19531                    } else if (s->sh_type == SHT_NOBITS) {
19532                        if (k != 4)
19533                            continue;
19534                    } else {
19535                        if (k != 3)
19536                            continue;
19537                    }
19538                    section_order[sh_order_index++] = i;
19539
19540                    /* section matches: we align it and add its size */
19541                    tmp = addr;
19542                    addr = (addr + s->sh_addralign - 1) &
19543                        ~(s->sh_addralign - 1);
19544                    file_offset += addr - tmp;
19545                    s->sh_offset = file_offset;
19546                    s->sh_addr = addr;
19547
19548                    /* update program header infos */
19549                    if (ph->p_offset == 0) {
19550                        ph->p_offset = file_offset;
19551                        ph->p_vaddr = addr;
19552                        ph->p_paddr = ph->p_vaddr;
19553                    }
19554                    /* update dynamic relocation infos */
19555                    if (s->sh_type == SHT_REL) {
19556                        if (rel_size == 0)
19557                            rel_addr = addr;
19558                        rel_size += s->sh_size;
19559                    }
19560                    addr += s->sh_size;
19561                    if (s->sh_type != SHT_NOBITS)
19562                        file_offset += s->sh_size;
19563                }
19564            }
19565            ph->p_filesz = file_offset - ph->p_offset;
19566            ph->p_memsz = addr - ph->p_vaddr;
19567            ph++;
19568            if (j == 0) {
19569                if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19570                    /* if in the middle of a page, we duplicate the page in
19571                       memory so that one copy is RX and the other is RW */
19572                    if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
19573                        addr += ELF_PAGE_SIZE;
19574                } else {
19575                    addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
19576                    file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
19577                        ~(ELF_PAGE_SIZE - 1);
19578                }
19579            }
19580        }
19581
19582        /* if interpreter, then add corresponing program header */
19583        if (interp) {
19584            ph = &phdr[0];
19585
19586            ph->p_type = PT_INTERP;
19587            ph->p_offset = interp->sh_offset;
19588            ph->p_vaddr = interp->sh_addr;
19589            ph->p_paddr = ph->p_vaddr;
19590            ph->p_filesz = interp->sh_size;
19591            ph->p_memsz = interp->sh_size;
19592            ph->p_flags = PF_R;
19593            ph->p_align = interp->sh_addralign;
19594        }
19595
19596        /* if dynamic section, then add corresponing program header */
19597        if (dynamic) {
19598            Elf32_Sym *sym_end;
19599
19600            ph = &phdr[phnum - 1];
19601
19602            ph->p_type = PT_DYNAMIC;
19603            ph->p_offset = dynamic->sh_offset;
19604            ph->p_vaddr = dynamic->sh_addr;
19605            ph->p_paddr = ph->p_vaddr;
19606            ph->p_filesz = dynamic->sh_size;
19607            ph->p_memsz = dynamic->sh_size;
19608            ph->p_flags = PF_R | PF_W;
19609            ph->p_align = dynamic->sh_addralign;
19610
19611            /* put GOT dynamic section address */
19612            put32(s1->got->data, dynamic->sh_addr);
19613
19614            /* relocate the PLT */
19615            if (file_type == TCC_OUTPUT_EXE) {
19616                uint8_t *p, *p_end;
19617
19618                p = s1->plt->data;
19619                p_end = p + s1->plt->data_offset;
19620                if (p < p_end) {
19621#if defined(TCC_TARGET_I386)
19622                    put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19623                    put32(p + 8, get32(p + 8) + s1->got->sh_addr);
19624                    p += 16;
19625                    while (p < p_end) {
19626                        put32(p + 2, get32(p + 2) + s1->got->sh_addr);
19627                        p += 16;
19628                    }
19629#elif defined(TCC_TARGET_ARM)
19630		    int x;
19631		    x=s1->got->sh_addr - s1->plt->sh_addr - 12;
19632		    p +=16;
19633		    while (p < p_end) {
19634		        put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
19635			p += 16;
19636		    }
19637#elif defined(TCC_TARGET_C67)
19638                    /* XXX: TODO */
19639#else
19640#error unsupported CPU
19641#endif
19642                }
19643            }
19644
19645            /* relocate symbols in .dynsym */
19646            sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
19647            for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
19648                sym < sym_end;
19649                sym++) {
19650                if (sym->st_shndx == SHN_UNDEF) {
19651                    /* relocate to the PLT if the symbol corresponds
19652                       to a PLT entry */
19653                    if (sym->st_value)
19654                        sym->st_value += s1->plt->sh_addr;
19655                } else if (sym->st_shndx < SHN_LORESERVE) {
19656                    /* do symbol relocation */
19657                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
19658                }
19659            }
19660
19661            /* put dynamic section entries */
19662            dynamic->data_offset = saved_dynamic_data_offset;
19663            put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
19664            put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
19665            put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
19666            put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
19667            put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
19668            put_dt(dynamic, DT_REL, rel_addr);
19669            put_dt(dynamic, DT_RELSZ, rel_size);
19670            put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
19671            put_dt(dynamic, DT_NULL, 0);
19672        }
19673
19674        ehdr.e_phentsize = sizeof(Elf32_Phdr);
19675        ehdr.e_phnum = phnum;
19676        ehdr.e_phoff = sizeof(Elf32_Ehdr);
19677    }
19678
19679    /* all other sections come after */
19680    for(i = 1; i < s1->nb_sections; i++) {
19681        s = s1->sections[i];
19682        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
19683            continue;
19684        section_order[sh_order_index++] = i;
19685
19686        file_offset = (file_offset + s->sh_addralign - 1) &
19687            ~(s->sh_addralign - 1);
19688        s->sh_offset = file_offset;
19689        if (s->sh_type != SHT_NOBITS)
19690            file_offset += s->sh_size;
19691    }
19692
19693    /* if building executable or DLL, then relocate each section
19694       except the GOT which is already relocated */
19695    if (file_type != TCC_OUTPUT_OBJ) {
19696        relocate_syms(s1, 0);
19697
19698        if (s1->nb_errors != 0) {
19699        fail:
19700            ret = -1;
19701            goto the_end;
19702        }
19703
19704        /* relocate sections */
19705        /* XXX: ignore sections with allocated relocations ? */
19706        for(i = 1; i < s1->nb_sections; i++) {
19707            s = s1->sections[i];
19708            if (s->reloc && s != s1->got)
19709                relocate_section(s1, s);
19710        }
19711
19712        /* relocate relocation entries if the relocation tables are
19713           allocated in the executable */
19714        for(i = 1; i < s1->nb_sections; i++) {
19715            s = s1->sections[i];
19716            if ((s->sh_flags & SHF_ALLOC) &&
19717                s->sh_type == SHT_REL) {
19718                relocate_rel(s1, s);
19719            }
19720        }
19721
19722        /* get entry point address */
19723        if (file_type == TCC_OUTPUT_EXE)
19724            ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
19725        else
19726            ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
19727    }
19728
19729    /* write elf file */
19730    if (file_type == TCC_OUTPUT_OBJ)
19731        mode = 0666;
19732    else
19733        mode = 0777;
19734    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
19735    if (fd < 0) {
19736        error_noabort("could not write '%s'", filename);
19737        goto fail;
19738    }
19739    f = fdopen(fd, "wb");
19740
19741#ifdef TCC_TARGET_COFF
19742    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
19743        tcc_output_coff(s1, f);
19744    } else
19745#endif
19746    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
19747        sort_syms(s1, symtab_section);
19748
19749        /* align to 4 */
19750        file_offset = (file_offset + 3) & -4;
19751
19752        /* fill header */
19753        ehdr.e_ident[0] = ELFMAG0;
19754        ehdr.e_ident[1] = ELFMAG1;
19755        ehdr.e_ident[2] = ELFMAG2;
19756        ehdr.e_ident[3] = ELFMAG3;
19757        ehdr.e_ident[4] = ELFCLASS32;
19758        ehdr.e_ident[5] = ELFDATA2LSB;
19759        ehdr.e_ident[6] = EV_CURRENT;
19760#ifdef __FreeBSD__
19761        ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
19762#endif
19763#ifdef TCC_TARGET_ARM
19764        ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
19765#endif
19766        switch(file_type) {
19767        default:
19768        case TCC_OUTPUT_EXE:
19769            ehdr.e_type = ET_EXEC;
19770            break;
19771        case TCC_OUTPUT_DLL:
19772            ehdr.e_type = ET_DYN;
19773            break;
19774        case TCC_OUTPUT_OBJ:
19775            ehdr.e_type = ET_REL;
19776            break;
19777        }
19778        ehdr.e_machine = EM_TCC_TARGET;
19779        ehdr.e_version = EV_CURRENT;
19780        ehdr.e_shoff = file_offset;
19781        ehdr.e_ehsize = sizeof(Elf32_Ehdr);
19782        ehdr.e_shentsize = sizeof(Elf32_Shdr);
19783        ehdr.e_shnum = shnum;
19784        ehdr.e_shstrndx = shnum - 1;
19785
19786        dummy_size_t = fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
19787        dummy_size_t = fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
19788        offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
19789
19790        for(i=1;i<s1->nb_sections;i++) {
19791            s = s1->sections[section_order[i]];
19792            if (s->sh_type != SHT_NOBITS) {
19793                while (offset < s->sh_offset) {
19794                    fputc(0, f);
19795                    offset++;
19796                }
19797                size = s->sh_size;
19798                dummy_size_t = fwrite(s->data, 1, size, f);
19799                offset += size;
19800            }
19801        }
19802
19803        /* output section headers */
19804        while (offset < ehdr.e_shoff) {
19805            fputc(0, f);
19806            offset++;
19807        }
19808
19809        for(i=0;i<s1->nb_sections;i++) {
19810            sh = &shdr;
19811            memset(sh, 0, sizeof(Elf32_Shdr));
19812            s = s1->sections[i];
19813            if (s) {
19814                sh->sh_name = s->sh_name;
19815                sh->sh_type = s->sh_type;
19816                sh->sh_flags = s->sh_flags;
19817                sh->sh_entsize = s->sh_entsize;
19818                sh->sh_info = s->sh_info;
19819                if (s->link)
19820                    sh->sh_link = s->link->sh_num;
19821                sh->sh_addralign = s->sh_addralign;
19822                sh->sh_addr = s->sh_addr;
19823                sh->sh_offset = s->sh_offset;
19824                sh->sh_size = s->sh_size;
19825            }
19826            dummy_size_t = fwrite(sh, 1, sizeof(Elf32_Shdr), f);
19827        }
19828    } else {
19829        tcc_output_binary(s1, f, section_order);
19830    }
19831    fclose(f);
19832
19833    ret = 0;
19834 the_end:
19835    tcc_free(s1->symtab_to_dynsym);
19836    tcc_free(section_order);
19837    tcc_free(phdr);
19838    tcc_free(s1->got_offsets);
19839    return ret;
19840}
19841
19842static void *load_data(int fd, unsigned long file_offset, unsigned long size)
19843{
19844    void *data;
19845
19846    data = tcc_malloc(size);
19847    lseek(fd, file_offset, SEEK_SET);
19848    dummy_size_t = read(fd, data, size);
19849    return data;
19850}
19851
19852typedef struct SectionMergeInfo {
19853    Section *s;            /* corresponding existing section */
19854    unsigned long offset;  /* offset of the new section in the existing section */
19855    uint8_t new_section;       /* true if section 's' was added */
19856    uint8_t link_once;         /* true if link once section */
19857} SectionMergeInfo;
19858
19859/* load an object file and merge it with current files */
19860/* XXX: handle correctly stab (debug) info */
19861static int tcc_load_object_file(TCCState *s1,
19862                                int fd, unsigned long file_offset)
19863{
19864    Elf32_Ehdr ehdr;
19865    Elf32_Shdr *shdr, *sh;
19866    int size, i, j, offset, offseti, nb_syms, sym_index, ret;
19867    unsigned char *strsec, *strtab;
19868    int *old_to_new_syms;
19869    char *sh_name, *name;
19870    SectionMergeInfo *sm_table, *sm;
19871    Elf32_Sym *sym, *symtab;
19872    Elf32_Rel *rel, *rel_end;
19873    Section *s;
19874
19875    if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
19876        goto fail1;
19877    if (ehdr.e_ident[0] != ELFMAG0 ||
19878        ehdr.e_ident[1] != ELFMAG1 ||
19879        ehdr.e_ident[2] != ELFMAG2 ||
19880        ehdr.e_ident[3] != ELFMAG3)
19881        goto fail1;
19882    /* test if object file */
19883    if (ehdr.e_type != ET_REL)
19884        goto fail1;
19885    /* test CPU specific stuff */
19886    if (ehdr.e_ident[5] != ELFDATA2LSB ||
19887        ehdr.e_machine != EM_TCC_TARGET) {
19888    fail1:
19889        error_noabort("invalid object file");
19890        return -1;
19891    }
19892    /* read sections */
19893    shdr = load_data(fd, file_offset + ehdr.e_shoff,
19894                     sizeof(Elf32_Shdr) * ehdr.e_shnum);
19895    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
19896
19897    /* load section names */
19898    sh = &shdr[ehdr.e_shstrndx];
19899    strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19900
19901    /* load symtab and strtab */
19902    old_to_new_syms = NULL;
19903    symtab = NULL;
19904    strtab = NULL;
19905    nb_syms = 0;
19906    for(i = 1; i < ehdr.e_shnum; i++) {
19907        sh = &shdr[i];
19908        if (sh->sh_type == SHT_SYMTAB) {
19909            if (symtab) {
19910                error_noabort("object must contain only one symtab");
19911            fail:
19912                ret = -1;
19913                goto the_end;
19914            }
19915            nb_syms = sh->sh_size / sizeof(Elf32_Sym);
19916            symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19917            sm_table[i].s = symtab_section;
19918
19919            /* now load strtab */
19920            sh = &shdr[sh->sh_link];
19921            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
19922        }
19923    }
19924
19925    /* now examine each section and try to merge its content with the
19926       ones in memory */
19927    for(i = 1; i < ehdr.e_shnum; i++) {
19928        /* no need to examine section name strtab */
19929        if (i == ehdr.e_shstrndx)
19930            continue;
19931        sh = &shdr[i];
19932        sh_name = strsec + sh->sh_name;
19933        /* ignore sections types we do not handle */
19934        if (sh->sh_type != SHT_PROGBITS &&
19935            sh->sh_type != SHT_REL &&
19936            sh->sh_type != SHT_NOBITS)
19937            continue;
19938        if (sh->sh_addralign < 1)
19939            sh->sh_addralign = 1;
19940        /* find corresponding section, if any */
19941        for(j = 1; j < s1->nb_sections;j++) {
19942            s = s1->sections[j];
19943            if (!strcmp(s->name, sh_name)) {
19944                if (!strncmp(sh_name, ".gnu.linkonce",
19945                             sizeof(".gnu.linkonce") - 1)) {
19946                    /* if a 'linkonce' section is already present, we
19947                       do not add it again. It is a little tricky as
19948                       symbols can still be defined in
19949                       it. */
19950                    sm_table[i].link_once = 1;
19951                    goto next;
19952                } else {
19953                    goto found;
19954                }
19955            }
19956        }
19957        /* not found: create new section */
19958        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
19959        /* take as much info as possible from the section. sh_link and
19960           sh_info will be updated later */
19961        s->sh_addralign = sh->sh_addralign;
19962        s->sh_entsize = sh->sh_entsize;
19963        sm_table[i].new_section = 1;
19964    found:
19965        if (sh->sh_type != s->sh_type) {
19966            error_noabort("invalid section type");
19967            goto fail;
19968        }
19969
19970        /* align start of section */
19971        offset = s->data_offset;
19972        size = sh->sh_addralign - 1;
19973        offset = (offset + size) & ~size;
19974        if (sh->sh_addralign > s->sh_addralign)
19975            s->sh_addralign = sh->sh_addralign;
19976        s->data_offset = offset;
19977        sm_table[i].offset = offset;
19978        sm_table[i].s = s;
19979        /* concatenate sections */
19980        size = sh->sh_size;
19981        if (sh->sh_type != SHT_NOBITS) {
19982            unsigned char *ptr;
19983            lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
19984            ptr = section_ptr_add(s, size);
19985            dummy_size_t = read(fd, ptr, size);
19986        } else {
19987            s->data_offset += size;
19988        }
19989    next: ;
19990    }
19991
19992    /* second short pass to update sh_link and sh_info fields of new
19993       sections */
19994    sm = sm_table;
19995    for(i = 1; i < ehdr.e_shnum; i++) {
19996        s = sm_table[i].s;
19997        if (!s || !sm_table[i].new_section)
19998            continue;
19999        sh = &shdr[i];
20000        if (sh->sh_link > 0)
20001            s->link = sm_table[sh->sh_link].s;
20002        if (sh->sh_type == SHT_REL) {
20003            s->sh_info = sm_table[sh->sh_info].s->sh_num;
20004            /* update backward link */
20005            s1->sections[s->sh_info]->reloc = s;
20006        }
20007    }
20008
20009    /* resolve symbols */
20010    old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
20011
20012    sym = symtab + 1;
20013    for(i = 1; i < nb_syms; i++, sym++) {
20014        if (sym->st_shndx != SHN_UNDEF &&
20015            sym->st_shndx < SHN_LORESERVE) {
20016            sm = &sm_table[sym->st_shndx];
20017            if (sm->link_once) {
20018                /* if a symbol is in a link once section, we use the
20019                   already defined symbol. It is very important to get
20020                   correct relocations */
20021                if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
20022                    name = strtab + sym->st_name;
20023                    sym_index = find_elf_sym(symtab_section, name);
20024                    if (sym_index)
20025                        old_to_new_syms[i] = sym_index;
20026                }
20027                continue;
20028            }
20029            /* if no corresponding section added, no need to add symbol */
20030            if (!sm->s)
20031                continue;
20032            /* convert section number */
20033            sym->st_shndx = sm->s->sh_num;
20034            /* offset value */
20035            sym->st_value += sm->offset;
20036        }
20037        /* add symbol */
20038        name = strtab + sym->st_name;
20039        sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
20040                                sym->st_info, sym->st_other,
20041                                sym->st_shndx, name);
20042        old_to_new_syms[i] = sym_index;
20043    }
20044
20045    /* third pass to patch relocation entries */
20046    for(i = 1; i < ehdr.e_shnum; i++) {
20047        s = sm_table[i].s;
20048        if (!s)
20049            continue;
20050        sh = &shdr[i];
20051        offset = sm_table[i].offset;
20052        switch(s->sh_type) {
20053        case SHT_REL:
20054            /* take relocation offset information */
20055            offseti = sm_table[sh->sh_info].offset;
20056            rel_end = (Elf32_Rel *)(s->data + s->data_offset);
20057            for(rel = (Elf32_Rel *)(s->data + offset);
20058                rel < rel_end;
20059                rel++) {
20060                int type;
20061                unsigned sym_index;
20062                /* convert symbol index */
20063                type = ELF32_R_TYPE(rel->r_info);
20064                sym_index = ELF32_R_SYM(rel->r_info);
20065                /* NOTE: only one symtab assumed */
20066                if (sym_index >= nb_syms)
20067                    goto invalid_reloc;
20068                sym_index = old_to_new_syms[sym_index];
20069                if (!sym_index) {
20070                invalid_reloc:
20071                    error_noabort("Invalid relocation entry");
20072                    goto fail;
20073                }
20074                rel->r_info = ELF32_R_INFO(sym_index, type);
20075                /* offset the relocation offset */
20076                rel->r_offset += offseti;
20077            }
20078            break;
20079        default:
20080            break;
20081        }
20082    }
20083
20084    ret = 0;
20085 the_end:
20086    tcc_free(symtab);
20087    tcc_free(strtab);
20088    tcc_free(old_to_new_syms);
20089    tcc_free(sm_table);
20090    tcc_free(strsec);
20091    tcc_free(shdr);
20092    return ret;
20093}
20094
20095#define ARMAG  "!<arch>\012"	/* For COFF and a.out archives */
20096
20097typedef struct ArchiveHeader {
20098    char ar_name[16];		/* name of this member */
20099    char ar_date[12];		/* file mtime */
20100    char ar_uid[6];		/* owner uid; printed as decimal */
20101    char ar_gid[6];		/* owner gid; printed as decimal */
20102    char ar_mode[8];		/* file mode, printed as octal   */
20103    char ar_size[10];		/* file size, printed as decimal */
20104    char ar_fmag[2];		/* should contain ARFMAG */
20105} ArchiveHeader;
20106
20107static int get_be32(const uint8_t *b)
20108{
20109    return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
20110}
20111
20112/* load only the objects which resolve undefined symbols */
20113static int tcc_load_alacarte(TCCState *s1, int fd, int size)
20114{
20115    int i, bound, nsyms, sym_index, off, ret;
20116    uint8_t *data;
20117    const char *ar_names, *p;
20118    const uint8_t *ar_index;
20119    Elf32_Sym *sym;
20120
20121    data = tcc_malloc(size);
20122    if (read(fd, data, size) != size)
20123        goto fail;
20124    nsyms = get_be32(data);
20125    ar_index = data + 4;
20126    ar_names = ar_index + nsyms * 4;
20127
20128    do {
20129	bound = 0;
20130	for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
20131	    sym_index = find_elf_sym(symtab_section, p);
20132	    if(sym_index) {
20133		sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
20134		if(sym->st_shndx == SHN_UNDEF) {
20135		    off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
20136#if 0
20137		    printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
20138#endif
20139		    ++bound;
20140		    lseek(fd, off, SEEK_SET);
20141		    if(tcc_load_object_file(s1, fd, off) < 0) {
20142                    fail:
20143                        ret = -1;
20144                        goto the_end;
20145                    }
20146		}
20147	    }
20148	}
20149    } while(bound);
20150    ret = 0;
20151 the_end:
20152    tcc_free(data);
20153    return ret;
20154}
20155
20156/* load a '.a' file */
20157static int tcc_load_archive(TCCState *s1, int fd)
20158{
20159    ArchiveHeader hdr;
20160    char ar_size[11];
20161    char ar_name[17];
20162    char magic[8];
20163    int size, len, i;
20164    unsigned long file_offset;
20165
20166    /* skip magic which was already checked */
20167    dummy_size_t = read(fd, magic, sizeof(magic));
20168
20169    for(;;) {
20170        len = read(fd, &hdr, sizeof(hdr));
20171        if (len == 0)
20172            break;
20173        if (len != sizeof(hdr)) {
20174            error_noabort("invalid archive");
20175            return -1;
20176        }
20177        memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
20178        ar_size[sizeof(hdr.ar_size)] = '\0';
20179        size = strtol(ar_size, NULL, 0);
20180        memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
20181        for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
20182            if (ar_name[i] != ' ')
20183                break;
20184        }
20185        ar_name[i + 1] = '\0';
20186        //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
20187        file_offset = lseek(fd, 0, SEEK_CUR);
20188        /* align to even */
20189        size = (size + 1) & ~1;
20190        if (!strcmp(ar_name, "/")) {
20191            /* coff symbol table : we handle it */
20192	    if(s1->alacarte_link)
20193		return tcc_load_alacarte(s1, fd, size);
20194        } else if (!strcmp(ar_name, "//") ||
20195                   !strcmp(ar_name, "__.SYMDEF") ||
20196                   !strcmp(ar_name, "__.SYMDEF/") ||
20197                   !strcmp(ar_name, "ARFILENAMES/")) {
20198            /* skip symbol table or archive names */
20199        } else {
20200            if (tcc_load_object_file(s1, fd, file_offset) < 0)
20201                return -1;
20202        }
20203        lseek(fd, file_offset + size, SEEK_SET);
20204    }
20205    return 0;
20206}
20207
20208/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
20209   is referenced by the user (so it should be added as DT_NEEDED in
20210   the generated ELF file) */
20211static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
20212{
20213    Elf32_Ehdr ehdr;
20214    Elf32_Shdr *shdr, *sh, *sh1;
20215    int i, nb_syms, nb_dts, sym_bind, ret;
20216    Elf32_Sym *sym, *dynsym;
20217    Elf32_Dyn *dt, *dynamic;
20218    unsigned char *dynstr;
20219    const char *name, *soname, *p;
20220    DLLReference *dllref;
20221
20222    dummy_size_t = read(fd, &ehdr, sizeof(ehdr));
20223
20224    /* test CPU specific stuff */
20225    if (ehdr.e_ident[5] != ELFDATA2LSB ||
20226        ehdr.e_machine != EM_TCC_TARGET) {
20227        error_noabort("bad architecture");
20228        return -1;
20229    }
20230
20231    /* read sections */
20232    shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
20233
20234    /* load dynamic section and dynamic symbols */
20235    nb_syms = 0;
20236    nb_dts = 0;
20237    dynamic = NULL;
20238    dynsym = NULL; /* avoid warning */
20239    dynstr = NULL; /* avoid warning */
20240    for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
20241        switch(sh->sh_type) {
20242        case SHT_DYNAMIC:
20243            nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
20244            dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
20245            break;
20246        case SHT_DYNSYM:
20247            nb_syms = sh->sh_size / sizeof(Elf32_Sym);
20248            dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
20249            sh1 = &shdr[sh->sh_link];
20250            dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
20251            break;
20252        default:
20253            break;
20254        }
20255    }
20256
20257    /* compute the real library name */
20258    soname = filename;
20259    p = strrchr(soname, '/');
20260    if (p)
20261        soname = p + 1;
20262
20263    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20264        if (dt->d_tag == DT_SONAME) {
20265            soname = dynstr + dt->d_un.d_val;
20266        }
20267    }
20268
20269    /* if the dll is already loaded, do not load it */
20270    for(i = 0; i < s1->nb_loaded_dlls; i++) {
20271        dllref = s1->loaded_dlls[i];
20272        if (!strcmp(soname, dllref->name)) {
20273            /* but update level if needed */
20274            if (level < dllref->level)
20275                dllref->level = level;
20276            ret = 0;
20277            goto the_end;
20278        }
20279    }
20280
20281    //    printf("loading dll '%s'\n", soname);
20282
20283    /* add the dll and its level */
20284    dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
20285    dllref->level = level;
20286    strcpy(dllref->name, soname);
20287    dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
20288
20289    /* add dynamic symbols in dynsym_section */
20290    for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
20291        sym_bind = ELF32_ST_BIND(sym->st_info);
20292        if (sym_bind == STB_LOCAL)
20293            continue;
20294        name = dynstr + sym->st_name;
20295        add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
20296                    sym->st_info, sym->st_other, sym->st_shndx, name);
20297    }
20298
20299    /* load all referenced DLLs */
20300    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
20301        switch(dt->d_tag) {
20302        case DT_NEEDED:
20303            name = dynstr + dt->d_un.d_val;
20304            for(i = 0; i < s1->nb_loaded_dlls; i++) {
20305                dllref = s1->loaded_dlls[i];
20306                if (!strcmp(name, dllref->name))
20307                    goto already_loaded;
20308            }
20309            if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
20310                error_noabort("referenced dll '%s' not found", name);
20311                ret = -1;
20312                goto the_end;
20313            }
20314        already_loaded:
20315            break;
20316        }
20317    }
20318    ret = 0;
20319 the_end:
20320    tcc_free(dynstr);
20321    tcc_free(dynsym);
20322    tcc_free(dynamic);
20323    tcc_free(shdr);
20324    return ret;
20325}
20326
20327#define LD_TOK_NAME 256
20328#define LD_TOK_EOF  (-1)
20329
20330/* return next ld script token */
20331static int ld_next(TCCState *s1, char *name, int name_size)
20332{
20333    int c;
20334    char *q;
20335
20336 redo:
20337    switch(ch) {
20338    case ' ':
20339    case '\t':
20340    case '\f':
20341    case '\v':
20342    case '\r':
20343    case '\n':
20344        inp();
20345        goto redo;
20346    case '/':
20347        minp();
20348        if (ch == '*') {
20349            file->buf_ptr = parse_comment(file->buf_ptr);
20350            ch = file->buf_ptr[0];
20351            goto redo;
20352        } else {
20353            q = name;
20354            *q++ = '/';
20355            goto parse_name;
20356        }
20357        break;
20358    case 'a' ... 'z':
20359    case 'A' ... 'Z':
20360    case '_':
20361    case '\\':
20362    case '.':
20363    case '$':
20364    case '~':
20365        q = name;
20366    parse_name:
20367        for(;;) {
20368            if (!((ch >= 'a' && ch <= 'z') ||
20369                  (ch >= 'A' && ch <= 'Z') ||
20370                  (ch >= '0' && ch <= '9') ||
20371                  strchr("/.-_+=$:\\,~", ch)))
20372                break;
20373            if ((q - name) < name_size - 1) {
20374                *q++ = ch;
20375            }
20376            minp();
20377        }
20378        *q = '\0';
20379        c = LD_TOK_NAME;
20380        break;
20381    case CH_EOF:
20382        c = LD_TOK_EOF;
20383        break;
20384    default:
20385        c = ch;
20386        inp();
20387        break;
20388    }
20389#if 0
20390    printf("tok=%c %d\n", c, c);
20391    if (c == LD_TOK_NAME)
20392        printf("  name=%s\n", name);
20393#endif
20394    return c;
20395}
20396
20397/* interpret a subset of GNU ldscripts to handle the dummy libc.so
20398   files */
20399static int tcc_load_ldscript(TCCState *s1)
20400{
20401    char cmd[64];
20402    char filename[1024];
20403    int t;
20404
20405    ch = file->buf_ptr[0];
20406    ch = handle_eob();
20407    for(;;) {
20408        t = ld_next(s1, cmd, sizeof(cmd));
20409        if (t == LD_TOK_EOF)
20410            return 0;
20411        else if (t != LD_TOK_NAME)
20412            return -1;
20413        if (!strcmp(cmd, "INPUT") ||
20414            !strcmp(cmd, "GROUP")) {
20415            t = ld_next(s1, cmd, sizeof(cmd));
20416            if (t != '(')
20417                expect("(");
20418            t = ld_next(s1, filename, sizeof(filename));
20419            for(;;) {
20420                if (t == LD_TOK_EOF) {
20421                    error_noabort("unexpected end of file");
20422                    return -1;
20423                } else if (t == ')') {
20424                    break;
20425                } else if (t != LD_TOK_NAME) {
20426                    error_noabort("filename expected");
20427                    return -1;
20428                }
20429                tcc_add_file(s1, filename);
20430                t = ld_next(s1, filename, sizeof(filename));
20431                if (t == ',') {
20432                    t = ld_next(s1, filename, sizeof(filename));
20433                }
20434            }
20435        } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
20436                   !strcmp(cmd, "TARGET")) {
20437            /* ignore some commands */
20438            t = ld_next(s1, cmd, sizeof(cmd));
20439            if (t != '(')
20440                expect("(");
20441            for(;;) {
20442                t = ld_next(s1, filename, sizeof(filename));
20443                if (t == LD_TOK_EOF) {
20444                    error_noabort("unexpected end of file");
20445                    return -1;
20446                } else if (t == ')') {
20447                    break;
20448                }
20449            }
20450        } else {
20451            return -1;
20452        }
20453    }
20454    return 0;
20455}
20456//---------------------------------------------------------------------------
20457
20458#ifdef TCC_TARGET_COFF
20459#include "tcccoff.c"
20460#endif
20461
20462#ifdef TCC_TARGET_PE
20463#include "tccpe.c"
20464#endif
20465
20466/* print the position in the source file of PC value 'pc' by reading
20467   the stabs debug information */
20468static void rt_printline(unsigned long wanted_pc)
20469{
20470    Stab_Sym *sym, *sym_end;
20471    char func_name[128], last_func_name[128];
20472    unsigned long func_addr, last_pc, pc;
20473    const char *incl_files[INCLUDE_STACK_SIZE];
20474    int incl_index, len, last_line_num, i;
20475    const char *str, *p;
20476
20477    fprintf(stderr, "0x%08lx:", wanted_pc);
20478
20479    func_name[0] = '\0';
20480    func_addr = 0;
20481    incl_index = 0;
20482    last_func_name[0] = '\0';
20483    last_pc = 0xffffffff;
20484    last_line_num = 1;
20485    sym = (Stab_Sym *)stab_section->data + 1;
20486    sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
20487    while (sym < sym_end) {
20488        switch(sym->n_type) {
20489            /* function start or end */
20490        case N_FUN:
20491            if (sym->n_strx == 0) {
20492                /* we test if between last line and end of function */
20493                pc = sym->n_value + func_addr;
20494                if (wanted_pc >= last_pc && wanted_pc < pc)
20495                    goto found;
20496                func_name[0] = '\0';
20497                func_addr = 0;
20498            } else {
20499                str = stabstr_section->data + sym->n_strx;
20500                p = strchr(str, ':');
20501                if (!p) {
20502                    pstrcpy(func_name, sizeof(func_name), str);
20503                } else {
20504                    len = p - str;
20505                    if (len > sizeof(func_name) - 1)
20506                        len = sizeof(func_name) - 1;
20507                    memcpy(func_name, str, len);
20508                    func_name[len] = '\0';
20509                }
20510                func_addr = sym->n_value;
20511            }
20512            break;
20513            /* line number info */
20514        case N_SLINE:
20515            pc = sym->n_value + func_addr;
20516            if (wanted_pc >= last_pc && wanted_pc < pc)
20517                goto found;
20518            last_pc = pc;
20519            last_line_num = sym->n_desc;
20520            /* XXX: slow! */
20521            strcpy(last_func_name, func_name);
20522            break;
20523            /* include files */
20524        case N_BINCL:
20525            str = stabstr_section->data + sym->n_strx;
20526        add_incl:
20527            if (incl_index < INCLUDE_STACK_SIZE) {
20528                incl_files[incl_index++] = str;
20529            }
20530            break;
20531        case N_EINCL:
20532            if (incl_index > 1)
20533                incl_index--;
20534            break;
20535        case N_SO:
20536            if (sym->n_strx == 0) {
20537                incl_index = 0; /* end of translation unit */
20538            } else {
20539                str = stabstr_section->data + sym->n_strx;
20540                /* do not add path */
20541                len = strlen(str);
20542                if (len > 0 && str[len - 1] != '/')
20543                    goto add_incl;
20544            }
20545            break;
20546        }
20547        sym++;
20548    }
20549
20550    /* second pass: we try symtab symbols (no line number info) */
20551    incl_index = 0;
20552    {
20553        Elf32_Sym *sym, *sym_end;
20554        int type;
20555
20556        sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
20557        for(sym = (Elf32_Sym *)symtab_section->data + 1;
20558            sym < sym_end;
20559            sym++) {
20560            type = ELF32_ST_TYPE(sym->st_info);
20561            if (type == STT_FUNC) {
20562                if (wanted_pc >= sym->st_value &&
20563                    wanted_pc < sym->st_value + sym->st_size) {
20564                    pstrcpy(last_func_name, sizeof(last_func_name),
20565                            strtab_section->data + sym->st_name);
20566                    goto found;
20567                }
20568            }
20569        }
20570    }
20571    /* did not find any info: */
20572    fprintf(stderr, " ???\n");
20573    return;
20574 found:
20575    if (last_func_name[0] != '\0') {
20576        fprintf(stderr, " %s()", last_func_name);
20577    }
20578    if (incl_index > 0) {
20579        fprintf(stderr, " (%s:%d",
20580                incl_files[incl_index - 1], last_line_num);
20581        for(i = incl_index - 2; i >= 0; i--)
20582            fprintf(stderr, ", included from %s", incl_files[i]);
20583        fprintf(stderr, ")");
20584    }
20585    fprintf(stderr, "\n");
20586}
20587
20588#if !defined(WIN32) && !defined(CONFIG_TCCBOOT)
20589
20590/* return the PC at frame level 'level'. Return non zero if not found */
20591static int rt_get_caller_pc(unsigned long *paddr,
20592                            ucontext_t *uc, int level)
20593{
20594    unsigned long fp __attribute__((unused));
20595    //int i;
20596
20597    if (level == 0) {
20598        *paddr = 12345; //uc->uc_mcontext.gregs[REG_EIP];
20599        return 0;
20600    } else {
20601        fp = 23456; //uc->uc_mcontext.gregs[REG_EBP];
20602        return 0;
20603    }
20604}
20605
20606/* emit a run time error at position 'pc' */
20607void rt_error(ucontext_t *uc, const char *fmt, ...)
20608{
20609    va_list ap;
20610    unsigned long pc = 0;  // shut gcc up
20611    int i;
20612
20613    va_start(ap, fmt);
20614    fprintf(stderr, "Runtime error: ");
20615    vfprintf(stderr, fmt, ap);
20616    fprintf(stderr, "\n");
20617    for(i=0;i<num_callers;i++) {
20618        if (rt_get_caller_pc(&pc, uc, i) < 0)
20619            break;
20620        if (i == 0)
20621            fprintf(stderr, "at ");
20622        else
20623            fprintf(stderr, "by ");
20624        rt_printline(pc);
20625    }
20626    exit(255);
20627    va_end(ap);
20628}
20629
20630/* signal handler for fatal errors */
20631static void sig_error(int signum, siginfo_t *siginf, void *puc)
20632{
20633    ucontext_t *uc = puc;
20634
20635    switch(signum) {
20636    case SIGFPE:
20637        switch(siginf->si_code) {
20638        case FPE_INTDIV:
20639        case FPE_FLTDIV:
20640            rt_error(uc, "division by zero");
20641            break;
20642        default:
20643            rt_error(uc, "floating point exception");
20644            break;
20645        }
20646        break;
20647    case SIGBUS:
20648    case SIGSEGV:
20649        if (rt_bound_error_msg && *rt_bound_error_msg)
20650            rt_error(uc, *rt_bound_error_msg);
20651        else
20652            rt_error(uc, "dereferencing invalid pointer");
20653        break;
20654    case SIGILL:
20655        rt_error(uc, "illegal instruction");
20656        break;
20657    case SIGABRT:
20658        rt_error(uc, "abort() called");
20659        break;
20660    default:
20661        rt_error(uc, "caught signal %d", signum);
20662        break;
20663    }
20664    exit(255);
20665}
20666#endif
20667
20668/* do all relocations (needed before using tcc_get_symbol()) */
20669int tcc_relocate(TCCState *s1)
20670{
20671    Section *s;
20672    int i;
20673
20674    s1->nb_errors = 0;
20675
20676#ifdef TCC_TARGET_PE
20677    pe_add_runtime(s1);
20678#else
20679    tcc_add_runtime(s1);
20680#endif
20681
20682    relocate_common_syms();
20683
20684    tcc_add_linker_symbols(s1);
20685
20686    build_got_entries(s1);
20687
20688    /* compute relocation address : section are relocated in place. We
20689       also alloc the bss space */
20690    for(i = 1; i < s1->nb_sections; i++) {
20691        s = s1->sections[i];
20692        if (s->sh_flags & SHF_ALLOC) {
20693            if (s->sh_type == SHT_NOBITS)
20694                s->data = tcc_mallocz(s->data_offset);
20695            s->sh_addr = (unsigned long)s->data;
20696        }
20697    }
20698
20699    relocate_syms(s1, 1);
20700
20701    if (s1->nb_errors != 0)
20702        return -1;
20703
20704    /* relocate each section */
20705    for(i = 1; i < s1->nb_sections; i++) {
20706        s = s1->sections[i];
20707        if (s->reloc)
20708            relocate_section(s1, s);
20709    }
20710    return 0;
20711}
20712
20713/* launch the compiled program with the given arguments */
20714int tcc_run(TCCState *s1, int argc, char **argv)
20715{
20716    int (*prog_main)(int, char **);
20717
20718    if (tcc_relocate(s1) < 0)
20719        return -1;
20720
20721    prog_main = tcc_get_symbol_err(s1, "main");
20722
20723    if (do_debug) {
20724#if defined(WIN32) || defined(CONFIG_TCCBOOT)
20725        error("debug mode currently not available for Windows");
20726#else
20727        struct sigaction sigact;
20728        /* install TCC signal handlers to print debug info on fatal
20729           runtime errors */
20730        sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
20731        sigact.sa_sigaction = sig_error;
20732        sigemptyset(&sigact.sa_mask);
20733        sigaction(SIGFPE, &sigact, NULL);
20734        sigaction(SIGILL, &sigact, NULL);
20735        sigaction(SIGSEGV, &sigact, NULL);
20736        sigaction(SIGBUS, &sigact, NULL);
20737        sigaction(SIGABRT, &sigact, NULL);
20738#endif
20739    }
20740
20741#ifdef CONFIG_TCC_BCHECK
20742    if (do_bounds_check) {
20743        void (*bound_init)(void);
20744
20745        /* set error function */
20746        rt_bound_error_msg = (void *)tcc_get_symbol_err(s1,
20747                                                        "__bound_error_msg");
20748
20749        /* XXX: use .init section so that it also work in binary ? */
20750        bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init");
20751        bound_init();
20752    }
20753#endif
20754    return (*prog_main)(argc, argv);
20755}
20756
20757TCCState *tcc_new(void)
20758{
20759    const char *p, *r;
20760    TCCState *s;
20761    TokenSym *ts __attribute__((unused));
20762    int i, c;
20763
20764    s = tcc_mallocz(sizeof(TCCState));
20765    if (!s)
20766        return NULL;
20767    tcc_state = s;
20768    s->output_type = TCC_OUTPUT_MEMORY;
20769
20770    /* init isid table */
20771    for(i=0;i<256;i++)
20772        isidnum_table[i] = isid(i) || isnum(i);
20773
20774    /* add all tokens */
20775    table_ident = NULL;
20776    memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
20777
20778    tok_ident = TOK_IDENT;
20779    p = tcc_keywords;
20780    while (*p) {
20781        r = p;
20782        for(;;) {
20783            c = *r++;
20784            if (c == '\0')
20785                break;
20786        }
20787        ts = tok_alloc(p, r - p - 1);
20788        p = r;
20789    }
20790
20791    /* we add dummy defines for some special macros to speed up tests
20792       and to have working defined() */
20793    define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
20794    define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
20795    define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
20796    define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
20797
20798    /* standard defines */
20799    tcc_define_symbol(s, "__STDC__", NULL);
20800#if defined(TCC_TARGET_I386)
20801    tcc_define_symbol(s, "__i386__", NULL);
20802#endif
20803#if defined(TCC_TARGET_ARM)
20804    tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
20805    tcc_define_symbol(s, "__arm_elf__", NULL);
20806    tcc_define_symbol(s, "__arm_elf", NULL);
20807    tcc_define_symbol(s, "arm_elf", NULL);
20808    tcc_define_symbol(s, "__arm__", NULL);
20809    tcc_define_symbol(s, "__arm", NULL);
20810    tcc_define_symbol(s, "arm", NULL);
20811    tcc_define_symbol(s, "__APCS_32__", NULL);
20812#endif
20813#if defined(linux)
20814    tcc_define_symbol(s, "__linux__", NULL);
20815    tcc_define_symbol(s, "linux", NULL);
20816#endif
20817    /* tiny C specific defines */
20818    tcc_define_symbol(s, "__TINYC__", NULL);
20819
20820    /* tiny C & gcc defines */
20821    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
20822    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
20823    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
20824
20825    /* default library paths */
20826#ifdef TCC_TARGET_PE
20827    {
20828        char buf[1024];
20829        snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path);
20830        tcc_add_library_path(s, buf);
20831    }
20832#else
20833    tcc_add_library_path(s, "/usr/local/lib");
20834    tcc_add_library_path(s, "/usr/lib");
20835    tcc_add_library_path(s, "/lib");
20836#endif
20837
20838    /* no section zero */
20839    dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
20840
20841    /* create standard sections */
20842    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
20843    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
20844    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
20845
20846    /* symbols are always generated for linking stage */
20847    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
20848                                ".strtab",
20849                                ".hashtab", SHF_PRIVATE);
20850    strtab_section = symtab_section->link;
20851
20852    /* private symbol table for dynamic symbols */
20853    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
20854                                      ".dynstrtab",
20855                                      ".dynhashtab", SHF_PRIVATE);
20856    s->alacarte_link = 1;
20857
20858#ifdef CHAR_IS_UNSIGNED
20859    s->char_is_unsigned = 1;
20860#endif
20861#if defined(TCC_TARGET_PE) && 0
20862    /* XXX: currently the PE linker is not ready to support that */
20863    s->leading_underscore = 1;
20864#endif
20865    return s;
20866}
20867
20868void tcc_delete(TCCState *s1)
20869{
20870    int i, n;
20871
20872    /* free -D defines */
20873    free_defines(NULL);
20874
20875    /* free tokens */
20876    n = tok_ident - TOK_IDENT;
20877    for(i = 0; i < n; i++)
20878        tcc_free(table_ident[i]);
20879    tcc_free(table_ident);
20880
20881    /* free all sections */
20882
20883    free_section(symtab_section->hash);
20884
20885    free_section(s1->dynsymtab_section->hash);
20886    free_section(s1->dynsymtab_section->link);
20887    free_section(s1->dynsymtab_section);
20888
20889    for(i = 1; i < s1->nb_sections; i++)
20890        free_section(s1->sections[i]);
20891    tcc_free(s1->sections);
20892
20893    /* free loaded dlls array */
20894    for(i = 0; i < s1->nb_loaded_dlls; i++)
20895        tcc_free(s1->loaded_dlls[i]);
20896    tcc_free(s1->loaded_dlls);
20897
20898    /* library paths */
20899    for(i = 0; i < s1->nb_library_paths; i++)
20900        tcc_free(s1->library_paths[i]);
20901    tcc_free(s1->library_paths);
20902
20903    /* cached includes */
20904    for(i = 0; i < s1->nb_cached_includes; i++)
20905        tcc_free(s1->cached_includes[i]);
20906    tcc_free(s1->cached_includes);
20907
20908    for(i = 0; i < s1->nb_include_paths; i++)
20909        tcc_free(s1->include_paths[i]);
20910    tcc_free(s1->include_paths);
20911
20912    for(i = 0; i < s1->nb_sysinclude_paths; i++)
20913        tcc_free(s1->sysinclude_paths[i]);
20914    tcc_free(s1->sysinclude_paths);
20915
20916    tcc_free(s1);
20917}
20918
20919int tcc_add_include_path(TCCState *s1, const char *pathname)
20920{
20921    char *pathname1;
20922
20923    pathname1 = tcc_strdup(pathname);
20924    dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
20925    return 0;
20926}
20927
20928int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
20929{
20930    char *pathname1;
20931
20932    pathname1 = tcc_strdup(pathname);
20933    dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
20934    return 0;
20935}
20936
20937static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
20938{
20939    const char *ext, *filename1;
20940    Elf32_Ehdr ehdr;
20941    int fd, ret;
20942    BufferedFile *saved_file;
20943
20944    /* find source file type with extension */
20945    filename1 = strrchr(filename, '/');
20946    if (filename1)
20947        filename1++;
20948    else
20949        filename1 = filename;
20950    ext = strrchr(filename1, '.');
20951    if (ext)
20952        ext++;
20953
20954    /* open the file */
20955    saved_file = file;
20956    file = tcc_open(s1, filename);
20957    if (!file) {
20958        if (flags & AFF_PRINT_ERROR) {
20959            error_noabort("file '%s' not found", filename);
20960        }
20961        ret = -1;
20962        goto fail1;
20963    }
20964
20965    if (!ext || !strcmp(ext, "c")) {
20966        /* C file assumed */
20967        ret = tcc_compile(s1);
20968    } else
20969#ifdef CONFIG_TCC_ASM
20970    if (!strcmp(ext, "S")) {
20971        /* preprocessed assembler */
20972        ret = tcc_assemble(s1, 1);
20973    } else if (!strcmp(ext, "s")) {
20974        /* non preprocessed assembler */
20975        ret = tcc_assemble(s1, 0);
20976    } else
20977#endif
20978#ifdef TCC_TARGET_PE
20979    if (!strcmp(ext, "def")) {
20980        ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
20981    } else
20982#endif
20983    {
20984        fd = file->fd;
20985        /* assume executable format: auto guess file type */
20986        ret = read(fd, &ehdr, sizeof(ehdr));
20987        lseek(fd, 0, SEEK_SET);
20988        if (ret <= 0) {
20989            error_noabort("could not read header");
20990            goto fail;
20991        } else if (ret != sizeof(ehdr)) {
20992            goto try_load_script;
20993        }
20994
20995        if (ehdr.e_ident[0] == ELFMAG0 &&
20996            ehdr.e_ident[1] == ELFMAG1 &&
20997            ehdr.e_ident[2] == ELFMAG2 &&
20998            ehdr.e_ident[3] == ELFMAG3) {
20999            file->line_num = 0; /* do not display line number if error */
21000            if (ehdr.e_type == ET_REL) {
21001                ret = tcc_load_object_file(s1, fd, 0);
21002            } else if (ehdr.e_type == ET_DYN) {
21003                if (s1->output_type == TCC_OUTPUT_MEMORY) {
21004#ifdef TCC_TARGET_PE
21005                    ret = -1;
21006#else
21007                    void *h;
21008		    assert(0);
21009		    h = 0;
21010                    //h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
21011		    // jrs: remove need for dlopen
21012                    if (h)
21013                        ret = 0;
21014                    else
21015                        ret = -1;
21016#endif
21017                } else {
21018                    ret = tcc_load_dll(s1, fd, filename,
21019                                       (flags & AFF_REFERENCED_DLL) != 0);
21020                }
21021            } else {
21022                error_noabort("unrecognized ELF file");
21023                goto fail;
21024            }
21025        } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
21026            file->line_num = 0; /* do not display line number if error */
21027            ret = tcc_load_archive(s1, fd);
21028        } else
21029#ifdef TCC_TARGET_COFF
21030        if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
21031            ret = tcc_load_coff(s1, fd);
21032        } else
21033#endif
21034        {
21035            /* as GNU ld, consider it is an ld script if not recognized */
21036        try_load_script:
21037            ret = tcc_load_ldscript(s1);
21038            if (ret < 0) {
21039                error_noabort("unrecognized file type");
21040                goto fail;
21041            }
21042        }
21043    }
21044 the_end:
21045    tcc_close(file);
21046 fail1:
21047    file = saved_file;
21048    return ret;
21049 fail:
21050    ret = -1;
21051    goto the_end;
21052}
21053
21054int tcc_add_file(TCCState *s, const char *filename)
21055{
21056    return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
21057}
21058
21059int tcc_add_library_path(TCCState *s, const char *pathname)
21060{
21061    char *pathname1;
21062
21063    pathname1 = tcc_strdup(pathname);
21064    dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
21065    return 0;
21066}
21067
21068/* find and load a dll. Return non zero if not found */
21069/* XXX: add '-rpath' option support ? */
21070static int tcc_add_dll(TCCState *s, const char *filename, int flags)
21071{
21072    char buf[1024];
21073    int i;
21074
21075    for(i = 0; i < s->nb_library_paths; i++) {
21076        snprintf(buf, sizeof(buf), "%s/%s",
21077                 s->library_paths[i], filename);
21078        if (tcc_add_file_internal(s, buf, flags) == 0)
21079            return 0;
21080    }
21081    return -1;
21082}
21083
21084/* the library name is the same as the argument of the '-l' option */
21085int tcc_add_library(TCCState *s, const char *libraryname)
21086{
21087    char buf[1024];
21088    int i;
21089
21090    /* first we look for the dynamic library if not static linking */
21091    if (!s->static_link) {
21092#ifdef TCC_TARGET_PE
21093        snprintf(buf, sizeof(buf), "%s.def", libraryname);
21094#else
21095        snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
21096#endif
21097        if (tcc_add_dll(s, buf, 0) == 0)
21098            return 0;
21099    }
21100
21101    /* then we look for the static library */
21102    for(i = 0; i < s->nb_library_paths; i++) {
21103        snprintf(buf, sizeof(buf), "%s/lib%s.a",
21104                 s->library_paths[i], libraryname);
21105        if (tcc_add_file_internal(s, buf, 0) == 0)
21106            return 0;
21107    }
21108    return -1;
21109}
21110
21111int tcc_add_symbol(TCCState *s, const char *name, unsigned long val)
21112{
21113    add_elf_sym(symtab_section, val, 0,
21114                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
21115                SHN_ABS, name);
21116    return 0;
21117}
21118
21119int tcc_set_output_type(TCCState *s, int output_type)
21120{
21121    s->output_type = output_type;
21122
21123    if (!s->nostdinc) {
21124        char buf[1024];
21125
21126        /* default include paths */
21127        /* XXX: reverse order needed if -isystem support */
21128#ifndef TCC_TARGET_PE
21129        tcc_add_sysinclude_path(s, "/usr/local/include");
21130        tcc_add_sysinclude_path(s, "/usr/include");
21131#endif
21132        snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path);
21133        tcc_add_sysinclude_path(s, buf);
21134#ifdef TCC_TARGET_PE
21135        snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path);
21136        tcc_add_sysinclude_path(s, buf);
21137#endif
21138    }
21139
21140    /* if bound checking, then add corresponding sections */
21141#ifdef CONFIG_TCC_BCHECK
21142    if (do_bounds_check) {
21143        /* define symbol */
21144        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
21145        /* create bounds sections */
21146        bounds_section = new_section(s, ".bounds",
21147                                     SHT_PROGBITS, SHF_ALLOC);
21148        lbounds_section = new_section(s, ".lbounds",
21149                                      SHT_PROGBITS, SHF_ALLOC);
21150    }
21151#endif
21152
21153    if (s->char_is_unsigned) {
21154        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
21155    }
21156
21157    /* add debug sections */
21158    if (do_debug) {
21159        /* stab symbols */
21160        stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
21161        stab_section->sh_entsize = sizeof(Stab_Sym);
21162        stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
21163        put_elf_str(stabstr_section, "");
21164        stab_section->link = stabstr_section;
21165        /* put first entry */
21166        put_stabs("", 0, 0, 0, 0);
21167    }
21168
21169    /* add libc crt1/crti objects */
21170#ifndef TCC_TARGET_PE
21171    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
21172        !s->nostdlib) {
21173        if (output_type != TCC_OUTPUT_DLL)
21174            tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
21175        tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
21176    }
21177#endif
21178    return 0;
21179}
21180
21181#define WD_ALL    0x0001 /* warning is activated when using -Wall */
21182#define FD_INVERT 0x0002 /* invert value before storing */
21183
21184typedef struct FlagDef {
21185    uint16_t offset;
21186    uint16_t flags;
21187    const char *name;
21188} FlagDef;
21189
21190static const FlagDef warning_defs[] = {
21191    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
21192    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
21193    { offsetof(TCCState, warn_error), 0, "error" },
21194    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
21195      "implicit-function-declaration" },
21196};
21197
21198static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
21199                    const char *name, int value)
21200{
21201    int i;
21202    const FlagDef *p;
21203    const char *r;
21204
21205    r = name;
21206    if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
21207        r += 3;
21208        value = !value;
21209    }
21210    for(i = 0, p = flags; i < nb_flags; i++, p++) {
21211        if (!strcmp(r, p->name))
21212            goto found;
21213    }
21214    return -1;
21215 found:
21216    if (p->flags & FD_INVERT)
21217        value = !value;
21218    *(int *)((uint8_t *)s + p->offset) = value;
21219    return 0;
21220}
21221
21222
21223/* set/reset a warning */
21224int tcc_set_warning(TCCState *s, const char *warning_name, int value)
21225{
21226    int i;
21227    const FlagDef *p;
21228
21229    if (!strcmp(warning_name, "all")) {
21230        for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
21231            if (p->flags & WD_ALL)
21232                *(int *)((uint8_t *)s + p->offset) = 1;
21233        }
21234        return 0;
21235    } else {
21236        return set_flag(s, warning_defs, countof(warning_defs),
21237                        warning_name, value);
21238    }
21239}
21240
21241static const FlagDef flag_defs[] = {
21242    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
21243    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
21244    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
21245    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
21246};
21247
21248/* set/reset a flag */
21249int tcc_set_flag(TCCState *s, const char *flag_name, int value)
21250{
21251    return set_flag(s, flag_defs, countof(flag_defs),
21252                    flag_name, value);
21253}
21254
21255#if !defined(LIBTCC)
21256
21257/* extract the basename of a file */
21258static const char *tcc_basename(const char *name)
21259{
21260    const char *p;
21261    p = strrchr(name, '/');
21262#ifdef WIN32
21263    if (!p)
21264        p = strrchr(name, '\\');
21265#endif
21266    if (!p)
21267        p = name;
21268    else
21269        p++;
21270    return p;
21271}
21272
21273static int64_t getclock_us(void)
21274{
21275#ifdef WIN32
21276    struct _timeb tb;
21277    _ftime(&tb);
21278    return (tb.time * 1000LL + tb.millitm) * 1000LL;
21279#else
21280    struct timeval tv;
21281    gettimeofday(&tv, NULL);
21282    return tv.tv_sec * 1000000LL + tv.tv_usec;
21283#endif
21284}
21285
21286void help(void)
21287{
21288    printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2013 Fabrice Bellard\n"
21289           "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
21290           "           [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n"
21291           "           [infile1 infile2...] [-run infile args...]\n"
21292           "\n"
21293           "General options:\n"
21294           "  -v          display current version\n"
21295           "  -c          compile only - generate an object file\n"
21296           "  -o outfile  set output filename\n"
21297           "  -Bdir       set tcc internal library path\n"
21298           "  -bench      output compilation statistics\n"
21299 	   "  -run        run compiled source\n"
21300           "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
21301           "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
21302           "  -w          disable all warnings\n"
21303           "Preprocessor options:\n"
21304           "  -Idir       add include path 'dir'\n"
21305           "  -Dsym[=val] define 'sym' with value 'val'\n"
21306           "  -Usym       undefine 'sym'\n"
21307           "Linker options:\n"
21308           "  -Ldir       add library path 'dir'\n"
21309           "  -llib       link with dynamic or static library 'lib'\n"
21310           "  -shared     generate a shared library\n"
21311           "  -static     static linking\n"
21312           "  -rdynamic   export all global symbols to dynamic linker\n"
21313           "  -r          relocatable output\n"
21314           "Debugger options:\n"
21315           "  -g          generate runtime debug info\n"
21316#ifdef CONFIG_TCC_BCHECK
21317           "  -b          compile with built-in memory and bounds checker (implies -g)\n"
21318#endif
21319           "  -bt N       show N callers in stack traces\n"
21320           );
21321}
21322
21323#define TCC_OPTION_HAS_ARG 0x0001
21324#define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
21325
21326typedef struct TCCOption {
21327    const char *name;
21328    uint16_t index;
21329    uint16_t flags;
21330} TCCOption;
21331
21332enum {
21333    TCC_OPTION_HELP,
21334    TCC_OPTION_I,
21335    TCC_OPTION_D,
21336    TCC_OPTION_U,
21337    TCC_OPTION_L,
21338    TCC_OPTION_B,
21339    TCC_OPTION_l,
21340    TCC_OPTION_bench,
21341    TCC_OPTION_bt,
21342    TCC_OPTION_b,
21343    TCC_OPTION_g,
21344    TCC_OPTION_c,
21345    TCC_OPTION_static,
21346    TCC_OPTION_shared,
21347    TCC_OPTION_o,
21348    TCC_OPTION_r,
21349    TCC_OPTION_Wl,
21350    TCC_OPTION_W,
21351    TCC_OPTION_O,
21352    TCC_OPTION_m,
21353    TCC_OPTION_f,
21354    TCC_OPTION_nostdinc,
21355    TCC_OPTION_nostdlib,
21356    TCC_OPTION_print_search_dirs,
21357    TCC_OPTION_rdynamic,
21358    TCC_OPTION_run,
21359    TCC_OPTION_v,
21360    TCC_OPTION_w,
21361    TCC_OPTION_pipe,
21362};
21363
21364static const TCCOption tcc_options[] = {
21365    { "h", TCC_OPTION_HELP, 0 },
21366    { "?", TCC_OPTION_HELP, 0 },
21367    { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
21368    { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
21369    { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
21370    { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
21371    { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
21372    { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21373    { "bench", TCC_OPTION_bench, 0 },
21374    { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
21375#ifdef CONFIG_TCC_BCHECK
21376    { "b", TCC_OPTION_b, 0 },
21377#endif
21378    { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21379    { "c", TCC_OPTION_c, 0 },
21380    { "static", TCC_OPTION_static, 0 },
21381    { "shared", TCC_OPTION_shared, 0 },
21382    { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
21383    { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21384    { "rdynamic", TCC_OPTION_rdynamic, 0 },
21385    { "r", TCC_OPTION_r, 0 },
21386    { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21387    { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21388    { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21389    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
21390    { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
21391    { "nostdinc", TCC_OPTION_nostdinc, 0 },
21392    { "nostdlib", TCC_OPTION_nostdlib, 0 },
21393    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
21394    { "v", TCC_OPTION_v, 0 },
21395    { "w", TCC_OPTION_w, 0 },
21396    { "pipe", TCC_OPTION_pipe, 0},
21397    { NULL },
21398};
21399
21400/* convert 'str' into an array of space separated strings */
21401static int expand_args(char ***pargv, const char *str)
21402{
21403    const char *s1;
21404    char **argv, *arg;
21405    int argc, len;
21406
21407    argc = 0;
21408    argv = NULL;
21409    for(;;) {
21410        while (is_space(*str))
21411            str++;
21412        if (*str == '\0')
21413            break;
21414        s1 = str;
21415        while (*str != '\0' && !is_space(*str))
21416            str++;
21417        len = str - s1;
21418        arg = tcc_malloc(len + 1);
21419        memcpy(arg, s1, len);
21420        arg[len] = '\0';
21421        dynarray_add((void ***)&argv, &argc, arg);
21422    }
21423    *pargv = argv;
21424    return argc;
21425}
21426
21427static char **files;
21428static int nb_files, nb_libraries;
21429static int multiple_files;
21430static int print_search_dirs;
21431static int output_type;
21432static int reloc_output;
21433static const char *outfile;
21434
21435int parse_args(TCCState *s, int argc, char **argv)
21436{
21437    int optind;
21438    const TCCOption *popt;
21439    const char *optarg, *p1, *r1;
21440    char *r;
21441
21442    optind = 0;
21443    while (1) {
21444        if (optind >= argc) {
21445            if (nb_files == 0 && !print_search_dirs)
21446                goto show_help;
21447            else
21448                break;
21449        }
21450        r = argv[optind++];
21451        if (r[0] != '-') {
21452            /* add a new file */
21453            dynarray_add((void ***)&files, &nb_files, r);
21454            if (!multiple_files) {
21455                optind--;
21456                /* argv[0] will be this file */
21457                break;
21458            }
21459        } else {
21460            /* find option in table (match only the first chars */
21461            popt = tcc_options;
21462            for(;;) {
21463                p1 = popt->name;
21464                if (p1 == NULL)
21465                    error("invalid option -- '%s'", r);
21466                r1 = r + 1;
21467                for(;;) {
21468                    if (*p1 == '\0')
21469                        goto option_found;
21470                    if (*r1 != *p1)
21471                        break;
21472                    p1++;
21473                    r1++;
21474                }
21475                popt++;
21476            }
21477        option_found:
21478            if (popt->flags & TCC_OPTION_HAS_ARG) {
21479                if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
21480                    optarg = r1;
21481                } else {
21482                    if (optind >= argc)
21483                        error("argument to '%s' is missing", r);
21484                    optarg = argv[optind++];
21485                }
21486            } else {
21487                if (*r1 != '\0')
21488                    goto show_help;
21489                optarg = NULL;
21490            }
21491
21492            switch(popt->index) {
21493            case TCC_OPTION_HELP:
21494            show_help:
21495                help();
21496                exit(1);
21497            case TCC_OPTION_I:
21498                if (tcc_add_include_path(s, optarg) < 0)
21499                    error("too many include paths");
21500                break;
21501            case TCC_OPTION_D:
21502                {
21503                    char *sym, *value;
21504                    sym = (char *)optarg;
21505                    value = strchr(sym, '=');
21506                    if (value) {
21507                        *value = '\0';
21508                        value++;
21509                    }
21510                    tcc_define_symbol(s, sym, value);
21511                }
21512                break;
21513            case TCC_OPTION_U:
21514                tcc_undefine_symbol(s, optarg);
21515                break;
21516            case TCC_OPTION_L:
21517                tcc_add_library_path(s, optarg);
21518                break;
21519            case TCC_OPTION_B:
21520                /* set tcc utilities path (mainly for tcc development) */
21521                tcc_lib_path = optarg;
21522                break;
21523            case TCC_OPTION_l:
21524                dynarray_add((void ***)&files, &nb_files, r);
21525                nb_libraries++;
21526                break;
21527            case TCC_OPTION_bench:
21528                do_bench = 1;
21529                break;
21530            case TCC_OPTION_bt:
21531                num_callers = atoi(optarg);
21532                break;
21533#ifdef CONFIG_TCC_BCHECK
21534            case TCC_OPTION_b:
21535                do_bounds_check = 1;
21536                do_debug = 1;
21537                break;
21538#endif
21539            case TCC_OPTION_g:
21540                do_debug = 1;
21541                break;
21542            case TCC_OPTION_c:
21543                multiple_files = 1;
21544                output_type = TCC_OUTPUT_OBJ;
21545                break;
21546            case TCC_OPTION_static:
21547                s->static_link = 1;
21548                break;
21549            case TCC_OPTION_shared:
21550                output_type = TCC_OUTPUT_DLL;
21551                break;
21552            case TCC_OPTION_o:
21553                multiple_files = 1;
21554                outfile = optarg;
21555                break;
21556            case TCC_OPTION_r:
21557                /* generate a .o merging several output files */
21558                reloc_output = 1;
21559                output_type = TCC_OUTPUT_OBJ;
21560                break;
21561            case TCC_OPTION_nostdinc:
21562                s->nostdinc = 1;
21563                break;
21564            case TCC_OPTION_nostdlib:
21565                s->nostdlib = 1;
21566                break;
21567            case TCC_OPTION_print_search_dirs:
21568                print_search_dirs = 1;
21569                break;
21570            case TCC_OPTION_run:
21571                {
21572                    int argc1;
21573                    char **argv1;
21574                    argc1 = expand_args(&argv1, optarg);
21575                    if (argc1 > 0) {
21576                        parse_args(s, argc1, argv1);
21577                    }
21578                    multiple_files = 0;
21579                    output_type = TCC_OUTPUT_MEMORY;
21580                }
21581                break;
21582            case TCC_OPTION_v:
21583                printf("tcc version %s\n", TCC_VERSION);
21584                exit(0);
21585            case TCC_OPTION_f:
21586                if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
21587                    goto unsupported_option;
21588                break;
21589            case TCC_OPTION_W:
21590                if (tcc_set_warning(s, optarg, 1) < 0 &&
21591                    s->warn_unsupported)
21592                    goto unsupported_option;
21593                break;
21594            case TCC_OPTION_w:
21595                s->warn_none = 1;
21596                break;
21597            case TCC_OPTION_rdynamic:
21598                s->rdynamic = 1;
21599                break;
21600            case TCC_OPTION_Wl:
21601                {
21602                    const char *p;
21603                    if (strstart(optarg, "-Ttext,", &p)) {
21604                        s->text_addr = strtoul(p, NULL, 16);
21605                        s->has_text_addr = 1;
21606                    } else if (strstart(optarg, "--oformat,", &p)) {
21607                        if (strstart(p, "elf32-", NULL)) {
21608                            s->output_format = TCC_OUTPUT_FORMAT_ELF;
21609                        } else if (!strcmp(p, "binary")) {
21610                            s->output_format = TCC_OUTPUT_FORMAT_BINARY;
21611                        } else
21612#ifdef TCC_TARGET_COFF
21613                        if (!strcmp(p, "coff")) {
21614                            s->output_format = TCC_OUTPUT_FORMAT_COFF;
21615                        } else
21616#endif
21617                        {
21618                            error("target %s not found", p);
21619                        }
21620                    } else {
21621                        error("unsupported linker option '%s'", optarg);
21622                    }
21623                }
21624                break;
21625            default:
21626                if (s->warn_unsupported) {
21627                unsupported_option:
21628                    warning("unsupported option '%s'", r);
21629                }
21630                break;
21631            }
21632        }
21633    }
21634    return optind;
21635}
21636
21637// njn: renamed main() as main2() in order to repeat it multiple times.
21638int main2(int argc, char **argv)
21639{
21640    int i;
21641    TCCState *s;
21642    int nb_objfiles, ret, optind;
21643    char objfilename[1024];
21644    int64_t start_time = 0;
21645
21646#ifdef WIN32
21647    /* on win32, we suppose the lib and includes are at the location
21648       of 'tcc.exe' */
21649    {
21650        static char path[1024];
21651        char *p, *d;
21652
21653        GetModuleFileNameA(NULL, path, sizeof path);
21654        p = d = strlwr(path);
21655        while (*d)
21656        {
21657            if (*d == '\\') *d = '/', p = d;
21658            ++d;
21659        }
21660        *p = '\0';
21661        tcc_lib_path = path;
21662    }
21663#endif
21664
21665    s = tcc_new();
21666    output_type = TCC_OUTPUT_EXE;
21667    outfile = NULL;
21668    multiple_files = 1;
21669    files = NULL;
21670    nb_files = 0;
21671    nb_libraries = 0;
21672    reloc_output = 0;
21673    print_search_dirs = 0;
21674
21675    optind = parse_args(s, argc - 1, argv + 1) + 1;
21676
21677    if (print_search_dirs) {
21678        /* enough for Linux kernel */
21679        printf("install: %s/\n", tcc_lib_path);
21680        return 0;
21681    }
21682
21683    nb_objfiles = nb_files - nb_libraries;
21684
21685    /* if outfile provided without other options, we output an
21686       executable */
21687    if (outfile && output_type == TCC_OUTPUT_MEMORY)
21688        output_type = TCC_OUTPUT_EXE;
21689
21690    /* check -c consistency : only single file handled. XXX: checks file type */
21691    if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21692        /* accepts only a single input file */
21693        if (nb_objfiles != 1)
21694            error("cannot specify multiple files with -c");
21695        if (nb_libraries != 0)
21696            error("cannot specify libraries with -c");
21697    }
21698
21699    if (output_type != TCC_OUTPUT_MEMORY) {
21700        if (!outfile) {
21701    /* compute default outfile name */
21702            pstrcpy(objfilename, sizeof(objfilename) - 1,
21703                    /* strip path */
21704                    tcc_basename(files[0]));
21705#ifdef TCC_TARGET_PE
21706            pe_guess_outfile(objfilename, output_type);
21707#else
21708            if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
21709                char *ext = strrchr(objfilename, '.');
21710            if (!ext)
21711                goto default_outfile;
21712                /* add .o extension */
21713            strcpy(ext + 1, "o");
21714        } else {
21715        default_outfile:
21716            pstrcpy(objfilename, sizeof(objfilename), "a.out");
21717        }
21718#endif
21719        outfile = objfilename;
21720        }
21721    }
21722
21723    if (do_bench) {
21724        start_time = getclock_us();
21725    }
21726
21727    tcc_set_output_type(s, output_type);
21728
21729    /* compile or add each files or library */
21730    for(i = 0;i < nb_files; i++) {
21731        const char *filename;
21732
21733        filename = files[i];
21734        if (filename[0] == '-') {
21735            if (tcc_add_library(s, filename + 2) < 0)
21736                error("cannot find %s", filename);
21737        } else {
21738            if (tcc_add_file(s, filename) < 0) {
21739                ret = 1;
21740                goto the_end;
21741            }
21742        }
21743    }
21744
21745    /* free all files */
21746    tcc_free(files);
21747
21748    if (do_bench) {
21749        double total_time;
21750        total_time = (double)(getclock_us() - start_time) / 1000000.0;
21751        if (total_time < 0.001)
21752            total_time = 0.001;
21753        if (total_bytes < 1)
21754            total_bytes = 1;
21755        printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n",
21756               tok_ident - TOK_IDENT, total_lines, total_bytes,
21757               total_time, (int)(total_lines / total_time),
21758               total_bytes / total_time / 1000000.0);
21759    }
21760
21761    if (s->output_type == TCC_OUTPUT_MEMORY) {
21762        ret = tcc_run(s, argc - optind, argv + optind);
21763    } else
21764#ifdef TCC_TARGET_PE
21765    if (s->output_type != TCC_OUTPUT_OBJ) {
21766        ret = tcc_output_pe(s, outfile);
21767    } else
21768#endif
21769    {
21770        tcc_output_file(s, outfile);
21771        ret = 0;
21772    }
21773 the_end:
21774    /* XXX: cannot do it with bound checking because of the malloc hooks */
21775    if (!do_bounds_check)
21776        tcc_delete(s);
21777
21778#ifdef MEM_DEBUG
21779    if (do_bench) {
21780        printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
21781    }
21782#endif
21783    return ret;
21784}
21785
21786// njn: created this wrapper main() function to execute compilation multiple
21787// times.  TinyCC is fast!
21788// Nb: we get a link error, and TinyCC would normally return non-zero.  But
21789// the link error is not a problem for benchmarking purposes, so we return
21790// zero here (as required by vg_perf).
21791int main(int argc, char **argv)
21792{
21793   #define REPS   30
21794   int i;
21795   for (i = 0; i < REPS; i++) {
21796      main2(argc, argv);
21797   }
21798   return 0;
21799}
21800
21801#endif
21802
21803// njn: copied these in from libtcc1.c to avoid link errors when libtcc1.a
21804// is not present.
21805unsigned short __tcc_fpu_control = 0x137f;
21806unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
21807
21808#if 0
21809long long __shldi3(long long a, int b)
21810{
21811#ifdef __TINYC__
21812    DWunion u;
21813    u.ll = a;
21814    if (b >= 32) {
21815        u.s.high = (unsigned)u.s.low << (b - 32);
21816        u.s.low = 0;
21817    } else if (b != 0) {
21818        u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b));
21819        u.s.low = (unsigned)u.s.low << b;
21820    }
21821    return u.ll;
21822#else
21823    return a << b;
21824#endif
21825}
21826#endif
21827