1 /* 2 * TCC - Tiny C Compiler 3 * 4 * Copyright (c) 2001-2004 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 #define _GNU_SOURCE 21 22 // njn: inlined config.h 23 //#include "config.h" 24 //--------------------------------------------------------------------------- 25 /* Automatically generated by configure - do not modify */ 26 #define CONFIG_TCCDIR "tinycc-extras" 27 #define GCC_MAJOR 3 28 #define HOST_I386 1 29 #define TCC_VERSION "0.9.23" 30 //--------------------------------------------------------------------------- 31 32 // njn: comment out CONFIG_TCCBOOT branch 33 //#ifdef CONFIG_TCCBOOT 34 // 35 //#include "tccboot.h" 36 //#define CONFIG_TCC_STATIC 37 // 38 //#else 39 40 #include <assert.h> 41 #include <stdlib.h> 42 #include <stdio.h> 43 #include <stdarg.h> 44 #include <string.h> 45 #include <errno.h> 46 #include <math.h> 47 #include <unistd.h> 48 #include <signal.h> 49 #include <fcntl.h> 50 #include <setjmp.h> 51 #include <time.h> 52 #ifdef WIN32 53 #include <sys/timeb.h> 54 #endif 55 #ifndef WIN32 56 #include <sys/time.h> 57 #include <sys/ucontext.h> 58 #endif 59 60 //#endif /* !CONFIG_TCCBOOT */ 61 62 // Dummy variables used to avoid warnings like these: 63 // warning: ignoring return value of fwrite, declared with attribute 64 // warn_unused_result 65 char* dummy_char_star; 66 size_t dummy_size_t; 67 68 // njn: inlined elf.h 69 //#include "elf.h" 70 //--------------------------------------------------------------------------- 71 /* This file defines standard ELF types, structures, and macros. 72 Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. 73 This file is part of the GNU C Library. 74 Contributed by Ian Lance Taylor <ian (at) cygnus.com>. 75 76 The GNU C Library is free software; you can redistribute it and/or 77 modify it under the terms of the GNU Library General Public License as 78 published by the Free Software Foundation; either version 2 of the 79 License, or (at your option) any later version. 80 81 The GNU C Library is distributed in the hope that it will be useful, 82 but WITHOUT ANY WARRANTY; without even the implied warranty of 83 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 84 Library General Public License for more details. 85 86 You should have received a copy of the GNU Library General Public 87 License along with the GNU C Library; see the file COPYING.LIB. If not, 88 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 89 Boston, MA 02111-1307, USA. */ 90 91 #ifndef _ELF_H 92 #define _ELF_H 1 93 94 #ifndef WIN32 95 #include <inttypes.h> 96 #else 97 #ifndef __int8_t_defined 98 #define __int8_t_defined 99 typedef signed char int8_t; 100 typedef short int int16_t; 101 typedef int int32_t; 102 typedef long long int int64_t; 103 #endif 104 105 typedef unsigned char uint8_t; 106 typedef unsigned short int uint16_t; 107 typedef unsigned int uint32_t; 108 typedef unsigned long long int uint64_t; 109 #endif 110 111 /* Standard ELF types. */ 112 113 /* Type for a 16-bit quantity. */ 114 typedef uint16_t Elf32_Half; 115 typedef uint16_t Elf64_Half; 116 117 /* Types for signed and unsigned 32-bit quantities. */ 118 typedef uint32_t Elf32_Word; 119 typedef int32_t Elf32_Sword; 120 typedef uint32_t Elf64_Word; 121 typedef int32_t Elf64_Sword; 122 123 /* Types for signed and unsigned 64-bit quantities. */ 124 typedef uint64_t Elf32_Xword; 125 typedef int64_t Elf32_Sxword; 126 typedef uint64_t Elf64_Xword; 127 typedef int64_t Elf64_Sxword; 128 129 /* Type of addresses. */ 130 typedef uint32_t Elf32_Addr; 131 typedef uint64_t Elf64_Addr; 132 133 /* Type of file offsets. */ 134 typedef uint32_t Elf32_Off; 135 typedef uint64_t Elf64_Off; 136 137 /* Type for section indices, which are 16-bit quantities. */ 138 typedef uint16_t Elf32_Section; 139 typedef uint16_t Elf64_Section; 140 141 /* Type of symbol indices. */ 142 typedef uint32_t Elf32_Symndx; 143 typedef uint64_t Elf64_Symndx; 144 145 146 /* The ELF file header. This appears at the start of every ELF file. */ 147 148 #define EI_NIDENT (16) 149 150 typedef struct 151 { 152 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ 153 Elf32_Half e_type; /* Object file type */ 154 Elf32_Half e_machine; /* Architecture */ 155 Elf32_Word e_version; /* Object file version */ 156 Elf32_Addr e_entry; /* Entry point virtual address */ 157 Elf32_Off e_phoff; /* Program header table file offset */ 158 Elf32_Off e_shoff; /* Section header table file offset */ 159 Elf32_Word e_flags; /* Processor-specific flags */ 160 Elf32_Half e_ehsize; /* ELF header size in bytes */ 161 Elf32_Half e_phentsize; /* Program header table entry size */ 162 Elf32_Half e_phnum; /* Program header table entry count */ 163 Elf32_Half e_shentsize; /* Section header table entry size */ 164 Elf32_Half e_shnum; /* Section header table entry count */ 165 Elf32_Half e_shstrndx; /* Section header string table index */ 166 } Elf32_Ehdr; 167 168 typedef struct 169 { 170 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ 171 Elf64_Half e_type; /* Object file type */ 172 Elf64_Half e_machine; /* Architecture */ 173 Elf64_Word e_version; /* Object file version */ 174 Elf64_Addr e_entry; /* Entry point virtual address */ 175 Elf64_Off e_phoff; /* Program header table file offset */ 176 Elf64_Off e_shoff; /* Section header table file offset */ 177 Elf64_Word e_flags; /* Processor-specific flags */ 178 Elf64_Half e_ehsize; /* ELF header size in bytes */ 179 Elf64_Half e_phentsize; /* Program header table entry size */ 180 Elf64_Half e_phnum; /* Program header table entry count */ 181 Elf64_Half e_shentsize; /* Section header table entry size */ 182 Elf64_Half e_shnum; /* Section header table entry count */ 183 Elf64_Half e_shstrndx; /* Section header string table index */ 184 } Elf64_Ehdr; 185 186 /* Fields in the e_ident array. The EI_* macros are indices into the 187 array. The macros under each EI_* macro are the values the byte 188 may have. */ 189 190 #define EI_MAG0 0 /* File identification byte 0 index */ 191 #define ELFMAG0 0x7f /* Magic number byte 0 */ 192 193 #define EI_MAG1 1 /* File identification byte 1 index */ 194 #define ELFMAG1 'E' /* Magic number byte 1 */ 195 196 #define EI_MAG2 2 /* File identification byte 2 index */ 197 #define ELFMAG2 'L' /* Magic number byte 2 */ 198 199 #define EI_MAG3 3 /* File identification byte 3 index */ 200 #define ELFMAG3 'F' /* Magic number byte 3 */ 201 202 /* Conglomeration of the identification bytes, for easy testing as a word. */ 203 #define ELFMAG "\177ELF" 204 #define SELFMAG 4 205 206 #define EI_CLASS 4 /* File class byte index */ 207 #define ELFCLASSNONE 0 /* Invalid class */ 208 #define ELFCLASS32 1 /* 32-bit objects */ 209 #define ELFCLASS64 2 /* 64-bit objects */ 210 #define ELFCLASSNUM 3 211 212 #define EI_DATA 5 /* Data encoding byte index */ 213 #define ELFDATANONE 0 /* Invalid data encoding */ 214 #define ELFDATA2LSB 1 /* 2's complement, little endian */ 215 #define ELFDATA2MSB 2 /* 2's complement, big endian */ 216 #define ELFDATANUM 3 217 218 #define EI_VERSION 6 /* File version byte index */ 219 /* Value must be EV_CURRENT */ 220 221 #define EI_OSABI 7 /* OS ABI identification */ 222 #define ELFOSABI_SYSV 0 /* UNIX System V ABI */ 223 #define ELFOSABI_HPUX 1 /* HP-UX */ 224 #define ELFOSABI_FREEBSD 9 /* Free BSD */ 225 #define ELFOSABI_ARM 97 /* ARM */ 226 #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ 227 228 #define EI_ABIVERSION 8 /* ABI version */ 229 230 #define EI_PAD 9 /* Byte index of padding bytes */ 231 232 /* Legal values for e_type (object file type). */ 233 234 #define ET_NONE 0 /* No file type */ 235 #define ET_REL 1 /* Relocatable file */ 236 #define ET_EXEC 2 /* Executable file */ 237 #define ET_DYN 3 /* Shared object file */ 238 #define ET_CORE 4 /* Core file */ 239 #define ET_NUM 5 /* Number of defined types */ 240 #define ET_LOPROC 0xff00 /* Processor-specific */ 241 #define ET_HIPROC 0xffff /* Processor-specific */ 242 243 /* Legal values for e_machine (architecture). */ 244 245 #define EM_NONE 0 /* No machine */ 246 #define EM_M32 1 /* AT&T WE 32100 */ 247 #define EM_SPARC 2 /* SUN SPARC */ 248 #define EM_386 3 /* Intel 80386 */ 249 #define EM_68K 4 /* Motorola m68k family */ 250 #define EM_88K 5 /* Motorola m88k family */ 251 #define EM_486 6 /* Intel 80486 */ 252 #define EM_860 7 /* Intel 80860 */ 253 #define EM_MIPS 8 /* MIPS R3000 big-endian */ 254 #define EM_S370 9 /* Amdahl */ 255 #define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ 256 #define EM_RS6000 11 /* RS6000 */ 257 258 #define EM_PARISC 15 /* HPPA */ 259 #define EM_nCUBE 16 /* nCUBE */ 260 #define EM_VPP500 17 /* Fujitsu VPP500 */ 261 #define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ 262 #define EM_960 19 /* Intel 80960 */ 263 #define EM_PPC 20 /* PowerPC */ 264 265 #define EM_V800 36 /* NEC V800 series */ 266 #define EM_FR20 37 /* Fujitsu FR20 */ 267 #define EM_RH32 38 /* TRW RH32 */ 268 #define EM_MMA 39 /* Fujitsu MMA */ 269 #define EM_ARM 40 /* ARM */ 270 #define EM_FAKE_ALPHA 41 /* Digital Alpha */ 271 #define EM_SH 42 /* Hitachi SH */ 272 #define EM_SPARCV9 43 /* SPARC v9 64-bit */ 273 #define EM_TRICORE 44 /* Siemens Tricore */ 274 #define EM_ARC 45 /* Argonaut RISC Core */ 275 #define EM_H8_300 46 /* Hitachi H8/300 */ 276 #define EM_H8_300H 47 /* Hitachi H8/300H */ 277 #define EM_H8S 48 /* Hitachi H8S */ 278 #define EM_H8_500 49 /* Hitachi H8/500 */ 279 #define EM_IA_64 50 /* Intel Merced */ 280 #define EM_MIPS_X 51 /* Stanford MIPS-X */ 281 #define EM_COLDFIRE 52 /* Motorola Coldfire */ 282 #define EM_68HC12 53 /* Motorola M68HC12 */ 283 #define EM_NUM 54 284 285 /* If it is necessary to assign new unofficial EM_* values, please 286 pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the 287 chances of collision with official or non-GNU unofficial values. */ 288 289 #define EM_ALPHA 0x9026 290 #define EM_C60 0x9c60 291 292 /* Legal values for e_version (version). */ 293 294 #define EV_NONE 0 /* Invalid ELF version */ 295 #define EV_CURRENT 1 /* Current version */ 296 #define EV_NUM 2 297 298 /* Section header. */ 299 300 typedef struct 301 { 302 Elf32_Word sh_name; /* Section name (string tbl index) */ 303 Elf32_Word sh_type; /* Section type */ 304 Elf32_Word sh_flags; /* Section flags */ 305 Elf32_Addr sh_addr; /* Section virtual addr at execution */ 306 Elf32_Off sh_offset; /* Section file offset */ 307 Elf32_Word sh_size; /* Section size in bytes */ 308 Elf32_Word sh_link; /* Link to another section */ 309 Elf32_Word sh_info; /* Additional section information */ 310 Elf32_Word sh_addralign; /* Section alignment */ 311 Elf32_Word sh_entsize; /* Entry size if section holds table */ 312 } Elf32_Shdr; 313 314 typedef struct 315 { 316 Elf64_Word sh_name; /* Section name (string tbl index) */ 317 Elf64_Word sh_type; /* Section type */ 318 Elf64_Xword sh_flags; /* Section flags */ 319 Elf64_Addr sh_addr; /* Section virtual addr at execution */ 320 Elf64_Off sh_offset; /* Section file offset */ 321 Elf64_Xword sh_size; /* Section size in bytes */ 322 Elf64_Word sh_link; /* Link to another section */ 323 Elf64_Word sh_info; /* Additional section information */ 324 Elf64_Xword sh_addralign; /* Section alignment */ 325 Elf64_Xword sh_entsize; /* Entry size if section holds table */ 326 } Elf64_Shdr; 327 328 /* Special section indices. */ 329 330 #define SHN_UNDEF 0 /* Undefined section */ 331 #define SHN_LORESERVE 0xff00 /* Start of reserved indices */ 332 #define SHN_LOPROC 0xff00 /* Start of processor-specific */ 333 #define SHN_HIPROC 0xff1f /* End of processor-specific */ 334 #define SHN_ABS 0xfff1 /* Associated symbol is absolute */ 335 #define SHN_COMMON 0xfff2 /* Associated symbol is common */ 336 #define SHN_HIRESERVE 0xffff /* End of reserved indices */ 337 338 /* Legal values for sh_type (section type). */ 339 340 #define SHT_NULL 0 /* Section header table entry unused */ 341 #define SHT_PROGBITS 1 /* Program data */ 342 #define SHT_SYMTAB 2 /* Symbol table */ 343 #define SHT_STRTAB 3 /* String table */ 344 #define SHT_RELA 4 /* Relocation entries with addends */ 345 #define SHT_HASH 5 /* Symbol hash table */ 346 #define SHT_DYNAMIC 6 /* Dynamic linking information */ 347 #define SHT_NOTE 7 /* Notes */ 348 #define SHT_NOBITS 8 /* Program space with no data (bss) */ 349 #define SHT_REL 9 /* Relocation entries, no addends */ 350 #define SHT_SHLIB 10 /* Reserved */ 351 #define SHT_DYNSYM 11 /* Dynamic linker symbol table */ 352 #define SHT_NUM 12 /* Number of defined types. */ 353 #define SHT_LOOS 0x60000000 /* Start OS-specific */ 354 #define SHT_LOSUNW 0x6ffffffb /* Sun-specific low bound. */ 355 #define SHT_SUNW_COMDAT 0x6ffffffb 356 #define SHT_SUNW_syminfo 0x6ffffffc 357 #define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ 358 #define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ 359 #define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ 360 #define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ 361 #define SHT_HIOS 0x6fffffff /* End OS-specific type */ 362 #define SHT_LOPROC 0x70000000 /* Start of processor-specific */ 363 #define SHT_HIPROC 0x7fffffff /* End of processor-specific */ 364 #define SHT_LOUSER 0x80000000 /* Start of application-specific */ 365 #define SHT_HIUSER 0x8fffffff /* End of application-specific */ 366 367 /* Legal values for sh_flags (section flags). */ 368 369 #define SHF_WRITE (1 << 0) /* Writable */ 370 #define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ 371 #define SHF_EXECINSTR (1 << 2) /* Executable */ 372 #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ 373 374 /* Symbol table entry. */ 375 376 typedef struct 377 { 378 Elf32_Word st_name; /* Symbol name (string tbl index) */ 379 Elf32_Addr st_value; /* Symbol value */ 380 Elf32_Word st_size; /* Symbol size */ 381 unsigned char st_info; /* Symbol type and binding */ 382 unsigned char st_other; /* No defined meaning, 0 */ 383 Elf32_Section st_shndx; /* Section index */ 384 } Elf32_Sym; 385 386 typedef struct 387 { 388 Elf64_Word st_name; /* Symbol name (string tbl index) */ 389 unsigned char st_info; /* Symbol type and binding */ 390 unsigned char st_other; /* No defined meaning, 0 */ 391 Elf64_Section st_shndx; /* Section index */ 392 Elf64_Addr st_value; /* Symbol value */ 393 Elf64_Xword st_size; /* Symbol size */ 394 } Elf64_Sym; 395 396 /* The syminfo section if available contains additional information about 397 every dynamic symbol. */ 398 399 typedef struct 400 { 401 Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ 402 Elf32_Half si_flags; /* Per symbol flags */ 403 } Elf32_Syminfo; 404 405 typedef struct 406 { 407 Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ 408 Elf64_Half si_flags; /* Per symbol flags */ 409 } Elf64_Syminfo; 410 411 /* Possible values for si_boundto. */ 412 #define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ 413 #define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ 414 #define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ 415 416 /* Possible bitmasks for si_flags. */ 417 #define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ 418 #define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ 419 #define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ 420 #define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy 421 loaded */ 422 /* Syminfo version values. */ 423 #define SYMINFO_NONE 0 424 #define SYMINFO_CURRENT 1 425 #define SYMINFO_NUM 2 426 427 428 /* Special section index. */ 429 430 #define SHN_UNDEF 0 /* No section, undefined symbol. */ 431 432 /* How to extract and insert information held in the st_info field. */ 433 434 #define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) 435 #define ELF32_ST_TYPE(val) ((val) & 0xf) 436 #define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) 437 438 /* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ 439 #define ELF64_ST_BIND(val) ELF32_ST_BIND (val) 440 #define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) 441 #define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) 442 443 /* Legal values for ST_BIND subfield of st_info (symbol binding). */ 444 445 #define STB_LOCAL 0 /* Local symbol */ 446 #define STB_GLOBAL 1 /* Global symbol */ 447 #define STB_WEAK 2 /* Weak symbol */ 448 #define STB_NUM 3 /* Number of defined types. */ 449 #define STB_LOOS 10 /* Start of OS-specific */ 450 #define STB_HIOS 12 /* End of OS-specific */ 451 #define STB_LOPROC 13 /* Start of processor-specific */ 452 #define STB_HIPROC 15 /* End of processor-specific */ 453 454 /* Legal values for ST_TYPE subfield of st_info (symbol type). */ 455 456 #define STT_NOTYPE 0 /* Symbol type is unspecified */ 457 #define STT_OBJECT 1 /* Symbol is a data object */ 458 #define STT_FUNC 2 /* Symbol is a code object */ 459 #define STT_SECTION 3 /* Symbol associated with a section */ 460 #define STT_FILE 4 /* Symbol's name is file name */ 461 #define STT_NUM 5 /* Number of defined types. */ 462 #define STT_LOOS 11 /* Start of OS-specific */ 463 #define STT_HIOS 12 /* End of OS-specific */ 464 #define STT_LOPROC 13 /* Start of processor-specific */ 465 #define STT_HIPROC 15 /* End of processor-specific */ 466 467 468 /* Symbol table indices are found in the hash buckets and chain table 469 of a symbol hash table section. This special index value indicates 470 the end of a chain, meaning no further symbols are found in that bucket. */ 471 472 #define STN_UNDEF 0 /* End of a chain. */ 473 474 475 /* How to extract and insert information held in the st_other field. */ 476 477 #define ELF32_ST_VISIBILITY(o) ((o) & 0x03) 478 479 /* For ELF64 the definitions are the same. */ 480 #define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) 481 482 /* Symbol visibility specification encoded in the st_other field. */ 483 #define STV_DEFAULT 0 /* Default symbol visibility rules */ 484 #define STV_INTERNAL 1 /* Processor specific hidden class */ 485 #define STV_HIDDEN 2 /* Sym unavailable in other modules */ 486 #define STV_PROTECTED 3 /* Not preemptible, not exported */ 487 488 489 /* Relocation table entry without addend (in section of type SHT_REL). */ 490 491 typedef struct 492 { 493 Elf32_Addr r_offset; /* Address */ 494 Elf32_Word r_info; /* Relocation type and symbol index */ 495 } Elf32_Rel; 496 497 /* I have seen two different definitions of the Elf64_Rel and 498 Elf64_Rela structures, so we'll leave them out until Novell (or 499 whoever) gets their act together. */ 500 /* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ 501 502 typedef struct 503 { 504 Elf64_Addr r_offset; /* Address */ 505 Elf64_Xword r_info; /* Relocation type and symbol index */ 506 } Elf64_Rel; 507 508 /* Relocation table entry with addend (in section of type SHT_RELA). */ 509 510 typedef struct 511 { 512 Elf32_Addr r_offset; /* Address */ 513 Elf32_Word r_info; /* Relocation type and symbol index */ 514 Elf32_Sword r_addend; /* Addend */ 515 } Elf32_Rela; 516 517 typedef struct 518 { 519 Elf64_Addr r_offset; /* Address */ 520 Elf64_Xword r_info; /* Relocation type and symbol index */ 521 Elf64_Sxword r_addend; /* Addend */ 522 } Elf64_Rela; 523 524 /* How to extract and insert information held in the r_info field. */ 525 526 #define ELF32_R_SYM(val) ((val) >> 8) 527 #define ELF32_R_TYPE(val) ((val) & 0xff) 528 #define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) 529 530 #define ELF64_R_SYM(i) ((i) >> 32) 531 #define ELF64_R_TYPE(i) ((i) & 0xffffffff) 532 #define ELF64_R_INFO(sym,type) (((sym) << 32) + (type)) 533 534 /* Program segment header. */ 535 536 typedef struct 537 { 538 Elf32_Word p_type; /* Segment type */ 539 Elf32_Off p_offset; /* Segment file offset */ 540 Elf32_Addr p_vaddr; /* Segment virtual address */ 541 Elf32_Addr p_paddr; /* Segment physical address */ 542 Elf32_Word p_filesz; /* Segment size in file */ 543 Elf32_Word p_memsz; /* Segment size in memory */ 544 Elf32_Word p_flags; /* Segment flags */ 545 Elf32_Word p_align; /* Segment alignment */ 546 } Elf32_Phdr; 547 548 typedef struct 549 { 550 Elf64_Word p_type; /* Segment type */ 551 Elf64_Word p_flags; /* Segment flags */ 552 Elf64_Off p_offset; /* Segment file offset */ 553 Elf64_Addr p_vaddr; /* Segment virtual address */ 554 Elf64_Addr p_paddr; /* Segment physical address */ 555 Elf64_Xword p_filesz; /* Segment size in file */ 556 Elf64_Xword p_memsz; /* Segment size in memory */ 557 Elf64_Xword p_align; /* Segment alignment */ 558 } Elf64_Phdr; 559 560 /* Legal values for p_type (segment type). */ 561 562 #define PT_NULL 0 /* Program header table entry unused */ 563 #define PT_LOAD 1 /* Loadable program segment */ 564 #define PT_DYNAMIC 2 /* Dynamic linking information */ 565 #define PT_INTERP 3 /* Program interpreter */ 566 #define PT_NOTE 4 /* Auxiliary information */ 567 #define PT_SHLIB 5 /* Reserved */ 568 #define PT_PHDR 6 /* Entry for header table itself */ 569 #define PT_NUM 7 /* Number of defined types. */ 570 #define PT_LOOS 0x60000000 /* Start of OS-specific */ 571 #define PT_HIOS 0x6fffffff /* End of OS-specific */ 572 #define PT_LOPROC 0x70000000 /* Start of processor-specific */ 573 #define PT_HIPROC 0x7fffffff /* End of processor-specific */ 574 575 /* Legal values for p_flags (segment flags). */ 576 577 #define PF_X (1 << 0) /* Segment is executable */ 578 #define PF_W (1 << 1) /* Segment is writable */ 579 #define PF_R (1 << 2) /* Segment is readable */ 580 #define PF_MASKPROC 0xf0000000 /* Processor-specific */ 581 582 /* Legal values for note segment descriptor types for core files. */ 583 584 #define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ 585 #define NT_FPREGSET 2 /* Contains copy of fpregset struct */ 586 #define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ 587 #define NT_PRXREG 4 /* Contains copy of prxregset struct */ 588 #define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ 589 #define NT_AUXV 6 /* Contains copy of auxv array */ 590 #define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ 591 #define NT_PSTATUS 10 /* Contains copy of pstatus struct */ 592 #define NT_PSINFO 13 /* Contains copy of psinfo struct */ 593 #define NT_PRCRED 14 /* Contains copy of prcred struct */ 594 #define NT_UTSNAME 15 /* Contains copy of utsname struct */ 595 #define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ 596 #define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ 597 598 /* Legal values for the note segment descriptor types for object files. */ 599 600 #define NT_VERSION 1 /* Contains a version string. */ 601 602 603 /* Dynamic section entry. */ 604 605 typedef struct 606 { 607 Elf32_Sword d_tag; /* Dynamic entry type */ 608 union 609 { 610 Elf32_Word d_val; /* Integer value */ 611 Elf32_Addr d_ptr; /* Address value */ 612 } d_un; 613 } Elf32_Dyn; 614 615 typedef struct 616 { 617 Elf64_Sxword d_tag; /* Dynamic entry type */ 618 union 619 { 620 Elf64_Xword d_val; /* Integer value */ 621 Elf64_Addr d_ptr; /* Address value */ 622 } d_un; 623 } Elf64_Dyn; 624 625 /* Legal values for d_tag (dynamic entry type). */ 626 627 #define DT_NULL 0 /* Marks end of dynamic section */ 628 #define DT_NEEDED 1 /* Name of needed library */ 629 #define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ 630 #define DT_PLTGOT 3 /* Processor defined value */ 631 #define DT_HASH 4 /* Address of symbol hash table */ 632 #define DT_STRTAB 5 /* Address of string table */ 633 #define DT_SYMTAB 6 /* Address of symbol table */ 634 #define DT_RELA 7 /* Address of Rela relocs */ 635 #define DT_RELASZ 8 /* Total size of Rela relocs */ 636 #define DT_RELAENT 9 /* Size of one Rela reloc */ 637 #define DT_STRSZ 10 /* Size of string table */ 638 #define DT_SYMENT 11 /* Size of one symbol table entry */ 639 #define DT_INIT 12 /* Address of init function */ 640 #define DT_FINI 13 /* Address of termination function */ 641 #define DT_SONAME 14 /* Name of shared object */ 642 #define DT_RPATH 15 /* Library search path */ 643 #define DT_SYMBOLIC 16 /* Start symbol search here */ 644 #define DT_REL 17 /* Address of Rel relocs */ 645 #define DT_RELSZ 18 /* Total size of Rel relocs */ 646 #define DT_RELENT 19 /* Size of one Rel reloc */ 647 #define DT_PLTREL 20 /* Type of reloc in PLT */ 648 #define DT_DEBUG 21 /* For debugging; unspecified */ 649 #define DT_TEXTREL 22 /* Reloc might modify .text */ 650 #define DT_JMPREL 23 /* Address of PLT relocs */ 651 #define DT_BIND_NOW 24 /* Process relocations of object */ 652 #define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ 653 #define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ 654 #define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ 655 #define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ 656 #define DT_NUM 29 /* Number used */ 657 #define DT_LOOS 0x60000000 /* Start of OS-specific */ 658 #define DT_HIOS 0x6fffffff /* End of OS-specific */ 659 #define DT_LOPROC 0x70000000 /* Start of processor-specific */ 660 #define DT_HIPROC 0x7fffffff /* End of processor-specific */ 661 #define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ 662 663 /* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the 664 Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's 665 approach. */ 666 #define DT_VALRNGLO 0x6ffffd00 667 #define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting 668 the following DT_* entry. */ 669 #define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ 670 #define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ 671 #define DT_VALRNGHI 0x6ffffdff 672 673 /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the 674 Dyn.d_un.d_ptr field of the Elf*_Dyn structure. 675 676 If any adjustment is made to the ELF object after it has been 677 built these entries will need to be adjusted. */ 678 #define DT_ADDRRNGLO 0x6ffffe00 679 #define DT_SYMINFO 0x6ffffeff /* syminfo table */ 680 #define DT_ADDRRNGHI 0x6ffffeff 681 682 /* The versioning entry types. The next are defined as part of the 683 GNU extension. */ 684 #define DT_VERSYM 0x6ffffff0 685 686 /* These were chosen by Sun. */ 687 #define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ 688 #define DT_VERDEF 0x6ffffffc /* Address of version definition 689 table */ 690 #define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ 691 #define DT_VERNEED 0x6ffffffe /* Address of table with needed 692 versions */ 693 #define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ 694 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ 695 #define DT_VERSIONTAGNUM 16 696 697 /* Sun added these machine-independent extensions in the "processor-specific" 698 range. Be compatible. */ 699 #define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ 700 #define DT_FILTER 0x7fffffff /* Shared object to get values from */ 701 #define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) 702 #define DT_EXTRANUM 3 703 704 /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 705 entry in the dynamic section. */ 706 #define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ 707 #define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ 708 #define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ 709 #define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ 710 #define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ 711 #define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ 712 #define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ 713 714 /* Version definition sections. */ 715 716 typedef struct 717 { 718 Elf32_Half vd_version; /* Version revision */ 719 Elf32_Half vd_flags; /* Version information */ 720 Elf32_Half vd_ndx; /* Version Index */ 721 Elf32_Half vd_cnt; /* Number of associated aux entries */ 722 Elf32_Word vd_hash; /* Version name hash value */ 723 Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ 724 Elf32_Word vd_next; /* Offset in bytes to next verdef 725 entry */ 726 } Elf32_Verdef; 727 728 typedef struct 729 { 730 Elf64_Half vd_version; /* Version revision */ 731 Elf64_Half vd_flags; /* Version information */ 732 Elf64_Half vd_ndx; /* Version Index */ 733 Elf64_Half vd_cnt; /* Number of associated aux entries */ 734 Elf64_Word vd_hash; /* Version name hash value */ 735 Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ 736 Elf64_Word vd_next; /* Offset in bytes to next verdef 737 entry */ 738 } Elf64_Verdef; 739 740 741 /* Legal values for vd_version (version revision). */ 742 #define VER_DEF_NONE 0 /* No version */ 743 #define VER_DEF_CURRENT 1 /* Current version */ 744 #define VER_DEF_NUM 2 /* Given version number */ 745 746 /* Legal values for vd_flags (version information flags). */ 747 #define VER_FLG_BASE 0x1 /* Version definition of file itself */ 748 #define VER_FLG_WEAK 0x2 /* Weak version identifier */ 749 750 /* Auxialiary version information. */ 751 752 typedef struct 753 { 754 Elf32_Word vda_name; /* Version or dependency names */ 755 Elf32_Word vda_next; /* Offset in bytes to next verdaux 756 entry */ 757 } Elf32_Verdaux; 758 759 typedef struct 760 { 761 Elf64_Word vda_name; /* Version or dependency names */ 762 Elf64_Word vda_next; /* Offset in bytes to next verdaux 763 entry */ 764 } Elf64_Verdaux; 765 766 767 /* Version dependency section. */ 768 769 typedef struct 770 { 771 Elf32_Half vn_version; /* Version of structure */ 772 Elf32_Half vn_cnt; /* Number of associated aux entries */ 773 Elf32_Word vn_file; /* Offset of filename for this 774 dependency */ 775 Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ 776 Elf32_Word vn_next; /* Offset in bytes to next verneed 777 entry */ 778 } Elf32_Verneed; 779 780 typedef struct 781 { 782 Elf64_Half vn_version; /* Version of structure */ 783 Elf64_Half vn_cnt; /* Number of associated aux entries */ 784 Elf64_Word vn_file; /* Offset of filename for this 785 dependency */ 786 Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ 787 Elf64_Word vn_next; /* Offset in bytes to next verneed 788 entry */ 789 } Elf64_Verneed; 790 791 792 /* Legal values for vn_version (version revision). */ 793 #define VER_NEED_NONE 0 /* No version */ 794 #define VER_NEED_CURRENT 1 /* Current version */ 795 #define VER_NEED_NUM 2 /* Given version number */ 796 797 /* Auxiliary needed version information. */ 798 799 typedef struct 800 { 801 Elf32_Word vna_hash; /* Hash value of dependency name */ 802 Elf32_Half vna_flags; /* Dependency specific information */ 803 Elf32_Half vna_other; /* Unused */ 804 Elf32_Word vna_name; /* Dependency name string offset */ 805 Elf32_Word vna_next; /* Offset in bytes to next vernaux 806 entry */ 807 } Elf32_Vernaux; 808 809 typedef struct 810 { 811 Elf64_Word vna_hash; /* Hash value of dependency name */ 812 Elf64_Half vna_flags; /* Dependency specific information */ 813 Elf64_Half vna_other; /* Unused */ 814 Elf64_Word vna_name; /* Dependency name string offset */ 815 Elf64_Word vna_next; /* Offset in bytes to next vernaux 816 entry */ 817 } Elf64_Vernaux; 818 819 820 /* Legal values for vna_flags. */ 821 #define VER_FLG_WEAK 0x2 /* Weak version identifier */ 822 823 824 /* Auxiliary vector. */ 825 826 /* This vector is normally only used by the program interpreter. The 827 usual definition in an ABI supplement uses the name auxv_t. The 828 vector is not usually defined in a standard <elf.h> file, but it 829 can't hurt. We rename it to avoid conflicts. The sizes of these 830 types are an arrangement between the exec server and the program 831 interpreter, so we don't fully specify them here. */ 832 833 typedef struct 834 { 835 int a_type; /* Entry type */ 836 union 837 { 838 long int a_val; /* Integer value */ 839 void *a_ptr; /* Pointer value */ 840 void (*a_fcn) (void); /* Function pointer value */ 841 } a_un; 842 } Elf32_auxv_t; 843 844 typedef struct 845 { 846 long int a_type; /* Entry type */ 847 union 848 { 849 long int a_val; /* Integer value */ 850 void *a_ptr; /* Pointer value */ 851 void (*a_fcn) (void); /* Function pointer value */ 852 } a_un; 853 } Elf64_auxv_t; 854 855 /* Legal values for a_type (entry type). */ 856 857 #define AT_NULL 0 /* End of vector */ 858 #define AT_IGNORE 1 /* Entry should be ignored */ 859 #define AT_EXECFD 2 /* File descriptor of program */ 860 #define AT_PHDR 3 /* Program headers for program */ 861 #define AT_PHENT 4 /* Size of program header entry */ 862 #define AT_PHNUM 5 /* Number of program headers */ 863 #define AT_PAGESZ 6 /* System page size */ 864 #define AT_BASE 7 /* Base address of interpreter */ 865 #define AT_FLAGS 8 /* Flags */ 866 #define AT_ENTRY 9 /* Entry point of program */ 867 #define AT_NOTELF 10 /* Program is not ELF */ 868 #define AT_UID 11 /* Real uid */ 869 #define AT_EUID 12 /* Effective uid */ 870 #define AT_GID 13 /* Real gid */ 871 #define AT_EGID 14 /* Effective gid */ 872 873 /* Some more special a_type values describing the hardware. */ 874 #define AT_PLATFORM 15 /* String identifying platform. */ 875 #define AT_HWCAP 16 /* Machine dependent hints about 876 processor capabilities. */ 877 878 /* This entry gives some information about the FPU initialization 879 performed by the kernel. */ 880 #define AT_FPUCW 17 /* Used FPU control word. */ 881 882 883 /* Note section contents. Each entry in the note section begins with 884 a header of a fixed form. */ 885 886 typedef struct 887 { 888 Elf32_Word n_namesz; /* Length of the note's name. */ 889 Elf32_Word n_descsz; /* Length of the note's descriptor. */ 890 Elf32_Word n_type; /* Type of the note. */ 891 } Elf32_Nhdr; 892 893 typedef struct 894 { 895 Elf64_Word n_namesz; /* Length of the note's name. */ 896 Elf64_Word n_descsz; /* Length of the note's descriptor. */ 897 Elf64_Word n_type; /* Type of the note. */ 898 } Elf64_Nhdr; 899 900 /* Known names of notes. */ 901 902 /* Solaris entries in the note section have this name. */ 903 #define ELF_NOTE_SOLARIS "SUNW Solaris" 904 905 /* Note entries for GNU systems have this name. */ 906 #define ELF_NOTE_GNU "GNU" 907 908 909 /* Defined types of notes for Solaris. */ 910 911 /* Value of descriptor (one word) is desired pagesize for the binary. */ 912 #define ELF_NOTE_PAGESIZE_HINT 1 913 914 915 /* Defined note types for GNU systems. */ 916 917 /* ABI information. The descriptor consists of words: 918 word 0: OS descriptor 919 word 1: major version of the ABI 920 word 2: minor version of the ABI 921 word 3: subminor version of the ABI 922 */ 923 #define ELF_NOTE_ABI 1 924 925 /* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI 926 note section entry. */ 927 #define ELF_NOTE_OS_LINUX 0 928 #define ELF_NOTE_OS_GNU 1 929 #define ELF_NOTE_OS_SOLARIS2 2 930 931 932 /* Motorola 68k specific definitions. */ 933 934 /* m68k relocs. */ 935 936 #define R_68K_NONE 0 /* No reloc */ 937 #define R_68K_32 1 /* Direct 32 bit */ 938 #define R_68K_16 2 /* Direct 16 bit */ 939 #define R_68K_8 3 /* Direct 8 bit */ 940 #define R_68K_PC32 4 /* PC relative 32 bit */ 941 #define R_68K_PC16 5 /* PC relative 16 bit */ 942 #define R_68K_PC8 6 /* PC relative 8 bit */ 943 #define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ 944 #define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ 945 #define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ 946 #define R_68K_GOT32O 10 /* 32 bit GOT offset */ 947 #define R_68K_GOT16O 11 /* 16 bit GOT offset */ 948 #define R_68K_GOT8O 12 /* 8 bit GOT offset */ 949 #define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ 950 #define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ 951 #define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ 952 #define R_68K_PLT32O 16 /* 32 bit PLT offset */ 953 #define R_68K_PLT16O 17 /* 16 bit PLT offset */ 954 #define R_68K_PLT8O 18 /* 8 bit PLT offset */ 955 #define R_68K_COPY 19 /* Copy symbol at runtime */ 956 #define R_68K_GLOB_DAT 20 /* Create GOT entry */ 957 #define R_68K_JMP_SLOT 21 /* Create PLT entry */ 958 #define R_68K_RELATIVE 22 /* Adjust by program base */ 959 /* Keep this the last entry. */ 960 #define R_68K_NUM 23 961 962 /* Intel 80386 specific definitions. */ 963 964 /* i386 relocs. */ 965 966 #define R_386_NONE 0 /* No reloc */ 967 #define R_386_32 1 /* Direct 32 bit */ 968 #define R_386_PC32 2 /* PC relative 32 bit */ 969 #define R_386_GOT32 3 /* 32 bit GOT entry */ 970 #define R_386_PLT32 4 /* 32 bit PLT address */ 971 #define R_386_COPY 5 /* Copy symbol at runtime */ 972 #define R_386_GLOB_DAT 6 /* Create GOT entry */ 973 #define R_386_JMP_SLOT 7 /* Create PLT entry */ 974 #define R_386_RELATIVE 8 /* Adjust by program base */ 975 #define R_386_GOTOFF 9 /* 32 bit offset to GOT */ 976 #define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ 977 /* Keep this the last entry. */ 978 #define R_386_NUM 11 979 980 /* SUN SPARC specific definitions. */ 981 982 /* Values for Elf64_Ehdr.e_flags. */ 983 984 #define EF_SPARCV9_MM 3 985 #define EF_SPARCV9_TSO 0 986 #define EF_SPARCV9_PSO 1 987 #define EF_SPARCV9_RMO 2 988 #define EF_SPARC_EXT_MASK 0xFFFF00 989 #define EF_SPARC_SUN_US1 0x000200 990 #define EF_SPARC_HAL_R1 0x000400 991 992 /* SPARC relocs. */ 993 994 #define R_SPARC_NONE 0 /* No reloc */ 995 #define R_SPARC_8 1 /* Direct 8 bit */ 996 #define R_SPARC_16 2 /* Direct 16 bit */ 997 #define R_SPARC_32 3 /* Direct 32 bit */ 998 #define R_SPARC_DISP8 4 /* PC relative 8 bit */ 999 #define R_SPARC_DISP16 5 /* PC relative 16 bit */ 1000 #define R_SPARC_DISP32 6 /* PC relative 32 bit */ 1001 #define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ 1002 #define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ 1003 #define R_SPARC_HI22 9 /* High 22 bit */ 1004 #define R_SPARC_22 10 /* Direct 22 bit */ 1005 #define R_SPARC_13 11 /* Direct 13 bit */ 1006 #define R_SPARC_LO10 12 /* Truncated 10 bit */ 1007 #define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ 1008 #define R_SPARC_GOT13 14 /* 13 bit GOT entry */ 1009 #define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ 1010 #define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ 1011 #define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ 1012 #define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ 1013 #define R_SPARC_COPY 19 /* Copy symbol at runtime */ 1014 #define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ 1015 #define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ 1016 #define R_SPARC_RELATIVE 22 /* Adjust by program base */ 1017 #define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ 1018 1019 /* Additional Sparc64 relocs. */ 1020 1021 #define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ 1022 #define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ 1023 #define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ 1024 #define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ 1025 #define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ 1026 #define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ 1027 #define R_SPARC_10 30 /* Direct 10 bit */ 1028 #define R_SPARC_11 31 /* Direct 11 bit */ 1029 #define R_SPARC_64 32 /* Direct 64 bit */ 1030 #define R_SPARC_OLO10 33 /* ?? */ 1031 #define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ 1032 #define R_SPARC_HM10 35 /* High middle 10 bits of ... */ 1033 #define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ 1034 #define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ 1035 #define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ 1036 #define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ 1037 #define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ 1038 #define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ 1039 #define R_SPARC_7 43 /* Direct 7 bit */ 1040 #define R_SPARC_5 44 /* Direct 5 bit */ 1041 #define R_SPARC_6 45 /* Direct 6 bit */ 1042 #define R_SPARC_DISP64 46 /* PC relative 64 bit */ 1043 #define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ 1044 #define R_SPARC_HIX22 48 /* High 22 bit complemented */ 1045 #define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ 1046 #define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ 1047 #define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ 1048 #define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ 1049 #define R_SPARC_REGISTER 53 /* Global register usage */ 1050 #define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ 1051 #define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ 1052 /* Keep this the last entry. */ 1053 #define R_SPARC_NUM 56 1054 1055 /* For Sparc64, legal values for d_tag of Elf64_Dyn. */ 1056 1057 #define DT_SPARC_REGISTER 0x70000001 1058 #define DT_SPARC_NUM 2 1059 1060 /* Bits present in AT_HWCAP, primarily for Sparc32. */ 1061 1062 #define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */ 1063 #define HWCAP_SPARC_STBAR 2 1064 #define HWCAP_SPARC_SWAP 4 1065 #define HWCAP_SPARC_MULDIV 8 1066 #define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */ 1067 1068 /* MIPS R3000 specific definitions. */ 1069 1070 /* Legal values for e_flags field of Elf32_Ehdr. */ 1071 1072 #define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ 1073 #define EF_MIPS_PIC 2 /* Contains PIC code */ 1074 #define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ 1075 #define EF_MIPS_XGOT 8 1076 #define EF_MIPS_64BIT_WHIRL 16 1077 #define EF_MIPS_ABI2 32 1078 #define EF_MIPS_ABI_ON32 64 1079 #define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ 1080 1081 /* Legal values for MIPS architecture level. */ 1082 1083 #define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ 1084 #define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ 1085 #define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ 1086 #define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ 1087 #define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ 1088 1089 /* The following are non-official names and should not be used. */ 1090 1091 #define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ 1092 #define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ 1093 #define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ 1094 #define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ 1095 #define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ 1096 1097 /* Special section indices. */ 1098 1099 #define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ 1100 #define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ 1101 #define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ 1102 #define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ 1103 #define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ 1104 1105 /* Legal values for sh_type field of Elf32_Shdr. */ 1106 1107 #define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ 1108 #define SHT_MIPS_MSYM 0x70000001 1109 #define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ 1110 #define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ 1111 #define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ 1112 #define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ 1113 #define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ 1114 #define SHT_MIPS_PACKAGE 0x70000007 1115 #define SHT_MIPS_PACKSYM 0x70000008 1116 #define SHT_MIPS_RELD 0x70000009 1117 #define SHT_MIPS_IFACE 0x7000000b 1118 #define SHT_MIPS_CONTENT 0x7000000c 1119 #define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ 1120 #define SHT_MIPS_SHDR 0x70000010 1121 #define SHT_MIPS_FDESC 0x70000011 1122 #define SHT_MIPS_EXTSYM 0x70000012 1123 #define SHT_MIPS_DENSE 0x70000013 1124 #define SHT_MIPS_PDESC 0x70000014 1125 #define SHT_MIPS_LOCSYM 0x70000015 1126 #define SHT_MIPS_AUXSYM 0x70000016 1127 #define SHT_MIPS_OPTSYM 0x70000017 1128 #define SHT_MIPS_LOCSTR 0x70000018 1129 #define SHT_MIPS_LINE 0x70000019 1130 #define SHT_MIPS_RFDESC 0x7000001a 1131 #define SHT_MIPS_DELTASYM 0x7000001b 1132 #define SHT_MIPS_DELTAINST 0x7000001c 1133 #define SHT_MIPS_DELTACLASS 0x7000001d 1134 #define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ 1135 #define SHT_MIPS_DELTADECL 0x7000001f 1136 #define SHT_MIPS_SYMBOL_LIB 0x70000020 1137 #define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ 1138 #define SHT_MIPS_TRANSLATE 0x70000022 1139 #define SHT_MIPS_PIXIE 0x70000023 1140 #define SHT_MIPS_XLATE 0x70000024 1141 #define SHT_MIPS_XLATE_DEBUG 0x70000025 1142 #define SHT_MIPS_WHIRL 0x70000026 1143 #define SHT_MIPS_EH_REGION 0x70000027 1144 #define SHT_MIPS_XLATE_OLD 0x70000028 1145 #define SHT_MIPS_PDR_EXCEPTION 0x70000029 1146 1147 /* Legal values for sh_flags field of Elf32_Shdr. */ 1148 1149 #define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ 1150 #define SHF_MIPS_MERGE 0x20000000 1151 #define SHF_MIPS_ADDR 0x40000000 1152 #define SHF_MIPS_STRINGS 0x80000000 1153 #define SHF_MIPS_NOSTRIP 0x08000000 1154 #define SHF_MIPS_LOCAL 0x04000000 1155 #define SHF_MIPS_NAMES 0x02000000 1156 #define SHF_MIPS_NODUPE 0x01000000 1157 1158 1159 /* Symbol tables. */ 1160 1161 /* MIPS specific values for `st_other'. */ 1162 #define STO_MIPS_DEFAULT 0x0 1163 #define STO_MIPS_INTERNAL 0x1 1164 #define STO_MIPS_HIDDEN 0x2 1165 #define STO_MIPS_PROTECTED 0x3 1166 #define STO_MIPS_SC_ALIGN_UNUSED 0xff 1167 1168 /* MIPS specific values for `st_info'. */ 1169 #define STB_MIPS_SPLIT_COMMON 13 1170 1171 /* Entries found in sections of type SHT_MIPS_GPTAB. */ 1172 1173 typedef union 1174 { 1175 struct 1176 { 1177 Elf32_Word gt_current_g_value; /* -G value used for compilation */ 1178 Elf32_Word gt_unused; /* Not used */ 1179 } gt_header; /* First entry in section */ 1180 struct 1181 { 1182 Elf32_Word gt_g_value; /* If this value were used for -G */ 1183 Elf32_Word gt_bytes; /* This many bytes would be used */ 1184 } gt_entry; /* Subsequent entries in section */ 1185 } Elf32_gptab; 1186 1187 /* Entry found in sections of type SHT_MIPS_REGINFO. */ 1188 1189 typedef struct 1190 { 1191 Elf32_Word ri_gprmask; /* General registers used */ 1192 Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ 1193 Elf32_Sword ri_gp_value; /* $gp register value */ 1194 } Elf32_RegInfo; 1195 1196 /* Entries found in sections of type SHT_MIPS_OPTIONS. */ 1197 1198 typedef struct 1199 { 1200 unsigned char kind; /* Determines interpretation of the 1201 variable part of descriptor. */ 1202 unsigned char size; /* Size of descriptor, including header. */ 1203 Elf32_Section section; /* Section header index of section affected, 1204 0 for global options. */ 1205 Elf32_Word info; /* Kind-specific information. */ 1206 } Elf_Options; 1207 1208 /* Values for `kind' field in Elf_Options. */ 1209 1210 #define ODK_NULL 0 /* Undefined. */ 1211 #define ODK_REGINFO 1 /* Register usage information. */ 1212 #define ODK_EXCEPTIONS 2 /* Exception processing options. */ 1213 #define ODK_PAD 3 /* Section padding options. */ 1214 #define ODK_HWPATCH 4 /* Hardware workarounds performed */ 1215 #define ODK_FILL 5 /* record the fill value used by the linker. */ 1216 #define ODK_TAGS 6 /* reserve space for desktop tools to write. */ 1217 #define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ 1218 #define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ 1219 1220 /* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ 1221 1222 #define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ 1223 #define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ 1224 #define OEX_PAGE0 0x10000 /* page zero must be mapped. */ 1225 #define OEX_SMM 0x20000 /* Force sequential memory mode? */ 1226 #define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ 1227 #define OEX_PRECISEFP OEX_FPDBUG 1228 #define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ 1229 1230 #define OEX_FPU_INVAL 0x10 1231 #define OEX_FPU_DIV0 0x08 1232 #define OEX_FPU_OFLO 0x04 1233 #define OEX_FPU_UFLO 0x02 1234 #define OEX_FPU_INEX 0x01 1235 1236 /* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ 1237 1238 #define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ 1239 #define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ 1240 #define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ 1241 #define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ 1242 1243 #define OPAD_PREFIX 0x1 1244 #define OPAD_POSTFIX 0x2 1245 #define OPAD_SYMBOL 0x4 1246 1247 /* Entry found in `.options' section. */ 1248 1249 typedef struct 1250 { 1251 Elf32_Word hwp_flags1; /* Extra flags. */ 1252 Elf32_Word hwp_flags2; /* Extra flags. */ 1253 } Elf_Options_Hw; 1254 1255 /* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ 1256 1257 #define OHWA0_R4KEOP_CHECKED 0x00000001 1258 #define OHWA1_R4KEOP_CLEAN 0x00000002 1259 1260 /* MIPS relocs. */ 1261 1262 #define R_MIPS_NONE 0 /* No reloc */ 1263 #define R_MIPS_16 1 /* Direct 16 bit */ 1264 #define R_MIPS_32 2 /* Direct 32 bit */ 1265 #define R_MIPS_REL32 3 /* PC relative 32 bit */ 1266 #define R_MIPS_26 4 /* Direct 26 bit shifted */ 1267 #define R_MIPS_HI16 5 /* High 16 bit */ 1268 #define R_MIPS_LO16 6 /* Low 16 bit */ 1269 #define R_MIPS_GPREL16 7 /* GP relative 16 bit */ 1270 #define R_MIPS_LITERAL 8 /* 16 bit literal entry */ 1271 #define R_MIPS_GOT16 9 /* 16 bit GOT entry */ 1272 #define R_MIPS_PC16 10 /* PC relative 16 bit */ 1273 #define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ 1274 #define R_MIPS_GPREL32 12 /* GP relative 32 bit */ 1275 1276 #define R_MIPS_SHIFT5 16 1277 #define R_MIPS_SHIFT6 17 1278 #define R_MIPS_64 18 1279 #define R_MIPS_GOT_DISP 19 1280 #define R_MIPS_GOT_PAGE 20 1281 #define R_MIPS_GOT_OFST 21 1282 #define R_MIPS_GOT_HI16 22 1283 #define R_MIPS_GOT_LO16 23 1284 #define R_MIPS_SUB 24 1285 #define R_MIPS_INSERT_A 25 1286 #define R_MIPS_INSERT_B 26 1287 #define R_MIPS_DELETE 27 1288 #define R_MIPS_HIGHER 28 1289 #define R_MIPS_HIGHEST 29 1290 #define R_MIPS_CALL_HI16 30 1291 #define R_MIPS_CALL_LO16 31 1292 #define R_MIPS_SCN_DISP 32 1293 #define R_MIPS_REL16 33 1294 #define R_MIPS_ADD_IMMEDIATE 34 1295 #define R_MIPS_PJUMP 35 1296 #define R_MIPS_RELGOT 36 1297 #define R_MIPS_JALR 37 1298 /* Keep this the last entry. */ 1299 #define R_MIPS_NUM 38 1300 1301 /* Legal values for p_type field of Elf32_Phdr. */ 1302 1303 #define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ 1304 #define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ 1305 #define PT_MIPS_OPTIONS 0x70000002 1306 1307 /* Special program header types. */ 1308 1309 #define PF_MIPS_LOCAL 0x10000000 1310 1311 /* Legal values for d_tag field of Elf32_Dyn. */ 1312 1313 #define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ 1314 #define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ 1315 #define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ 1316 #define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ 1317 #define DT_MIPS_FLAGS 0x70000005 /* Flags */ 1318 #define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ 1319 #define DT_MIPS_MSYM 0x70000007 1320 #define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ 1321 #define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ 1322 #define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ 1323 #define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ 1324 #define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ 1325 #define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ 1326 #define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ 1327 #define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ 1328 #define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ 1329 #define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ 1330 #define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ 1331 #define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in 1332 DT_MIPS_DELTA_CLASS. */ 1333 #define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ 1334 #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in 1335 DT_MIPS_DELTA_INSTANCE. */ 1336 #define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ 1337 #define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in 1338 DT_MIPS_DELTA_RELOC. */ 1339 #define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta 1340 relocations refer to. */ 1341 #define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in 1342 DT_MIPS_DELTA_SYM. */ 1343 #define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the 1344 class declaration. */ 1345 #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in 1346 DT_MIPS_DELTA_CLASSSYM. */ 1347 #define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ 1348 #define DT_MIPS_PIXIE_INIT 0x70000023 1349 #define DT_MIPS_SYMBOL_LIB 0x70000024 1350 #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 1351 #define DT_MIPS_LOCAL_GOTIDX 0x70000026 1352 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027 1353 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028 1354 #define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ 1355 #define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ 1356 #define DT_MIPS_DYNSTR_ALIGN 0x7000002b 1357 #define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ 1358 #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve 1359 function stored in GOT. */ 1360 #define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added 1361 by rld on dlopen() calls. */ 1362 #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ 1363 #define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ 1364 #define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ 1365 #define DT_MIPS_NUM 0x32 1366 1367 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ 1368 1369 #define RHF_NONE 0 /* No flags */ 1370 #define RHF_QUICKSTART (1 << 0) /* Use quickstart */ 1371 #define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ 1372 #define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ 1373 #define RHF_NO_MOVE (1 << 3) 1374 #define RHF_SGI_ONLY (1 << 4) 1375 #define RHF_GUARANTEE_INIT (1 << 5) 1376 #define RHF_DELTA_C_PLUS_PLUS (1 << 6) 1377 #define RHF_GUARANTEE_START_INIT (1 << 7) 1378 #define RHF_PIXIE (1 << 8) 1379 #define RHF_DEFAULT_DELAY_LOAD (1 << 9) 1380 #define RHF_REQUICKSTART (1 << 10) 1381 #define RHF_REQUICKSTARTED (1 << 11) 1382 #define RHF_CORD (1 << 12) 1383 #define RHF_NO_UNRES_UNDEF (1 << 13) 1384 #define RHF_RLD_ORDER_SAFE (1 << 14) 1385 1386 /* Entries found in sections of type SHT_MIPS_LIBLIST. */ 1387 1388 typedef struct 1389 { 1390 Elf32_Word l_name; /* Name (string table index) */ 1391 Elf32_Word l_time_stamp; /* Timestamp */ 1392 Elf32_Word l_checksum; /* Checksum */ 1393 Elf32_Word l_version; /* Interface version */ 1394 Elf32_Word l_flags; /* Flags */ 1395 } Elf32_Lib; 1396 1397 typedef struct 1398 { 1399 Elf64_Word l_name; /* Name (string table index) */ 1400 Elf64_Word l_time_stamp; /* Timestamp */ 1401 Elf64_Word l_checksum; /* Checksum */ 1402 Elf64_Word l_version; /* Interface version */ 1403 Elf64_Word l_flags; /* Flags */ 1404 } Elf64_Lib; 1405 1406 1407 /* Legal values for l_flags. */ 1408 1409 #define LL_NONE 0 1410 #define LL_EXACT_MATCH (1 << 0) /* Require exact match */ 1411 #define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ 1412 #define LL_REQUIRE_MINOR (1 << 2) 1413 #define LL_EXPORTS (1 << 3) 1414 #define LL_DELAY_LOAD (1 << 4) 1415 #define LL_DELTA (1 << 5) 1416 1417 /* Entries found in sections of type SHT_MIPS_CONFLICT. */ 1418 1419 typedef Elf32_Addr Elf32_Conflict; 1420 1421 1422 /* HPPA specific definitions. */ 1423 1424 /* Legal values for e_flags field of Elf32_Ehdr. */ 1425 1426 #define EF_PARISC_TRAPNL 1 /* Trap nil pointer dereference. */ 1427 #define EF_PARISC_EXT 2 /* Program uses arch. extensions. */ 1428 #define EF_PARISC_ARCH 0xffff0000 /* Architecture version. */ 1429 /* Defined values are: 1430 0x020b PA-RISC 1.0 big-endian 1431 0x0210 PA-RISC 1.1 big-endian 1432 0x028b PA-RISC 1.0 little-endian 1433 0x0290 PA-RISC 1.1 little-endian 1434 */ 1435 1436 /* Legal values for sh_type field of Elf32_Shdr. */ 1437 1438 #define SHT_PARISC_GOT 0x70000000 /* GOT for external data. */ 1439 #define SHT_PARISC_ARCH 0x70000001 /* Architecture extensions. */ 1440 #define SHT_PARISC_GLOBAL 0x70000002 /* Definition of $global$. */ 1441 #define SHT_PARISC_MILLI 0x70000003 /* Millicode routines. */ 1442 #define SHT_PARISC_UNWIND 0x70000004 /* Unwind information. */ 1443 #define SHT_PARISC_PLT 0x70000005 /* Procedure linkage table. */ 1444 #define SHT_PARISC_SDATA 0x70000006 /* Short initialized data. */ 1445 #define SHT_PARISC_SBSS 0x70000007 /* Short uninitialized data. */ 1446 #define SHT_PARISC_SYMEXTN 0x70000008 /* Argument/relocation info. */ 1447 #define SHT_PARISC_STUBS 0x70000009 /* Linker stubs. */ 1448 1449 /* Legal values for sh_flags field of Elf32_Shdr. */ 1450 1451 #define SHF_PARISC_GLOBAL 0x10000000 /* Section defines dp. */ 1452 #define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ 1453 1454 /* Legal values for ST_TYPE subfield of st_info (symbol type). */ 1455 1456 #define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ 1457 1458 /* HPPA relocs. */ 1459 1460 #define R_PARISC_NONE 0 /* No reloc. */ 1461 #define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ 1462 #define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ 1463 #define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ 1464 #define R_PARISC_DIR14R 4 /* Right 14 bits of eff. address. */ 1465 #define R_PARISC_PCREL21L 5 /* PC-relative, left 21 bits. */ 1466 #define R_PARISC_PCREL14R 6 /* PC-relative, right 14 bits. */ 1467 #define R_PARISC_PCREL17C 7 /* Conditional PC-relative, ignore 1468 if displacement > 17bits. */ 1469 #define R_PARISC_PCREL17F 8 /* Conditional PC-relative, must 1470 fit in 17bits. */ 1471 #define R_PARISC_DPREL21L 9 /* DP-relative, left 21 bits. */ 1472 #define R_PARISC_DPREL14R 10 /* DP-relative, right 14 bits. */ 1473 #define R_PARISC_DPREL14F 11 /* DP-relative, must bit in 14 bits. */ 1474 #define R_PARISC_DLTREL21L 12 /* DLT-relative, left 21 bits. */ 1475 #define R_PARISC_DLTREL14R 13 /* DLT-relative, right 14 bits. */ 1476 #define R_PARISC_DLTREL14F 14 /* DLT-relative, must fit in 14 bits.*/ 1477 #define R_PARISC_DLTIND21L 15 /* DLT-relative indirect, left 1478 21 bits. */ 1479 #define R_PARISC_DLTIND14R 16 /* DLT-relative indirect, right 1480 14 bits. */ 1481 #define R_PARISC_DLTIND14F 17 /* DLT-relative indirect, must fit 1482 int 14 bits. */ 1483 #define R_PARISC_PLABEL32 18 /* Direct 32-bit reference to proc. */ 1484 1485 /* Alpha specific definitions. */ 1486 1487 /* Legal values for e_flags field of Elf64_Ehdr. */ 1488 1489 #define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ 1490 #define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ 1491 1492 /* Legal values for sh_type field of Elf64_Shdr. */ 1493 1494 /* These two are primerily concerned with ECOFF debugging info. */ 1495 #define SHT_ALPHA_DEBUG 0x70000001 1496 #define SHT_ALPHA_REGINFO 0x70000002 1497 1498 /* Legal values for sh_flags field of Elf64_Shdr. */ 1499 1500 #define SHF_ALPHA_GPREL 0x10000000 1501 1502 /* Legal values for st_other field of Elf64_Sym. */ 1503 #define STO_ALPHA_NOPV 0x80 /* No PV required. */ 1504 #define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ 1505 1506 /* Alpha relocs. */ 1507 1508 #define R_ALPHA_NONE 0 /* No reloc */ 1509 #define R_ALPHA_REFLONG 1 /* Direct 32 bit */ 1510 #define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ 1511 #define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ 1512 #define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ 1513 #define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ 1514 #define R_ALPHA_GPDISP 6 /* Add displacement to GP */ 1515 #define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ 1516 #define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ 1517 #define R_ALPHA_SREL16 9 /* PC relative 16 bit */ 1518 #define R_ALPHA_SREL32 10 /* PC relative 32 bit */ 1519 #define R_ALPHA_SREL64 11 /* PC relative 64 bit */ 1520 #define R_ALPHA_OP_PUSH 12 /* OP stack push */ 1521 #define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ 1522 #define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ 1523 #define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ 1524 #define R_ALPHA_GPVALUE 16 1525 #define R_ALPHA_GPRELHIGH 17 1526 #define R_ALPHA_GPRELLOW 18 1527 #define R_ALPHA_IMMED_GP_16 19 1528 #define R_ALPHA_IMMED_GP_HI32 20 1529 #define R_ALPHA_IMMED_SCN_HI32 21 1530 #define R_ALPHA_IMMED_BR_HI32 22 1531 #define R_ALPHA_IMMED_LO32 23 1532 #define R_ALPHA_COPY 24 /* Copy symbol at runtime */ 1533 #define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ 1534 #define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ 1535 #define R_ALPHA_RELATIVE 27 /* Adjust by program base */ 1536 /* Keep this the last entry. */ 1537 #define R_ALPHA_NUM 28 1538 1539 1540 /* PowerPC specific declarations */ 1541 1542 /* PowerPC relocations defined by the ABIs */ 1543 #define R_PPC_NONE 0 1544 #define R_PPC_ADDR32 1 /* 32bit absolute address */ 1545 #define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ 1546 #define R_PPC_ADDR16 3 /* 16bit absolute address */ 1547 #define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ 1548 #define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ 1549 #define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ 1550 #define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ 1551 #define R_PPC_ADDR14_BRTAKEN 8 1552 #define R_PPC_ADDR14_BRNTAKEN 9 1553 #define R_PPC_REL24 10 /* PC relative 26 bit */ 1554 #define R_PPC_REL14 11 /* PC relative 16 bit */ 1555 #define R_PPC_REL14_BRTAKEN 12 1556 #define R_PPC_REL14_BRNTAKEN 13 1557 #define R_PPC_GOT16 14 1558 #define R_PPC_GOT16_LO 15 1559 #define R_PPC_GOT16_HI 16 1560 #define R_PPC_GOT16_HA 17 1561 #define R_PPC_PLTREL24 18 1562 #define R_PPC_COPY 19 1563 #define R_PPC_GLOB_DAT 20 1564 #define R_PPC_JMP_SLOT 21 1565 #define R_PPC_RELATIVE 22 1566 #define R_PPC_LOCAL24PC 23 1567 #define R_PPC_UADDR32 24 1568 #define R_PPC_UADDR16 25 1569 #define R_PPC_REL32 26 1570 #define R_PPC_PLT32 27 1571 #define R_PPC_PLTREL32 28 1572 #define R_PPC_PLT16_LO 29 1573 #define R_PPC_PLT16_HI 30 1574 #define R_PPC_PLT16_HA 31 1575 #define R_PPC_SDAREL16 32 1576 #define R_PPC_SECTOFF 33 1577 #define R_PPC_SECTOFF_LO 34 1578 #define R_PPC_SECTOFF_HI 35 1579 #define R_PPC_SECTOFF_HA 36 1580 /* Keep this the last entry. */ 1581 #define R_PPC_NUMm 37 1582 1583 /* The remaining relocs are from the Embedded ELF ABI, and are not 1584 in the SVR4 ELF ABI. */ 1585 #define R_PPC_EMB_NADDR32 101 1586 #define R_PPC_EMB_NADDR16 102 1587 #define R_PPC_EMB_NADDR16_LO 103 1588 #define R_PPC_EMB_NADDR16_HI 104 1589 #define R_PPC_EMB_NADDR16_HA 105 1590 #define R_PPC_EMB_SDAI16 106 1591 #define R_PPC_EMB_SDA2I16 107 1592 #define R_PPC_EMB_SDA2REL 108 1593 #define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ 1594 #define R_PPC_EMB_MRKREF 110 1595 #define R_PPC_EMB_RELSEC16 111 1596 #define R_PPC_EMB_RELST_LO 112 1597 #define R_PPC_EMB_RELST_HI 113 1598 #define R_PPC_EMB_RELST_HA 114 1599 #define R_PPC_EMB_BIT_FLD 115 1600 #define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ 1601 1602 /* Diab tool relocations. */ 1603 #define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ 1604 #define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ 1605 #define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ 1606 #define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ 1607 #define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ 1608 #define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ 1609 1610 /* This is a phony reloc to handle any old fashioned TOC16 references 1611 that may still be in object files. */ 1612 #define R_PPC_TOC16 255 1613 1614 1615 /* ARM specific declarations */ 1616 1617 /* Processor specific flags for the ELF header e_flags field. */ 1618 #define EF_ARM_RELEXEC 0x01 1619 #define EF_ARM_HASENTRY 0x02 1620 #define EF_ARM_INTERWORK 0x04 1621 #define EF_ARM_APCS_26 0x08 1622 #define EF_ARM_APCS_FLOAT 0x10 1623 #define EF_ARM_PIC 0x20 1624 #define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */ 1625 #define EF_NEW_ABI 0x80 1626 #define EF_OLD_ABI 0x100 1627 1628 /* Additional symbol types for Thumb */ 1629 #define STT_ARM_TFUNC 0xd 1630 1631 /* ARM-specific values for sh_flags */ 1632 #define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ 1633 #define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined 1634 in the input to a link step */ 1635 1636 /* ARM-specific program header flags */ 1637 #define PF_ARM_SB 0x10000000 /* Segment contains the location 1638 addressed by the static base */ 1639 1640 /* ARM relocs. */ 1641 #define R_ARM_NONE 0 /* No reloc */ 1642 #define R_ARM_PC24 1 /* PC relative 26 bit branch */ 1643 #define R_ARM_ABS32 2 /* Direct 32 bit */ 1644 #define R_ARM_REL32 3 /* PC relative 32 bit */ 1645 #define R_ARM_PC13 4 1646 #define R_ARM_ABS16 5 /* Direct 16 bit */ 1647 #define R_ARM_ABS12 6 /* Direct 12 bit */ 1648 #define R_ARM_THM_ABS5 7 1649 #define R_ARM_ABS8 8 /* Direct 8 bit */ 1650 #define R_ARM_SBREL32 9 1651 #define R_ARM_THM_PC22 10 1652 #define R_ARM_THM_PC8 11 1653 #define R_ARM_AMP_VCALL9 12 1654 #define R_ARM_SWI24 13 1655 #define R_ARM_THM_SWI8 14 1656 #define R_ARM_XPC25 15 1657 #define R_ARM_THM_XPC22 16 1658 #define R_ARM_COPY 20 /* Copy symbol at runtime */ 1659 #define R_ARM_GLOB_DAT 21 /* Create GOT entry */ 1660 #define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ 1661 #define R_ARM_RELATIVE 23 /* Adjust by program base */ 1662 #define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ 1663 #define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ 1664 #define R_ARM_GOT32 26 /* 32 bit GOT entry */ 1665 #define R_ARM_PLT32 27 /* 32 bit PLT address */ 1666 #define R_ARM_GNU_VTENTRY 100 1667 #define R_ARM_GNU_VTINHERIT 101 1668 #define R_ARM_THM_PC11 102 /* thumb unconditional branch */ 1669 #define R_ARM_THM_PC9 103 /* thumb conditional branch */ 1670 #define R_ARM_RXPC25 249 1671 #define R_ARM_RSBREL32 250 1672 #define R_ARM_THM_RPC22 251 1673 #define R_ARM_RREL32 252 1674 #define R_ARM_RABS22 253 1675 #define R_ARM_RPC24 254 1676 #define R_ARM_RBASE 255 1677 /* Keep this the last entry. */ 1678 #define R_ARM_NUM 256 1679 1680 /* TMS320C67xx specific declarations */ 1681 /* XXX: no ELF standard yet */ 1682 1683 /* TMS320C67xx relocs. */ 1684 #define R_C60_32 1 1685 #define R_C60_GOT32 3 /* 32 bit GOT entry */ 1686 #define R_C60_PLT32 4 /* 32 bit PLT address */ 1687 #define R_C60_COPY 5 /* Copy symbol at runtime */ 1688 #define R_C60_GLOB_DAT 6 /* Create GOT entry */ 1689 #define R_C60_JMP_SLOT 7 /* Create PLT entry */ 1690 #define R_C60_RELATIVE 8 /* Adjust by program base */ 1691 #define R_C60_GOTOFF 9 /* 32 bit offset to GOT */ 1692 #define R_C60_GOTPC 10 /* 32 bit PC relative offset to GOT */ 1693 1694 #define R_C60HI16 0x55 // high 16 bit MVKH embedded 1695 #define R_C60LO16 0x54 // low 16 bit MVKL embedded 1696 1697 #endif /* elf.h */ 1698 //--------------------------------------------------------------------------- 1699 1700 1701 // njn: inlined stab.h 1702 //#include "stab.h" 1703 //--------------------------------------------------------------------------- 1704 #ifndef __GNU_STAB__ 1705 1706 /* Indicate the GNU stab.h is in use. */ 1707 1708 #define __GNU_STAB__ 1709 1710 #define __define_stab(NAME, CODE, STRING) NAME=CODE, 1711 1712 enum __stab_debug_code 1713 { 1714 // njn: inlined stab.def 1715 //#include "stab.def" 1716 //--------------------------------------------------------------------------- 1717 /* Table of DBX symbol codes for the GNU system. 1718 Copyright (C) 1988, 1997 Free Software Foundation, Inc. 1719 This file is part of the GNU C Library. 1720 1721 The GNU C Library is free software; you can redistribute it and/or 1722 modify it under the terms of the GNU Library General Public License as 1723 published by the Free Software Foundation; either version 2 of the 1724 License, or (at your option) any later version. 1725 1726 The GNU C Library is distributed in the hope that it will be useful, 1727 but WITHOUT ANY WARRANTY; without even the implied warranty of 1728 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1729 Library General Public License for more details. 1730 1731 You should have received a copy of the GNU Library General Public 1732 License along with the GNU C Library; see the file COPYING.LIB. If not, 1733 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 1734 Boston, MA 02111-1307, USA. */ 1735 1736 /* This contains contribution from Cygnus Support. */ 1737 1738 /* Global variable. Only the name is significant. 1740 To find the address, look in the corresponding external symbol. */ 1741 __define_stab (N_GSYM, 0x20, "GSYM") 1742 1743 /* Function name for BSD Fortran. Only the name is significant. 1744 To find the address, look in the corresponding external symbol. */ 1745 __define_stab (N_FNAME, 0x22, "FNAME") 1746 1747 /* Function name or text-segment variable for C. Value is its address. 1748 Desc is supposedly starting line number, but GCC doesn't set it 1749 and DBX seems not to miss it. */ 1750 __define_stab (N_FUN, 0x24, "FUN") 1751 1752 /* Data-segment variable with internal linkage. Value is its address. 1753 "Static Sym". */ 1754 __define_stab (N_STSYM, 0x26, "STSYM") 1755 1756 /* BSS-segment variable with internal linkage. Value is its address. */ 1757 __define_stab (N_LCSYM, 0x28, "LCSYM") 1758 1759 /* Name of main routine. Only the name is significant. 1760 This is not used in C. */ 1761 __define_stab (N_MAIN, 0x2a, "MAIN") 1762 1763 /* Global symbol in Pascal. 1764 Supposedly the value is its line number; I'm skeptical. */ 1765 __define_stab (N_PC, 0x30, "PC") 1766 1767 /* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */ 1768 __define_stab (N_NSYMS, 0x32, "NSYMS") 1769 1770 /* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */ 1771 __define_stab (N_NOMAP, 0x34, "NOMAP") 1772 1773 /* New stab from Solaris. I don't know what it means, but it 1774 don't seem to contain useful information. */ 1775 __define_stab (N_OBJ, 0x38, "OBJ") 1776 1777 /* New stab from Solaris. I don't know what it means, but it 1778 don't seem to contain useful information. Possibly related to the 1779 optimization flags used in this module. */ 1780 __define_stab (N_OPT, 0x3c, "OPT") 1781 1782 /* Register variable. Value is number of register. */ 1783 __define_stab (N_RSYM, 0x40, "RSYM") 1784 1785 /* Modula-2 compilation unit. Can someone say what info it contains? */ 1786 __define_stab (N_M2C, 0x42, "M2C") 1787 1788 /* Line number in text segment. Desc is the line number; 1789 value is corresponding address. */ 1790 __define_stab (N_SLINE, 0x44, "SLINE") 1791 1792 /* Similar, for data segment. */ 1793 __define_stab (N_DSLINE, 0x46, "DSLINE") 1794 1795 /* Similar, for bss segment. */ 1796 __define_stab (N_BSLINE, 0x48, "BSLINE") 1797 1798 /* Sun's source-code browser stabs. ?? Don't know what the fields are. 1799 Supposedly the field is "path to associated .cb file". THIS VALUE 1800 OVERLAPS WITH N_BSLINE! */ 1801 __define_stab (N_BROWS, 0x48, "BROWS") 1802 1803 /* GNU Modula-2 definition module dependency. Value is the modification time 1804 of the definition file. Other is non-zero if it is imported with the 1805 GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there 1806 are enough empty fields? */ 1807 __define_stab(N_DEFD, 0x4a, "DEFD") 1808 1809 /* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2 1810 and one is for C++. Still,... */ 1811 /* GNU C++ exception variable. Name is variable name. */ 1812 __define_stab (N_EHDECL, 0x50, "EHDECL") 1813 /* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */ 1814 __define_stab (N_MOD2, 0x50, "MOD2") 1815 1816 /* GNU C++ `catch' clause. Value is its address. Desc is nonzero if 1817 this entry is immediately followed by a CAUGHT stab saying what exception 1818 was caught. Multiple CAUGHT stabs means that multiple exceptions 1819 can be caught here. If Desc is 0, it means all exceptions are caught 1820 here. */ 1821 __define_stab (N_CATCH, 0x54, "CATCH") 1822 1823 /* Structure or union element. Value is offset in the structure. */ 1824 __define_stab (N_SSYM, 0x60, "SSYM") 1825 1826 /* Name of main source file. 1827 Value is starting text address of the compilation. */ 1828 __define_stab (N_SO, 0x64, "SO") 1829 1830 /* Automatic variable in the stack. Value is offset from frame pointer. 1831 Also used for type descriptions. */ 1832 __define_stab (N_LSYM, 0x80, "LSYM") 1833 1834 /* Beginning of an include file. Only Sun uses this. 1835 In an object file, only the name is significant. 1836 The Sun linker puts data into some of the other fields. */ 1837 __define_stab (N_BINCL, 0x82, "BINCL") 1838 1839 /* Name of sub-source file (#include file). 1840 Value is starting text address of the compilation. */ 1841 __define_stab (N_SOL, 0x84, "SOL") 1842 1843 /* Parameter variable. Value is offset from argument pointer. 1844 (On most machines the argument pointer is the same as the frame pointer. */ 1845 __define_stab (N_PSYM, 0xa0, "PSYM") 1846 1847 /* End of an include file. No name. 1848 This and N_BINCL act as brackets around the file's output. 1849 In an object file, there is no significant data in this entry. 1850 The Sun linker puts data into some of the fields. */ 1851 __define_stab (N_EINCL, 0xa2, "EINCL") 1852 1853 /* Alternate entry point. Value is its address. */ 1854 __define_stab (N_ENTRY, 0xa4, "ENTRY") 1855 1856 /* Beginning of lexical block. 1857 The desc is the nesting level in lexical blocks. 1858 The value is the address of the start of the text for the block. 1859 The variables declared inside the block *precede* the N_LBRAC symbol. */ 1860 __define_stab (N_LBRAC, 0xc0, "LBRAC") 1861 1862 /* Place holder for deleted include file. Replaces a N_BINCL and everything 1863 up to the corresponding N_EINCL. The Sun linker generates these when 1864 it finds multiple identical copies of the symbols from an include file. 1865 This appears only in output from the Sun linker. */ 1866 __define_stab (N_EXCL, 0xc2, "EXCL") 1867 1868 /* Modula-2 scope information. Can someone say what info it contains? */ 1869 __define_stab (N_SCOPE, 0xc4, "SCOPE") 1870 1871 /* End of a lexical block. Desc matches the N_LBRAC's desc. 1872 The value is the address of the end of the text for the block. */ 1873 __define_stab (N_RBRAC, 0xe0, "RBRAC") 1874 1875 /* Begin named common block. Only the name is significant. */ 1876 __define_stab (N_BCOMM, 0xe2, "BCOMM") 1877 1878 /* End named common block. Only the name is significant 1879 (and it should match the N_BCOMM). */ 1880 __define_stab (N_ECOMM, 0xe4, "ECOMM") 1881 1882 /* End common (local name): value is address. 1883 I'm not sure how this is used. */ 1884 __define_stab (N_ECOML, 0xe8, "ECOML") 1885 1886 /* These STAB's are used on Gould systems for Non-Base register symbols 1887 or something like that. FIXME. I have assigned the values at random 1888 since I don't have a Gould here. Fixups from Gould folk welcome... */ 1889 __define_stab (N_NBTEXT, 0xF0, "NBTEXT") 1890 __define_stab (N_NBDATA, 0xF2, "NBDATA") 1891 __define_stab (N_NBBSS, 0xF4, "NBBSS") 1892 __define_stab (N_NBSTS, 0xF6, "NBSTS") 1893 __define_stab (N_NBLCS, 0xF8, "NBLCS") 1894 1895 /* Second symbol entry containing a length-value for the preceding entry. 1896 The value is the length. */ 1897 __define_stab (N_LENG, 0xfe, "LENG") 1898 1899 /* The above information, in matrix format. 1901 1902 STAB MATRIX 1903 _________________________________________________ 1904 | 00 - 1F are not dbx stab symbols | 1905 | In most cases, the low bit is the EXTernal bit| 1906 1907 | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | 1908 | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | 1909 1910 | 08 BSS | 0A INDR | 0C FN_SEQ | 0E | 1911 | 09 |EXT | 0B | 0D | 0F | 1912 1913 | 10 | 12 COMM | 14 SETA | 16 SETT | 1914 | 11 | 13 | 15 | 17 | 1915 1916 | 18 SETD | 1A SETB | 1C SETV | 1E WARNING| 1917 | 19 | 1B | 1D | 1F FN | 1918 1919 |_______________________________________________| 1920 | Debug entries with bit 01 set are unused. | 1921 | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM | 1922 | 28 LCSYM | 2A MAIN | 2C | 2E | 1923 | 30 PC | 32 NSYMS | 34 NOMAP | 36 | 1924 | 38 OBJ | 3A | 3C OPT | 3E | 1925 | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE | 1926 | 48 BSLINE*| 4A DEFD | 4C | 4E | 1927 | 50 EHDECL*| 52 | 54 CATCH | 56 | 1928 | 58 | 5A | 5C | 5E | 1929 | 60 SSYM | 62 | 64 SO | 66 | 1930 | 68 | 6A | 6C | 6E | 1931 | 70 | 72 | 74 | 76 | 1932 | 78 | 7A | 7C | 7E | 1933 | 80 LSYM | 82 BINCL | 84 SOL | 86 | 1934 | 88 | 8A | 8C | 8E | 1935 | 90 | 92 | 94 | 96 | 1936 | 98 | 9A | 9C | 9E | 1937 | A0 PSYM | A2 EINCL | A4 ENTRY | A6 | 1938 | A8 | AA | AC | AE | 1939 | B0 | B2 | B4 | B6 | 1940 | B8 | BA | BC | BE | 1941 | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 | 1942 | C8 | CA | CC | CE | 1943 | D0 | D2 | D4 | D6 | 1944 | D8 | DA | DC | DE | 1945 | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 | 1946 | E8 ECOML | EA | EC | EE | 1947 | F0 | F2 | F4 | F6 | 1948 | F8 | FA | FC | FE LENG | 1949 +-----------------------------------------------+ 1950 * 50 EHDECL is also MOD2. 1951 * 48 BSLINE is also BROWS. 1952 */ 1953 //--------------------------------------------------------------------------- 1954 LAST_UNUSED_STAB_CODE 1955 }; 1956 1957 #undef __define_stab 1958 1959 #endif /* __GNU_STAB_ */ 1960 //--------------------------------------------------------------------------- 1961 1962 #ifndef O_BINARY 1963 #define O_BINARY 0 1964 #endif 1965 1966 // njn: inlined libtcc.h 1967 //#include "libtcc.h" 1968 //--------------------------------------------------------------------------- 1969 #ifndef LIBTCC_H 1970 #define LIBTCC_H 1971 1972 #ifdef __cplusplus 1973 extern "C" { 1974 #endif 1975 1976 struct TCCState; 1977 1978 typedef struct TCCState TCCState; 1979 1980 /* create a new TCC compilation context */ 1981 TCCState *tcc_new(void); 1982 1983 /* free a TCC compilation context */ 1984 void tcc_delete(TCCState *s); 1985 1986 /* add debug information in the generated code */ 1987 void tcc_enable_debug(TCCState *s); 1988 1989 /* set error/warning display callback */ 1990 void tcc_set_error_func(TCCState *s, void *error_opaque, 1991 void (*error_func)(void *opaque, const char *msg)); 1992 1993 /* set/reset a warning */ 1994 int tcc_set_warning(TCCState *s, const char *warning_name, int value); 1995 1996 /*****************************/ 1997 /* preprocessor */ 1998 1999 /* add include path */ 2000 int tcc_add_include_path(TCCState *s, const char *pathname); 2001 2002 /* add in system include path */ 2003 int tcc_add_sysinclude_path(TCCState *s, const char *pathname); 2004 2005 /* define preprocessor symbol 'sym'. Can put optional value */ 2006 void tcc_define_symbol(TCCState *s, const char *sym, const char *value); 2007 2008 /* undefine preprocess symbol 'sym' */ 2009 void tcc_undefine_symbol(TCCState *s, const char *sym); 2010 2011 /*****************************/ 2012 /* compiling */ 2013 2014 /* add a file (either a C file, dll, an object, a library or an ld 2015 script). Return -1 if error. */ 2016 int tcc_add_file(TCCState *s, const char *filename); 2017 2018 /* compile a string containing a C source. Return non zero if 2019 error. */ 2020 int tcc_compile_string(TCCState *s, const char *buf); 2021 2022 /*****************************/ 2023 /* linking commands */ 2024 2025 /* set output type. MUST BE CALLED before any compilation */ 2026 #define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no 2027 output file) (default) */ 2028 #define TCC_OUTPUT_EXE 1 /* executable file */ 2029 #define TCC_OUTPUT_DLL 2 /* dynamic library */ 2030 #define TCC_OUTPUT_OBJ 3 /* object file */ 2031 int tcc_set_output_type(TCCState *s, int output_type); 2032 2033 #define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */ 2034 #define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */ 2035 #define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */ 2036 2037 /* equivalent to -Lpath option */ 2038 int tcc_add_library_path(TCCState *s, const char *pathname); 2039 2040 /* the library name is the same as the argument of the '-l' option */ 2041 int tcc_add_library(TCCState *s, const char *libraryname); 2042 2043 /* add a symbol to the compiled program */ 2044 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val); 2045 2046 /* output an executable, library or object file. DO NOT call 2047 tcc_relocate() before. */ 2048 int tcc_output_file(TCCState *s, const char *filename); 2049 2050 /* link and run main() function and return its value. DO NOT call 2051 tcc_relocate() before. */ 2052 int tcc_run(TCCState *s, int argc, char **argv); 2053 2054 /* do all relocations (needed before using tcc_get_symbol()). Return 2055 non zero if link error. */ 2056 int tcc_relocate(TCCState *s); 2057 2058 /* return symbol value. return 0 if OK, -1 if symbol not found */ 2059 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name); 2060 2061 #ifdef __cplusplus 2062 } 2063 #endif 2064 2065 #endif 2066 //--------------------------------------------------------------------------- 2067 2068 /* parser debug */ 2069 //#define PARSE_DEBUG 2070 /* preprocessor debug */ 2071 //#define PP_DEBUG 2072 /* include file debug */ 2073 //#define INC_DEBUG 2074 2075 //#define MEM_DEBUG 2076 2077 /* assembler debug */ 2078 //#define ASM_DEBUG 2079 2080 /* target selection */ 2081 //#define TCC_TARGET_I386 /* i386 code generator */ 2082 //#define TCC_TARGET_ARM /* ARMv4 code generator */ 2083 //#define TCC_TARGET_C67 /* TMS320C67xx code generator */ 2084 2085 /* default target is I386 */ 2086 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ 2087 !defined(TCC_TARGET_C67) 2088 #define TCC_TARGET_I386 2089 #endif 2090 2091 #if !defined(WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \ 2092 !defined(TCC_TARGET_C67) 2093 #define CONFIG_TCC_BCHECK /* enable bound checking code */ 2094 #endif 2095 2096 #if defined(WIN32) && !defined(TCC_TARGET_PE) 2097 #define CONFIG_TCC_STATIC 2098 #endif 2099 2100 /* define it to include assembler support */ 2101 #if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) 2102 #define CONFIG_TCC_ASM 2103 #endif 2104 2105 /* object format selection */ 2106 #if defined(TCC_TARGET_C67) 2107 #define TCC_TARGET_COFF 2108 #endif 2109 2110 #define FALSE 0 2111 #define false 0 2112 #define TRUE 1 2113 #define true 1 2114 typedef int BOOL; 2115 2116 /* path to find crt1.o, crti.o and crtn.o. Only needed when generating 2117 executables or dlls */ 2118 #define CONFIG_TCC_CRT_PREFIX "/usr/lib" 2119 2120 #define INCLUDE_STACK_SIZE 32 2121 #define IFDEF_STACK_SIZE 64 2122 #define VSTACK_SIZE 256 2123 #define STRING_MAX_SIZE 1024 2124 #define PACK_STACK_SIZE 8 2125 2126 #define TOK_HASH_SIZE 8192 /* must be a power of two */ 2127 #define TOK_ALLOC_INCR 512 /* must be a power of two */ 2128 #define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */ 2129 2130 /* token symbol management */ 2131 typedef struct TokenSym { 2132 struct TokenSym *hash_next; 2133 struct Sym *sym_define; /* direct pointer to define */ 2134 struct Sym *sym_label; /* direct pointer to label */ 2135 struct Sym *sym_struct; /* direct pointer to structure */ 2136 struct Sym *sym_identifier; /* direct pointer to identifier */ 2137 int tok; /* token number */ 2138 int len; 2139 char str[1]; 2140 } TokenSym; 2141 2142 typedef struct CString { 2143 int size; /* size in bytes */ 2144 void *data; /* either 'char *' or 'int *' */ 2145 int size_allocated; 2146 void *data_allocated; /* if non NULL, data has been malloced */ 2147 } CString; 2148 2149 /* type definition */ 2150 typedef struct CType { 2151 int t; 2152 struct Sym *ref; 2153 } CType; 2154 2155 /* constant value */ 2156 typedef union CValue { 2157 long double ld; 2158 double d; 2159 float f; 2160 int i; 2161 unsigned int ui; 2162 unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */ 2163 long long ll; 2164 unsigned long long ull; 2165 struct CString *cstr; 2166 void *ptr; 2167 int tab[sizeof(long double) / sizeof(int)]; 2168 } CValue; 2169 2170 /* value on stack */ 2171 typedef struct SValue { 2172 CType type; /* type */ 2173 unsigned short r; /* register + flags */ 2174 unsigned short r2; /* second register, used for 'long long' 2175 type. If not used, set to VT_CONST */ 2176 CValue c; /* constant, if VT_CONST */ 2177 struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */ 2178 } SValue; 2179 2180 /* symbol management */ 2181 typedef struct Sym { 2182 long v; /* symbol token */ 2183 long r; /* associated register */ 2184 long c; /* associated number */ 2185 CType type; /* associated type */ 2186 struct Sym *next; /* next related symbol */ 2187 struct Sym *prev; /* prev symbol in stack */ 2188 struct Sym *prev_tok; /* previous symbol for this token */ 2189 } Sym; 2190 2191 /* section definition */ 2192 /* XXX: use directly ELF structure for parameters ? */ 2193 /* special flag to indicate that the section should not be linked to 2194 the other ones */ 2195 #define SHF_PRIVATE 0x80000000 2196 2197 typedef struct Section { 2198 unsigned long data_offset; /* current data offset */ 2199 unsigned char *data; /* section data */ 2200 unsigned long data_allocated; /* used for realloc() handling */ 2201 int sh_name; /* elf section name (only used during output) */ 2202 int sh_num; /* elf section number */ 2203 int sh_type; /* elf section type */ 2204 int sh_flags; /* elf section flags */ 2205 int sh_info; /* elf section info */ 2206 int sh_addralign; /* elf section alignment */ 2207 int sh_entsize; /* elf entry size */ 2208 unsigned long sh_size; /* section size (only used during output) */ 2209 unsigned long sh_addr; /* address at which the section is relocated */ 2210 unsigned long sh_offset; /* address at which the section is relocated */ 2211 int nb_hashed_syms; /* used to resize the hash table */ 2212 struct Section *link; /* link to another section */ 2213 struct Section *reloc; /* corresponding section for relocation, if any */ 2214 struct Section *hash; /* hash table for symbols */ 2215 struct Section *next; 2216 char name[1]; /* section name */ 2217 } Section; 2218 2219 typedef struct DLLReference { 2220 int level; 2221 char name[1]; 2222 } DLLReference; 2223 2224 /* GNUC attribute definition */ 2225 typedef struct AttributeDef { 2226 int aligned; 2227 int packed; 2228 Section *section; 2229 unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */ 2230 unsigned char dllexport; 2231 } AttributeDef; 2232 2233 #define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */ 2234 #define SYM_FIELD 0x20000000 /* struct/union field symbol space */ 2235 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */ 2236 2237 /* stored in 'Sym.c' field */ 2238 #define FUNC_NEW 1 /* ansi function prototype */ 2239 #define FUNC_OLD 2 /* old function prototype */ 2240 #define FUNC_ELLIPSIS 3 /* ansi function prototype with ... */ 2241 2242 /* stored in 'Sym.r' field */ 2243 #define FUNC_CDECL 0 /* standard c call */ 2244 #define FUNC_STDCALL 1 /* pascal c call */ 2245 #define FUNC_FASTCALL1 2 /* first param in %eax */ 2246 #define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */ 2247 #define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */ 2248 2249 /* field 'Sym.t' for macros */ 2250 #define MACRO_OBJ 0 /* object like macro */ 2251 #define MACRO_FUNC 1 /* function like macro */ 2252 2253 /* field 'Sym.r' for C labels */ 2254 #define LABEL_DEFINED 0 /* label is defined */ 2255 #define LABEL_FORWARD 1 /* label is forward defined */ 2256 #define LABEL_DECLARED 2 /* label is declared but never used */ 2257 2258 /* type_decl() types */ 2259 #define TYPE_ABSTRACT 1 /* type without variable */ 2260 #define TYPE_DIRECT 2 /* type with variable */ 2261 2262 #define IO_BUF_SIZE 8192 2263 2264 typedef struct BufferedFile { 2265 uint8_t *buf_ptr; 2266 uint8_t *buf_end; 2267 int fd; 2268 int line_num; /* current line number - here to simplify code */ 2269 int ifndef_macro; /* #ifndef macro / #endif search */ 2270 int ifndef_macro_saved; /* saved ifndef_macro */ 2271 int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */ 2272 char inc_type; /* type of include */ 2273 char inc_filename[512]; /* filename specified by the user */ 2274 char filename[1024]; /* current filename - here to simplify code */ 2275 unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */ 2276 } BufferedFile; 2277 2278 #define CH_EOB '\\' /* end of buffer or '\0' char in file */ 2279 #define CH_EOF (-1) /* end of file */ 2280 2281 /* parsing state (used to save parser state to reparse part of the 2282 source several times) */ 2283 typedef struct ParseState { 2284 int *macro_ptr; 2285 int line_num; 2286 int tok; 2287 CValue tokc; 2288 } ParseState; 2289 2290 /* used to record tokens */ 2291 typedef struct TokenString { 2292 int *str; 2293 int len; 2294 int allocated_len; 2295 int last_line_num; 2296 } TokenString; 2297 2298 /* include file cache, used to find files faster and also to eliminate 2299 inclusion if the include file is protected by #ifndef ... #endif */ 2300 typedef struct CachedInclude { 2301 int ifndef_macro; 2302 int hash_next; /* -1 if none */ 2303 char type; /* '"' or '>' to give include type */ 2304 char filename[1]; /* path specified in #include */ 2305 } CachedInclude; 2306 2307 #define CACHED_INCLUDES_HASH_SIZE 512 2308 2309 /* parser */ 2310 static struct BufferedFile *file; 2311 static int ch, tok; 2312 static CValue tokc; 2313 static CString tokcstr; /* current parsed string, if any */ 2314 /* additional informations about token */ 2315 static int tok_flags; 2316 #define TOK_FLAG_BOL 0x0001 /* beginning of line before */ 2317 #define TOK_FLAG_BOF 0x0002 /* beginning of file before */ 2318 #define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */ 2319 2320 static int *macro_ptr, *macro_ptr_allocated; 2321 static int *unget_saved_macro_ptr; 2322 static int unget_saved_buffer[TOK_MAX_SIZE + 1]; 2323 static int unget_buffer_enabled; 2324 static int parse_flags; 2325 #define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */ 2326 #define PARSE_FLAG_TOK_NUM 0x0002 /* return numbers instead of TOK_PPNUM */ 2327 #define PARSE_FLAG_LINEFEED 0x0004 /* line feed is returned as a 2328 token. line feed is also 2329 returned at eof */ 2330 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */ 2331 2332 static Section *text_section, *data_section, *bss_section; /* predefined sections */ 2333 static Section *cur_text_section; /* current section where function code is 2334 generated */ 2335 #ifdef CONFIG_TCC_ASM 2336 static Section *last_text_section; /* to handle .previous asm directive */ 2337 #endif 2338 /* bound check related sections */ 2339 static Section *bounds_section; /* contains global data bound description */ 2340 static Section *lbounds_section; /* contains local data bound description */ 2341 /* symbol sections */ 2342 static Section *symtab_section, *strtab_section; 2343 2344 /* debug sections */ 2345 static Section *stab_section, *stabstr_section; 2346 2347 /* loc : local variable index 2348 ind : output code index 2349 rsym: return symbol 2350 anon_sym: anonymous symbol index 2351 */ 2352 static long rsym, anon_sym, ind, loc; 2353 /* expression generation modifiers */ 2354 static int const_wanted; /* true if constant wanted */ 2355 static int nocode_wanted; /* true if no code generation wanted for an expression */ 2356 static int global_expr; /* true if compound literals must be allocated 2357 globally (used during initializers parsing */ 2358 static CType func_vt; /* current function return type (used by return 2359 instruction) */ 2360 static int func_vc; 2361 static long last_line_num, last_ind, func_ind; /* debug last line number and pc */ 2362 static int tok_ident; 2363 static TokenSym **table_ident; 2364 static TokenSym *hash_ident[TOK_HASH_SIZE]; 2365 static char token_buf[STRING_MAX_SIZE + 1]; 2366 static char *funcname; 2367 static Sym *global_stack, *local_stack; 2368 static Sym *define_stack; 2369 static Sym *global_label_stack, *local_label_stack; 2370 /* symbol allocator */ 2371 #define SYM_POOL_NB (8192 / sizeof(Sym)) 2372 static Sym *sym_free_first; 2373 2374 static SValue vstack[VSTACK_SIZE], *vtop; 2375 /* some predefined types */ 2376 static CType char_pointer_type, func_old_type, int_type; 2377 /* true if isid(c) || isnum(c) */ 2378 static unsigned char isidnum_table[256]; 2379 2380 /* compile with debug symbol (and use them if error during execution) */ 2381 static int do_debug = 0; 2382 2383 /* compile with built-in memory and bounds checker */ 2384 static int do_bounds_check = 0; 2385 2386 /* display benchmark infos */ 2387 #if !defined(LIBTCC) 2388 static int do_bench = 0; 2389 #endif 2390 static int total_lines; 2391 static int total_bytes; 2392 2393 /* use GNU C extensions */ 2394 static int gnu_ext = 1; 2395 2396 /* use Tiny C extensions */ 2397 static int tcc_ext = 1; 2398 2399 /* max number of callers shown if error */ 2400 static int num_callers = 6; 2401 static const char **rt_bound_error_msg; 2402 2403 /* XXX: get rid of this ASAP */ 2404 static struct TCCState *tcc_state; 2405 2406 /* give the path of the tcc libraries */ 2407 static const char *tcc_lib_path = CONFIG_TCCDIR; 2408 2409 struct TCCState { 2410 int output_type; 2411 2412 BufferedFile **include_stack_ptr; 2413 int *ifdef_stack_ptr; 2414 2415 /* include file handling */ 2416 char **include_paths; 2417 int nb_include_paths; 2418 char **sysinclude_paths; 2419 int nb_sysinclude_paths; 2420 CachedInclude **cached_includes; 2421 int nb_cached_includes; 2422 2423 char **library_paths; 2424 int nb_library_paths; 2425 2426 /* array of all loaded dlls (including those referenced by loaded 2427 dlls) */ 2428 DLLReference **loaded_dlls; 2429 int nb_loaded_dlls; 2430 2431 /* sections */ 2432 Section **sections; 2433 int nb_sections; /* number of sections, including first dummy section */ 2434 2435 /* got handling */ 2436 Section *got; 2437 Section *plt; 2438 unsigned long *got_offsets; 2439 int nb_got_offsets; 2440 /* give the correspondance from symtab indexes to dynsym indexes */ 2441 int *symtab_to_dynsym; 2442 2443 /* temporary dynamic symbol sections (for dll loading) */ 2444 Section *dynsymtab_section; 2445 /* exported dynamic symbol section */ 2446 Section *dynsym; 2447 2448 int nostdinc; /* if true, no standard headers are added */ 2449 int nostdlib; /* if true, no standard libraries are added */ 2450 2451 int nocommon; /* if true, do not use common symbols for .bss data */ 2452 2453 /* if true, static linking is performed */ 2454 int static_link; 2455 2456 /* if true, all symbols are exported */ 2457 int rdynamic; 2458 2459 /* if true, only link in referenced objects from archive */ 2460 int alacarte_link; 2461 2462 /* address of text section */ 2463 unsigned long text_addr; 2464 int has_text_addr; 2465 2466 /* output format, see TCC_OUTPUT_FORMAT_xxx */ 2467 int output_format; 2468 2469 /* C language options */ 2470 int char_is_unsigned; 2471 int leading_underscore; 2472 2473 /* warning switches */ 2474 int warn_write_strings; 2475 int warn_unsupported; 2476 int warn_error; 2477 int warn_none; 2478 int warn_implicit_function_declaration; 2479 2480 /* error handling */ 2481 void *error_opaque; 2482 void (*error_func)(void *opaque, const char *msg); 2483 int error_set_jmp_enabled; 2484 jmp_buf error_jmp_buf; 2485 int nb_errors; 2486 2487 /* tiny assembler state */ 2488 Sym *asm_labels; 2489 2490 /* see include_stack_ptr */ 2491 BufferedFile *include_stack[INCLUDE_STACK_SIZE]; 2492 2493 /* see ifdef_stack_ptr */ 2494 int ifdef_stack[IFDEF_STACK_SIZE]; 2495 2496 /* see cached_includes */ 2497 int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE]; 2498 2499 /* pack stack */ 2500 int pack_stack[PACK_STACK_SIZE]; 2501 int *pack_stack_ptr; 2502 }; 2503 2504 /* The current value can be: */ 2505 #define VT_VALMASK 0x00ff 2506 #define VT_CONST 0x00f0 /* constant in vc 2507 (must be first non register value) */ 2508 #define VT_LLOCAL 0x00f1 /* lvalue, offset on stack */ 2509 #define VT_LOCAL 0x00f2 /* offset on stack */ 2510 #define VT_CMP 0x00f3 /* the value is stored in processor flags (in vc) */ 2511 #define VT_JMP 0x00f4 /* value is the consequence of jmp true (even) */ 2512 #define VT_JMPI 0x00f5 /* value is the consequence of jmp false (odd) */ 2513 #define VT_LVAL 0x0100 /* var is an lvalue */ 2514 #define VT_SYM 0x0200 /* a symbol value is added */ 2515 #define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for 2516 char/short stored in integer registers) */ 2517 #define VT_MUSTBOUND 0x0800 /* bound checking must be done before 2518 dereferencing value */ 2519 #define VT_BOUNDED 0x8000 /* value is bounded. The address of the 2520 bounding function call point is in vc */ 2521 #define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */ 2522 #define VT_LVAL_SHORT 0x2000 /* lvalue is a short */ 2523 #define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */ 2524 #define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED) 2525 2526 /* types */ 2527 #define VT_INT 0 /* integer type */ 2528 #define VT_BYTE 1 /* signed byte type */ 2529 #define VT_SHORT 2 /* short type */ 2530 #define VT_VOID 3 /* void type */ 2531 #define VT_PTR 4 /* pointer */ 2532 #define VT_ENUM 5 /* enum definition */ 2533 #define VT_FUNC 6 /* function type */ 2534 #define VT_STRUCT 7 /* struct/union definition */ 2535 #define VT_FLOAT 8 /* IEEE float */ 2536 #define VT_DOUBLE 9 /* IEEE double */ 2537 #define VT_LDOUBLE 10 /* IEEE long double */ 2538 #define VT_BOOL 11 /* ISOC99 boolean type */ 2539 #define VT_LLONG 12 /* 64 bit integer */ 2540 #define VT_LONG 13 /* long integer (NEVER USED as type, only 2541 during parsing) */ 2542 #define VT_BTYPE 0x000f /* mask for basic type */ 2543 #define VT_UNSIGNED 0x0010 /* unsigned type */ 2544 #define VT_ARRAY 0x0020 /* array type (also has VT_PTR) */ 2545 #define VT_BITFIELD 0x0040 /* bitfield modifier */ 2546 #define VT_CONSTANT 0x0800 /* const modifier */ 2547 #define VT_VOLATILE 0x1000 /* volatile modifier */ 2548 #define VT_SIGNED 0x2000 /* signed type */ 2549 2550 /* storage */ 2551 #define VT_EXTERN 0x00000080 /* extern definition */ 2552 #define VT_STATIC 0x00000100 /* static variable */ 2553 #define VT_TYPEDEF 0x00000200 /* typedef definition */ 2554 #define VT_INLINE 0x00000400 /* inline definition */ 2555 2556 #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ 2557 2558 /* type mask (except storage) */ 2559 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) 2560 #define VT_TYPE (~(VT_STORAGE)) 2561 2562 /* token values */ 2563 2564 /* warning: the following compare tokens depend on i386 asm code */ 2565 #define TOK_ULT 0x92 2566 #define TOK_UGE 0x93 2567 #define TOK_EQ 0x94 2568 #define TOK_NE 0x95 2569 #define TOK_ULE 0x96 2570 #define TOK_UGT 0x97 2571 #define TOK_LT 0x9c 2572 #define TOK_GE 0x9d 2573 #define TOK_LE 0x9e 2574 #define TOK_GT 0x9f 2575 2576 #define TOK_LAND 0xa0 2577 #define TOK_LOR 0xa1 2578 2579 #define TOK_DEC 0xa2 2580 #define TOK_MID 0xa3 /* inc/dec, to void constant */ 2581 #define TOK_INC 0xa4 2582 #define TOK_UDIV 0xb0 /* unsigned division */ 2583 #define TOK_UMOD 0xb1 /* unsigned modulo */ 2584 #define TOK_PDIV 0xb2 /* fast division with undefined rounding for pointers */ 2585 #define TOK_CINT 0xb3 /* number in tokc */ 2586 #define TOK_CCHAR 0xb4 /* char constant in tokc */ 2587 #define TOK_STR 0xb5 /* pointer to string in tokc */ 2588 #define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */ 2589 #define TOK_LCHAR 0xb7 2590 #define TOK_LSTR 0xb8 2591 #define TOK_CFLOAT 0xb9 /* float constant */ 2592 #define TOK_LINENUM 0xba /* line number info */ 2593 #define TOK_CDOUBLE 0xc0 /* double constant */ 2594 #define TOK_CLDOUBLE 0xc1 /* long double constant */ 2595 #define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */ 2596 #define TOK_ADDC1 0xc3 /* add with carry generation */ 2597 #define TOK_ADDC2 0xc4 /* add with carry use */ 2598 #define TOK_SUBC1 0xc5 /* add with carry generation */ 2599 #define TOK_SUBC2 0xc6 /* add with carry use */ 2600 #define TOK_CUINT 0xc8 /* unsigned int constant */ 2601 #define TOK_CLLONG 0xc9 /* long long constant */ 2602 #define TOK_CULLONG 0xca /* unsigned long long constant */ 2603 #define TOK_ARROW 0xcb 2604 #define TOK_DOTS 0xcc /* three dots */ 2605 #define TOK_SHR 0xcd /* unsigned shift right */ 2606 #define TOK_PPNUM 0xce /* preprocessor number */ 2607 2608 #define TOK_SHL 0x01 /* shift left */ 2609 #define TOK_SAR 0x02 /* signed shift right */ 2610 2611 /* assignement operators : normal operator or 0x80 */ 2612 #define TOK_A_MOD 0xa5 2613 #define TOK_A_AND 0xa6 2614 #define TOK_A_MUL 0xaa 2615 #define TOK_A_ADD 0xab 2616 #define TOK_A_SUB 0xad 2617 #define TOK_A_DIV 0xaf 2618 #define TOK_A_XOR 0xde 2619 #define TOK_A_OR 0xfc 2620 #define TOK_A_SHL 0x81 2621 #define TOK_A_SAR 0x82 2622 2623 #ifndef offsetof 2624 #define offsetof(type, field) ((size_t) &((type *)0)->field) 2625 #endif 2626 2627 #ifndef countof 2628 #define countof(tab) (sizeof(tab) / sizeof((tab)[0])) 2629 #endif 2630 2631 /* WARNING: the content of this string encodes token numbers */ 2632 static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266"; 2633 2634 #define TOK_EOF (-1) /* end of file */ 2635 #define TOK_LINEFEED 10 /* line feed */ 2636 2637 /* all identificators and strings have token above that */ 2638 #define TOK_IDENT 256 2639 2640 /* only used for i386 asm opcodes definitions */ 2641 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x) 2642 2643 #define DEF_BWL(x) \ 2644 DEF(TOK_ASM_ ## x ## b, #x "b") \ 2645 DEF(TOK_ASM_ ## x ## w, #x "w") \ 2646 DEF(TOK_ASM_ ## x ## l, #x "l") \ 2647 DEF(TOK_ASM_ ## x, #x) 2648 2649 #define DEF_WL(x) \ 2650 DEF(TOK_ASM_ ## x ## w, #x "w") \ 2651 DEF(TOK_ASM_ ## x ## l, #x "l") \ 2652 DEF(TOK_ASM_ ## x, #x) 2653 2654 #define DEF_FP1(x) \ 2655 DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \ 2656 DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \ 2657 DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \ 2658 DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s") 2659 2660 #define DEF_FP(x) \ 2661 DEF(TOK_ASM_ ## f ## x, "f" #x ) \ 2662 DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \ 2663 DEF_FP1(x) 2664 2665 #define DEF_ASMTEST(x) \ 2666 DEF_ASM(x ## o) \ 2667 DEF_ASM(x ## no) \ 2668 DEF_ASM(x ## b) \ 2669 DEF_ASM(x ## c) \ 2670 DEF_ASM(x ## nae) \ 2671 DEF_ASM(x ## nb) \ 2672 DEF_ASM(x ## nc) \ 2673 DEF_ASM(x ## ae) \ 2674 DEF_ASM(x ## e) \ 2675 DEF_ASM(x ## z) \ 2676 DEF_ASM(x ## ne) \ 2677 DEF_ASM(x ## nz) \ 2678 DEF_ASM(x ## be) \ 2679 DEF_ASM(x ## na) \ 2680 DEF_ASM(x ## nbe) \ 2681 DEF_ASM(x ## a) \ 2682 DEF_ASM(x ## s) \ 2683 DEF_ASM(x ## ns) \ 2684 DEF_ASM(x ## p) \ 2685 DEF_ASM(x ## pe) \ 2686 DEF_ASM(x ## np) \ 2687 DEF_ASM(x ## po) \ 2688 DEF_ASM(x ## l) \ 2689 DEF_ASM(x ## nge) \ 2690 DEF_ASM(x ## nl) \ 2691 DEF_ASM(x ## ge) \ 2692 DEF_ASM(x ## le) \ 2693 DEF_ASM(x ## ng) \ 2694 DEF_ASM(x ## nle) \ 2695 DEF_ASM(x ## g) 2696 2697 #define TOK_ASM_int TOK_INT 2698 2699 enum tcc_token { 2700 TOK_LAST = TOK_IDENT - 1, 2701 #define DEF(id, str) id, 2702 // njn: inlined tcctok.h 2703 //#include "tcctok.h" 2704 //--------------------------------------------------------------------------- 2705 /* keywords */ 2706 DEF(TOK_INT, "int") 2707 DEF(TOK_VOID, "void") 2708 DEF(TOK_CHAR, "char") 2709 DEF(TOK_IF, "if") 2710 DEF(TOK_ELSE, "else") 2711 DEF(TOK_WHILE, "while") 2712 DEF(TOK_BREAK, "break") 2713 DEF(TOK_RETURN, "return") 2714 DEF(TOK_FOR, "for") 2715 DEF(TOK_EXTERN, "extern") 2716 DEF(TOK_STATIC, "static") 2717 DEF(TOK_UNSIGNED, "unsigned") 2718 DEF(TOK_GOTO, "goto") 2719 DEF(TOK_DO, "do") 2720 DEF(TOK_CONTINUE, "continue") 2721 DEF(TOK_SWITCH, "switch") 2722 DEF(TOK_CASE, "case") 2723 2724 DEF(TOK_CONST1, "const") 2725 DEF(TOK_CONST2, "__const") /* gcc keyword */ 2726 DEF(TOK_CONST3, "__const__") /* gcc keyword */ 2727 DEF(TOK_VOLATILE1, "volatile") 2728 DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */ 2729 DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */ 2730 DEF(TOK_LONG, "long") 2731 DEF(TOK_REGISTER, "register") 2732 DEF(TOK_SIGNED1, "signed") 2733 DEF(TOK_SIGNED2, "__signed") /* gcc keyword */ 2734 DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */ 2735 DEF(TOK_AUTO, "auto") 2736 DEF(TOK_INLINE1, "inline") 2737 DEF(TOK_INLINE2, "__inline") /* gcc keyword */ 2738 DEF(TOK_INLINE3, "__inline__") /* gcc keyword */ 2739 DEF(TOK_RESTRICT1, "restrict") 2740 DEF(TOK_RESTRICT2, "__restrict") 2741 DEF(TOK_RESTRICT3, "__restrict__") 2742 DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */ 2743 2744 DEF(TOK_FLOAT, "float") 2745 DEF(TOK_DOUBLE, "double") 2746 DEF(TOK_BOOL, "_Bool") 2747 DEF(TOK_SHORT, "short") 2748 DEF(TOK_STRUCT, "struct") 2749 DEF(TOK_UNION, "union") 2750 DEF(TOK_TYPEDEF, "typedef") 2751 DEF(TOK_DEFAULT, "default") 2752 DEF(TOK_ENUM, "enum") 2753 DEF(TOK_SIZEOF, "sizeof") 2754 DEF(TOK_ATTRIBUTE1, "__attribute") 2755 DEF(TOK_ATTRIBUTE2, "__attribute__") 2756 DEF(TOK_ALIGNOF1, "__alignof") 2757 DEF(TOK_ALIGNOF2, "__alignof__") 2758 DEF(TOK_TYPEOF1, "typeof") 2759 DEF(TOK_TYPEOF2, "__typeof") 2760 DEF(TOK_TYPEOF3, "__typeof__") 2761 DEF(TOK_LABEL, "__label__") 2762 DEF(TOK_ASM1, "asm") 2763 DEF(TOK_ASM2, "__asm") 2764 DEF(TOK_ASM3, "__asm__") 2765 2766 /*********************************************************************/ 2767 /* the following are not keywords. They are included to ease parsing */ 2768 /* preprocessor only */ 2769 DEF(TOK_DEFINE, "define") 2770 DEF(TOK_INCLUDE, "include") 2771 DEF(TOK_INCLUDE_NEXT, "include_next") 2772 DEF(TOK_IFDEF, "ifdef") 2773 DEF(TOK_IFNDEF, "ifndef") 2774 DEF(TOK_ELIF, "elif") 2775 DEF(TOK_ENDIF, "endif") 2776 DEF(TOK_DEFINED, "defined") 2777 DEF(TOK_UNDEF, "undef") 2778 DEF(TOK_ERROR, "error") 2779 DEF(TOK_WARNING, "warning") 2780 DEF(TOK_LINE, "line") 2781 DEF(TOK_PRAGMA, "pragma") 2782 DEF(TOK___LINE__, "__LINE__") 2783 DEF(TOK___FILE__, "__FILE__") 2784 DEF(TOK___DATE__, "__DATE__") 2785 DEF(TOK___TIME__, "__TIME__") 2786 DEF(TOK___FUNCTION__, "__FUNCTION__") 2787 DEF(TOK___VA_ARGS__, "__VA_ARGS__") 2788 2789 /* special identifiers */ 2790 DEF(TOK___FUNC__, "__func__") 2791 2792 /* attribute identifiers */ 2793 /* XXX: handle all tokens generically since speed is not critical */ 2794 DEF(TOK_SECTION1, "section") 2795 DEF(TOK_SECTION2, "__section__") 2796 DEF(TOK_ALIGNED1, "aligned") 2797 DEF(TOK_ALIGNED2, "__aligned__") 2798 DEF(TOK_PACKED1, "packed") 2799 DEF(TOK_PACKED2, "__packed__") 2800 DEF(TOK_UNUSED1, "unused") 2801 DEF(TOK_UNUSED2, "__unused__") 2802 DEF(TOK_CDECL1, "cdecl") 2803 DEF(TOK_CDECL2, "__cdecl") 2804 DEF(TOK_CDECL3, "__cdecl__") 2805 DEF(TOK_STDCALL1, "stdcall") 2806 DEF(TOK_STDCALL2, "__stdcall") 2807 DEF(TOK_STDCALL3, "__stdcall__") 2808 DEF(TOK_DLLEXPORT, "dllexport") 2809 DEF(TOK_NORETURN1, "noreturn") 2810 DEF(TOK_NORETURN2, "__noreturn__") 2811 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") 2812 DEF(TOK_builtin_constant_p, "__builtin_constant_p") 2813 DEF(TOK_REGPARM1, "regparm") 2814 DEF(TOK_REGPARM2, "__regparm__") 2815 2816 /* pragma */ 2817 DEF(TOK_pack, "pack") 2818 #if !defined(TCC_TARGET_I386) 2819 /* already defined for assembler */ 2820 DEF(TOK_ASM_push, "push") 2821 DEF(TOK_ASM_pop, "pop") 2822 #endif 2823 2824 /* builtin functions or variables */ 2825 DEF(TOK_memcpy, "memcpy") 2826 DEF(TOK_memset, "memset") 2827 DEF(TOK_alloca, "alloca") 2828 DEF(TOK___divdi3, "__divdi3") 2829 DEF(TOK___moddi3, "__moddi3") 2830 DEF(TOK___udivdi3, "__udivdi3") 2831 DEF(TOK___umoddi3, "__umoddi3") 2832 #if defined(TCC_TARGET_ARM) 2833 DEF(TOK___divsi3, "__divsi3") 2834 DEF(TOK___modsi3, "__modsi3") 2835 DEF(TOK___udivsi3, "__udivsi3") 2836 DEF(TOK___umodsi3, "__umodsi3") 2837 DEF(TOK___sardi3, "__ashrdi3") 2838 DEF(TOK___shrdi3, "__lshrdi3") 2839 DEF(TOK___shldi3, "__ashldi3") 2840 DEF(TOK___slltold, "__slltold") 2841 DEF(TOK___fixunssfsi, "__fixunssfsi") 2842 DEF(TOK___fixunsdfsi, "__fixunsdfsi") 2843 DEF(TOK___fixunsxfsi, "__fixunsxfsi") 2844 DEF(TOK___fixsfdi, "__fixsfdi") 2845 DEF(TOK___fixdfdi, "__fixdfdi") 2846 DEF(TOK___fixxfdi, "__fixxfdi") 2847 #elif defined(TCC_TARGET_C67) 2848 DEF(TOK__divi, "_divi") 2849 DEF(TOK__divu, "_divu") 2850 DEF(TOK__divf, "_divf") 2851 DEF(TOK__divd, "_divd") 2852 DEF(TOK__remi, "_remi") 2853 DEF(TOK__remu, "_remu") 2854 DEF(TOK___sardi3, "__sardi3") 2855 DEF(TOK___shrdi3, "__shrdi3") 2856 DEF(TOK___shldi3, "__shldi3") 2857 #else 2858 /* XXX: same names on i386 ? */ 2859 DEF(TOK___sardi3, "__sardi3") 2860 DEF(TOK___shrdi3, "__shrdi3") 2861 DEF(TOK___shldi3, "__shldi3") 2862 #endif 2863 DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") 2864 DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") 2865 DEF(TOK___ulltof, "__ulltof") 2866 DEF(TOK___ulltod, "__ulltod") 2867 DEF(TOK___ulltold, "__ulltold") 2868 DEF(TOK___fixunssfdi, "__fixunssfdi") 2869 DEF(TOK___fixunsdfdi, "__fixunsdfdi") 2870 DEF(TOK___fixunsxfdi, "__fixunsxfdi") 2871 DEF(TOK___chkstk, "__chkstk") 2872 2873 /* bound checking symbols */ 2874 #ifdef CONFIG_TCC_BCHECK 2875 DEF(TOK___bound_ptr_add, "__bound_ptr_add") 2876 DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1") 2877 DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2") 2878 DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4") 2879 DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8") 2880 DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12") 2881 DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") 2882 DEF(TOK___bound_local_new, "__bound_local_new") 2883 DEF(TOK___bound_local_delete, "__bound_local_delete") 2884 DEF(TOK_malloc, "malloc") 2885 DEF(TOK_free, "free") 2886 DEF(TOK_realloc, "realloc") 2887 DEF(TOK_memalign, "memalign") 2888 DEF(TOK_calloc, "calloc") 2889 DEF(TOK_memmove, "memmove") 2890 DEF(TOK_strlen, "strlen") 2891 DEF(TOK_strcpy, "strcpy") 2892 #endif 2893 2894 /* Tiny Assembler */ 2895 2896 DEF_ASM(byte) 2897 DEF_ASM(align) 2898 DEF_ASM(skip) 2899 DEF_ASM(space) 2900 DEF_ASM(string) 2901 DEF_ASM(asciz) 2902 DEF_ASM(ascii) 2903 DEF_ASM(globl) 2904 DEF_ASM(global) 2905 DEF_ASM(text) 2906 DEF_ASM(data) 2907 DEF_ASM(bss) 2908 DEF_ASM(previous) 2909 DEF_ASM(fill) 2910 DEF_ASM(org) 2911 DEF_ASM(quad) 2912 2913 #ifdef TCC_TARGET_I386 2914 2915 /* WARNING: relative order of tokens is important. */ 2916 DEF_ASM(al) 2917 DEF_ASM(cl) 2918 DEF_ASM(dl) 2919 DEF_ASM(bl) 2920 DEF_ASM(ah) 2921 DEF_ASM(ch) 2922 DEF_ASM(dh) 2923 DEF_ASM(bh) 2924 DEF_ASM(ax) 2925 DEF_ASM(cx) 2926 DEF_ASM(dx) 2927 DEF_ASM(bx) 2928 DEF_ASM(sp) 2929 DEF_ASM(bp) 2930 DEF_ASM(si) 2931 DEF_ASM(di) 2932 DEF_ASM(eax) 2933 DEF_ASM(ecx) 2934 DEF_ASM(edx) 2935 DEF_ASM(ebx) 2936 DEF_ASM(esp) 2937 DEF_ASM(ebp) 2938 DEF_ASM(esi) 2939 DEF_ASM(edi) 2940 DEF_ASM(mm0) 2941 DEF_ASM(mm1) 2942 DEF_ASM(mm2) 2943 DEF_ASM(mm3) 2944 DEF_ASM(mm4) 2945 DEF_ASM(mm5) 2946 DEF_ASM(mm6) 2947 DEF_ASM(mm7) 2948 DEF_ASM(xmm0) 2949 DEF_ASM(xmm1) 2950 DEF_ASM(xmm2) 2951 DEF_ASM(xmm3) 2952 DEF_ASM(xmm4) 2953 DEF_ASM(xmm5) 2954 DEF_ASM(xmm6) 2955 DEF_ASM(xmm7) 2956 DEF_ASM(cr0) 2957 DEF_ASM(cr1) 2958 DEF_ASM(cr2) 2959 DEF_ASM(cr3) 2960 DEF_ASM(cr4) 2961 DEF_ASM(cr5) 2962 DEF_ASM(cr6) 2963 DEF_ASM(cr7) 2964 DEF_ASM(tr0) 2965 DEF_ASM(tr1) 2966 DEF_ASM(tr2) 2967 DEF_ASM(tr3) 2968 DEF_ASM(tr4) 2969 DEF_ASM(tr5) 2970 DEF_ASM(tr6) 2971 DEF_ASM(tr7) 2972 DEF_ASM(db0) 2973 DEF_ASM(db1) 2974 DEF_ASM(db2) 2975 DEF_ASM(db3) 2976 DEF_ASM(db4) 2977 DEF_ASM(db5) 2978 DEF_ASM(db6) 2979 DEF_ASM(db7) 2980 DEF_ASM(dr0) 2981 DEF_ASM(dr1) 2982 DEF_ASM(dr2) 2983 DEF_ASM(dr3) 2984 DEF_ASM(dr4) 2985 DEF_ASM(dr5) 2986 DEF_ASM(dr6) 2987 DEF_ASM(dr7) 2988 DEF_ASM(es) 2989 DEF_ASM(cs) 2990 DEF_ASM(ss) 2991 DEF_ASM(ds) 2992 DEF_ASM(fs) 2993 DEF_ASM(gs) 2994 DEF_ASM(st) 2995 2996 DEF_BWL(mov) 2997 2998 /* generic two operands */ 2999 DEF_BWL(add) 3000 DEF_BWL(or) 3001 DEF_BWL(adc) 3002 DEF_BWL(sbb) 3003 DEF_BWL(and) 3004 DEF_BWL(sub) 3005 DEF_BWL(xor) 3006 DEF_BWL(cmp) 3007 3008 /* unary ops */ 3009 DEF_BWL(inc) 3010 DEF_BWL(dec) 3011 DEF_BWL(not) 3012 DEF_BWL(neg) 3013 DEF_BWL(mul) 3014 DEF_BWL(imul) 3015 DEF_BWL(div) 3016 DEF_BWL(idiv) 3017 3018 DEF_BWL(xchg) 3019 DEF_BWL(test) 3020 3021 /* shifts */ 3022 DEF_BWL(rol) 3023 DEF_BWL(ror) 3024 DEF_BWL(rcl) 3025 DEF_BWL(rcr) 3026 DEF_BWL(shl) 3027 DEF_BWL(shr) 3028 DEF_BWL(sar) 3029 3030 DEF_ASM(shldw) 3031 DEF_ASM(shldl) 3032 DEF_ASM(shld) 3033 DEF_ASM(shrdw) 3034 DEF_ASM(shrdl) 3035 DEF_ASM(shrd) 3036 3037 DEF_ASM(pushw) 3038 DEF_ASM(pushl) 3039 DEF_ASM(push) 3040 DEF_ASM(popw) 3041 DEF_ASM(popl) 3042 DEF_ASM(pop) 3043 DEF_BWL(in) 3044 DEF_BWL(out) 3045 3046 DEF_WL(movzb) 3047 3048 DEF_ASM(movzwl) 3049 DEF_ASM(movsbw) 3050 DEF_ASM(movsbl) 3051 DEF_ASM(movswl) 3052 3053 DEF_WL(lea) 3054 3055 DEF_ASM(les) 3056 DEF_ASM(lds) 3057 DEF_ASM(lss) 3058 DEF_ASM(lfs) 3059 DEF_ASM(lgs) 3060 3061 DEF_ASM(call) 3062 DEF_ASM(jmp) 3063 DEF_ASM(lcall) 3064 DEF_ASM(ljmp) 3065 3066 DEF_ASMTEST(j) 3067 3068 DEF_ASMTEST(set) 3069 DEF_ASMTEST(cmov) 3070 3071 DEF_WL(bsf) 3072 DEF_WL(bsr) 3073 DEF_WL(bt) 3074 DEF_WL(bts) 3075 DEF_WL(btr) 3076 DEF_WL(btc) 3077 3078 DEF_WL(lsl) 3079 3080 /* generic FP ops */ 3081 DEF_FP(add) 3082 DEF_FP(mul) 3083 3084 DEF_ASM(fcom) 3085 DEF_ASM(fcom_1) /* non existent op, just to have a regular table */ 3086 DEF_FP1(com) 3087 3088 DEF_FP(comp) 3089 DEF_FP(sub) 3090 DEF_FP(subr) 3091 DEF_FP(div) 3092 DEF_FP(divr) 3093 3094 DEF_BWL(xadd) 3095 DEF_BWL(cmpxchg) 3096 3097 /* string ops */ 3098 DEF_BWL(cmps) 3099 DEF_BWL(scmp) 3100 DEF_BWL(ins) 3101 DEF_BWL(outs) 3102 DEF_BWL(lods) 3103 DEF_BWL(slod) 3104 DEF_BWL(movs) 3105 DEF_BWL(smov) 3106 DEF_BWL(scas) 3107 DEF_BWL(ssca) 3108 DEF_BWL(stos) 3109 DEF_BWL(ssto) 3110 3111 /* generic asm ops */ 3112 3113 #define ALT(x) 3114 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name) 3115 #define DEF_ASM_OP0L(name, opcode, group, instr_type) 3116 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) 3117 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) 3118 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) 3119 // njn: inlined i386-asm.h 3120 //#include "i386-asm.h" 3121 //--------------------------------------------------------------------------- 3122 DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ 3123 DEF_ASM_OP0(popa, 0x61) 3124 DEF_ASM_OP0(clc, 0xf8) 3125 DEF_ASM_OP0(cld, 0xfc) 3126 DEF_ASM_OP0(cli, 0xfa) 3127 DEF_ASM_OP0(clts, 0x0f06) 3128 DEF_ASM_OP0(cmc, 0xf5) 3129 DEF_ASM_OP0(lahf, 0x9f) 3130 DEF_ASM_OP0(sahf, 0x9e) 3131 DEF_ASM_OP0(pushfl, 0x9c) 3132 DEF_ASM_OP0(popfl, 0x9d) 3133 DEF_ASM_OP0(pushf, 0x9c) 3134 DEF_ASM_OP0(popf, 0x9d) 3135 DEF_ASM_OP0(stc, 0xf9) 3136 DEF_ASM_OP0(std, 0xfd) 3137 DEF_ASM_OP0(sti, 0xfb) 3138 DEF_ASM_OP0(aaa, 0x37) 3139 DEF_ASM_OP0(aas, 0x3f) 3140 DEF_ASM_OP0(daa, 0x27) 3141 DEF_ASM_OP0(das, 0x2f) 3142 DEF_ASM_OP0(aad, 0xd50a) 3143 DEF_ASM_OP0(aam, 0xd40a) 3144 DEF_ASM_OP0(cbw, 0x6698) 3145 DEF_ASM_OP0(cwd, 0x6699) 3146 DEF_ASM_OP0(cwde, 0x98) 3147 DEF_ASM_OP0(cdq, 0x99) 3148 DEF_ASM_OP0(cbtw, 0x6698) 3149 DEF_ASM_OP0(cwtl, 0x98) 3150 DEF_ASM_OP0(cwtd, 0x6699) 3151 DEF_ASM_OP0(cltd, 0x99) 3152 DEF_ASM_OP0(int3, 0xcc) 3153 DEF_ASM_OP0(into, 0xce) 3154 DEF_ASM_OP0(iret, 0xcf) 3155 DEF_ASM_OP0(rsm, 0x0faa) 3156 DEF_ASM_OP0(hlt, 0xf4) 3157 DEF_ASM_OP0(wait, 0x9b) 3158 DEF_ASM_OP0(nop, 0x90) 3159 DEF_ASM_OP0(xlat, 0xd7) 3160 3161 /* strings */ 3162 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) 3163 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) 3164 3165 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) 3166 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) 3167 3168 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) 3169 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) 3170 3171 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) 3172 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) 3173 3174 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) 3175 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) 3176 3177 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) 3178 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) 3179 3180 /* bits */ 3181 3182 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 3183 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 3184 3185 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3186 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3187 3188 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3189 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3190 3191 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3192 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3193 3194 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3195 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3196 3197 /* prefixes */ 3198 DEF_ASM_OP0(aword, 0x67) 3199 DEF_ASM_OP0(addr16, 0x67) 3200 DEF_ASM_OP0(word, 0x66) 3201 DEF_ASM_OP0(data16, 0x66) 3202 DEF_ASM_OP0(lock, 0xf0) 3203 DEF_ASM_OP0(rep, 0xf3) 3204 DEF_ASM_OP0(repe, 0xf3) 3205 DEF_ASM_OP0(repz, 0xf3) 3206 DEF_ASM_OP0(repne, 0xf2) 3207 DEF_ASM_OP0(repnz, 0xf2) 3208 3209 DEF_ASM_OP0(invd, 0x0f08) 3210 DEF_ASM_OP0(wbinvd, 0x0f09) 3211 DEF_ASM_OP0(cpuid, 0x0fa2) 3212 DEF_ASM_OP0(wrmsr, 0x0f30) 3213 DEF_ASM_OP0(rdtsc, 0x0f31) 3214 DEF_ASM_OP0(rdmsr, 0x0f32) 3215 DEF_ASM_OP0(rdpmc, 0x0f33) 3216 DEF_ASM_OP0(ud2, 0x0f0b) 3217 3218 /* NOTE: we took the same order as gas opcode definition order */ 3219 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) 3220 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) 3221 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 3222 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3223 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) 3224 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) 3225 3226 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) 3227 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) 3228 3229 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) 3230 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) 3231 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) 3232 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) 3233 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) 3234 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) 3235 3236 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) 3237 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) 3238 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 3239 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) 3240 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 3241 3242 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) 3243 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 3244 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) 3245 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) 3246 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) 3247 3248 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) 3249 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 3250 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) 3251 3252 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) 3253 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) 3254 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 3255 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3256 3257 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) 3258 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) 3259 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) 3260 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) 3261 3262 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) 3263 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) 3264 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) 3265 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) 3266 3267 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) 3268 3269 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3270 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3271 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3272 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3273 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3274 3275 /* arith */ 3276 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ 3277 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3278 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) 3279 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 3280 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) 3281 3282 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3283 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 3284 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) 3285 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 3286 3287 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) 3288 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3289 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) 3290 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3291 3292 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3293 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3294 3295 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3296 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3297 3298 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) 3299 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) 3300 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) 3301 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) 3302 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) 3303 3304 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3305 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 3306 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3307 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 3308 3309 /* shifts */ 3310 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) 3311 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) 3312 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) 3313 3314 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 3315 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 3316 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 3317 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 3318 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 3319 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 3320 3321 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) 3322 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) 3323 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) 3324 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) 3325 3326 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 3327 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) 3328 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) 3329 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) 3330 3331 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) 3332 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) 3333 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) 3334 DEF_ASM_OP0(leave, 0xc9) 3335 DEF_ASM_OP0(ret, 0xc3) 3336 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) 3337 DEF_ASM_OP0(lret, 0xcb) 3338 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) 3339 3340 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) 3341 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 3342 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 3343 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 3344 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 3345 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) 3346 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) 3347 3348 /* float */ 3349 /* specific fcomp handling */ 3350 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) 3351 3352 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 3353 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 3354 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) 3355 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 3356 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 3357 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) 3358 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) 3359 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3360 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3361 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3362 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3363 3364 DEF_ASM_OP0(fucompp, 0xdae9) 3365 DEF_ASM_OP0(ftst, 0xd9e4) 3366 DEF_ASM_OP0(fxam, 0xd9e5) 3367 DEF_ASM_OP0(fld1, 0xd9e8) 3368 DEF_ASM_OP0(fldl2t, 0xd9e9) 3369 DEF_ASM_OP0(fldl2e, 0xd9ea) 3370 DEF_ASM_OP0(fldpi, 0xd9eb) 3371 DEF_ASM_OP0(fldlg2, 0xd9ec) 3372 DEF_ASM_OP0(fldln2, 0xd9ed) 3373 DEF_ASM_OP0(fldz, 0xd9ee) 3374 3375 DEF_ASM_OP0(f2xm1, 0xd9f0) 3376 DEF_ASM_OP0(fyl2x, 0xd9f1) 3377 DEF_ASM_OP0(fptan, 0xd9f2) 3378 DEF_ASM_OP0(fpatan, 0xd9f3) 3379 DEF_ASM_OP0(fxtract, 0xd9f4) 3380 DEF_ASM_OP0(fprem1, 0xd9f5) 3381 DEF_ASM_OP0(fdecstp, 0xd9f6) 3382 DEF_ASM_OP0(fincstp, 0xd9f7) 3383 DEF_ASM_OP0(fprem, 0xd9f8) 3384 DEF_ASM_OP0(fyl2xp1, 0xd9f9) 3385 DEF_ASM_OP0(fsqrt, 0xd9fa) 3386 DEF_ASM_OP0(fsincos, 0xd9fb) 3387 DEF_ASM_OP0(frndint, 0xd9fc) 3388 DEF_ASM_OP0(fscale, 0xd9fd) 3389 DEF_ASM_OP0(fsin, 0xd9fe) 3390 DEF_ASM_OP0(fcos, 0xd9ff) 3391 DEF_ASM_OP0(fchs, 0xd9e0) 3392 DEF_ASM_OP0(fabs, 0xd9e1) 3393 DEF_ASM_OP0(fninit, 0xdbe3) 3394 DEF_ASM_OP0(fnclex, 0xdbe2) 3395 DEF_ASM_OP0(fnop, 0xd9d0) 3396 DEF_ASM_OP0(fwait, 0x9b) 3397 3398 /* fp load */ 3399 DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) 3400 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) 3401 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) 3402 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) 3403 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) 3404 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) 3405 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) 3406 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) 3407 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) 3408 3409 /* fp store */ 3410 DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) 3411 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) 3412 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) 3413 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) 3414 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) 3415 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) 3416 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) 3417 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) 3418 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) 3419 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) 3420 3421 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) 3422 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) 3423 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) 3424 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) 3425 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) 3426 3427 /* exchange */ 3428 DEF_ASM_OP0(fxch, 0xd9c9) 3429 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) 3430 3431 /* misc FPU */ 3432 DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) 3433 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) 3434 3435 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) 3436 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) 3437 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) 3438 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) 3439 DEF_ASM_OP0(fnstsw, 0xdfe0) 3440 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) 3441 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) 3442 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) 3443 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) 3444 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) 3445 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) 3446 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) 3447 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 3448 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) 3449 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) 3450 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 3451 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) 3452 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) 3453 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) 3454 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) 3455 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) 3456 3457 /* segments */ 3458 DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) 3459 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) 3460 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) 3461 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) 3462 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) 3463 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) 3464 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) 3465 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) 3466 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) 3467 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) 3468 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) 3469 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) 3470 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) 3471 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) 3472 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) 3473 3474 /* 486 */ 3475 DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) 3476 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 3477 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 3478 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) 3479 3480 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) 3481 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) 3482 3483 /* pentium */ 3484 DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) 3485 3486 /* pentium pro */ 3487 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) 3488 3489 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3490 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3491 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3492 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3493 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3494 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3495 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3496 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3497 3498 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3499 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3500 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3501 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3502 3503 /* mmx */ 3504 DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ 3505 DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) 3506 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) 3507 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3508 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) 3509 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3510 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3511 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3512 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3513 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3514 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3515 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3516 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3517 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3518 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3519 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3520 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3521 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3522 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3523 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3524 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3525 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3526 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3527 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3528 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3529 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3530 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3531 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3532 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 3533 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3534 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 3535 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3536 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 3537 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3538 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 3539 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3540 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 3541 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3542 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 3543 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3544 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 3545 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3546 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 3547 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3548 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3549 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3550 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3551 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3552 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3553 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3554 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3555 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3556 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3557 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3558 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3559 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3560 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3561 3562 #undef ALT 3563 #undef DEF_ASM_OP0 3564 #undef DEF_ASM_OP0L 3565 #undef DEF_ASM_OP1 3566 #undef DEF_ASM_OP2 3567 #undef DEF_ASM_OP3 3568 //--------------------------------------------------------------------------- 3569 3570 #define ALT(x) 3571 #define DEF_ASM_OP0(name, opcode) 3572 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name) 3573 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name) 3574 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name) 3575 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name) 3576 // njn: inlined i386-asm.h 3577 //#include "i386-asm.h" 3578 //--------------------------------------------------------------------------- 3579 DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ 3580 DEF_ASM_OP0(popa, 0x61) 3581 DEF_ASM_OP0(clc, 0xf8) 3582 DEF_ASM_OP0(cld, 0xfc) 3583 DEF_ASM_OP0(cli, 0xfa) 3584 DEF_ASM_OP0(clts, 0x0f06) 3585 DEF_ASM_OP0(cmc, 0xf5) 3586 DEF_ASM_OP0(lahf, 0x9f) 3587 DEF_ASM_OP0(sahf, 0x9e) 3588 DEF_ASM_OP0(pushfl, 0x9c) 3589 DEF_ASM_OP0(popfl, 0x9d) 3590 DEF_ASM_OP0(pushf, 0x9c) 3591 DEF_ASM_OP0(popf, 0x9d) 3592 DEF_ASM_OP0(stc, 0xf9) 3593 DEF_ASM_OP0(std, 0xfd) 3594 DEF_ASM_OP0(sti, 0xfb) 3595 DEF_ASM_OP0(aaa, 0x37) 3596 DEF_ASM_OP0(aas, 0x3f) 3597 DEF_ASM_OP0(daa, 0x27) 3598 DEF_ASM_OP0(das, 0x2f) 3599 DEF_ASM_OP0(aad, 0xd50a) 3600 DEF_ASM_OP0(aam, 0xd40a) 3601 DEF_ASM_OP0(cbw, 0x6698) 3602 DEF_ASM_OP0(cwd, 0x6699) 3603 DEF_ASM_OP0(cwde, 0x98) 3604 DEF_ASM_OP0(cdq, 0x99) 3605 DEF_ASM_OP0(cbtw, 0x6698) 3606 DEF_ASM_OP0(cwtl, 0x98) 3607 DEF_ASM_OP0(cwtd, 0x6699) 3608 DEF_ASM_OP0(cltd, 0x99) 3609 DEF_ASM_OP0(int3, 0xcc) 3610 DEF_ASM_OP0(into, 0xce) 3611 DEF_ASM_OP0(iret, 0xcf) 3612 DEF_ASM_OP0(rsm, 0x0faa) 3613 DEF_ASM_OP0(hlt, 0xf4) 3614 DEF_ASM_OP0(wait, 0x9b) 3615 DEF_ASM_OP0(nop, 0x90) 3616 DEF_ASM_OP0(xlat, 0xd7) 3617 3618 /* strings */ 3619 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) 3620 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) 3621 3622 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) 3623 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) 3624 3625 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) 3626 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) 3627 3628 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) 3629 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) 3630 3631 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) 3632 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) 3633 3634 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) 3635 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) 3636 3637 /* bits */ 3638 3639 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 3640 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 3641 3642 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3643 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3644 3645 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3646 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3647 3648 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3649 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3650 3651 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 3652 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 3653 3654 /* prefixes */ 3655 DEF_ASM_OP0(aword, 0x67) 3656 DEF_ASM_OP0(addr16, 0x67) 3657 DEF_ASM_OP0(word, 0x66) 3658 DEF_ASM_OP0(data16, 0x66) 3659 DEF_ASM_OP0(lock, 0xf0) 3660 DEF_ASM_OP0(rep, 0xf3) 3661 DEF_ASM_OP0(repe, 0xf3) 3662 DEF_ASM_OP0(repz, 0xf3) 3663 DEF_ASM_OP0(repne, 0xf2) 3664 DEF_ASM_OP0(repnz, 0xf2) 3665 3666 DEF_ASM_OP0(invd, 0x0f08) 3667 DEF_ASM_OP0(wbinvd, 0x0f09) 3668 DEF_ASM_OP0(cpuid, 0x0fa2) 3669 DEF_ASM_OP0(wrmsr, 0x0f30) 3670 DEF_ASM_OP0(rdtsc, 0x0f31) 3671 DEF_ASM_OP0(rdmsr, 0x0f32) 3672 DEF_ASM_OP0(rdpmc, 0x0f33) 3673 DEF_ASM_OP0(ud2, 0x0f0b) 3674 3675 /* NOTE: we took the same order as gas opcode definition order */ 3676 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) 3677 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) 3678 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 3679 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3680 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) 3681 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) 3682 3683 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) 3684 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) 3685 3686 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) 3687 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) 3688 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) 3689 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) 3690 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) 3691 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) 3692 3693 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) 3694 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) 3695 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 3696 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) 3697 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 3698 3699 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) 3700 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 3701 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) 3702 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) 3703 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) 3704 3705 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) 3706 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 3707 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) 3708 3709 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) 3710 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) 3711 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 3712 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3713 3714 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) 3715 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) 3716 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) 3717 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) 3718 3719 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) 3720 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) 3721 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) 3722 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) 3723 3724 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) 3725 3726 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3727 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3728 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3729 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3730 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 3731 3732 /* arith */ 3733 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ 3734 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3735 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) 3736 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 3737 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) 3738 3739 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 3740 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 3741 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) 3742 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 3743 3744 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) 3745 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3746 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) 3747 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3748 3749 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3750 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3751 3752 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3753 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3754 3755 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) 3756 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) 3757 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) 3758 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) 3759 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) 3760 3761 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3762 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 3763 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 3764 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 3765 3766 /* shifts */ 3767 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) 3768 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) 3769 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) 3770 3771 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 3772 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 3773 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 3774 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 3775 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 3776 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 3777 3778 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) 3779 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) 3780 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) 3781 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) 3782 3783 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 3784 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) 3785 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) 3786 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) 3787 3788 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) 3789 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) 3790 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) 3791 DEF_ASM_OP0(leave, 0xc9) 3792 DEF_ASM_OP0(ret, 0xc3) 3793 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) 3794 DEF_ASM_OP0(lret, 0xcb) 3795 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) 3796 3797 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) 3798 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 3799 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 3800 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 3801 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 3802 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) 3803 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) 3804 3805 /* float */ 3806 /* specific fcomp handling */ 3807 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) 3808 3809 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 3810 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 3811 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) 3812 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 3813 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 3814 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) 3815 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) 3816 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3817 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3818 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3819 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 3820 3821 DEF_ASM_OP0(fucompp, 0xdae9) 3822 DEF_ASM_OP0(ftst, 0xd9e4) 3823 DEF_ASM_OP0(fxam, 0xd9e5) 3824 DEF_ASM_OP0(fld1, 0xd9e8) 3825 DEF_ASM_OP0(fldl2t, 0xd9e9) 3826 DEF_ASM_OP0(fldl2e, 0xd9ea) 3827 DEF_ASM_OP0(fldpi, 0xd9eb) 3828 DEF_ASM_OP0(fldlg2, 0xd9ec) 3829 DEF_ASM_OP0(fldln2, 0xd9ed) 3830 DEF_ASM_OP0(fldz, 0xd9ee) 3831 3832 DEF_ASM_OP0(f2xm1, 0xd9f0) 3833 DEF_ASM_OP0(fyl2x, 0xd9f1) 3834 DEF_ASM_OP0(fptan, 0xd9f2) 3835 DEF_ASM_OP0(fpatan, 0xd9f3) 3836 DEF_ASM_OP0(fxtract, 0xd9f4) 3837 DEF_ASM_OP0(fprem1, 0xd9f5) 3838 DEF_ASM_OP0(fdecstp, 0xd9f6) 3839 DEF_ASM_OP0(fincstp, 0xd9f7) 3840 DEF_ASM_OP0(fprem, 0xd9f8) 3841 DEF_ASM_OP0(fyl2xp1, 0xd9f9) 3842 DEF_ASM_OP0(fsqrt, 0xd9fa) 3843 DEF_ASM_OP0(fsincos, 0xd9fb) 3844 DEF_ASM_OP0(frndint, 0xd9fc) 3845 DEF_ASM_OP0(fscale, 0xd9fd) 3846 DEF_ASM_OP0(fsin, 0xd9fe) 3847 DEF_ASM_OP0(fcos, 0xd9ff) 3848 DEF_ASM_OP0(fchs, 0xd9e0) 3849 DEF_ASM_OP0(fabs, 0xd9e1) 3850 DEF_ASM_OP0(fninit, 0xdbe3) 3851 DEF_ASM_OP0(fnclex, 0xdbe2) 3852 DEF_ASM_OP0(fnop, 0xd9d0) 3853 DEF_ASM_OP0(fwait, 0x9b) 3854 3855 /* fp load */ 3856 DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) 3857 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) 3858 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) 3859 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) 3860 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) 3861 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) 3862 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) 3863 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) 3864 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) 3865 3866 /* fp store */ 3867 DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) 3868 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) 3869 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) 3870 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) 3871 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) 3872 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) 3873 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) 3874 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) 3875 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) 3876 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) 3877 3878 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) 3879 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) 3880 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) 3881 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) 3882 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) 3883 3884 /* exchange */ 3885 DEF_ASM_OP0(fxch, 0xd9c9) 3886 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) 3887 3888 /* misc FPU */ 3889 DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) 3890 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) 3891 3892 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) 3893 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) 3894 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) 3895 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) 3896 DEF_ASM_OP0(fnstsw, 0xdfe0) 3897 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) 3898 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) 3899 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) 3900 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) 3901 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) 3902 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) 3903 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) 3904 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 3905 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) 3906 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) 3907 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 3908 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) 3909 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) 3910 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) 3911 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) 3912 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) 3913 3914 /* segments */ 3915 DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) 3916 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) 3917 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) 3918 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) 3919 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) 3920 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) 3921 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) 3922 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) 3923 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) 3924 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) 3925 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) 3926 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) 3927 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) 3928 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) 3929 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) 3930 3931 /* 486 */ 3932 DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) 3933 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 3934 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 3935 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) 3936 3937 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) 3938 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) 3939 3940 /* pentium */ 3941 DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) 3942 3943 /* pentium pro */ 3944 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) 3945 3946 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3947 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3948 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3949 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3950 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3951 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3952 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3953 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3954 3955 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3956 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3957 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3958 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 3959 3960 /* mmx */ 3961 DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ 3962 DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) 3963 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) 3964 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3965 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) 3966 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3967 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3968 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3969 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3970 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3971 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3972 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3973 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3974 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3975 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3976 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3977 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3978 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3979 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3980 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3981 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3982 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3983 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3984 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3985 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3986 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3987 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3988 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3989 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 3990 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3991 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 3992 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3993 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 3994 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3995 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 3996 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3997 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 3998 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 3999 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 4000 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4001 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 4002 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4003 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 4004 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4005 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4006 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4007 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4008 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4009 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4010 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4011 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4012 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4013 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4014 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4015 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4016 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4017 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4018 4019 #undef ALT 4020 #undef DEF_ASM_OP0 4021 #undef DEF_ASM_OP0L 4022 #undef DEF_ASM_OP1 4023 #undef DEF_ASM_OP2 4024 #undef DEF_ASM_OP3 4025 //--------------------------------------------------------------------------- 4026 4027 #endif 4028 //--------------------------------------------------------------------------- 4029 #undef DEF 4030 }; 4031 4032 static const char tcc_keywords[] = 4033 #define DEF(id, str) str "\0" 4034 // njn: inlined tcctok.h 4035 //#include "tcctok.h" 4036 //--------------------------------------------------------------------------- 4037 /* keywords */ 4038 DEF(TOK_INT, "int") 4039 DEF(TOK_VOID, "void") 4040 DEF(TOK_CHAR, "char") 4041 DEF(TOK_IF, "if") 4042 DEF(TOK_ELSE, "else") 4043 DEF(TOK_WHILE, "while") 4044 DEF(TOK_BREAK, "break") 4045 DEF(TOK_RETURN, "return") 4046 DEF(TOK_FOR, "for") 4047 DEF(TOK_EXTERN, "extern") 4048 DEF(TOK_STATIC, "static") 4049 DEF(TOK_UNSIGNED, "unsigned") 4050 DEF(TOK_GOTO, "goto") 4051 DEF(TOK_DO, "do") 4052 DEF(TOK_CONTINUE, "continue") 4053 DEF(TOK_SWITCH, "switch") 4054 DEF(TOK_CASE, "case") 4055 4056 DEF(TOK_CONST1, "const") 4057 DEF(TOK_CONST2, "__const") /* gcc keyword */ 4058 DEF(TOK_CONST3, "__const__") /* gcc keyword */ 4059 DEF(TOK_VOLATILE1, "volatile") 4060 DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */ 4061 DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */ 4062 DEF(TOK_LONG, "long") 4063 DEF(TOK_REGISTER, "register") 4064 DEF(TOK_SIGNED1, "signed") 4065 DEF(TOK_SIGNED2, "__signed") /* gcc keyword */ 4066 DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */ 4067 DEF(TOK_AUTO, "auto") 4068 DEF(TOK_INLINE1, "inline") 4069 DEF(TOK_INLINE2, "__inline") /* gcc keyword */ 4070 DEF(TOK_INLINE3, "__inline__") /* gcc keyword */ 4071 DEF(TOK_RESTRICT1, "restrict") 4072 DEF(TOK_RESTRICT2, "__restrict") 4073 DEF(TOK_RESTRICT3, "__restrict__") 4074 DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */ 4075 4076 DEF(TOK_FLOAT, "float") 4077 DEF(TOK_DOUBLE, "double") 4078 DEF(TOK_BOOL, "_Bool") 4079 DEF(TOK_SHORT, "short") 4080 DEF(TOK_STRUCT, "struct") 4081 DEF(TOK_UNION, "union") 4082 DEF(TOK_TYPEDEF, "typedef") 4083 DEF(TOK_DEFAULT, "default") 4084 DEF(TOK_ENUM, "enum") 4085 DEF(TOK_SIZEOF, "sizeof") 4086 DEF(TOK_ATTRIBUTE1, "__attribute") 4087 DEF(TOK_ATTRIBUTE2, "__attribute__") 4088 DEF(TOK_ALIGNOF1, "__alignof") 4089 DEF(TOK_ALIGNOF2, "__alignof__") 4090 DEF(TOK_TYPEOF1, "typeof") 4091 DEF(TOK_TYPEOF2, "__typeof") 4092 DEF(TOK_TYPEOF3, "__typeof__") 4093 DEF(TOK_LABEL, "__label__") 4094 DEF(TOK_ASM1, "asm") 4095 DEF(TOK_ASM2, "__asm") 4096 DEF(TOK_ASM3, "__asm__") 4097 4098 /*********************************************************************/ 4099 /* the following are not keywords. They are included to ease parsing */ 4100 /* preprocessor only */ 4101 DEF(TOK_DEFINE, "define") 4102 DEF(TOK_INCLUDE, "include") 4103 DEF(TOK_INCLUDE_NEXT, "include_next") 4104 DEF(TOK_IFDEF, "ifdef") 4105 DEF(TOK_IFNDEF, "ifndef") 4106 DEF(TOK_ELIF, "elif") 4107 DEF(TOK_ENDIF, "endif") 4108 DEF(TOK_DEFINED, "defined") 4109 DEF(TOK_UNDEF, "undef") 4110 DEF(TOK_ERROR, "error") 4111 DEF(TOK_WARNING, "warning") 4112 DEF(TOK_LINE, "line") 4113 DEF(TOK_PRAGMA, "pragma") 4114 DEF(TOK___LINE__, "__LINE__") 4115 DEF(TOK___FILE__, "__FILE__") 4116 DEF(TOK___DATE__, "__DATE__") 4117 DEF(TOK___TIME__, "__TIME__") 4118 DEF(TOK___FUNCTION__, "__FUNCTION__") 4119 DEF(TOK___VA_ARGS__, "__VA_ARGS__") 4120 4121 /* special identifiers */ 4122 DEF(TOK___FUNC__, "__func__") 4123 4124 /* attribute identifiers */ 4125 /* XXX: handle all tokens generically since speed is not critical */ 4126 DEF(TOK_SECTION1, "section") 4127 DEF(TOK_SECTION2, "__section__") 4128 DEF(TOK_ALIGNED1, "aligned") 4129 DEF(TOK_ALIGNED2, "__aligned__") 4130 DEF(TOK_PACKED1, "packed") 4131 DEF(TOK_PACKED2, "__packed__") 4132 DEF(TOK_UNUSED1, "unused") 4133 DEF(TOK_UNUSED2, "__unused__") 4134 DEF(TOK_CDECL1, "cdecl") 4135 DEF(TOK_CDECL2, "__cdecl") 4136 DEF(TOK_CDECL3, "__cdecl__") 4137 DEF(TOK_STDCALL1, "stdcall") 4138 DEF(TOK_STDCALL2, "__stdcall") 4139 DEF(TOK_STDCALL3, "__stdcall__") 4140 DEF(TOK_DLLEXPORT, "dllexport") 4141 DEF(TOK_NORETURN1, "noreturn") 4142 DEF(TOK_NORETURN2, "__noreturn__") 4143 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") 4144 DEF(TOK_builtin_constant_p, "__builtin_constant_p") 4145 DEF(TOK_REGPARM1, "regparm") 4146 DEF(TOK_REGPARM2, "__regparm__") 4147 4148 /* pragma */ 4149 DEF(TOK_pack, "pack") 4150 #if !defined(TCC_TARGET_I386) 4151 /* already defined for assembler */ 4152 DEF(TOK_ASM_push, "push") 4153 DEF(TOK_ASM_pop, "pop") 4154 #endif 4155 4156 /* builtin functions or variables */ 4157 DEF(TOK_memcpy, "memcpy") 4158 DEF(TOK_memset, "memset") 4159 DEF(TOK_alloca, "alloca") 4160 DEF(TOK___divdi3, "__divdi3") 4161 DEF(TOK___moddi3, "__moddi3") 4162 DEF(TOK___udivdi3, "__udivdi3") 4163 DEF(TOK___umoddi3, "__umoddi3") 4164 #if defined(TCC_TARGET_ARM) 4165 DEF(TOK___divsi3, "__divsi3") 4166 DEF(TOK___modsi3, "__modsi3") 4167 DEF(TOK___udivsi3, "__udivsi3") 4168 DEF(TOK___umodsi3, "__umodsi3") 4169 DEF(TOK___sardi3, "__ashrdi3") 4170 DEF(TOK___shrdi3, "__lshrdi3") 4171 DEF(TOK___shldi3, "__ashldi3") 4172 DEF(TOK___slltold, "__slltold") 4173 DEF(TOK___fixunssfsi, "__fixunssfsi") 4174 DEF(TOK___fixunsdfsi, "__fixunsdfsi") 4175 DEF(TOK___fixunsxfsi, "__fixunsxfsi") 4176 DEF(TOK___fixsfdi, "__fixsfdi") 4177 DEF(TOK___fixdfdi, "__fixdfdi") 4178 DEF(TOK___fixxfdi, "__fixxfdi") 4179 #elif defined(TCC_TARGET_C67) 4180 DEF(TOK__divi, "_divi") 4181 DEF(TOK__divu, "_divu") 4182 DEF(TOK__divf, "_divf") 4183 DEF(TOK__divd, "_divd") 4184 DEF(TOK__remi, "_remi") 4185 DEF(TOK__remu, "_remu") 4186 DEF(TOK___sardi3, "__sardi3") 4187 DEF(TOK___shrdi3, "__shrdi3") 4188 DEF(TOK___shldi3, "__shldi3") 4189 #else 4190 /* XXX: same names on i386 ? */ 4191 DEF(TOK___sardi3, "__sardi3") 4192 DEF(TOK___shrdi3, "__shrdi3") 4193 DEF(TOK___shldi3, "__shldi3") 4194 #endif 4195 DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") 4196 DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") 4197 DEF(TOK___ulltof, "__ulltof") 4198 DEF(TOK___ulltod, "__ulltod") 4199 DEF(TOK___ulltold, "__ulltold") 4200 DEF(TOK___fixunssfdi, "__fixunssfdi") 4201 DEF(TOK___fixunsdfdi, "__fixunsdfdi") 4202 DEF(TOK___fixunsxfdi, "__fixunsxfdi") 4203 DEF(TOK___chkstk, "__chkstk") 4204 4205 /* bound checking symbols */ 4206 #ifdef CONFIG_TCC_BCHECK 4207 DEF(TOK___bound_ptr_add, "__bound_ptr_add") 4208 DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1") 4209 DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2") 4210 DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4") 4211 DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8") 4212 DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12") 4213 DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") 4214 DEF(TOK___bound_local_new, "__bound_local_new") 4215 DEF(TOK___bound_local_delete, "__bound_local_delete") 4216 DEF(TOK_malloc, "malloc") 4217 DEF(TOK_free, "free") 4218 DEF(TOK_realloc, "realloc") 4219 DEF(TOK_memalign, "memalign") 4220 DEF(TOK_calloc, "calloc") 4221 DEF(TOK_memmove, "memmove") 4222 DEF(TOK_strlen, "strlen") 4223 DEF(TOK_strcpy, "strcpy") 4224 #endif 4225 4226 /* Tiny Assembler */ 4227 4228 DEF_ASM(byte) 4229 DEF_ASM(align) 4230 DEF_ASM(skip) 4231 DEF_ASM(space) 4232 DEF_ASM(string) 4233 DEF_ASM(asciz) 4234 DEF_ASM(ascii) 4235 DEF_ASM(globl) 4236 DEF_ASM(global) 4237 DEF_ASM(text) 4238 DEF_ASM(data) 4239 DEF_ASM(bss) 4240 DEF_ASM(previous) 4241 DEF_ASM(fill) 4242 DEF_ASM(org) 4243 DEF_ASM(quad) 4244 4245 #ifdef TCC_TARGET_I386 4246 4247 /* WARNING: relative order of tokens is important. */ 4248 DEF_ASM(al) 4249 DEF_ASM(cl) 4250 DEF_ASM(dl) 4251 DEF_ASM(bl) 4252 DEF_ASM(ah) 4253 DEF_ASM(ch) 4254 DEF_ASM(dh) 4255 DEF_ASM(bh) 4256 DEF_ASM(ax) 4257 DEF_ASM(cx) 4258 DEF_ASM(dx) 4259 DEF_ASM(bx) 4260 DEF_ASM(sp) 4261 DEF_ASM(bp) 4262 DEF_ASM(si) 4263 DEF_ASM(di) 4264 DEF_ASM(eax) 4265 DEF_ASM(ecx) 4266 DEF_ASM(edx) 4267 DEF_ASM(ebx) 4268 DEF_ASM(esp) 4269 DEF_ASM(ebp) 4270 DEF_ASM(esi) 4271 DEF_ASM(edi) 4272 DEF_ASM(mm0) 4273 DEF_ASM(mm1) 4274 DEF_ASM(mm2) 4275 DEF_ASM(mm3) 4276 DEF_ASM(mm4) 4277 DEF_ASM(mm5) 4278 DEF_ASM(mm6) 4279 DEF_ASM(mm7) 4280 DEF_ASM(xmm0) 4281 DEF_ASM(xmm1) 4282 DEF_ASM(xmm2) 4283 DEF_ASM(xmm3) 4284 DEF_ASM(xmm4) 4285 DEF_ASM(xmm5) 4286 DEF_ASM(xmm6) 4287 DEF_ASM(xmm7) 4288 DEF_ASM(cr0) 4289 DEF_ASM(cr1) 4290 DEF_ASM(cr2) 4291 DEF_ASM(cr3) 4292 DEF_ASM(cr4) 4293 DEF_ASM(cr5) 4294 DEF_ASM(cr6) 4295 DEF_ASM(cr7) 4296 DEF_ASM(tr0) 4297 DEF_ASM(tr1) 4298 DEF_ASM(tr2) 4299 DEF_ASM(tr3) 4300 DEF_ASM(tr4) 4301 DEF_ASM(tr5) 4302 DEF_ASM(tr6) 4303 DEF_ASM(tr7) 4304 DEF_ASM(db0) 4305 DEF_ASM(db1) 4306 DEF_ASM(db2) 4307 DEF_ASM(db3) 4308 DEF_ASM(db4) 4309 DEF_ASM(db5) 4310 DEF_ASM(db6) 4311 DEF_ASM(db7) 4312 DEF_ASM(dr0) 4313 DEF_ASM(dr1) 4314 DEF_ASM(dr2) 4315 DEF_ASM(dr3) 4316 DEF_ASM(dr4) 4317 DEF_ASM(dr5) 4318 DEF_ASM(dr6) 4319 DEF_ASM(dr7) 4320 DEF_ASM(es) 4321 DEF_ASM(cs) 4322 DEF_ASM(ss) 4323 DEF_ASM(ds) 4324 DEF_ASM(fs) 4325 DEF_ASM(gs) 4326 DEF_ASM(st) 4327 4328 DEF_BWL(mov) 4329 4330 /* generic two operands */ 4331 DEF_BWL(add) 4332 DEF_BWL(or) 4333 DEF_BWL(adc) 4334 DEF_BWL(sbb) 4335 DEF_BWL(and) 4336 DEF_BWL(sub) 4337 DEF_BWL(xor) 4338 DEF_BWL(cmp) 4339 4340 /* unary ops */ 4341 DEF_BWL(inc) 4342 DEF_BWL(dec) 4343 DEF_BWL(not) 4344 DEF_BWL(neg) 4345 DEF_BWL(mul) 4346 DEF_BWL(imul) 4347 DEF_BWL(div) 4348 DEF_BWL(idiv) 4349 4350 DEF_BWL(xchg) 4351 DEF_BWL(test) 4352 4353 /* shifts */ 4354 DEF_BWL(rol) 4355 DEF_BWL(ror) 4356 DEF_BWL(rcl) 4357 DEF_BWL(rcr) 4358 DEF_BWL(shl) 4359 DEF_BWL(shr) 4360 DEF_BWL(sar) 4361 4362 DEF_ASM(shldw) 4363 DEF_ASM(shldl) 4364 DEF_ASM(shld) 4365 DEF_ASM(shrdw) 4366 DEF_ASM(shrdl) 4367 DEF_ASM(shrd) 4368 4369 DEF_ASM(pushw) 4370 DEF_ASM(pushl) 4371 DEF_ASM(push) 4372 DEF_ASM(popw) 4373 DEF_ASM(popl) 4374 DEF_ASM(pop) 4375 DEF_BWL(in) 4376 DEF_BWL(out) 4377 4378 DEF_WL(movzb) 4379 4380 DEF_ASM(movzwl) 4381 DEF_ASM(movsbw) 4382 DEF_ASM(movsbl) 4383 DEF_ASM(movswl) 4384 4385 DEF_WL(lea) 4386 4387 DEF_ASM(les) 4388 DEF_ASM(lds) 4389 DEF_ASM(lss) 4390 DEF_ASM(lfs) 4391 DEF_ASM(lgs) 4392 4393 DEF_ASM(call) 4394 DEF_ASM(jmp) 4395 DEF_ASM(lcall) 4396 DEF_ASM(ljmp) 4397 4398 DEF_ASMTEST(j) 4399 4400 DEF_ASMTEST(set) 4401 DEF_ASMTEST(cmov) 4402 4403 DEF_WL(bsf) 4404 DEF_WL(bsr) 4405 DEF_WL(bt) 4406 DEF_WL(bts) 4407 DEF_WL(btr) 4408 DEF_WL(btc) 4409 4410 DEF_WL(lsl) 4411 4412 /* generic FP ops */ 4413 DEF_FP(add) 4414 DEF_FP(mul) 4415 4416 DEF_ASM(fcom) 4417 DEF_ASM(fcom_1) /* non existent op, just to have a regular table */ 4418 DEF_FP1(com) 4419 4420 DEF_FP(comp) 4421 DEF_FP(sub) 4422 DEF_FP(subr) 4423 DEF_FP(div) 4424 DEF_FP(divr) 4425 4426 DEF_BWL(xadd) 4427 DEF_BWL(cmpxchg) 4428 4429 /* string ops */ 4430 DEF_BWL(cmps) 4431 DEF_BWL(scmp) 4432 DEF_BWL(ins) 4433 DEF_BWL(outs) 4434 DEF_BWL(lods) 4435 DEF_BWL(slod) 4436 DEF_BWL(movs) 4437 DEF_BWL(smov) 4438 DEF_BWL(scas) 4439 DEF_BWL(ssca) 4440 DEF_BWL(stos) 4441 DEF_BWL(ssto) 4442 4443 /* generic asm ops */ 4444 4445 #define ALT(x) 4446 #define DEF_ASM_OP0(name, opcode) DEF_ASM(name) 4447 #define DEF_ASM_OP0L(name, opcode, group, instr_type) 4448 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) 4449 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) 4450 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) 4451 // njn: inlined i386-asm.h 4452 //#include "i386-asm.h" 4453 //--------------------------------------------------------------------------- 4454 DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ 4455 DEF_ASM_OP0(popa, 0x61) 4456 DEF_ASM_OP0(clc, 0xf8) 4457 DEF_ASM_OP0(cld, 0xfc) 4458 DEF_ASM_OP0(cli, 0xfa) 4459 DEF_ASM_OP0(clts, 0x0f06) 4460 DEF_ASM_OP0(cmc, 0xf5) 4461 DEF_ASM_OP0(lahf, 0x9f) 4462 DEF_ASM_OP0(sahf, 0x9e) 4463 DEF_ASM_OP0(pushfl, 0x9c) 4464 DEF_ASM_OP0(popfl, 0x9d) 4465 DEF_ASM_OP0(pushf, 0x9c) 4466 DEF_ASM_OP0(popf, 0x9d) 4467 DEF_ASM_OP0(stc, 0xf9) 4468 DEF_ASM_OP0(std, 0xfd) 4469 DEF_ASM_OP0(sti, 0xfb) 4470 DEF_ASM_OP0(aaa, 0x37) 4471 DEF_ASM_OP0(aas, 0x3f) 4472 DEF_ASM_OP0(daa, 0x27) 4473 DEF_ASM_OP0(das, 0x2f) 4474 DEF_ASM_OP0(aad, 0xd50a) 4475 DEF_ASM_OP0(aam, 0xd40a) 4476 DEF_ASM_OP0(cbw, 0x6698) 4477 DEF_ASM_OP0(cwd, 0x6699) 4478 DEF_ASM_OP0(cwde, 0x98) 4479 DEF_ASM_OP0(cdq, 0x99) 4480 DEF_ASM_OP0(cbtw, 0x6698) 4481 DEF_ASM_OP0(cwtl, 0x98) 4482 DEF_ASM_OP0(cwtd, 0x6699) 4483 DEF_ASM_OP0(cltd, 0x99) 4484 DEF_ASM_OP0(int3, 0xcc) 4485 DEF_ASM_OP0(into, 0xce) 4486 DEF_ASM_OP0(iret, 0xcf) 4487 DEF_ASM_OP0(rsm, 0x0faa) 4488 DEF_ASM_OP0(hlt, 0xf4) 4489 DEF_ASM_OP0(wait, 0x9b) 4490 DEF_ASM_OP0(nop, 0x90) 4491 DEF_ASM_OP0(xlat, 0xd7) 4492 4493 /* strings */ 4494 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) 4495 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) 4496 4497 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) 4498 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) 4499 4500 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) 4501 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) 4502 4503 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) 4504 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) 4505 4506 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) 4507 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) 4508 4509 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) 4510 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) 4511 4512 /* bits */ 4513 4514 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 4515 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 4516 4517 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4518 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4519 4520 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4521 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4522 4523 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4524 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4525 4526 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4527 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4528 4529 /* prefixes */ 4530 DEF_ASM_OP0(aword, 0x67) 4531 DEF_ASM_OP0(addr16, 0x67) 4532 DEF_ASM_OP0(word, 0x66) 4533 DEF_ASM_OP0(data16, 0x66) 4534 DEF_ASM_OP0(lock, 0xf0) 4535 DEF_ASM_OP0(rep, 0xf3) 4536 DEF_ASM_OP0(repe, 0xf3) 4537 DEF_ASM_OP0(repz, 0xf3) 4538 DEF_ASM_OP0(repne, 0xf2) 4539 DEF_ASM_OP0(repnz, 0xf2) 4540 4541 DEF_ASM_OP0(invd, 0x0f08) 4542 DEF_ASM_OP0(wbinvd, 0x0f09) 4543 DEF_ASM_OP0(cpuid, 0x0fa2) 4544 DEF_ASM_OP0(wrmsr, 0x0f30) 4545 DEF_ASM_OP0(rdtsc, 0x0f31) 4546 DEF_ASM_OP0(rdmsr, 0x0f32) 4547 DEF_ASM_OP0(rdpmc, 0x0f33) 4548 DEF_ASM_OP0(ud2, 0x0f0b) 4549 4550 /* NOTE: we took the same order as gas opcode definition order */ 4551 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) 4552 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) 4553 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 4554 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 4555 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) 4556 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) 4557 4558 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) 4559 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) 4560 4561 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) 4562 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) 4563 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) 4564 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) 4565 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) 4566 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) 4567 4568 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) 4569 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) 4570 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 4571 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) 4572 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 4573 4574 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) 4575 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 4576 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) 4577 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) 4578 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) 4579 4580 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) 4581 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 4582 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) 4583 4584 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) 4585 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) 4586 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 4587 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 4588 4589 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) 4590 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) 4591 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) 4592 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) 4593 4594 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) 4595 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) 4596 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) 4597 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) 4598 4599 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) 4600 4601 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 4602 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 4603 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 4604 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 4605 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 4606 4607 /* arith */ 4608 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ 4609 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 4610 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) 4611 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 4612 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) 4613 4614 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 4615 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 4616 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) 4617 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 4618 4619 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) 4620 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4621 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) 4622 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4623 4624 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4625 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4626 4627 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4628 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4629 4630 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) 4631 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) 4632 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) 4633 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) 4634 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) 4635 4636 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4637 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 4638 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 4639 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 4640 4641 /* shifts */ 4642 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) 4643 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) 4644 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) 4645 4646 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 4647 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 4648 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 4649 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 4650 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 4651 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 4652 4653 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) 4654 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) 4655 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) 4656 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) 4657 4658 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 4659 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) 4660 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) 4661 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) 4662 4663 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) 4664 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) 4665 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) 4666 DEF_ASM_OP0(leave, 0xc9) 4667 DEF_ASM_OP0(ret, 0xc3) 4668 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) 4669 DEF_ASM_OP0(lret, 0xcb) 4670 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) 4671 4672 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) 4673 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 4674 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 4675 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 4676 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 4677 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) 4678 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) 4679 4680 /* float */ 4681 /* specific fcomp handling */ 4682 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) 4683 4684 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 4685 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 4686 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) 4687 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 4688 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 4689 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) 4690 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) 4691 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 4692 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 4693 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 4694 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 4695 4696 DEF_ASM_OP0(fucompp, 0xdae9) 4697 DEF_ASM_OP0(ftst, 0xd9e4) 4698 DEF_ASM_OP0(fxam, 0xd9e5) 4699 DEF_ASM_OP0(fld1, 0xd9e8) 4700 DEF_ASM_OP0(fldl2t, 0xd9e9) 4701 DEF_ASM_OP0(fldl2e, 0xd9ea) 4702 DEF_ASM_OP0(fldpi, 0xd9eb) 4703 DEF_ASM_OP0(fldlg2, 0xd9ec) 4704 DEF_ASM_OP0(fldln2, 0xd9ed) 4705 DEF_ASM_OP0(fldz, 0xd9ee) 4706 4707 DEF_ASM_OP0(f2xm1, 0xd9f0) 4708 DEF_ASM_OP0(fyl2x, 0xd9f1) 4709 DEF_ASM_OP0(fptan, 0xd9f2) 4710 DEF_ASM_OP0(fpatan, 0xd9f3) 4711 DEF_ASM_OP0(fxtract, 0xd9f4) 4712 DEF_ASM_OP0(fprem1, 0xd9f5) 4713 DEF_ASM_OP0(fdecstp, 0xd9f6) 4714 DEF_ASM_OP0(fincstp, 0xd9f7) 4715 DEF_ASM_OP0(fprem, 0xd9f8) 4716 DEF_ASM_OP0(fyl2xp1, 0xd9f9) 4717 DEF_ASM_OP0(fsqrt, 0xd9fa) 4718 DEF_ASM_OP0(fsincos, 0xd9fb) 4719 DEF_ASM_OP0(frndint, 0xd9fc) 4720 DEF_ASM_OP0(fscale, 0xd9fd) 4721 DEF_ASM_OP0(fsin, 0xd9fe) 4722 DEF_ASM_OP0(fcos, 0xd9ff) 4723 DEF_ASM_OP0(fchs, 0xd9e0) 4724 DEF_ASM_OP0(fabs, 0xd9e1) 4725 DEF_ASM_OP0(fninit, 0xdbe3) 4726 DEF_ASM_OP0(fnclex, 0xdbe2) 4727 DEF_ASM_OP0(fnop, 0xd9d0) 4728 DEF_ASM_OP0(fwait, 0x9b) 4729 4730 /* fp load */ 4731 DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) 4732 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) 4733 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) 4734 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) 4735 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) 4736 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) 4737 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) 4738 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) 4739 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) 4740 4741 /* fp store */ 4742 DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) 4743 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) 4744 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) 4745 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) 4746 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) 4747 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) 4748 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) 4749 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) 4750 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) 4751 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) 4752 4753 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) 4754 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) 4755 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) 4756 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) 4757 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) 4758 4759 /* exchange */ 4760 DEF_ASM_OP0(fxch, 0xd9c9) 4761 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) 4762 4763 /* misc FPU */ 4764 DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) 4765 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) 4766 4767 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) 4768 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) 4769 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) 4770 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) 4771 DEF_ASM_OP0(fnstsw, 0xdfe0) 4772 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) 4773 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) 4774 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) 4775 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) 4776 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) 4777 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) 4778 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) 4779 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 4780 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) 4781 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) 4782 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 4783 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) 4784 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) 4785 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) 4786 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) 4787 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) 4788 4789 /* segments */ 4790 DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) 4791 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) 4792 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) 4793 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) 4794 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) 4795 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) 4796 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) 4797 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) 4798 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) 4799 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) 4800 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) 4801 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) 4802 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) 4803 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) 4804 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) 4805 4806 /* 486 */ 4807 DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) 4808 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 4809 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 4810 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) 4811 4812 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) 4813 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) 4814 4815 /* pentium */ 4816 DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) 4817 4818 /* pentium pro */ 4819 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) 4820 4821 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4822 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4823 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4824 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4825 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4826 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4827 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4828 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4829 4830 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4831 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4832 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4833 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 4834 4835 /* mmx */ 4836 DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ 4837 DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) 4838 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) 4839 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4840 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) 4841 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4842 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4843 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4844 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4845 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4846 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4847 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4848 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4849 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4850 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4851 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4852 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4853 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4854 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4855 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4856 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4857 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4858 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4859 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4860 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4861 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4862 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4863 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4864 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 4865 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4866 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 4867 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4868 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 4869 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4870 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 4871 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4872 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 4873 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4874 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 4875 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4876 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 4877 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4878 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 4879 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4880 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4881 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4882 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4883 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4884 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4885 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4886 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4887 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4888 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4889 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4890 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4891 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4892 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 4893 4894 #undef ALT 4895 #undef DEF_ASM_OP0 4896 #undef DEF_ASM_OP0L 4897 #undef DEF_ASM_OP1 4898 #undef DEF_ASM_OP2 4899 #undef DEF_ASM_OP3 4900 //--------------------------------------------------------------------------- 4901 4902 #define ALT(x) 4903 #define DEF_ASM_OP0(name, opcode) 4904 #define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name) 4905 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name) 4906 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name) 4907 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name) 4908 // njn: inlined i386-asm.h 4909 //#include "i386-asm.h" 4910 //--------------------------------------------------------------------------- 4911 DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ 4912 DEF_ASM_OP0(popa, 0x61) 4913 DEF_ASM_OP0(clc, 0xf8) 4914 DEF_ASM_OP0(cld, 0xfc) 4915 DEF_ASM_OP0(cli, 0xfa) 4916 DEF_ASM_OP0(clts, 0x0f06) 4917 DEF_ASM_OP0(cmc, 0xf5) 4918 DEF_ASM_OP0(lahf, 0x9f) 4919 DEF_ASM_OP0(sahf, 0x9e) 4920 DEF_ASM_OP0(pushfl, 0x9c) 4921 DEF_ASM_OP0(popfl, 0x9d) 4922 DEF_ASM_OP0(pushf, 0x9c) 4923 DEF_ASM_OP0(popf, 0x9d) 4924 DEF_ASM_OP0(stc, 0xf9) 4925 DEF_ASM_OP0(std, 0xfd) 4926 DEF_ASM_OP0(sti, 0xfb) 4927 DEF_ASM_OP0(aaa, 0x37) 4928 DEF_ASM_OP0(aas, 0x3f) 4929 DEF_ASM_OP0(daa, 0x27) 4930 DEF_ASM_OP0(das, 0x2f) 4931 DEF_ASM_OP0(aad, 0xd50a) 4932 DEF_ASM_OP0(aam, 0xd40a) 4933 DEF_ASM_OP0(cbw, 0x6698) 4934 DEF_ASM_OP0(cwd, 0x6699) 4935 DEF_ASM_OP0(cwde, 0x98) 4936 DEF_ASM_OP0(cdq, 0x99) 4937 DEF_ASM_OP0(cbtw, 0x6698) 4938 DEF_ASM_OP0(cwtl, 0x98) 4939 DEF_ASM_OP0(cwtd, 0x6699) 4940 DEF_ASM_OP0(cltd, 0x99) 4941 DEF_ASM_OP0(int3, 0xcc) 4942 DEF_ASM_OP0(into, 0xce) 4943 DEF_ASM_OP0(iret, 0xcf) 4944 DEF_ASM_OP0(rsm, 0x0faa) 4945 DEF_ASM_OP0(hlt, 0xf4) 4946 DEF_ASM_OP0(wait, 0x9b) 4947 DEF_ASM_OP0(nop, 0x90) 4948 DEF_ASM_OP0(xlat, 0xd7) 4949 4950 /* strings */ 4951 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) 4952 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) 4953 4954 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) 4955 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) 4956 4957 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) 4958 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) 4959 4960 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) 4961 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) 4962 4963 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) 4964 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) 4965 4966 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) 4967 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) 4968 4969 /* bits */ 4970 4971 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 4972 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 4973 4974 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4975 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4976 4977 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4978 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4979 4980 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4981 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4982 4983 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 4984 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 4985 4986 /* prefixes */ 4987 DEF_ASM_OP0(aword, 0x67) 4988 DEF_ASM_OP0(addr16, 0x67) 4989 DEF_ASM_OP0(word, 0x66) 4990 DEF_ASM_OP0(data16, 0x66) 4991 DEF_ASM_OP0(lock, 0xf0) 4992 DEF_ASM_OP0(rep, 0xf3) 4993 DEF_ASM_OP0(repe, 0xf3) 4994 DEF_ASM_OP0(repz, 0xf3) 4995 DEF_ASM_OP0(repne, 0xf2) 4996 DEF_ASM_OP0(repnz, 0xf2) 4997 4998 DEF_ASM_OP0(invd, 0x0f08) 4999 DEF_ASM_OP0(wbinvd, 0x0f09) 5000 DEF_ASM_OP0(cpuid, 0x0fa2) 5001 DEF_ASM_OP0(wrmsr, 0x0f30) 5002 DEF_ASM_OP0(rdtsc, 0x0f31) 5003 DEF_ASM_OP0(rdmsr, 0x0f32) 5004 DEF_ASM_OP0(rdpmc, 0x0f33) 5005 DEF_ASM_OP0(ud2, 0x0f0b) 5006 5007 /* NOTE: we took the same order as gas opcode definition order */ 5008 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) 5009 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) 5010 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 5011 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 5012 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) 5013 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) 5014 5015 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) 5016 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) 5017 5018 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) 5019 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) 5020 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) 5021 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) 5022 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) 5023 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) 5024 5025 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) 5026 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) 5027 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 5028 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) 5029 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 5030 5031 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) 5032 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 5033 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) 5034 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) 5035 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) 5036 5037 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) 5038 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 5039 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) 5040 5041 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) 5042 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) 5043 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 5044 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 5045 5046 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) 5047 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) 5048 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) 5049 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) 5050 5051 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) 5052 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) 5053 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) 5054 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) 5055 5056 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) 5057 5058 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 5059 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 5060 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 5061 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 5062 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 5063 5064 /* arith */ 5065 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ 5066 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 5067 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) 5068 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 5069 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) 5070 5071 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 5072 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 5073 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) 5074 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 5075 5076 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) 5077 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5078 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) 5079 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5080 5081 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5082 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5083 5084 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5085 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5086 5087 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) 5088 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) 5089 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) 5090 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) 5091 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) 5092 5093 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5094 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 5095 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 5096 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 5097 5098 /* shifts */ 5099 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) 5100 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) 5101 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) 5102 5103 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 5104 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 5105 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 5106 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 5107 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 5108 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 5109 5110 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) 5111 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) 5112 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) 5113 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) 5114 5115 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 5116 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) 5117 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) 5118 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) 5119 5120 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) 5121 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) 5122 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) 5123 DEF_ASM_OP0(leave, 0xc9) 5124 DEF_ASM_OP0(ret, 0xc3) 5125 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) 5126 DEF_ASM_OP0(lret, 0xcb) 5127 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) 5128 5129 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) 5130 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 5131 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 5132 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 5133 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 5134 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) 5135 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) 5136 5137 /* float */ 5138 /* specific fcomp handling */ 5139 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) 5140 5141 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 5142 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 5143 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) 5144 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 5145 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 5146 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) 5147 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) 5148 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 5149 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 5150 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 5151 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 5152 5153 DEF_ASM_OP0(fucompp, 0xdae9) 5154 DEF_ASM_OP0(ftst, 0xd9e4) 5155 DEF_ASM_OP0(fxam, 0xd9e5) 5156 DEF_ASM_OP0(fld1, 0xd9e8) 5157 DEF_ASM_OP0(fldl2t, 0xd9e9) 5158 DEF_ASM_OP0(fldl2e, 0xd9ea) 5159 DEF_ASM_OP0(fldpi, 0xd9eb) 5160 DEF_ASM_OP0(fldlg2, 0xd9ec) 5161 DEF_ASM_OP0(fldln2, 0xd9ed) 5162 DEF_ASM_OP0(fldz, 0xd9ee) 5163 5164 DEF_ASM_OP0(f2xm1, 0xd9f0) 5165 DEF_ASM_OP0(fyl2x, 0xd9f1) 5166 DEF_ASM_OP0(fptan, 0xd9f2) 5167 DEF_ASM_OP0(fpatan, 0xd9f3) 5168 DEF_ASM_OP0(fxtract, 0xd9f4) 5169 DEF_ASM_OP0(fprem1, 0xd9f5) 5170 DEF_ASM_OP0(fdecstp, 0xd9f6) 5171 DEF_ASM_OP0(fincstp, 0xd9f7) 5172 DEF_ASM_OP0(fprem, 0xd9f8) 5173 DEF_ASM_OP0(fyl2xp1, 0xd9f9) 5174 DEF_ASM_OP0(fsqrt, 0xd9fa) 5175 DEF_ASM_OP0(fsincos, 0xd9fb) 5176 DEF_ASM_OP0(frndint, 0xd9fc) 5177 DEF_ASM_OP0(fscale, 0xd9fd) 5178 DEF_ASM_OP0(fsin, 0xd9fe) 5179 DEF_ASM_OP0(fcos, 0xd9ff) 5180 DEF_ASM_OP0(fchs, 0xd9e0) 5181 DEF_ASM_OP0(fabs, 0xd9e1) 5182 DEF_ASM_OP0(fninit, 0xdbe3) 5183 DEF_ASM_OP0(fnclex, 0xdbe2) 5184 DEF_ASM_OP0(fnop, 0xd9d0) 5185 DEF_ASM_OP0(fwait, 0x9b) 5186 5187 /* fp load */ 5188 DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) 5189 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) 5190 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) 5191 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) 5192 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) 5193 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) 5194 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) 5195 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) 5196 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) 5197 5198 /* fp store */ 5199 DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) 5200 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) 5201 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) 5202 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) 5203 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) 5204 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) 5205 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) 5206 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) 5207 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) 5208 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) 5209 5210 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) 5211 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) 5212 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) 5213 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) 5214 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) 5215 5216 /* exchange */ 5217 DEF_ASM_OP0(fxch, 0xd9c9) 5218 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) 5219 5220 /* misc FPU */ 5221 DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) 5222 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) 5223 5224 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) 5225 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) 5226 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) 5227 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) 5228 DEF_ASM_OP0(fnstsw, 0xdfe0) 5229 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) 5230 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) 5231 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) 5232 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) 5233 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) 5234 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) 5235 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) 5236 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 5237 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) 5238 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) 5239 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 5240 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) 5241 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) 5242 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) 5243 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) 5244 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) 5245 5246 /* segments */ 5247 DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) 5248 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) 5249 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) 5250 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) 5251 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) 5252 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) 5253 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) 5254 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) 5255 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) 5256 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) 5257 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) 5258 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) 5259 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) 5260 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) 5261 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) 5262 5263 /* 486 */ 5264 DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) 5265 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 5266 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 5267 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) 5268 5269 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) 5270 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) 5271 5272 /* pentium */ 5273 DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) 5274 5275 /* pentium pro */ 5276 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) 5277 5278 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5279 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5280 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5281 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5282 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5283 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5284 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5285 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5286 5287 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5288 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5289 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5290 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 5291 5292 /* mmx */ 5293 DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ 5294 DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) 5295 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) 5296 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5297 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) 5298 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5299 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5300 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5301 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5302 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5303 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5304 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5305 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5306 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5307 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5308 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5309 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5310 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5311 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5312 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5313 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5314 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5315 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5316 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5317 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5318 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5319 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5320 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5321 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 5322 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5323 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 5324 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5325 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 5326 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5327 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 5328 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5329 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 5330 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5331 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 5332 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5333 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 5334 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5335 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 5336 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5337 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5338 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5339 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5340 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5341 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5342 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5343 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5344 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5345 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5346 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5347 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5348 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5349 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 5350 5351 #undef ALT 5352 #undef DEF_ASM_OP0 5353 #undef DEF_ASM_OP0L 5354 #undef DEF_ASM_OP1 5355 #undef DEF_ASM_OP2 5356 #undef DEF_ASM_OP3 5357 //--------------------------------------------------------------------------- 5358 5359 #endif 5360 //--------------------------------------------------------------------------- 5361 #undef DEF 5362 ; 5363 5364 #define TOK_UIDENT TOK_DEFINE 5365 5366 #ifdef WIN32 5367 int __stdcall GetModuleFileNameA(void *, char *, int); 5368 void *__stdcall GetProcAddress(void *, const char *); 5369 void *__stdcall GetModuleHandleA(const char *); 5370 void *__stdcall LoadLibraryA(const char *); 5371 int __stdcall FreeConsole(void); 5372 5373 #define snprintf _snprintf 5374 #define vsnprintf _vsnprintf 5375 #ifndef __GNUC__ 5376 #define strtold (long double)strtod 5377 #define strtof (float)strtod 5378 #define strtoll (long long)strtol 5379 #endif 5380 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__) 5381 /* currently incorrect */ 5382 long double strtold(const char *nptr, char **endptr) 5383 { 5384 return (long double)strtod(nptr, endptr); 5385 } 5386 float strtof(const char *nptr, char **endptr) 5387 { 5388 return (float)strtod(nptr, endptr); 5389 } 5390 #else 5391 /* XXX: need to define this to use them in non ISOC99 context */ 5392 extern float strtof (const char *__nptr, char **__endptr); 5393 extern long double strtold (const char *__nptr, char **__endptr); 5394 #endif 5395 5396 static char *pstrcpy(char *buf, int buf_size, const char *s); 5397 static char *pstrcat(char *buf, int buf_size, const char *s); 5398 static const char *tcc_basename(const char *name); 5399 5400 static void next(void); 5401 static void next_nomacro(void); 5402 static void parse_expr_type(CType *type); 5403 static void expr_type(CType *type); 5404 static void unary_type(CType *type); 5405 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 5406 int case_reg, int is_expr); 5407 static int expr_const(void); 5408 static void expr_eq(void); 5409 static void gexpr(void); 5410 static void gen_inline_functions(void); 5411 static void decl(int l); 5412 static void decl_initializer(CType *type, Section *sec, unsigned long c, 5413 int first, int size_only); 5414 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 5415 int has_init, int v, int scope); 5416 int gv(int rc); 5417 void gv2(int rc1, int rc2); 5418 void move_reg(int r, int s); 5419 void save_regs(int n); 5420 void save_reg(int r); 5421 void vpop(void); 5422 void vswap(void); 5423 void vdup(void); 5424 int get_reg(int rc); 5425 int get_reg_ex(int rc,int rc2); 5426 5427 struct macro_level { 5428 struct macro_level *prev; 5429 int *p; 5430 }; 5431 5432 static void macro_subst(TokenString *tok_str, Sym **nested_list, 5433 const int *macro_str, struct macro_level **can_read_stream); 5434 void gen_op(int op); 5435 void force_charshort_cast(int t); 5436 static void gen_cast(CType *type); 5437 void vstore(void); 5438 static Sym *sym_find(int v); 5439 static Sym *sym_push(int v, CType *type, int r, int c); 5440 5441 /* type handling */ 5442 static int type_size(CType *type, int *a); 5443 static inline CType *pointed_type(CType *type); 5444 static int pointed_size(CType *type); 5445 static int lvalue_type(int t); 5446 static int parse_btype(CType *type, AttributeDef *ad); 5447 static void type_decl(CType *type, AttributeDef *ad, int *v, int td); 5448 static int is_compatible_types(CType *type1, CType *type2); 5449 5450 int ieee_finite(double d); 5451 void error(const char *fmt, ...); 5452 void vpushi(int v); 5453 void vrott(int n); 5454 void vnrott(int n); 5455 void lexpand_nr(void); 5456 static void vpush_global_sym(CType *type, int v); 5457 void vset(CType *type, int r, int v); 5458 void type_to_str(char *buf, int buf_size, 5459 CType *type, const char *varstr); 5460 char *get_tok_str(int v, CValue *cv); 5461 static Sym *get_sym_ref(CType *type, Section *sec, 5462 unsigned long offset, unsigned long size); 5463 static Sym *external_global_sym(int v, CType *type, int r); 5464 5465 /* section generation */ 5466 static void section_realloc(Section *sec, unsigned long new_size); 5467 static void *section_ptr_add(Section *sec, unsigned long size); 5468 static void put_extern_sym(Sym *sym, Section *section, 5469 unsigned long value, unsigned long size); 5470 static void greloc(Section *s, Sym *sym, unsigned long addr, int type); 5471 static int put_elf_str(Section *s, const char *sym); 5472 static int put_elf_sym(Section *s, 5473 unsigned long value, unsigned long size, 5474 int info, int other, int shndx, const char *name); 5475 static int add_elf_sym(Section *s, unsigned long value, unsigned long size, 5476 int info, int other, int sh_num, const char *name); 5477 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, 5478 int type, int symbol); 5479 static void put_stabs(const char *str, int type, int other, int desc, 5480 unsigned long value); 5481 static void put_stabs_r(const char *str, int type, int other, int desc, 5482 unsigned long value, Section *sec, int sym_index); 5483 static void put_stabn(int type, int other, int desc, int value); 5484 static void put_stabd(int type, int other, int desc); 5485 static int tcc_add_dll(TCCState *s, const char *filename, int flags); 5486 5487 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */ 5488 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */ 5489 static int tcc_add_file_internal(TCCState *s, const char *filename, int flags); 5490 5491 /* tcccoff.c */ 5492 int tcc_output_coff(TCCState *s1, FILE *f); 5493 5494 /* tccpe.c */ 5495 void *resolve_sym(TCCState *s1, const char *sym, int type); 5496 int pe_load_def_file(struct TCCState *s1, FILE *fp); 5497 void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file); 5498 unsigned long pe_add_runtime(struct TCCState *s1); 5499 int tcc_output_pe(struct TCCState *s1, const char *filename); 5500 5501 /* tccasm.c */ 5502 5503 #ifdef CONFIG_TCC_ASM 5504 5505 typedef struct ExprValue { 5506 uint32_t v; 5507 Sym *sym; 5508 } ExprValue; 5509 5510 #define MAX_ASM_OPERANDS 30 5511 5512 typedef struct ASMOperand { 5513 int id; /* GCC 3 optionnal identifier (0 if number only supported */ 5514 char *constraint; 5515 char asm_str[16]; /* computed asm string for operand */ 5516 SValue *vt; /* C value of the expression */ 5517 int ref_index; /* if >= 0, gives reference to a output constraint */ 5518 int input_index; /* if >= 0, gives reference to an input constraint */ 5519 int priority; /* priority, used to assign registers */ 5520 int reg; /* if >= 0, register number used for this operand */ 5521 int is_llong; /* true if double register value */ 5522 int is_memory; /* true if memory operand */ 5523 int is_rw; /* for '+' modifier */ 5524 } ASMOperand; 5525 5526 static void asm_expr(TCCState *s1, ExprValue *pe); 5527 static int asm_int_expr(TCCState *s1); 5528 static int find_constraint(ASMOperand *operands, int nb_operands, 5529 const char *name, const char **pp); 5530 5531 static int tcc_assemble(TCCState *s1, int do_preprocess); 5532 5533 #endif 5534 5535 static void asm_instr(void); 5536 static void asm_global_instr(void); 5537 5538 /* true if float/double/long double type */ 5539 static inline int is_float(int t) 5540 { 5541 int bt; 5542 bt = t & VT_BTYPE; 5543 return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT; 5544 } 5545 5546 #ifdef TCC_TARGET_I386 5547 // njn: inlined i386-gen.c 5548 //#include "i386-gen.c" 5549 //--------------------------------------------------------------------------- 5550 /* 5551 * X86 code generator for TCC 5552 * 5553 * Copyright (c) 2001-2004 Fabrice Bellard 5554 * 5555 * This library is free software; you can redistribute it and/or 5556 * modify it under the terms of the GNU Lesser General Public 5557 * License as published by the Free Software Foundation; either 5558 * version 2 of the License, or (at your option) any later version. 5559 * 5560 * This library is distributed in the hope that it will be useful, 5561 * but WITHOUT ANY WARRANTY; without even the implied warranty of 5562 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 5563 * Lesser General Public License for more details. 5564 * 5565 * You should have received a copy of the GNU Lesser General Public 5566 * License along with this library; if not, write to the Free Software 5567 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 5568 */ 5569 5570 /* number of available registers */ 5571 #define NB_REGS 4 5572 5573 /* a register can belong to several classes. The classes must be 5574 sorted from more general to more precise (see gv2() code which does 5575 assumptions on it). */ 5576 #define RC_INT 0x0001 /* generic integer register */ 5577 #define RC_FLOAT 0x0002 /* generic float register */ 5578 #define RC_EAX 0x0004 5579 #define RC_ST0 0x0008 5580 #define RC_ECX 0x0010 5581 #define RC_EDX 0x0020 5582 #define RC_IRET RC_EAX /* function return: integer register */ 5583 #define RC_LRET RC_EDX /* function return: second integer register */ 5584 #define RC_FRET RC_ST0 /* function return: float register */ 5585 5586 /* pretty names for the registers */ 5587 enum { 5588 TREG_EAX = 0, 5589 TREG_ECX, 5590 TREG_EDX, 5591 TREG_ST0, 5592 }; 5593 5594 int reg_classes[NB_REGS] = { 5595 /* eax */ RC_INT | RC_EAX, 5596 /* ecx */ RC_INT | RC_ECX, 5597 /* edx */ RC_INT | RC_EDX, 5598 /* st0 */ RC_FLOAT | RC_ST0, 5599 }; 5600 5601 /* return registers for function */ 5602 #define REG_IRET TREG_EAX /* single word int return register */ 5603 #define REG_LRET TREG_EDX /* second word return register (for long long) */ 5604 #define REG_FRET TREG_ST0 /* float return register */ 5605 5606 /* defined if function parameters must be evaluated in reverse order */ 5607 #define INVERT_FUNC_PARAMS 5608 5609 /* defined if structures are passed as pointers. Otherwise structures 5610 are directly pushed on stack. */ 5611 //#define FUNC_STRUCT_PARAM_AS_PTR 5612 5613 /* pointer size, in bytes */ 5614 #define PTR_SIZE 4 5615 5616 /* long double size and alignment, in bytes */ 5617 #define LDOUBLE_SIZE 12 5618 #define LDOUBLE_ALIGN 4 5619 /* maximum alignment (for aligned attribute support) */ 5620 #define MAX_ALIGN 8 5621 5622 /******************************************************/ 5623 /* ELF defines */ 5624 5625 #define EM_TCC_TARGET EM_386 5626 5627 /* relocation type for 32 bit data relocation */ 5628 #define R_DATA_32 R_386_32 5629 #define R_JMP_SLOT R_386_JMP_SLOT 5630 #define R_COPY R_386_COPY 5631 5632 #define ELF_START_ADDR 0x08048000 5633 #define ELF_PAGE_SIZE 0x1000 5634 5635 /******************************************************/ 5636 5637 static unsigned long func_sub_sp_offset; 5638 static unsigned long func_bound_offset; 5639 static int func_ret_sub; 5640 5641 /* XXX: make it faster ? */ 5642 void g(int c) 5643 { 5644 int ind1; 5645 ind1 = ind + 1; 5646 if (ind1 > cur_text_section->data_allocated) 5647 section_realloc(cur_text_section, ind1); 5648 cur_text_section->data[ind] = c; 5649 ind = ind1; 5650 } 5651 5652 void o(unsigned int c) 5653 { 5654 while (c) { 5655 g(c); 5656 c = c >> 8; 5657 } 5658 } 5659 5660 void gen_le32(int c) 5661 { 5662 g(c); 5663 g(c >> 8); 5664 g(c >> 16); 5665 g(c >> 24); 5666 } 5667 5668 /* output a symbol and patch all calls to it */ 5669 void gsym_addr(int t, int a) 5670 { 5671 int n, *ptr; 5672 while (t) { 5673 ptr = (int *)(cur_text_section->data + t); 5674 n = *ptr; /* next value */ 5675 *ptr = a - t - 4; 5676 t = n; 5677 } 5678 } 5679 5680 void gsym(int t) 5681 { 5682 gsym_addr(t, ind); 5683 } 5684 5685 /* psym is used to put an instruction with a data field which is a 5686 reference to a symbol. It is in fact the same as oad ! */ 5687 #define psym oad 5688 5689 /* instruction + 4 bytes data. Return the address of the data */ 5690 static int oad(int c, int s) 5691 { 5692 int ind1; 5693 5694 o(c); 5695 ind1 = ind + 4; 5696 if (ind1 > cur_text_section->data_allocated) 5697 section_realloc(cur_text_section, ind1); 5698 *(int *)(cur_text_section->data + ind) = s; 5699 s = ind; 5700 ind = ind1; 5701 return s; 5702 } 5703 5704 /* output constant with relocation if 'r & VT_SYM' is true */ 5705 static void gen_addr32(int r, Sym *sym, int c) 5706 { 5707 if (r & VT_SYM) 5708 greloc(cur_text_section, sym, ind, R_386_32); 5709 gen_le32(c); 5710 } 5711 5712 /* generate a modrm reference. 'op_reg' contains the addtionnal 3 5713 opcode bits */ 5714 static void gen_modrm(int op_reg, int r, Sym *sym, int c) 5715 { 5716 op_reg = op_reg << 3; 5717 if ((r & VT_VALMASK) == VT_CONST) { 5718 /* constant memory reference */ 5719 o(0x05 | op_reg); 5720 gen_addr32(r, sym, c); 5721 } else if ((r & VT_VALMASK) == VT_LOCAL) { 5722 /* currently, we use only ebp as base */ 5723 if (c == (char)c) { 5724 /* short reference */ 5725 o(0x45 | op_reg); 5726 g(c); 5727 } else { 5728 oad(0x85 | op_reg, c); 5729 } 5730 } else { 5731 g(0x00 | op_reg | (r & VT_VALMASK)); 5732 } 5733 } 5734 5735 5736 /* load 'r' from value 'sv' */ 5737 void load(int r, SValue *sv) 5738 { 5739 int v, t, ft, fc, fr; 5740 SValue v1; 5741 5742 fr = sv->r; 5743 ft = sv->type.t; 5744 fc = sv->c.ul; 5745 5746 v = fr & VT_VALMASK; 5747 if (fr & VT_LVAL) { 5748 if (v == VT_LLOCAL) { 5749 v1.type.t = VT_INT; 5750 v1.r = VT_LOCAL | VT_LVAL; 5751 v1.c.ul = fc; 5752 load(r, &v1); 5753 fr = r; 5754 } 5755 if ((ft & VT_BTYPE) == VT_FLOAT) { 5756 o(0xd9); /* flds */ 5757 r = 0; 5758 } else if ((ft & VT_BTYPE) == VT_DOUBLE) { 5759 o(0xdd); /* fldl */ 5760 r = 0; 5761 } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { 5762 o(0xdb); /* fldt */ 5763 r = 5; 5764 } else if ((ft & VT_TYPE) == VT_BYTE) { 5765 o(0xbe0f); /* movsbl */ 5766 } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { 5767 o(0xb60f); /* movzbl */ 5768 } else if ((ft & VT_TYPE) == VT_SHORT) { 5769 o(0xbf0f); /* movswl */ 5770 } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { 5771 o(0xb70f); /* movzwl */ 5772 } else { 5773 o(0x8b); /* movl */ 5774 } 5775 gen_modrm(r, fr, sv->sym, fc); 5776 } else { 5777 if (v == VT_CONST) { 5778 o(0xb8 + r); /* mov $xx, r */ 5779 gen_addr32(fr, sv->sym, fc); 5780 } else if (v == VT_LOCAL) { 5781 o(0x8d); /* lea xxx(%ebp), r */ 5782 gen_modrm(r, VT_LOCAL, sv->sym, fc); 5783 } else if (v == VT_CMP) { 5784 oad(0xb8 + r, 0); /* mov $0, r */ 5785 o(0x0f); /* setxx %br */ 5786 o(fc); 5787 o(0xc0 + r); 5788 } else if (v == VT_JMP || v == VT_JMPI) { 5789 t = v & 1; 5790 oad(0xb8 + r, t); /* mov $1, r */ 5791 o(0x05eb); /* jmp after */ 5792 gsym(fc); 5793 oad(0xb8 + r, t ^ 1); /* mov $0, r */ 5794 } else if (v != r) { 5795 o(0x89); 5796 o(0xc0 + r + v * 8); /* mov v, r */ 5797 } 5798 } 5799 } 5800 5801 /* store register 'r' in lvalue 'v' */ 5802 void store(int r, SValue *v) 5803 { 5804 int fr, bt, ft, fc; 5805 5806 ft = v->type.t; 5807 fc = v->c.ul; 5808 fr = v->r & VT_VALMASK; 5809 bt = ft & VT_BTYPE; 5810 /* XXX: incorrect if float reg to reg */ 5811 if (bt == VT_FLOAT) { 5812 o(0xd9); /* fsts */ 5813 r = 2; 5814 } else if (bt == VT_DOUBLE) { 5815 o(0xdd); /* fstpl */ 5816 r = 2; 5817 } else if (bt == VT_LDOUBLE) { 5818 o(0xc0d9); /* fld %st(0) */ 5819 o(0xdb); /* fstpt */ 5820 r = 7; 5821 } else { 5822 if (bt == VT_SHORT) 5823 o(0x66); 5824 if (bt == VT_BYTE || bt == VT_BOOL) 5825 o(0x88); 5826 else 5827 o(0x89); 5828 } 5829 if (fr == VT_CONST || 5830 fr == VT_LOCAL || 5831 (v->r & VT_LVAL)) { 5832 gen_modrm(r, v->r, v->sym, fc); 5833 } else if (fr != r) { 5834 o(0xc0 + fr + r * 8); /* mov r, fr */ 5835 } 5836 } 5837 5838 static void gadd_sp(int val) 5839 { 5840 if (val == (char)val) { 5841 o(0xc483); 5842 g(val); 5843 } else { 5844 oad(0xc481, val); /* add $xxx, %esp */ 5845 } 5846 } 5847 5848 /* 'is_jmp' is '1' if it is a jump */ 5849 static void gcall_or_jmp(int is_jmp) 5850 { 5851 int r; 5852 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { 5853 /* constant case */ 5854 if (vtop->r & VT_SYM) { 5855 /* relocation case */ 5856 greloc(cur_text_section, vtop->sym, 5857 ind + 1, R_386_PC32); 5858 } else { 5859 /* put an empty PC32 relocation */ 5860 put_elf_reloc(symtab_section, cur_text_section, 5861 ind + 1, R_386_PC32, 0); 5862 } 5863 oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ 5864 } else { 5865 /* otherwise, indirect call */ 5866 r = gv(RC_INT); 5867 o(0xff); /* call/jmp *r */ 5868 o(0xd0 + r + (is_jmp << 4)); 5869 } 5870 } 5871 5872 static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX }; 5873 5874 /* Generate function call. The function address is pushed first, then 5875 all the parameters in call order. This functions pops all the 5876 parameters and the function address. */ 5877 void gfunc_call(int nb_args) 5878 { 5879 int size, align, r, args_size, i, func_call; 5880 Sym *func_sym; 5881 5882 args_size = 0; 5883 for(i = 0;i < nb_args; i++) { 5884 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { 5885 size = type_size(&vtop->type, &align); 5886 /* align to stack align size */ 5887 size = (size + 3) & ~3; 5888 /* allocate the necessary size on stack */ 5889 oad(0xec81, size); /* sub $xxx, %esp */ 5890 /* generate structure store */ 5891 r = get_reg(RC_INT); 5892 o(0x89); /* mov %esp, r */ 5893 o(0xe0 + r); 5894 vset(&vtop->type, r | VT_LVAL, 0); 5895 vswap(); 5896 vstore(); 5897 args_size += size; 5898 } else if (is_float(vtop->type.t)) { 5899 gv(RC_FLOAT); /* only one float register */ 5900 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) 5901 size = 4; 5902 else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 5903 size = 8; 5904 else 5905 size = 12; 5906 oad(0xec81, size); /* sub $xxx, %esp */ 5907 if (size == 12) 5908 o(0x7cdb); 5909 else 5910 o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ 5911 g(0x24); 5912 g(0x00); 5913 args_size += size; 5914 } else { 5915 /* simple type (currently always same size) */ 5916 /* XXX: implicit cast ? */ 5917 r = gv(RC_INT); 5918 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { 5919 size = 8; 5920 o(0x50 + vtop->r2); /* push r */ 5921 } else { 5922 size = 4; 5923 } 5924 o(0x50 + r); /* push r */ 5925 args_size += size; 5926 } 5927 vtop--; 5928 } 5929 save_regs(0); /* save used temporary registers */ 5930 func_sym = vtop->type.ref; 5931 func_call = func_sym->r; 5932 /* fast call case */ 5933 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { 5934 int fastcall_nb_regs; 5935 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; 5936 for(i = 0;i < fastcall_nb_regs; i++) { 5937 if (args_size <= 0) 5938 break; 5939 o(0x58 + fastcall_regs[i]); /* pop r */ 5940 /* XXX: incorrect for struct/floats */ 5941 args_size -= 4; 5942 } 5943 } 5944 gcall_or_jmp(0); 5945 if (args_size && func_sym->r != FUNC_STDCALL) 5946 gadd_sp(args_size); 5947 vtop--; 5948 } 5949 5950 #ifdef TCC_TARGET_PE 5951 #define FUNC_PROLOG_SIZE 10 5952 #else 5953 #define FUNC_PROLOG_SIZE 9 5954 #endif 5955 5956 /* generate function prolog of type 't' */ 5957 void gfunc_prolog(CType *func_type) 5958 { 5959 int addr, align, size, func_call, fastcall_nb_regs; 5960 int param_index, param_addr; 5961 Sym *sym; 5962 CType *type; 5963 5964 sym = func_type->ref; 5965 func_call = sym->r; 5966 addr = 8; 5967 loc = 0; 5968 if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { 5969 fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1; 5970 } else { 5971 fastcall_nb_regs = 0; 5972 } 5973 param_index = 0; 5974 5975 ind += FUNC_PROLOG_SIZE; 5976 func_sub_sp_offset = ind; 5977 /* if the function returns a structure, then add an 5978 implicit pointer parameter */ 5979 func_vt = sym->type; 5980 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { 5981 /* XXX: fastcall case ? */ 5982 func_vc = addr; 5983 addr += 4; 5984 param_index++; 5985 } 5986 /* define parameters */ 5987 while ((sym = sym->next) != NULL) { 5988 type = &sym->type; 5989 size = type_size(type, &align); 5990 size = (size + 3) & ~3; 5991 #ifdef FUNC_STRUCT_PARAM_AS_PTR 5992 /* structs are passed as pointer */ 5993 if ((type->t & VT_BTYPE) == VT_STRUCT) { 5994 size = 4; 5995 } 5996 #endif 5997 if (param_index < fastcall_nb_regs) { 5998 /* save FASTCALL register */ 5999 loc -= 4; 6000 o(0x89); /* movl */ 6001 gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc); 6002 param_addr = loc; 6003 } else { 6004 param_addr = addr; 6005 addr += size; 6006 } 6007 sym_push(sym->v & ~SYM_FIELD, type, 6008 VT_LOCAL | VT_LVAL, param_addr); 6009 param_index++; 6010 } 6011 func_ret_sub = 0; 6012 /* pascal type call ? */ 6013 if (func_call == FUNC_STDCALL) 6014 func_ret_sub = addr - 8; 6015 6016 /* leave some room for bound checking code */ 6017 if (do_bounds_check) { 6018 oad(0xb8, 0); /* lbound section pointer */ 6019 oad(0xb8, 0); /* call to function */ 6020 func_bound_offset = lbounds_section->data_offset; 6021 } 6022 } 6023 6024 /* generate function epilog */ 6025 void gfunc_epilog(void) 6026 { 6027 int v, saved_ind; 6028 6029 #ifdef CONFIG_TCC_BCHECK 6030 if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) { 6031 int saved_ind; 6032 int *bounds_ptr; 6033 Sym *sym, *sym_data; 6034 /* add end of table info */ 6035 bounds_ptr = section_ptr_add(lbounds_section, sizeof(int)); 6036 *bounds_ptr = 0; 6037 /* generate bound local allocation */ 6038 saved_ind = ind; 6039 ind = func_sub_sp_offset; 6040 sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 6041 func_bound_offset, lbounds_section->data_offset); 6042 greloc(cur_text_section, sym_data, 6043 ind + 1, R_386_32); 6044 oad(0xb8, 0); /* mov %eax, xxx */ 6045 sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0); 6046 greloc(cur_text_section, sym, 6047 ind + 1, R_386_PC32); 6048 oad(0xe8, -4); 6049 ind = saved_ind; 6050 /* generate bound check local freeing */ 6051 o(0x5250); /* save returned value, if any */ 6052 greloc(cur_text_section, sym_data, 6053 ind + 1, R_386_32); 6054 oad(0xb8, 0); /* mov %eax, xxx */ 6055 sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0); 6056 greloc(cur_text_section, sym, 6057 ind + 1, R_386_PC32); 6058 oad(0xe8, -4); 6059 o(0x585a); /* restore returned value, if any */ 6060 } 6061 #endif 6062 o(0xc9); /* leave */ 6063 if (func_ret_sub == 0) { 6064 o(0xc3); /* ret */ 6065 } else { 6066 o(0xc2); /* ret n */ 6067 g(func_ret_sub); 6068 g(func_ret_sub >> 8); 6069 } 6070 /* align local size to word & save local variables */ 6071 6072 v = (-loc + 3) & -4; 6073 saved_ind = ind; 6074 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; 6075 #ifdef TCC_TARGET_PE 6076 if (v >= 4096) { 6077 Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0); 6078 oad(0xb8, v); /* mov stacksize, %eax */ 6079 oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */ 6080 greloc(cur_text_section, sym, ind-4, R_386_PC32); 6081 } else 6082 #endif 6083 { 6084 o(0xe58955); /* push %ebp, mov %esp, %ebp */ 6085 o(0xec81); /* sub esp, stacksize */ 6086 gen_le32(v); 6087 #if FUNC_PROLOG_SIZE == 10 6088 o(0x90); /* adjust to FUNC_PROLOG_SIZE */ 6089 #endif 6090 } 6091 ind = saved_ind; 6092 } 6093 6094 /* generate a jump to a label */ 6095 long gjmp(int t) 6096 { 6097 return psym(0xe9, t); 6098 } 6099 6100 /* generate a jump to a fixed address */ 6101 void gjmp_addr(int a) 6102 { 6103 int r; 6104 r = a - ind - 2; 6105 if (r == (char)r) { 6106 g(0xeb); 6107 g(r); 6108 } else { 6109 oad(0xe9, a - ind - 5); 6110 } 6111 } 6112 6113 /* generate a test. set 'inv' to invert test. Stack entry is popped */ 6114 int gtst(int inv, int t) 6115 { 6116 int v, *p; 6117 6118 v = vtop->r & VT_VALMASK; 6119 if (v == VT_CMP) { 6120 /* fast case : can jump directly since flags are set */ 6121 g(0x0f); 6122 t = psym((vtop->c.i - 16) ^ inv, t); 6123 } else if (v == VT_JMP || v == VT_JMPI) { 6124 /* && or || optimization */ 6125 if ((v & 1) == inv) { 6126 /* insert vtop->c jump list in t */ 6127 p = &vtop->c.i; 6128 while (*p != 0) 6129 p = (int *)(cur_text_section->data + *p); 6130 *p = t; 6131 t = vtop->c.i; 6132 } else { 6133 t = gjmp(t); 6134 gsym(vtop->c.i); 6135 } 6136 } else { 6137 if (is_float(vtop->type.t)) { 6138 vpushi(0); 6139 gen_op(TOK_NE); 6140 } 6141 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 6142 /* constant jmp optimization */ 6143 if ((vtop->c.i != 0) != inv) 6144 t = gjmp(t); 6145 } else { 6146 v = gv(RC_INT); 6147 o(0x85); 6148 o(0xc0 + v * 9); 6149 g(0x0f); 6150 t = psym(0x85 ^ inv, t); 6151 } 6152 } 6153 vtop--; 6154 return t; 6155 } 6156 6157 /* generate an integer binary operation */ 6158 void gen_opi(int op) 6159 { 6160 int r, fr, opc, c; 6161 6162 switch(op) { 6163 case '+': 6164 case TOK_ADDC1: /* add with carry generation */ 6165 opc = 0; 6166 gen_op8: 6167 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 6168 /* constant case */ 6169 vswap(); 6170 r = gv(RC_INT); 6171 vswap(); 6172 c = vtop->c.i; 6173 if (c == (char)c) { 6174 /* XXX: generate inc and dec for smaller code ? */ 6175 o(0x83); 6176 o(0xc0 | (opc << 3) | r); 6177 g(c); 6178 } else { 6179 o(0x81); 6180 oad(0xc0 | (opc << 3) | r, c); 6181 } 6182 } else { 6183 gv2(RC_INT, RC_INT); 6184 r = vtop[-1].r; 6185 fr = vtop[0].r; 6186 o((opc << 3) | 0x01); 6187 o(0xc0 + r + fr * 8); 6188 } 6189 vtop--; 6190 if (op >= TOK_ULT && op <= TOK_GT) { 6191 vtop->r = VT_CMP; 6192 vtop->c.i = op; 6193 } 6194 break; 6195 case '-': 6196 case TOK_SUBC1: /* sub with carry generation */ 6197 opc = 5; 6198 goto gen_op8; 6199 case TOK_ADDC2: /* add with carry use */ 6200 opc = 2; 6201 goto gen_op8; 6202 case TOK_SUBC2: /* sub with carry use */ 6203 opc = 3; 6204 goto gen_op8; 6205 case '&': 6206 opc = 4; 6207 goto gen_op8; 6208 case '^': 6209 opc = 6; 6210 goto gen_op8; 6211 case '|': 6212 opc = 1; 6213 goto gen_op8; 6214 case '*': 6215 gv2(RC_INT, RC_INT); 6216 r = vtop[-1].r; 6217 fr = vtop[0].r; 6218 vtop--; 6219 o(0xaf0f); /* imul fr, r */ 6220 o(0xc0 + fr + r * 8); 6221 break; 6222 case TOK_SHL: 6223 opc = 4; 6224 goto gen_shift; 6225 case TOK_SHR: 6226 opc = 5; 6227 goto gen_shift; 6228 case TOK_SAR: 6229 opc = 7; 6230 gen_shift: 6231 opc = 0xc0 | (opc << 3); 6232 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 6233 /* constant case */ 6234 vswap(); 6235 r = gv(RC_INT); 6236 vswap(); 6237 c = vtop->c.i & 0x1f; 6238 o(0xc1); /* shl/shr/sar $xxx, r */ 6239 o(opc | r); 6240 g(c); 6241 } else { 6242 /* we generate the shift in ecx */ 6243 gv2(RC_INT, RC_ECX); 6244 r = vtop[-1].r; 6245 o(0xd3); /* shl/shr/sar %cl, r */ 6246 o(opc | r); 6247 } 6248 vtop--; 6249 break; 6250 case '/': 6251 case TOK_UDIV: 6252 case TOK_PDIV: 6253 case '%': 6254 case TOK_UMOD: 6255 case TOK_UMULL: 6256 /* first operand must be in eax */ 6257 /* XXX: need better constraint for second operand */ 6258 gv2(RC_EAX, RC_ECX); 6259 r = vtop[-1].r; 6260 fr = vtop[0].r; 6261 vtop--; 6262 save_reg(TREG_EDX); 6263 if (op == TOK_UMULL) { 6264 o(0xf7); /* mul fr */ 6265 o(0xe0 + fr); 6266 vtop->r2 = TREG_EDX; 6267 r = TREG_EAX; 6268 } else { 6269 if (op == TOK_UDIV || op == TOK_UMOD) { 6270 o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ 6271 o(0xf0 + fr); 6272 } else { 6273 o(0xf799); /* cltd, idiv fr, %eax */ 6274 o(0xf8 + fr); 6275 } 6276 if (op == '%' || op == TOK_UMOD) 6277 r = TREG_EDX; 6278 else 6279 r = TREG_EAX; 6280 } 6281 vtop->r = r; 6282 break; 6283 default: 6284 opc = 7; 6285 goto gen_op8; 6286 } 6287 } 6288 6289 /* generate a floating point operation 'v = t1 op t2' instruction. The 6290 two operands are guaranted to have the same floating point type */ 6291 /* XXX: need to use ST1 too */ 6292 void gen_opf(int op) 6293 { 6294 int a, ft, fc, swapped, r; 6295 6296 /* convert constants to memory references */ 6297 if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { 6298 vswap(); 6299 gv(RC_FLOAT); 6300 vswap(); 6301 } 6302 if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) 6303 gv(RC_FLOAT); 6304 6305 /* must put at least one value in the floating point register */ 6306 if ((vtop[-1].r & VT_LVAL) && 6307 (vtop[0].r & VT_LVAL)) { 6308 vswap(); 6309 gv(RC_FLOAT); 6310 vswap(); 6311 } 6312 swapped = 0; 6313 /* swap the stack if needed so that t1 is the register and t2 is 6314 the memory reference */ 6315 if (vtop[-1].r & VT_LVAL) { 6316 vswap(); 6317 swapped = 1; 6318 } 6319 if (op >= TOK_ULT && op <= TOK_GT) { 6320 /* load on stack second operand */ 6321 load(TREG_ST0, vtop); 6322 save_reg(TREG_EAX); /* eax is used by FP comparison code */ 6323 if (op == TOK_GE || op == TOK_GT) 6324 swapped = !swapped; 6325 else if (op == TOK_EQ || op == TOK_NE) 6326 swapped = 0; 6327 if (swapped) 6328 o(0xc9d9); /* fxch %st(1) */ 6329 o(0xe9da); /* fucompp */ 6330 o(0xe0df); /* fnstsw %ax */ 6331 if (op == TOK_EQ) { 6332 o(0x45e480); /* and $0x45, %ah */ 6333 o(0x40fC80); /* cmp $0x40, %ah */ 6334 } else if (op == TOK_NE) { 6335 o(0x45e480); /* and $0x45, %ah */ 6336 o(0x40f480); /* xor $0x40, %ah */ 6337 op = TOK_NE; 6338 } else if (op == TOK_GE || op == TOK_LE) { 6339 o(0x05c4f6); /* test $0x05, %ah */ 6340 op = TOK_EQ; 6341 } else { 6342 o(0x45c4f6); /* test $0x45, %ah */ 6343 op = TOK_EQ; 6344 } 6345 vtop--; 6346 vtop->r = VT_CMP; 6347 vtop->c.i = op; 6348 } else { 6349 /* no memory reference possible for long double operations */ 6350 if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { 6351 load(TREG_ST0, vtop); 6352 swapped = !swapped; 6353 } 6354 6355 switch(op) { 6356 default: 6357 case '+': 6358 a = 0; 6359 break; 6360 case '-': 6361 a = 4; 6362 if (swapped) 6363 a++; 6364 break; 6365 case '*': 6366 a = 1; 6367 break; 6368 case '/': 6369 a = 6; 6370 if (swapped) 6371 a++; 6372 break; 6373 } 6374 ft = vtop->type.t; 6375 fc = vtop->c.ul; 6376 if ((ft & VT_BTYPE) == VT_LDOUBLE) { 6377 o(0xde); /* fxxxp %st, %st(1) */ 6378 o(0xc1 + (a << 3)); 6379 } else { 6380 /* if saved lvalue, then we must reload it */ 6381 r = vtop->r; 6382 if ((r & VT_VALMASK) == VT_LLOCAL) { 6383 SValue v1; 6384 r = get_reg(RC_INT); 6385 v1.type.t = VT_INT; 6386 v1.r = VT_LOCAL | VT_LVAL; 6387 v1.c.ul = fc; 6388 load(r, &v1); 6389 fc = 0; 6390 } 6391 6392 if ((ft & VT_BTYPE) == VT_DOUBLE) 6393 o(0xdc); 6394 else 6395 o(0xd8); 6396 gen_modrm(a, r, vtop->sym, fc); 6397 } 6398 vtop--; 6399 } 6400 } 6401 6402 /* convert integers to fp 't' type. Must handle 'int', 'unsigned int' 6403 and 'long long' cases. */ 6404 void gen_cvt_itof(int t) 6405 { 6406 save_reg(TREG_ST0); 6407 gv(RC_INT); 6408 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { 6409 /* signed long long to float/double/long double (unsigned case 6410 is handled generically) */ 6411 o(0x50 + vtop->r2); /* push r2 */ 6412 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ 6413 o(0x242cdf); /* fildll (%esp) */ 6414 o(0x08c483); /* add $8, %esp */ 6415 } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 6416 (VT_INT | VT_UNSIGNED)) { 6417 /* unsigned int to float/double/long double */ 6418 o(0x6a); /* push $0 */ 6419 g(0x00); 6420 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ 6421 o(0x242cdf); /* fildll (%esp) */ 6422 o(0x08c483); /* add $8, %esp */ 6423 } else { 6424 /* int to float/double/long double */ 6425 o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ 6426 o(0x2404db); /* fildl (%esp) */ 6427 o(0x04c483); /* add $4, %esp */ 6428 } 6429 vtop->r = TREG_ST0; 6430 } 6431 6432 /* convert fp to int 't' type */ 6433 /* XXX: handle long long case */ 6434 void gen_cvt_ftoi(int t) 6435 { 6436 int r, r2, size; 6437 Sym *sym; 6438 CType ushort_type; 6439 6440 ushort_type.t = VT_SHORT | VT_UNSIGNED; 6441 6442 gv(RC_FLOAT); 6443 if (t != VT_INT) 6444 size = 8; 6445 else 6446 size = 4; 6447 6448 o(0x2dd9); /* ldcw xxx */ 6449 sym = external_global_sym(TOK___tcc_int_fpu_control, 6450 &ushort_type, VT_LVAL); 6451 greloc(cur_text_section, sym, 6452 ind, R_386_32); 6453 gen_le32(0); 6454 6455 oad(0xec81, size); /* sub $xxx, %esp */ 6456 if (size == 4) 6457 o(0x1cdb); /* fistpl */ 6458 else 6459 o(0x3cdf); /* fistpll */ 6460 o(0x24); 6461 o(0x2dd9); /* ldcw xxx */ 6462 sym = external_global_sym(TOK___tcc_fpu_control, 6463 &ushort_type, VT_LVAL); 6464 greloc(cur_text_section, sym, 6465 ind, R_386_32); 6466 gen_le32(0); 6467 6468 r = get_reg(RC_INT); 6469 o(0x58 + r); /* pop r */ 6470 if (size == 8) { 6471 if (t == VT_LLONG) { 6472 vtop->r = r; /* mark reg as used */ 6473 r2 = get_reg(RC_INT); 6474 o(0x58 + r2); /* pop r2 */ 6475 vtop->r2 = r2; 6476 } else { 6477 o(0x04c483); /* add $4, %esp */ 6478 } 6479 } 6480 vtop->r = r; 6481 } 6482 6483 /* convert from one floating point type to another */ 6484 void gen_cvt_ftof(int t) 6485 { 6486 /* all we have to do on i386 is to put the float in a register */ 6487 gv(RC_FLOAT); 6488 } 6489 6490 /* computed goto support */ 6491 void ggoto(void) 6492 { 6493 gcall_or_jmp(1); 6494 vtop--; 6495 } 6496 6497 /* bound check support functions */ 6498 #ifdef CONFIG_TCC_BCHECK 6499 6500 /* generate a bounded pointer addition */ 6501 void gen_bounded_ptr_add(void) 6502 { 6503 Sym *sym; 6504 6505 /* prepare fast i386 function call (args in eax and edx) */ 6506 gv2(RC_EAX, RC_EDX); 6507 /* save all temporary registers */ 6508 vtop -= 2; 6509 save_regs(0); 6510 /* do a fast function call */ 6511 sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0); 6512 greloc(cur_text_section, sym, 6513 ind + 1, R_386_PC32); 6514 oad(0xe8, -4); 6515 /* returned pointer is in eax */ 6516 vtop++; 6517 vtop->r = TREG_EAX | VT_BOUNDED; 6518 /* address of bounding function call point */ 6519 vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 6520 } 6521 6522 /* patch pointer addition in vtop so that pointer dereferencing is 6523 also tested */ 6524 void gen_bounded_ptr_deref(void) 6525 { 6526 int func; 6527 int size, align; 6528 Elf32_Rel *rel; 6529 Sym *sym; 6530 6531 size = 0; 6532 /* XXX: put that code in generic part of tcc */ 6533 if (!is_float(vtop->type.t)) { 6534 if (vtop->r & VT_LVAL_BYTE) 6535 size = 1; 6536 else if (vtop->r & VT_LVAL_SHORT) 6537 size = 2; 6538 } 6539 if (!size) 6540 size = type_size(&vtop->type, &align); 6541 switch(size) { 6542 case 1: func = TOK___bound_ptr_indir1; break; 6543 case 2: func = TOK___bound_ptr_indir2; break; 6544 case 4: func = TOK___bound_ptr_indir4; break; 6545 case 8: func = TOK___bound_ptr_indir8; break; 6546 case 12: func = TOK___bound_ptr_indir12; break; 6547 case 16: func = TOK___bound_ptr_indir16; break; 6548 default: 6549 error("unhandled size when derefencing bounded pointer"); 6550 func = 0; 6551 break; 6552 } 6553 6554 /* patch relocation */ 6555 /* XXX: find a better solution ? */ 6556 rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul); 6557 sym = external_global_sym(func, &func_old_type, 0); 6558 if (!sym->c) 6559 put_extern_sym(sym, NULL, 0, 0); 6560 rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info)); 6561 } 6562 #endif 6563 6564 /* end of X86 code generator */ 6565 /*************************************************************/ 6566 6567 //--------------------------------------------------------------------------- 6568 #endif 6569 6570 // njn: commented these out 6571 //#ifdef TCC_TARGET_ARM 6572 //#include "arm-gen.c" 6573 //#endif 6574 // 6575 //#ifdef TCC_TARGET_C67 6576 //#include "c67-gen.c" 6577 //#endif 6578 6579 #ifdef CONFIG_TCC_STATIC 6580 6581 #define RTLD_LAZY 0x001 6582 #define RTLD_NOW 0x002 6583 #define RTLD_GLOBAL 0x100 6584 #define RTLD_DEFAULT NULL 6585 6586 /* dummy function for profiling */ 6587 void *dlopen(const char *filename, int flag) 6588 { 6589 return NULL; 6590 } 6591 6592 const char *dlerror(void) 6593 { 6594 return "error"; 6595 } 6596 6597 typedef struct TCCSyms { 6598 char *str; 6599 void *ptr; 6600 } TCCSyms; 6601 6602 #define TCCSYM(a) { #a, &a, }, 6603 6604 /* add the symbol you want here if no dynamic linking is done */ 6605 static TCCSyms tcc_syms[] = { 6606 #if !defined(CONFIG_TCCBOOT) 6607 TCCSYM(printf) 6608 TCCSYM(fprintf) 6609 TCCSYM(fopen) 6610 TCCSYM(fclose) 6611 #endif 6612 { NULL, NULL }, 6613 }; 6614 6615 void *resolve_sym(TCCState *s1, const char *symbol, int type) 6616 { 6617 TCCSyms *p; 6618 p = tcc_syms; 6619 while (p->str != NULL) { 6620 if (!strcmp(p->str, symbol)) 6621 return p->ptr; 6622 p++; 6623 } 6624 return NULL; 6625 } 6626 6627 #elif !defined(WIN32) 6628 6629 #include <dlfcn.h> 6630 6631 void *resolve_sym(TCCState *s1, const char *sym, int type) 6632 { 6633 assert(0); 6634 return 0; //dlsym(RTLD_DEFAULT, sym); 6635 // jrs: remove need for dlsym 6636 } 6637 6638 #endif 6639 6640 /********************************************************/ 6641 6642 /* we use our own 'finite' function to avoid potential problems with 6643 non standard math libs */ 6644 /* XXX: endianness dependent */ 6645 int ieee_finite(double d) 6646 { 6647 int *p = (int *)&d; 6648 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31; 6649 } 6650 6651 /* copy a string and truncate it. */ 6652 static char *pstrcpy(char *buf, int buf_size, const char *s) 6653 { 6654 char *q, *q_end; 6655 int c; 6656 6657 if (buf_size > 0) { 6658 q = buf; 6659 q_end = buf + buf_size - 1; 6660 while (q < q_end) { 6661 c = *s++; 6662 if (c == '\0') 6663 break; 6664 *q++ = c; 6665 } 6666 *q = '\0'; 6667 } 6668 return buf; 6669 } 6670 6671 /* strcat and truncate. */ 6672 static char *pstrcat(char *buf, int buf_size, const char *s) 6673 { 6674 int len; 6675 len = strlen(buf); 6676 if (len < buf_size) 6677 pstrcpy(buf + len, buf_size - len, s); 6678 return buf; 6679 } 6680 6681 static int strstart(const char *str, const char *val, const char **ptr) 6682 { 6683 const char *p, *q; 6684 p = str; 6685 q = val; 6686 while (*q != '\0') { 6687 if (*p != *q) 6688 return 0; 6689 p++; 6690 q++; 6691 } 6692 if (ptr) 6693 *ptr = p; 6694 return 1; 6695 } 6696 6697 /* memory management */ 6698 #ifdef MEM_DEBUG 6699 int mem_cur_size; 6700 int mem_max_size; 6701 #endif 6702 6703 static inline void tcc_free(void *ptr) 6704 { 6705 #ifdef MEM_DEBUG 6706 mem_cur_size -= malloc_usable_size(ptr); 6707 #endif 6708 free(ptr); 6709 } 6710 6711 static void *tcc_malloc(unsigned long size) 6712 { 6713 void *ptr; 6714 ptr = malloc(size); 6715 if (!ptr && size) 6716 error("memory full"); 6717 #ifdef MEM_DEBUG 6718 mem_cur_size += malloc_usable_size(ptr); 6719 if (mem_cur_size > mem_max_size) 6720 mem_max_size = mem_cur_size; 6721 #endif 6722 return ptr; 6723 } 6724 6725 static void *tcc_mallocz(unsigned long size) 6726 { 6727 void *ptr; 6728 ptr = tcc_malloc(size); 6729 memset(ptr, 0, size); 6730 return ptr; 6731 } 6732 6733 static inline void *tcc_realloc(void *ptr, unsigned long size) 6734 { 6735 void *ptr1; 6736 #ifdef MEM_DEBUG 6737 mem_cur_size -= malloc_usable_size(ptr); 6738 #endif 6739 ptr1 = realloc(ptr, size); 6740 #ifdef MEM_DEBUG 6741 /* NOTE: count not correct if alloc error, but not critical */ 6742 mem_cur_size += malloc_usable_size(ptr1); 6743 if (mem_cur_size > mem_max_size) 6744 mem_max_size = mem_cur_size; 6745 #endif 6746 return ptr1; 6747 } 6748 6749 static char *tcc_strdup(const char *str) 6750 { 6751 char *ptr; 6752 ptr = tcc_malloc(strlen(str) + 1); 6753 strcpy(ptr, str); 6754 return ptr; 6755 } 6756 6757 #define free(p) use_tcc_free(p) 6758 #define malloc(s) use_tcc_malloc(s) 6759 #define realloc(p, s) use_tcc_realloc(p, s) 6760 6761 static void dynarray_add(void ***ptab, int *nb_ptr, void *data) 6762 { 6763 int nb, nb_alloc; 6764 void **pp; 6765 6766 nb = *nb_ptr; 6767 pp = *ptab; 6768 /* every power of two we double array size */ 6769 if ((nb & (nb - 1)) == 0) { 6770 if (!nb) 6771 nb_alloc = 1; 6772 else 6773 nb_alloc = nb * 2; 6774 pp = tcc_realloc(pp, nb_alloc * sizeof(void *)); 6775 if (!pp) 6776 error("memory full"); 6777 *ptab = pp; 6778 } 6779 pp[nb++] = data; 6780 *nb_ptr = nb; 6781 } 6782 6783 /* symbol allocator */ 6784 static Sym *__sym_malloc(void) 6785 { 6786 Sym *sym_pool, *sym, *last_sym; 6787 int i; 6788 6789 sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym)); 6790 6791 last_sym = sym_free_first; 6792 sym = sym_pool; 6793 for(i = 0; i < SYM_POOL_NB; i++) { 6794 sym->next = last_sym; 6795 last_sym = sym; 6796 sym++; 6797 } 6798 sym_free_first = last_sym; 6799 return last_sym; 6800 } 6801 6802 static inline Sym *sym_malloc(void) 6803 { 6804 Sym *sym; 6805 sym = sym_free_first; 6806 if (!sym) 6807 sym = __sym_malloc(); 6808 sym_free_first = sym->next; 6809 return sym; 6810 } 6811 6812 static inline void sym_free(Sym *sym) 6813 { 6814 sym->next = sym_free_first; 6815 sym_free_first = sym; 6816 } 6817 6818 Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) 6819 { 6820 Section *sec; 6821 6822 sec = tcc_mallocz(sizeof(Section) + strlen(name)); 6823 strcpy(sec->name, name); 6824 sec->sh_type = sh_type; 6825 sec->sh_flags = sh_flags; 6826 switch(sh_type) { 6827 case SHT_HASH: 6828 case SHT_REL: 6829 case SHT_DYNSYM: 6830 case SHT_SYMTAB: 6831 case SHT_DYNAMIC: 6832 sec->sh_addralign = 4; 6833 break; 6834 case SHT_STRTAB: 6835 sec->sh_addralign = 1; 6836 break; 6837 default: 6838 sec->sh_addralign = 32; /* default conservative alignment */ 6839 break; 6840 } 6841 6842 /* only add section if not private */ 6843 if (!(sh_flags & SHF_PRIVATE)) { 6844 sec->sh_num = s1->nb_sections; 6845 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec); 6846 } 6847 return sec; 6848 } 6849 6850 static void free_section(Section *s) 6851 { 6852 tcc_free(s->data); 6853 tcc_free(s); 6854 } 6855 6856 /* realloc section and set its content to zero */ 6857 static void section_realloc(Section *sec, unsigned long new_size) 6858 { 6859 unsigned long size; 6860 unsigned char *data; 6861 6862 size = sec->data_allocated; 6863 if (size == 0) 6864 size = 1; 6865 while (size < new_size) 6866 size = size * 2; 6867 data = tcc_realloc(sec->data, size); 6868 if (!data) 6869 error("memory full"); 6870 memset(data + sec->data_allocated, 0, size - sec->data_allocated); 6871 sec->data = data; 6872 sec->data_allocated = size; 6873 } 6874 6875 /* reserve at least 'size' bytes in section 'sec' from 6876 sec->data_offset. */ 6877 static void *section_ptr_add(Section *sec, unsigned long size) 6878 { 6879 unsigned long offset, offset1; 6880 6881 offset = sec->data_offset; 6882 offset1 = offset + size; 6883 if (offset1 > sec->data_allocated) 6884 section_realloc(sec, offset1); 6885 sec->data_offset = offset1; 6886 return sec->data + offset; 6887 } 6888 6889 /* return a reference to a section, and create it if it does not 6890 exists */ 6891 Section *find_section(TCCState *s1, const char *name) 6892 { 6893 Section *sec; 6894 int i; 6895 for(i = 1; i < s1->nb_sections; i++) { 6896 sec = s1->sections[i]; 6897 if (!strcmp(name, sec->name)) 6898 return sec; 6899 } 6900 /* sections are created as PROGBITS */ 6901 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC); 6902 } 6903 6904 #define SECTION_ABS ((void *)1) 6905 6906 /* update sym->c so that it points to an external symbol in section 6907 'section' with value 'value' */ 6908 static void put_extern_sym2(Sym *sym, Section *section, 6909 unsigned long value, unsigned long size, 6910 int can_add_underscore) 6911 { 6912 int sym_type, sym_bind, sh_num, info; 6913 Elf32_Sym *esym; 6914 const char *name; 6915 char buf1[256]; 6916 6917 if (section == NULL) 6918 sh_num = SHN_UNDEF; 6919 else if (section == SECTION_ABS) 6920 sh_num = SHN_ABS; 6921 else 6922 sh_num = section->sh_num; 6923 if (!sym->c) { 6924 if ((sym->type.t & VT_BTYPE) == VT_FUNC) 6925 sym_type = STT_FUNC; 6926 else 6927 sym_type = STT_OBJECT; 6928 if (sym->type.t & VT_STATIC) 6929 sym_bind = STB_LOCAL; 6930 else 6931 sym_bind = STB_GLOBAL; 6932 6933 name = get_tok_str(sym->v, NULL); 6934 #ifdef CONFIG_TCC_BCHECK 6935 if (do_bounds_check) { 6936 char buf[32]; 6937 6938 /* XXX: avoid doing that for statics ? */ 6939 /* if bound checking is activated, we change some function 6940 names by adding the "__bound" prefix */ 6941 switch(sym->v) { 6942 #if 0 6943 /* XXX: we rely only on malloc hooks */ 6944 case TOK_malloc: 6945 case TOK_free: 6946 case TOK_realloc: 6947 case TOK_memalign: 6948 case TOK_calloc: 6949 #endif 6950 case TOK_memcpy: 6951 case TOK_memmove: 6952 case TOK_memset: 6953 case TOK_strlen: 6954 case TOK_strcpy: 6955 strcpy(buf, "__bound_"); 6956 strcat(buf, name); 6957 name = buf; 6958 break; 6959 } 6960 } 6961 #endif 6962 if (tcc_state->leading_underscore && can_add_underscore) { 6963 buf1[0] = '_'; 6964 pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); 6965 name = buf1; 6966 } 6967 info = ELF32_ST_INFO(sym_bind, sym_type); 6968 sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name); 6969 } else { 6970 esym = &((Elf32_Sym *)symtab_section->data)[sym->c]; 6971 esym->st_value = value; 6972 esym->st_size = size; 6973 esym->st_shndx = sh_num; 6974 } 6975 } 6976 6977 static void put_extern_sym(Sym *sym, Section *section, 6978 unsigned long value, unsigned long size) 6979 { 6980 put_extern_sym2(sym, section, value, size, 1); 6981 } 6982 6983 /* add a new relocation entry to symbol 'sym' in section 's' */ 6984 static void greloc(Section *s, Sym *sym, unsigned long offset, int type) 6985 { 6986 if (!sym->c) 6987 put_extern_sym(sym, NULL, 0, 0); 6988 /* now we can add ELF relocation info */ 6989 put_elf_reloc(symtab_section, s, offset, type, sym->c); 6990 } 6991 6992 static inline int isid(int c) 6993 { 6994 return (c >= 'a' && c <= 'z') || 6995 (c >= 'A' && c <= 'Z') || 6996 c == '_'; 6997 } 6998 6999 static inline int isnum(int c) 7000 { 7001 return c >= '0' && c <= '9'; 7002 } 7003 7004 static inline int isoct(int c) 7005 { 7006 return c >= '0' && c <= '7'; 7007 } 7008 7009 static inline int toup(int c) 7010 { 7011 if (c >= 'a' && c <= 'z') 7012 return c - 'a' + 'A'; 7013 else 7014 return c; 7015 } 7016 7017 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap) 7018 { 7019 int len; 7020 len = strlen(buf); 7021 vsnprintf(buf + len, buf_size - len, fmt, ap); 7022 } 7023 7024 static void strcat_printf(char *buf, int buf_size, const char *fmt, ...) 7025 { 7026 va_list ap; 7027 va_start(ap, fmt); 7028 strcat_vprintf(buf, buf_size, fmt, ap); 7029 va_end(ap); 7030 } 7031 7032 void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap) 7033 { 7034 char buf[2048]; 7035 BufferedFile **f; 7036 7037 buf[0] = '\0'; 7038 if (file) { 7039 for(f = s1->include_stack; f < s1->include_stack_ptr; f++) 7040 strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", 7041 (*f)->filename, (*f)->line_num); 7042 if (file->line_num > 0) { 7043 strcat_printf(buf, sizeof(buf), 7044 "%s:%d: ", file->filename, file->line_num); 7045 } else { 7046 strcat_printf(buf, sizeof(buf), 7047 "%s: ", file->filename); 7048 } 7049 } else { 7050 strcat_printf(buf, sizeof(buf), 7051 "tcc: "); 7052 } 7053 if (is_warning) 7054 strcat_printf(buf, sizeof(buf), "warning: "); 7055 strcat_vprintf(buf, sizeof(buf), fmt, ap); 7056 7057 if (!s1->error_func) { 7058 /* default case: stderr */ 7059 fprintf(stderr, "%s\n", buf); 7060 } else { 7061 s1->error_func(s1->error_opaque, buf); 7062 } 7063 if (!is_warning || s1->warn_error) 7064 s1->nb_errors++; 7065 } 7066 7067 #ifdef LIBTCC 7068 void tcc_set_error_func(TCCState *s, void *error_opaque, 7069 void (*error_func)(void *opaque, const char *msg)) 7070 { 7071 s->error_opaque = error_opaque; 7072 s->error_func = error_func; 7073 } 7074 #endif 7075 7076 /* error without aborting current compilation */ 7077 void error_noabort(const char *fmt, ...) 7078 { 7079 TCCState *s1 = tcc_state; 7080 va_list ap; 7081 7082 va_start(ap, fmt); 7083 error1(s1, 0, fmt, ap); 7084 va_end(ap); 7085 } 7086 7087 void error(const char *fmt, ...) 7088 { 7089 TCCState *s1 = tcc_state; 7090 va_list ap; 7091 7092 va_start(ap, fmt); 7093 error1(s1, 0, fmt, ap); 7094 va_end(ap); 7095 /* better than nothing: in some cases, we accept to handle errors */ 7096 if (s1->error_set_jmp_enabled) { 7097 longjmp(s1->error_jmp_buf, 1); 7098 } else { 7099 /* XXX: eliminate this someday */ 7100 exit(1); 7101 } 7102 } 7103 7104 void expect(const char *msg) 7105 { 7106 error("%s expected", msg); 7107 } 7108 7109 void warning(const char *fmt, ...) 7110 { 7111 TCCState *s1 = tcc_state; 7112 va_list ap; 7113 7114 if (s1->warn_none) 7115 return; 7116 7117 va_start(ap, fmt); 7118 error1(s1, 1, fmt, ap); 7119 va_end(ap); 7120 } 7121 7122 void skip(int c) 7123 { 7124 if (tok != c) 7125 error("'%c' expected", c); 7126 next(); 7127 } 7128 7129 static void test_lvalue(void) 7130 { 7131 if (!(vtop->r & VT_LVAL)) 7132 expect("lvalue"); 7133 } 7134 7135 /* allocate a new token */ 7136 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len) 7137 { 7138 TokenSym *ts, **ptable; 7139 int i; 7140 7141 if (tok_ident >= SYM_FIRST_ANOM) 7142 error("memory full"); 7143 7144 /* expand token table if needed */ 7145 i = tok_ident - TOK_IDENT; 7146 if ((i % TOK_ALLOC_INCR) == 0) { 7147 ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *)); 7148 if (!ptable) 7149 error("memory full"); 7150 table_ident = ptable; 7151 } 7152 7153 ts = tcc_malloc(sizeof(TokenSym) + len); 7154 table_ident[i] = ts; 7155 ts->tok = tok_ident++; 7156 ts->sym_define = NULL; 7157 ts->sym_label = NULL; 7158 ts->sym_struct = NULL; 7159 ts->sym_identifier = NULL; 7160 ts->len = len; 7161 ts->hash_next = NULL; 7162 memcpy(ts->str, str, len); 7163 ts->str[len] = '\0'; 7164 *pts = ts; 7165 return ts; 7166 } 7167 7168 #define TOK_HASH_INIT 1 7169 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c)) 7170 7171 /* find a token and add it if not found */ 7172 static TokenSym *tok_alloc(const char *str, int len) 7173 { 7174 TokenSym *ts, **pts; 7175 int i; 7176 unsigned int h; 7177 7178 h = TOK_HASH_INIT; 7179 for(i=0;i<len;i++) 7180 h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]); 7181 h &= (TOK_HASH_SIZE - 1); 7182 7183 pts = &hash_ident[h]; 7184 for(;;) { 7185 ts = *pts; 7186 if (!ts) 7187 break; 7188 if (ts->len == len && !memcmp(ts->str, str, len)) 7189 return ts; 7190 pts = &(ts->hash_next); 7191 } 7192 return tok_alloc_new(pts, str, len); 7193 } 7194 7195 /* CString handling */ 7196 7197 static void cstr_realloc(CString *cstr, int new_size) 7198 { 7199 int size; 7200 void *data; 7201 7202 size = cstr->size_allocated; 7203 if (size == 0) 7204 size = 8; /* no need to allocate a too small first string */ 7205 while (size < new_size) 7206 size = size * 2; 7207 data = tcc_realloc(cstr->data_allocated, size); 7208 if (!data) 7209 error("memory full"); 7210 cstr->data_allocated = data; 7211 cstr->size_allocated = size; 7212 cstr->data = data; 7213 } 7214 7215 /* add a byte */ 7216 static inline void cstr_ccat(CString *cstr, int ch) 7217 { 7218 int size; 7219 size = cstr->size + 1; 7220 if (size > cstr->size_allocated) 7221 cstr_realloc(cstr, size); 7222 ((unsigned char *)cstr->data)[size - 1] = ch; 7223 cstr->size = size; 7224 } 7225 7226 static void cstr_cat(CString *cstr, const char *str) 7227 { 7228 int c; 7229 for(;;) { 7230 c = *str; 7231 if (c == '\0') 7232 break; 7233 cstr_ccat(cstr, c); 7234 str++; 7235 } 7236 } 7237 7238 /* add a wide char */ 7239 static void cstr_wccat(CString *cstr, int ch) 7240 { 7241 int size; 7242 size = cstr->size + sizeof(int); 7243 if (size > cstr->size_allocated) 7244 cstr_realloc(cstr, size); 7245 *(int *)(((unsigned char *)cstr->data) + size - sizeof(int)) = ch; 7246 cstr->size = size; 7247 } 7248 7249 static void cstr_new(CString *cstr) 7250 { 7251 memset(cstr, 0, sizeof(CString)); 7252 } 7253 7254 /* free string and reset it to NULL */ 7255 static void cstr_free(CString *cstr) 7256 { 7257 tcc_free(cstr->data_allocated); 7258 cstr_new(cstr); 7259 } 7260 7261 #define cstr_reset(cstr) cstr_free(cstr) 7262 7263 /* XXX: unicode ? */ 7264 static void add_char(CString *cstr, int c) 7265 { 7266 if (c == '\'' || c == '\"' || c == '\\') { 7267 /* XXX: could be more precise if char or string */ 7268 cstr_ccat(cstr, '\\'); 7269 } 7270 if (c >= 32 && c <= 126) { 7271 cstr_ccat(cstr, c); 7272 } else { 7273 cstr_ccat(cstr, '\\'); 7274 if (c == '\n') { 7275 cstr_ccat(cstr, 'n'); 7276 } else { 7277 cstr_ccat(cstr, '0' + ((c >> 6) & 7)); 7278 cstr_ccat(cstr, '0' + ((c >> 3) & 7)); 7279 cstr_ccat(cstr, '0' + (c & 7)); 7280 } 7281 } 7282 } 7283 7284 /* XXX: buffer overflow */ 7285 /* XXX: float tokens */ 7286 char *get_tok_str(int v, CValue *cv) 7287 { 7288 static char buf[STRING_MAX_SIZE + 1]; 7289 static CString cstr_buf; 7290 CString *cstr; 7291 unsigned char *q; 7292 char *p; 7293 int i, len; 7294 7295 /* NOTE: to go faster, we give a fixed buffer for small strings */ 7296 cstr_reset(&cstr_buf); 7297 cstr_buf.data = buf; 7298 cstr_buf.size_allocated = sizeof(buf); 7299 p = buf; 7300 7301 switch(v) { 7302 case TOK_CINT: 7303 case TOK_CUINT: 7304 /* XXX: not quite exact, but only useful for testing */ 7305 sprintf(p, "%u", cv->ui); 7306 break; 7307 case TOK_CLLONG: 7308 case TOK_CULLONG: 7309 /* XXX: not quite exact, but only useful for testing */ 7310 sprintf(p, "%llu", cv->ull); 7311 break; 7312 case TOK_CCHAR: 7313 case TOK_LCHAR: 7314 cstr_ccat(&cstr_buf, '\''); 7315 add_char(&cstr_buf, cv->i); 7316 cstr_ccat(&cstr_buf, '\''); 7317 cstr_ccat(&cstr_buf, '\0'); 7318 break; 7319 case TOK_PPNUM: 7320 cstr = cv->cstr; 7321 len = cstr->size - 1; 7322 for(i=0;i<len;i++) 7323 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); 7324 cstr_ccat(&cstr_buf, '\0'); 7325 break; 7326 case TOK_STR: 7327 case TOK_LSTR: 7328 cstr = cv->cstr; 7329 cstr_ccat(&cstr_buf, '\"'); 7330 if (v == TOK_STR) { 7331 len = cstr->size - 1; 7332 for(i=0;i<len;i++) 7333 add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]); 7334 } else { 7335 len = (cstr->size / sizeof(int)) - 1; 7336 for(i=0;i<len;i++) 7337 add_char(&cstr_buf, ((int *)cstr->data)[i]); 7338 } 7339 cstr_ccat(&cstr_buf, '\"'); 7340 cstr_ccat(&cstr_buf, '\0'); 7341 break; 7342 case TOK_LT: 7343 v = '<'; 7344 goto addv; 7345 case TOK_GT: 7346 v = '>'; 7347 goto addv; 7348 case TOK_A_SHL: 7349 return strcpy(p, "<<="); 7350 case TOK_A_SAR: 7351 return strcpy(p, ">>="); 7352 default: 7353 if (v < TOK_IDENT) { 7354 /* search in two bytes table */ 7355 q = tok_two_chars; 7356 while (*q) { 7357 if (q[2] == v) { 7358 *p++ = q[0]; 7359 *p++ = q[1]; 7360 *p = '\0'; 7361 return buf; 7362 } 7363 q += 3; 7364 } 7365 addv: 7366 *p++ = v; 7367 *p = '\0'; 7368 } else if (v < tok_ident) { 7369 return table_ident[v - TOK_IDENT]->str; 7370 } else if (v >= SYM_FIRST_ANOM) { 7371 /* special name for anonymous symbol */ 7372 sprintf(p, "L.%u", v - SYM_FIRST_ANOM); 7373 } else { 7374 /* should never happen */ 7375 return NULL; 7376 } 7377 break; 7378 } 7379 return cstr_buf.data; 7380 } 7381 7382 /* push, without hashing */ 7383 static Sym *sym_push2(Sym **ps, long v, long t, long c) 7384 { 7385 Sym *s; 7386 s = sym_malloc(); 7387 s->v = v; 7388 s->type.t = t; 7389 s->c = c; 7390 s->next = NULL; 7391 /* add in stack */ 7392 s->prev = *ps; 7393 *ps = s; 7394 return s; 7395 } 7396 7397 /* find a symbol and return its associated structure. 's' is the top 7398 of the symbol stack */ 7399 static Sym *sym_find2(Sym *s, int v) 7400 { 7401 while (s) { 7402 if (s->v == v) 7403 return s; 7404 s = s->prev; 7405 } 7406 return NULL; 7407 } 7408 7409 /* structure lookup */ 7410 static inline Sym *struct_find(int v) 7411 { 7412 v -= TOK_IDENT; 7413 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) 7414 return NULL; 7415 return table_ident[v]->sym_struct; 7416 } 7417 7418 /* find an identifier */ 7419 static inline Sym *sym_find(int v) 7420 { 7421 v -= TOK_IDENT; 7422 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) 7423 return NULL; 7424 return table_ident[v]->sym_identifier; 7425 } 7426 7427 /* push a given symbol on the symbol stack */ 7428 static Sym *sym_push(int v, CType *type, int r, int c) 7429 { 7430 Sym *s, **ps; 7431 TokenSym *ts; 7432 7433 if (local_stack) 7434 ps = &local_stack; 7435 else 7436 ps = &global_stack; 7437 s = sym_push2(ps, v, type->t, c); 7438 s->type.ref = type->ref; 7439 s->r = r; 7440 /* don't record fields or anonymous symbols */ 7441 /* XXX: simplify */ 7442 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { 7443 /* record symbol in token array */ 7444 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; 7445 if (v & SYM_STRUCT) 7446 ps = &ts->sym_struct; 7447 else 7448 ps = &ts->sym_identifier; 7449 s->prev_tok = *ps; 7450 *ps = s; 7451 } 7452 return s; 7453 } 7454 7455 /* push a global identifier */ 7456 static Sym *global_identifier_push(int v, int t, int c) 7457 { 7458 Sym *s, **ps; 7459 s = sym_push2(&global_stack, v, t, c); 7460 /* don't record anonymous symbol */ 7461 if (v < SYM_FIRST_ANOM) { 7462 ps = &table_ident[v - TOK_IDENT]->sym_identifier; 7463 /* modify the top most local identifier, so that 7464 sym_identifier will point to 's' when popped */ 7465 while (*ps != NULL) 7466 ps = &(*ps)->prev_tok; 7467 s->prev_tok = NULL; 7468 *ps = s; 7469 } 7470 return s; 7471 } 7472 7473 /* pop symbols until top reaches 'b' */ 7474 static void sym_pop(Sym **ptop, Sym *b) 7475 { 7476 Sym *s, *ss, **ps; 7477 TokenSym *ts; 7478 int v; 7479 7480 s = *ptop; 7481 while(s != b) { 7482 ss = s->prev; 7483 v = s->v; 7484 /* remove symbol in token array */ 7485 /* XXX: simplify */ 7486 if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { 7487 ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT]; 7488 if (v & SYM_STRUCT) 7489 ps = &ts->sym_struct; 7490 else 7491 ps = &ts->sym_identifier; 7492 *ps = s->prev_tok; 7493 } 7494 sym_free(s); 7495 s = ss; 7496 } 7497 *ptop = b; 7498 } 7499 7500 /* I/O layer */ 7501 7502 BufferedFile *tcc_open(TCCState *s1, const char *filename) 7503 { 7504 int fd; 7505 BufferedFile *bf; 7506 7507 fd = open(filename, O_RDONLY | O_BINARY); 7508 if (fd < 0) 7509 return NULL; 7510 bf = tcc_malloc(sizeof(BufferedFile)); 7511 if (!bf) { 7512 close(fd); 7513 return NULL; 7514 } 7515 bf->fd = fd; 7516 bf->buf_ptr = bf->buffer; 7517 bf->buf_end = bf->buffer; 7518 bf->buffer[0] = CH_EOB; /* put eob symbol */ 7519 pstrcpy(bf->filename, sizeof(bf->filename), filename); 7520 bf->line_num = 1; 7521 bf->ifndef_macro = 0; 7522 bf->ifdef_stack_ptr = s1->ifdef_stack_ptr; 7523 // printf("opening '%s'\n", filename); 7524 return bf; 7525 } 7526 7527 void tcc_close(BufferedFile *bf) 7528 { 7529 total_lines += bf->line_num; 7530 close(bf->fd); 7531 tcc_free(bf); 7532 } 7533 7534 /* fill input buffer and peek next char */ 7535 static int tcc_peekc_slow(BufferedFile *bf) 7536 { 7537 int len; 7538 /* only tries to read if really end of buffer */ 7539 if (bf->buf_ptr >= bf->buf_end) { 7540 if (bf->fd != -1) { 7541 #if defined(PARSE_DEBUG) 7542 len = 8; 7543 #else 7544 len = IO_BUF_SIZE; 7545 #endif 7546 len = read(bf->fd, bf->buffer, len); 7547 if (len < 0) 7548 len = 0; 7549 } else { 7550 len = 0; 7551 } 7552 total_bytes += len; 7553 bf->buf_ptr = bf->buffer; 7554 bf->buf_end = bf->buffer + len; 7555 *bf->buf_end = CH_EOB; 7556 } 7557 if (bf->buf_ptr < bf->buf_end) { 7558 return bf->buf_ptr[0]; 7559 } else { 7560 bf->buf_ptr = bf->buf_end; 7561 return CH_EOF; 7562 } 7563 } 7564 7565 /* return the current character, handling end of block if necessary 7566 (but not stray) */ 7567 static int handle_eob(void) 7568 { 7569 return tcc_peekc_slow(file); 7570 } 7571 7572 /* read next char from current input file and handle end of input buffer */ 7573 static inline void inp(void) 7574 { 7575 ch = *(++(file->buf_ptr)); 7576 /* end of buffer/file handling */ 7577 if (ch == CH_EOB) 7578 ch = handle_eob(); 7579 } 7580 7581 /* handle '\[\r]\n' */ 7582 static void handle_stray(void) 7583 { 7584 while (ch == '\\') { 7585 inp(); 7586 if (ch == '\n') { 7587 file->line_num++; 7588 inp(); 7589 } else if (ch == '\r') { 7590 inp(); 7591 if (ch != '\n') 7592 goto fail; 7593 file->line_num++; 7594 inp(); 7595 } else { 7596 fail: 7597 error("stray '\\' in program"); 7598 } 7599 } 7600 } 7601 7602 /* skip the stray and handle the \\n case. Output an error if 7603 incorrect char after the stray */ 7604 static int handle_stray1(uint8_t *p) 7605 { 7606 int c; 7607 7608 if (p >= file->buf_end) { 7609 file->buf_ptr = p; 7610 c = handle_eob(); 7611 p = file->buf_ptr; 7612 if (c == '\\') 7613 goto parse_stray; 7614 } else { 7615 parse_stray: 7616 file->buf_ptr = p; 7617 ch = *p; 7618 handle_stray(); 7619 p = file->buf_ptr; 7620 c = *p; 7621 } 7622 return c; 7623 } 7624 7625 /* handle just the EOB case, but not stray */ 7626 #define PEEKC_EOB(c, p)\ 7627 {\ 7628 p++;\ 7629 c = *p;\ 7630 if (c == '\\') {\ 7631 file->buf_ptr = p;\ 7632 c = handle_eob();\ 7633 p = file->buf_ptr;\ 7634 }\ 7635 } 7636 7637 /* handle the complicated stray case */ 7638 #define PEEKC(c, p)\ 7639 {\ 7640 p++;\ 7641 c = *p;\ 7642 if (c == '\\') {\ 7643 c = handle_stray1(p);\ 7644 p = file->buf_ptr;\ 7645 }\ 7646 } 7647 7648 /* input with '\[\r]\n' handling. Note that this function cannot 7649 handle other characters after '\', so you cannot call it inside 7650 strings or comments */ 7651 static void minp(void) 7652 { 7653 inp(); 7654 if (ch == '\\') 7655 handle_stray(); 7656 } 7657 7658 7659 /* single line C++ comments */ 7660 static uint8_t *parse_line_comment(uint8_t *p) 7661 { 7662 int c; 7663 7664 p++; 7665 for(;;) { 7666 c = *p; 7667 redo: 7668 if (c == '\n' || c == CH_EOF) { 7669 break; 7670 } else if (c == '\\') { 7671 file->buf_ptr = p; 7672 c = handle_eob(); 7673 p = file->buf_ptr; 7674 if (c == '\\') { 7675 PEEKC_EOB(c, p); 7676 if (c == '\n') { 7677 file->line_num++; 7678 PEEKC_EOB(c, p); 7679 } else if (c == '\r') { 7680 PEEKC_EOB(c, p); 7681 if (c == '\n') { 7682 file->line_num++; 7683 PEEKC_EOB(c, p); 7684 } 7685 } 7686 } else { 7687 goto redo; 7688 } 7689 } else { 7690 p++; 7691 } 7692 } 7693 return p; 7694 } 7695 7696 /* C comments */ 7697 static uint8_t *parse_comment(uint8_t *p) 7698 { 7699 int c; 7700 7701 p++; 7702 for(;;) { 7703 /* fast skip loop */ 7704 for(;;) { 7705 c = *p; 7706 if (c == '\n' || c == '*' || c == '\\') 7707 break; 7708 p++; 7709 c = *p; 7710 if (c == '\n' || c == '*' || c == '\\') 7711 break; 7712 p++; 7713 } 7714 /* now we can handle all the cases */ 7715 if (c == '\n') { 7716 file->line_num++; 7717 p++; 7718 } else if (c == '*') { 7719 p++; 7720 for(;;) { 7721 c = *p; 7722 if (c == '*') { 7723 p++; 7724 } else if (c == '/') { 7725 goto end_of_comment; 7726 } else if (c == '\\') { 7727 file->buf_ptr = p; 7728 c = handle_eob(); 7729 p = file->buf_ptr; 7730 if (c == '\\') { 7731 /* skip '\[\r]\n', otherwise just skip the stray */ 7732 while (c == '\\') { 7733 PEEKC_EOB(c, p); 7734 if (c == '\n') { 7735 file->line_num++; 7736 PEEKC_EOB(c, p); 7737 } else if (c == '\r') { 7738 PEEKC_EOB(c, p); 7739 if (c == '\n') { 7740 file->line_num++; 7741 PEEKC_EOB(c, p); 7742 } 7743 } else { 7744 goto after_star; 7745 } 7746 } 7747 } 7748 } else { 7749 break; 7750 } 7751 } 7752 after_star: ; 7753 } else { 7754 /* stray, eob or eof */ 7755 file->buf_ptr = p; 7756 c = handle_eob(); 7757 p = file->buf_ptr; 7758 if (c == CH_EOF) { 7759 error("unexpected end of file in comment"); 7760 } else if (c == '\\') { 7761 p++; 7762 } 7763 } 7764 } 7765 end_of_comment: 7766 p++; 7767 return p; 7768 } 7769 7770 #define cinp minp 7771 7772 /* space exlcuding newline */ 7773 static inline int is_space(int ch) 7774 { 7775 return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r'; 7776 } 7777 7778 static inline void skip_spaces(void) 7779 { 7780 while (is_space(ch)) 7781 cinp(); 7782 } 7783 7784 /* parse a string without interpreting escapes */ 7785 static uint8_t *parse_pp_string(uint8_t *p, 7786 int sep, CString *str) 7787 { 7788 int c; 7789 p++; 7790 for(;;) { 7791 c = *p; 7792 if (c == sep) { 7793 break; 7794 } else if (c == '\\') { 7795 file->buf_ptr = p; 7796 c = handle_eob(); 7797 p = file->buf_ptr; 7798 if (c == CH_EOF) { 7799 unterminated_string: 7800 /* XXX: indicate line number of start of string */ 7801 error("missing terminating %c character", sep); 7802 } else if (c == '\\') { 7803 /* escape : just skip \[\r]\n */ 7804 PEEKC_EOB(c, p); 7805 if (c == '\n') { 7806 file->line_num++; 7807 p++; 7808 } else if (c == '\r') { 7809 PEEKC_EOB(c, p); 7810 if (c != '\n') 7811 expect("'\n' after '\r'"); 7812 file->line_num++; 7813 p++; 7814 } else if (c == CH_EOF) { 7815 goto unterminated_string; 7816 } else { 7817 if (str) { 7818 cstr_ccat(str, '\\'); 7819 cstr_ccat(str, c); 7820 } 7821 p++; 7822 } 7823 } 7824 } else if (c == '\n') { 7825 file->line_num++; 7826 goto add_char; 7827 } else if (c == '\r') { 7828 PEEKC_EOB(c, p); 7829 if (c != '\n') { 7830 if (str) 7831 cstr_ccat(str, '\r'); 7832 } else { 7833 file->line_num++; 7834 goto add_char; 7835 } 7836 } else { 7837 add_char: 7838 if (str) 7839 cstr_ccat(str, c); 7840 p++; 7841 } 7842 } 7843 p++; 7844 return p; 7845 } 7846 7847 /* skip block of text until #else, #elif or #endif. skip also pairs of 7848 #if/#endif */ 7849 void preprocess_skip(void) 7850 { 7851 int a, start_of_line, c; 7852 uint8_t *p; 7853 7854 p = file->buf_ptr; 7855 start_of_line = 1; 7856 a = 0; 7857 for(;;) { 7858 redo_no_start: 7859 c = *p; 7860 switch(c) { 7861 case ' ': 7862 case '\t': 7863 case '\f': 7864 case '\v': 7865 case '\r': 7866 p++; 7867 goto redo_no_start; 7868 case '\n': 7869 start_of_line = 1; 7870 file->line_num++; 7871 p++; 7872 goto redo_no_start; 7873 case '\\': 7874 file->buf_ptr = p; 7875 c = handle_eob(); 7876 if (c == CH_EOF) { 7877 expect("#endif"); 7878 } else if (c == '\\') { 7879 /* XXX: incorrect: should not give an error */ 7880 ch = file->buf_ptr[0]; 7881 handle_stray(); 7882 } 7883 p = file->buf_ptr; 7884 goto redo_no_start; 7885 /* skip strings */ 7886 case '\"': 7887 case '\'': 7888 p = parse_pp_string(p, c, NULL); 7889 break; 7890 /* skip comments */ 7891 case '/': 7892 file->buf_ptr = p; 7893 ch = *p; 7894 minp(); 7895 p = file->buf_ptr; 7896 if (ch == '*') { 7897 p = parse_comment(p); 7898 } else if (ch == '/') { 7899 p = parse_line_comment(p); 7900 } 7901 break; 7902 7903 case '#': 7904 p++; 7905 if (start_of_line) { 7906 file->buf_ptr = p; 7907 next_nomacro(); 7908 p = file->buf_ptr; 7909 if (a == 0 && 7910 (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF)) 7911 goto the_end; 7912 if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF) 7913 a++; 7914 else if (tok == TOK_ENDIF) 7915 a--; 7916 } 7917 break; 7918 default: 7919 p++; 7920 break; 7921 } 7922 start_of_line = 0; 7923 } 7924 the_end: ; 7925 file->buf_ptr = p; 7926 } 7927 7928 /* ParseState handling */ 7929 7930 /* XXX: currently, no include file info is stored. Thus, we cannot display 7931 accurate messages if the function or data definition spans multiple 7932 files */ 7933 7934 /* save current parse state in 's' */ 7935 void save_parse_state(ParseState *s) 7936 { 7937 s->line_num = file->line_num; 7938 s->macro_ptr = macro_ptr; 7939 s->tok = tok; 7940 s->tokc = tokc; 7941 } 7942 7943 /* restore parse state from 's' */ 7944 void restore_parse_state(ParseState *s) 7945 { 7946 file->line_num = s->line_num; 7947 macro_ptr = s->macro_ptr; 7948 tok = s->tok; 7949 tokc = s->tokc; 7950 } 7951 7952 /* return the number of additional 'ints' necessary to store the 7953 token */ 7954 static inline int tok_ext_size(int t) 7955 { 7956 switch(t) { 7957 /* 4 bytes */ 7958 case TOK_CINT: 7959 case TOK_CUINT: 7960 case TOK_CCHAR: 7961 case TOK_LCHAR: 7962 case TOK_CFLOAT: 7963 case TOK_LINENUM: 7964 return 1; 7965 case TOK_STR: 7966 case TOK_LSTR: 7967 case TOK_PPNUM: 7968 error("unsupported token"); 7969 return 1; 7970 case TOK_CDOUBLE: 7971 case TOK_CLLONG: 7972 case TOK_CULLONG: 7973 return 2; 7974 case TOK_CLDOUBLE: 7975 return LDOUBLE_SIZE / 4; 7976 default: 7977 return 0; 7978 } 7979 } 7980 7981 /* token string handling */ 7982 7983 static inline void tok_str_new(TokenString *s) 7984 { 7985 s->str = NULL; 7986 s->len = 0; 7987 s->allocated_len = 0; 7988 s->last_line_num = -1; 7989 } 7990 7991 static void tok_str_free(int *str) 7992 { 7993 tcc_free(str); 7994 } 7995 7996 static int *tok_str_realloc(TokenString *s) 7997 { 7998 int *str, len; 7999 8000 if (s->allocated_len == 0) { 8001 len = 8; 8002 } else { 8003 len = s->allocated_len * 2; 8004 } 8005 str = tcc_realloc(s->str, len * sizeof(int)); 8006 if (!str) 8007 error("memory full"); 8008 s->allocated_len = len; 8009 s->str = str; 8010 return str; 8011 } 8012 8013 static void tok_str_add(TokenString *s, int t) 8014 { 8015 int len, *str; 8016 8017 len = s->len; 8018 str = s->str; 8019 if (len >= s->allocated_len) 8020 str = tok_str_realloc(s); 8021 str[len++] = t; 8022 s->len = len; 8023 } 8024 8025 static void tok_str_add2(TokenString *s, int t, CValue *cv) 8026 { 8027 int len, *str; 8028 8029 len = s->len; 8030 str = s->str; 8031 8032 /* allocate space for worst case */ 8033 if (len + TOK_MAX_SIZE > s->allocated_len) 8034 str = tok_str_realloc(s); 8035 str[len++] = t; 8036 switch(t) { 8037 case TOK_CINT: 8038 case TOK_CUINT: 8039 case TOK_CCHAR: 8040 case TOK_LCHAR: 8041 case TOK_CFLOAT: 8042 case TOK_LINENUM: 8043 str[len++] = cv->tab[0]; 8044 break; 8045 case TOK_PPNUM: 8046 case TOK_STR: 8047 case TOK_LSTR: 8048 { 8049 int nb_words; 8050 CString *cstr; 8051 8052 nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2; 8053 while ((len + nb_words) > s->allocated_len) 8054 str = tok_str_realloc(s); 8055 cstr = (CString *)(str + len); 8056 cstr->data = NULL; 8057 cstr->size = cv->cstr->size; 8058 cstr->data_allocated = NULL; 8059 cstr->size_allocated = cstr->size; 8060 memcpy((char *)cstr + sizeof(CString), 8061 cv->cstr->data, cstr->size); 8062 len += nb_words; 8063 } 8064 break; 8065 case TOK_CDOUBLE: 8066 case TOK_CLLONG: 8067 case TOK_CULLONG: 8068 #if LDOUBLE_SIZE == 8 8069 case TOK_CLDOUBLE: 8070 #endif 8071 str[len++] = cv->tab[0]; 8072 str[len++] = cv->tab[1]; 8073 break; 8074 #if LDOUBLE_SIZE == 12 8075 case TOK_CLDOUBLE: 8076 str[len++] = cv->tab[0]; 8077 str[len++] = cv->tab[1]; 8078 str[len++] = cv->tab[2]; 8079 #elif LDOUBLE_SIZE != 8 8080 #error add long double size support 8081 #endif 8082 break; 8083 default: 8084 break; 8085 } 8086 s->len = len; 8087 } 8088 8089 /* add the current parse token in token string 's' */ 8090 static void tok_str_add_tok(TokenString *s) 8091 { 8092 CValue cval; 8093 8094 /* save line number info */ 8095 if (file->line_num != s->last_line_num) { 8096 s->last_line_num = file->line_num; 8097 cval.i = s->last_line_num; 8098 tok_str_add2(s, TOK_LINENUM, &cval); 8099 } 8100 tok_str_add2(s, tok, &tokc); 8101 } 8102 8103 #if LDOUBLE_SIZE == 12 8104 #define LDOUBLE_GET(p, cv) \ 8105 cv.tab[0] = p[0]; \ 8106 cv.tab[1] = p[1]; \ 8107 cv.tab[2] = p[2]; 8108 #elif LDOUBLE_SIZE == 8 8109 #define LDOUBLE_GET(p, cv) \ 8110 cv.tab[0] = p[0]; \ 8111 cv.tab[1] = p[1]; 8112 #else 8113 #error add long double size support 8114 #endif 8115 8116 8117 /* get a token from an integer array and increment pointer 8118 accordingly. we code it as a macro to avoid pointer aliasing. */ 8119 #define TOK_GET(t, p, cv) \ 8120 { \ 8121 t = *p++; \ 8122 switch(t) { \ 8123 case TOK_CINT: \ 8124 case TOK_CUINT: \ 8125 case TOK_CCHAR: \ 8126 case TOK_LCHAR: \ 8127 case TOK_CFLOAT: \ 8128 case TOK_LINENUM: \ 8129 cv.tab[0] = *p++; \ 8130 break; \ 8131 case TOK_STR: \ 8132 case TOK_LSTR: \ 8133 case TOK_PPNUM: \ 8134 cv.cstr = (CString *)p; \ 8135 cv.cstr->data = (char *)p + sizeof(CString);\ 8136 p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\ 8137 break; \ 8138 case TOK_CDOUBLE: \ 8139 case TOK_CLLONG: \ 8140 case TOK_CULLONG: \ 8141 cv.tab[0] = p[0]; \ 8142 cv.tab[1] = p[1]; \ 8143 p += 2; \ 8144 break; \ 8145 case TOK_CLDOUBLE: \ 8146 LDOUBLE_GET(p, cv); \ 8147 p += LDOUBLE_SIZE / 4; \ 8148 break; \ 8149 default: \ 8150 break; \ 8151 } \ 8152 } 8153 8154 /* defines handling */ 8155 static inline void define_push(int v, int macro_type, int *str, Sym *first_arg) 8156 { 8157 Sym *s; 8158 8159 s = sym_push2(&define_stack, v, macro_type, (long)str); 8160 s->next = first_arg; 8161 table_ident[v - TOK_IDENT]->sym_define = s; 8162 } 8163 8164 /* undefined a define symbol. Its name is just set to zero */ 8165 static void define_undef(Sym *s) 8166 { 8167 int v; 8168 v = s->v; 8169 if (v >= TOK_IDENT && v < tok_ident) 8170 table_ident[v - TOK_IDENT]->sym_define = NULL; 8171 s->v = 0; 8172 } 8173 8174 static inline Sym *define_find(int v) 8175 { 8176 v -= TOK_IDENT; 8177 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) 8178 return NULL; 8179 return table_ident[v]->sym_define; 8180 } 8181 8182 /* free define stack until top reaches 'b' */ 8183 static void free_defines(Sym *b) 8184 { 8185 Sym *top, *top1; 8186 int v; 8187 8188 top = define_stack; 8189 while (top != b) { 8190 top1 = top->prev; 8191 /* do not free args or predefined defines */ 8192 if (top->c) 8193 tok_str_free((int *)top->c); 8194 v = top->v; 8195 if (v >= TOK_IDENT && v < tok_ident) 8196 table_ident[v - TOK_IDENT]->sym_define = NULL; 8197 sym_free(top); 8198 top = top1; 8199 } 8200 define_stack = b; 8201 } 8202 8203 /* label lookup */ 8204 static Sym *label_find(int v) 8205 { 8206 v -= TOK_IDENT; 8207 if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT)) 8208 return NULL; 8209 return table_ident[v]->sym_label; 8210 } 8211 8212 static Sym *label_push(Sym **ptop, int v, int flags) 8213 { 8214 Sym *s, **ps; 8215 s = sym_push2(ptop, v, 0, 0); 8216 s->r = flags; 8217 ps = &table_ident[v - TOK_IDENT]->sym_label; 8218 if (ptop == &global_label_stack) { 8219 /* modify the top most local identifier, so that 8220 sym_identifier will point to 's' when popped */ 8221 while (*ps != NULL) 8222 ps = &(*ps)->prev_tok; 8223 } 8224 s->prev_tok = *ps; 8225 *ps = s; 8226 return s; 8227 } 8228 8229 /* pop labels until element last is reached. Look if any labels are 8230 undefined. Define symbols if '&&label' was used. */ 8231 static void label_pop(Sym **ptop, Sym *slast) 8232 { 8233 Sym *s, *s1; 8234 for(s = *ptop; s != slast; s = s1) { 8235 s1 = s->prev; 8236 if (s->r == LABEL_DECLARED) { 8237 warning("label '%s' declared but not used", get_tok_str(s->v, NULL)); 8238 } else if (s->r == LABEL_FORWARD) { 8239 error("label '%s' used but not defined", 8240 get_tok_str(s->v, NULL)); 8241 } else { 8242 if (s->c) { 8243 /* define corresponding symbol. A size of 8244 1 is put. */ 8245 put_extern_sym(s, cur_text_section, (long)s->next, 1); 8246 } 8247 } 8248 /* remove label */ 8249 table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok; 8250 sym_free(s); 8251 } 8252 *ptop = slast; 8253 } 8254 8255 /* eval an expression for #if/#elif */ 8256 static int expr_preprocess(void) 8257 { 8258 int c, t; 8259 TokenString str; 8260 8261 tok_str_new(&str); 8262 while (tok != TOK_LINEFEED && tok != TOK_EOF) { 8263 next(); /* do macro subst */ 8264 if (tok == TOK_DEFINED) { 8265 next_nomacro(); 8266 t = tok; 8267 if (t == '(') 8268 next_nomacro(); 8269 c = define_find(tok) != 0; 8270 if (t == '(') 8271 next_nomacro(); 8272 tok = TOK_CINT; 8273 tokc.i = c; 8274 } else if (tok >= TOK_IDENT) { 8275 /* if undefined macro */ 8276 tok = TOK_CINT; 8277 tokc.i = 0; 8278 } 8279 tok_str_add_tok(&str); 8280 } 8281 tok_str_add(&str, -1); /* simulate end of file */ 8282 tok_str_add(&str, 0); 8283 /* now evaluate C constant expression */ 8284 macro_ptr = str.str; 8285 next(); 8286 c = expr_const(); 8287 macro_ptr = NULL; 8288 tok_str_free(str.str); 8289 return c != 0; 8290 } 8291 8292 #if defined(PARSE_DEBUG) || defined(PP_DEBUG) 8293 static void tok_print(int *str) 8294 { 8295 int t; 8296 CValue cval; 8297 8298 while (1) { 8299 TOK_GET(t, str, cval); 8300 if (!t) 8301 break; 8302 printf(" %s", get_tok_str(t, &cval)); 8303 } 8304 printf("\n"); 8305 } 8306 #endif 8307 8308 /* parse after #define */ 8309 static void parse_define(void) 8310 { 8311 Sym *s, *first, **ps; 8312 int v, t, varg, is_vaargs, c; 8313 TokenString str; 8314 8315 v = tok; 8316 if (v < TOK_IDENT) 8317 error("invalid macro name '%s'", get_tok_str(tok, &tokc)); 8318 /* XXX: should check if same macro (ANSI) */ 8319 first = NULL; 8320 t = MACRO_OBJ; 8321 /* '(' must be just after macro definition for MACRO_FUNC */ 8322 c = file->buf_ptr[0]; 8323 if (c == '\\') 8324 c = handle_stray1(file->buf_ptr); 8325 if (c == '(') { 8326 next_nomacro(); 8327 next_nomacro(); 8328 ps = &first; 8329 while (tok != ')') { 8330 varg = tok; 8331 next_nomacro(); 8332 is_vaargs = 0; 8333 if (varg == TOK_DOTS) { 8334 varg = TOK___VA_ARGS__; 8335 is_vaargs = 1; 8336 } else if (tok == TOK_DOTS && gnu_ext) { 8337 is_vaargs = 1; 8338 next_nomacro(); 8339 } 8340 if (varg < TOK_IDENT) 8341 error("badly punctuated parameter list"); 8342 s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0); 8343 *ps = s; 8344 ps = &s->next; 8345 if (tok != ',') 8346 break; 8347 next_nomacro(); 8348 } 8349 t = MACRO_FUNC; 8350 } 8351 tok_str_new(&str); 8352 next_nomacro(); 8353 /* EOF testing necessary for '-D' handling */ 8354 while (tok != TOK_LINEFEED && tok != TOK_EOF) { 8355 tok_str_add2(&str, tok, &tokc); 8356 next_nomacro(); 8357 } 8358 tok_str_add(&str, 0); 8359 #ifdef PP_DEBUG 8360 printf("define %s %d: ", get_tok_str(v, NULL), t); 8361 tok_print(str.str); 8362 #endif 8363 define_push(v, t, str.str, first); 8364 } 8365 8366 static inline int hash_cached_include(int type, const char *filename) 8367 { 8368 const unsigned char *s; 8369 unsigned int h; 8370 8371 h = TOK_HASH_INIT; 8372 h = TOK_HASH_FUNC(h, type); 8373 s = filename; 8374 while (*s) { 8375 h = TOK_HASH_FUNC(h, *s); 8376 s++; 8377 } 8378 h &= (CACHED_INCLUDES_HASH_SIZE - 1); 8379 return h; 8380 } 8381 8382 /* XXX: use a token or a hash table to accelerate matching ? */ 8383 static CachedInclude *search_cached_include(TCCState *s1, 8384 int type, const char *filename) 8385 { 8386 CachedInclude *e; 8387 int i, h; 8388 h = hash_cached_include(type, filename); 8389 i = s1->cached_includes_hash[h]; 8390 for(;;) { 8391 if (i == 0) 8392 break; 8393 e = s1->cached_includes[i - 1]; 8394 if (e->type == type && !strcmp(e->filename, filename)) 8395 return e; 8396 i = e->hash_next; 8397 } 8398 return NULL; 8399 } 8400 8401 static inline void add_cached_include(TCCState *s1, int type, 8402 const char *filename, int ifndef_macro) 8403 { 8404 CachedInclude *e; 8405 int h; 8406 8407 if (search_cached_include(s1, type, filename)) 8408 return; 8409 #ifdef INC_DEBUG 8410 printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL)); 8411 #endif 8412 e = tcc_malloc(sizeof(CachedInclude) + strlen(filename)); 8413 if (!e) 8414 return; 8415 e->type = type; 8416 strcpy(e->filename, filename); 8417 e->ifndef_macro = ifndef_macro; 8418 dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e); 8419 /* add in hash table */ 8420 h = hash_cached_include(type, filename); 8421 e->hash_next = s1->cached_includes_hash[h]; 8422 s1->cached_includes_hash[h] = s1->nb_cached_includes; 8423 } 8424 8425 static void pragma_parse(TCCState *s1) 8426 { 8427 int val; 8428 8429 next(); 8430 if (tok == TOK_pack) { 8431 /* 8432 This may be: 8433 #pragma pack(1) // set 8434 #pragma pack() // reset to default 8435 #pragma pack(push,1) // push & set 8436 #pragma pack(pop) // restore previous 8437 */ 8438 next(); 8439 skip('('); 8440 if (tok == TOK_ASM_pop) { 8441 next(); 8442 if (s1->pack_stack_ptr <= s1->pack_stack) { 8443 stk_error: 8444 error("out of pack stack"); 8445 } 8446 s1->pack_stack_ptr--; 8447 } else { 8448 val = 0; 8449 if (tok != ')') { 8450 if (tok == TOK_ASM_push) { 8451 next(); 8452 if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1) 8453 goto stk_error; 8454 s1->pack_stack_ptr++; 8455 skip(','); 8456 } 8457 if (tok != TOK_CINT) { 8458 pack_error: 8459 error("invalid pack pragma"); 8460 } 8461 val = tokc.i; 8462 if (val < 1 || val > 16 || (val & (val - 1)) != 0) 8463 goto pack_error; 8464 next(); 8465 } 8466 *s1->pack_stack_ptr = val; 8467 skip(')'); 8468 } 8469 } 8470 } 8471 8472 /* is_bof is true if first non space token at beginning of file */ 8473 static void preprocess(int is_bof) 8474 { 8475 TCCState *s1 = tcc_state; 8476 int size, i, c, n, saved_parse_flags; 8477 char buf[1024], *q, *p; 8478 char buf1[1024]; 8479 BufferedFile *f; 8480 Sym *s; 8481 CachedInclude *e; 8482 8483 saved_parse_flags = parse_flags; 8484 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 8485 PARSE_FLAG_LINEFEED; 8486 next_nomacro(); 8487 redo: 8488 switch(tok) { 8489 case TOK_DEFINE: 8490 next_nomacro(); 8491 parse_define(); 8492 break; 8493 case TOK_UNDEF: 8494 next_nomacro(); 8495 s = define_find(tok); 8496 /* undefine symbol by putting an invalid name */ 8497 if (s) 8498 define_undef(s); 8499 break; 8500 case TOK_INCLUDE: 8501 case TOK_INCLUDE_NEXT: 8502 ch = file->buf_ptr[0]; 8503 /* XXX: incorrect if comments : use next_nomacro with a special mode */ 8504 skip_spaces(); 8505 if (ch == '<') { 8506 c = '>'; 8507 goto read_name; 8508 } else if (ch == '\"') { 8509 c = ch; 8510 read_name: 8511 /* XXX: better stray handling */ 8512 minp(); 8513 q = buf; 8514 while (ch != c && ch != '\n' && ch != CH_EOF) { 8515 if ((q - buf) < sizeof(buf) - 1) 8516 *q++ = ch; 8517 minp(); 8518 } 8519 *q = '\0'; 8520 minp(); 8521 #if 0 8522 /* eat all spaces and comments after include */ 8523 /* XXX: slightly incorrect */ 8524 while (ch1 != '\n' && ch1 != CH_EOF) 8525 inp(); 8526 #endif 8527 } else { 8528 /* computed #include : either we have only strings or 8529 we have anything enclosed in '<>' */ 8530 next(); 8531 buf[0] = '\0'; 8532 if (tok == TOK_STR) { 8533 while (tok != TOK_LINEFEED) { 8534 if (tok != TOK_STR) { 8535 include_syntax: 8536 error("'#include' expects \"FILENAME\" or <FILENAME>"); 8537 } 8538 pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data); 8539 next(); 8540 } 8541 c = '\"'; 8542 } else { 8543 int len; 8544 while (tok != TOK_LINEFEED) { 8545 pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); 8546 next(); 8547 } 8548 len = strlen(buf); 8549 /* check syntax and remove '<>' */ 8550 if (len < 2 || buf[0] != '<' || buf[len - 1] != '>') 8551 goto include_syntax; 8552 memmove(buf, buf + 1, len - 2); 8553 buf[len - 2] = '\0'; 8554 c = '>'; 8555 } 8556 } 8557 8558 e = search_cached_include(s1, c, buf); 8559 if (e && define_find(e->ifndef_macro)) { 8560 /* no need to parse the include because the 'ifndef macro' 8561 is defined */ 8562 #ifdef INC_DEBUG 8563 printf("%s: skipping %s\n", file->filename, buf); 8564 #endif 8565 } else { 8566 if (c == '\"') { 8567 /* first search in current dir if "header.h" */ 8568 size = 0; 8569 p = strrchr(file->filename, '/'); 8570 if (p) 8571 size = p + 1 - file->filename; 8572 if (size > sizeof(buf1) - 1) 8573 size = sizeof(buf1) - 1; 8574 memcpy(buf1, file->filename, size); 8575 buf1[size] = '\0'; 8576 pstrcat(buf1, sizeof(buf1), buf); 8577 f = tcc_open(s1, buf1); 8578 if (f) { 8579 if (tok == TOK_INCLUDE_NEXT) 8580 tok = TOK_INCLUDE; 8581 else 8582 goto found; 8583 } 8584 } 8585 if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) 8586 error("#include recursion too deep"); 8587 /* now search in all the include paths */ 8588 n = s1->nb_include_paths + s1->nb_sysinclude_paths; 8589 for(i = 0; i < n; i++) { 8590 const char *path; 8591 if (i < s1->nb_include_paths) 8592 path = s1->include_paths[i]; 8593 else 8594 path = s1->sysinclude_paths[i - s1->nb_include_paths]; 8595 pstrcpy(buf1, sizeof(buf1), path); 8596 pstrcat(buf1, sizeof(buf1), "/"); 8597 pstrcat(buf1, sizeof(buf1), buf); 8598 f = tcc_open(s1, buf1); 8599 if (f) { 8600 if (tok == TOK_INCLUDE_NEXT) 8601 tok = TOK_INCLUDE; 8602 else 8603 goto found; 8604 } 8605 } 8606 error("include file '%s' not found", buf); 8607 f = NULL; 8608 found: 8609 #ifdef INC_DEBUG 8610 printf("%s: including %s\n", file->filename, buf1); 8611 #endif 8612 f->inc_type = c; 8613 pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf); 8614 /* push current file in stack */ 8615 /* XXX: fix current line init */ 8616 *s1->include_stack_ptr++ = file; 8617 file = f; 8618 /* add include file debug info */ 8619 if (do_debug) { 8620 put_stabs(file->filename, N_BINCL, 0, 0, 0); 8621 } 8622 tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; 8623 ch = file->buf_ptr[0]; 8624 goto the_end; 8625 } 8626 break; 8627 case TOK_IFNDEF: 8628 c = 1; 8629 goto do_ifdef; 8630 case TOK_IF: 8631 c = expr_preprocess(); 8632 goto do_if; 8633 case TOK_IFDEF: 8634 c = 0; 8635 do_ifdef: 8636 next_nomacro(); 8637 if (tok < TOK_IDENT) 8638 error("invalid argument for '#if%sdef'", c ? "n" : ""); 8639 if (is_bof) { 8640 if (c) { 8641 #ifdef INC_DEBUG 8642 printf("#ifndef %s\n", get_tok_str(tok, NULL)); 8643 #endif 8644 file->ifndef_macro = tok; 8645 } 8646 } 8647 c = (define_find(tok) != 0) ^ c; 8648 do_if: 8649 if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) 8650 error("memory full"); 8651 *s1->ifdef_stack_ptr++ = c; 8652 goto test_skip; 8653 case TOK_ELSE: 8654 if (s1->ifdef_stack_ptr == s1->ifdef_stack) 8655 error("#else without matching #if"); 8656 if (s1->ifdef_stack_ptr[-1] & 2) 8657 error("#else after #else"); 8658 c = (s1->ifdef_stack_ptr[-1] ^= 3); 8659 goto test_skip; 8660 case TOK_ELIF: 8661 if (s1->ifdef_stack_ptr == s1->ifdef_stack) 8662 error("#elif without matching #if"); 8663 c = s1->ifdef_stack_ptr[-1]; 8664 if (c > 1) 8665 error("#elif after #else"); 8666 /* last #if/#elif expression was true: we skip */ 8667 if (c == 1) 8668 goto skip; 8669 c = expr_preprocess(); 8670 s1->ifdef_stack_ptr[-1] = c; 8671 test_skip: 8672 if (!(c & 1)) { 8673 skip: 8674 preprocess_skip(); 8675 is_bof = 0; 8676 goto redo; 8677 } 8678 break; 8679 case TOK_ENDIF: 8680 if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr) 8681 error("#endif without matching #if"); 8682 s1->ifdef_stack_ptr--; 8683 /* '#ifndef macro' was at the start of file. Now we check if 8684 an '#endif' is exactly at the end of file */ 8685 if (file->ifndef_macro && 8686 s1->ifdef_stack_ptr == file->ifdef_stack_ptr) { 8687 file->ifndef_macro_saved = file->ifndef_macro; 8688 /* need to set to zero to avoid false matches if another 8689 #ifndef at middle of file */ 8690 file->ifndef_macro = 0; 8691 while (tok != TOK_LINEFEED) 8692 next_nomacro(); 8693 tok_flags |= TOK_FLAG_ENDIF; 8694 goto the_end; 8695 } 8696 break; 8697 case TOK_LINE: 8698 next(); 8699 if (tok != TOK_CINT) 8700 error("#line"); 8701 file->line_num = tokc.i - 1; /* the line number will be incremented after */ 8702 next(); 8703 if (tok != TOK_LINEFEED) { 8704 if (tok != TOK_STR) 8705 error("#line"); 8706 pstrcpy(file->filename, sizeof(file->filename), 8707 (char *)tokc.cstr->data); 8708 } 8709 break; 8710 case TOK_ERROR: 8711 case TOK_WARNING: 8712 c = tok; 8713 ch = file->buf_ptr[0]; 8714 skip_spaces(); 8715 q = buf; 8716 while (ch != '\n' && ch != CH_EOF) { 8717 if ((q - buf) < sizeof(buf) - 1) 8718 *q++ = ch; 8719 minp(); 8720 } 8721 *q = '\0'; 8722 if (c == TOK_ERROR) 8723 error("#error %s", buf); 8724 else 8725 warning("#warning %s", buf); 8726 break; 8727 case TOK_PRAGMA: 8728 pragma_parse(s1); 8729 break; 8730 default: 8731 if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) { 8732 /* '!' is ignored to allow C scripts. numbers are ignored 8733 to emulate cpp behaviour */ 8734 } else { 8735 if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS)) 8736 error("invalid preprocessing directive #%s", get_tok_str(tok, &tokc)); 8737 } 8738 break; 8739 } 8740 /* ignore other preprocess commands or #! for C scripts */ 8741 while (tok != TOK_LINEFEED) 8742 next_nomacro(); 8743 the_end: 8744 parse_flags = saved_parse_flags; 8745 } 8746 8747 /* evaluate escape codes in a string. */ 8748 static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long) 8749 { 8750 int c, n; 8751 const uint8_t *p; 8752 8753 p = buf; 8754 for(;;) { 8755 c = *p; 8756 if (c == '\0') 8757 break; 8758 if (c == '\\') { 8759 p++; 8760 /* escape */ 8761 c = *p; 8762 switch(c) { 8763 case '0': case '1': case '2': case '3': 8764 case '4': case '5': case '6': case '7': 8765 /* at most three octal digits */ 8766 n = c - '0'; 8767 p++; 8768 c = *p; 8769 if (isoct(c)) { 8770 n = n * 8 + c - '0'; 8771 p++; 8772 c = *p; 8773 if (isoct(c)) { 8774 n = n * 8 + c - '0'; 8775 p++; 8776 } 8777 } 8778 c = n; 8779 goto add_char_nonext; 8780 case 'x': 8781 p++; 8782 n = 0; 8783 for(;;) { 8784 c = *p; 8785 if (c >= 'a' && c <= 'f') 8786 c = c - 'a' + 10; 8787 else if (c >= 'A' && c <= 'F') 8788 c = c - 'A' + 10; 8789 else if (isnum(c)) 8790 c = c - '0'; 8791 else 8792 break; 8793 n = n * 16 + c; 8794 p++; 8795 } 8796 c = n; 8797 goto add_char_nonext; 8798 case 'a': 8799 c = '\a'; 8800 break; 8801 case 'b': 8802 c = '\b'; 8803 break; 8804 case 'f': 8805 c = '\f'; 8806 break; 8807 case 'n': 8808 c = '\n'; 8809 break; 8810 case 'r': 8811 c = '\r'; 8812 break; 8813 case 't': 8814 c = '\t'; 8815 break; 8816 case 'v': 8817 c = '\v'; 8818 break; 8819 case 'e': 8820 if (!gnu_ext) 8821 goto invalid_escape; 8822 c = 27; 8823 break; 8824 case '\'': 8825 case '\"': 8826 case '\\': 8827 case '?': 8828 break; 8829 default: 8830 invalid_escape: 8831 if (c >= '!' && c <= '~') 8832 warning("unknown escape sequence: \'\\%c\'", c); 8833 else 8834 warning("unknown escape sequence: \'\\x%x\'", c); 8835 break; 8836 } 8837 } 8838 p++; 8839 add_char_nonext: 8840 if (!is_long) 8841 cstr_ccat(outstr, c); 8842 else 8843 cstr_wccat(outstr, c); 8844 } 8845 /* add a trailing '\0' */ 8846 if (!is_long) 8847 cstr_ccat(outstr, '\0'); 8848 else 8849 cstr_wccat(outstr, '\0'); 8850 } 8851 8852 /* we use 64 bit numbers */ 8853 #define BN_SIZE 2 8854 8855 /* bn = (bn << shift) | or_val */ 8856 void bn_lshift(unsigned int *bn, int shift, int or_val) 8857 { 8858 int i; 8859 unsigned int v; 8860 for(i=0;i<BN_SIZE;i++) { 8861 v = bn[i]; 8862 bn[i] = (v << shift) | or_val; 8863 or_val = v >> (32 - shift); 8864 } 8865 } 8866 8867 void bn_zero(unsigned int *bn) 8868 { 8869 int i; 8870 for(i=0;i<BN_SIZE;i++) { 8871 bn[i] = 0; 8872 } 8873 } 8874 8875 /* parse number in null terminated string 'p' and return it in the 8876 current token */ 8877 void parse_number(const char *p) 8878 { 8879 int b, t, shift, frac_bits, s, exp_val, ch; 8880 char *q; 8881 unsigned int bn[BN_SIZE]; 8882 double d; 8883 8884 /* number */ 8885 q = token_buf; 8886 ch = *p++; 8887 t = ch; 8888 ch = *p++; 8889 *q++ = t; 8890 b = 10; 8891 if (t == '.') { 8892 goto float_frac_parse; 8893 } else if (t == '0') { 8894 if (ch == 'x' || ch == 'X') { 8895 q--; 8896 ch = *p++; 8897 b = 16; 8898 } else if (tcc_ext && (ch == 'b' || ch == 'B')) { 8899 q--; 8900 ch = *p++; 8901 b = 2; 8902 } 8903 } 8904 /* parse all digits. cannot check octal numbers at this stage 8905 because of floating point constants */ 8906 while (1) { 8907 if (ch >= 'a' && ch <= 'f') 8908 t = ch - 'a' + 10; 8909 else if (ch >= 'A' && ch <= 'F') 8910 t = ch - 'A' + 10; 8911 else if (isnum(ch)) 8912 t = ch - '0'; 8913 else 8914 break; 8915 if (t >= b) 8916 break; 8917 if (q >= token_buf + STRING_MAX_SIZE) { 8918 num_too_long: 8919 error("number too long"); 8920 } 8921 *q++ = ch; 8922 ch = *p++; 8923 } 8924 if (ch == '.' || 8925 ((ch == 'e' || ch == 'E') && b == 10) || 8926 ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) { 8927 if (b != 10) { 8928 /* NOTE: strtox should support that for hexa numbers, but 8929 non ISOC99 libcs do not support it, so we prefer to do 8930 it by hand */ 8931 /* hexadecimal or binary floats */ 8932 /* XXX: handle overflows */ 8933 *q = '\0'; 8934 if (b == 16) 8935 shift = 4; 8936 else 8937 shift = 2; 8938 bn_zero(bn); 8939 q = token_buf; 8940 while (1) { 8941 t = *q++; 8942 if (t == '\0') { 8943 break; 8944 } else if (t >= 'a') { 8945 t = t - 'a' + 10; 8946 } else if (t >= 'A') { 8947 t = t - 'A' + 10; 8948 } else { 8949 t = t - '0'; 8950 } 8951 bn_lshift(bn, shift, t); 8952 } 8953 frac_bits = 0; 8954 if (ch == '.') { 8955 ch = *p++; 8956 while (1) { 8957 t = ch; 8958 if (t >= 'a' && t <= 'f') { 8959 t = t - 'a' + 10; 8960 } else if (t >= 'A' && t <= 'F') { 8961 t = t - 'A' + 10; 8962 } else if (t >= '0' && t <= '9') { 8963 t = t - '0'; 8964 } else { 8965 break; 8966 } 8967 if (t >= b) 8968 error("invalid digit"); 8969 bn_lshift(bn, shift, t); 8970 frac_bits += shift; 8971 ch = *p++; 8972 } 8973 } 8974 if (ch != 'p' && ch != 'P') 8975 expect("exponent"); 8976 ch = *p++; 8977 s = 1; 8978 exp_val = 0; 8979 if (ch == '+') { 8980 ch = *p++; 8981 } else if (ch == '-') { 8982 s = -1; 8983 ch = *p++; 8984 } 8985 if (ch < '0' || ch > '9') 8986 expect("exponent digits"); 8987 while (ch >= '0' && ch <= '9') { 8988 exp_val = exp_val * 10 + ch - '0'; 8989 ch = *p++; 8990 } 8991 exp_val = exp_val * s; 8992 8993 /* now we can generate the number */ 8994 /* XXX: should patch directly float number */ 8995 d = (double)bn[1] * 4294967296.0 + (double)bn[0]; 8996 d = ldexp(d, exp_val - frac_bits); 8997 t = toup(ch); 8998 if (t == 'F') { 8999 ch = *p++; 9000 tok = TOK_CFLOAT; 9001 /* float : should handle overflow */ 9002 tokc.f = (float)d; 9003 } else if (t == 'L') { 9004 ch = *p++; 9005 tok = TOK_CLDOUBLE; 9006 /* XXX: not large enough */ 9007 tokc.ld = (long double)d; 9008 } else { 9009 tok = TOK_CDOUBLE; 9010 tokc.d = d; 9011 } 9012 } else { 9013 /* decimal floats */ 9014 if (ch == '.') { 9015 if (q >= token_buf + STRING_MAX_SIZE) 9016 goto num_too_long; 9017 *q++ = ch; 9018 ch = *p++; 9019 float_frac_parse: 9020 while (ch >= '0' && ch <= '9') { 9021 if (q >= token_buf + STRING_MAX_SIZE) 9022 goto num_too_long; 9023 *q++ = ch; 9024 ch = *p++; 9025 } 9026 } 9027 if (ch == 'e' || ch == 'E') { 9028 if (q >= token_buf + STRING_MAX_SIZE) 9029 goto num_too_long; 9030 *q++ = ch; 9031 ch = *p++; 9032 if (ch == '-' || ch == '+') { 9033 if (q >= token_buf + STRING_MAX_SIZE) 9034 goto num_too_long; 9035 *q++ = ch; 9036 ch = *p++; 9037 } 9038 if (ch < '0' || ch > '9') 9039 expect("exponent digits"); 9040 while (ch >= '0' && ch <= '9') { 9041 if (q >= token_buf + STRING_MAX_SIZE) 9042 goto num_too_long; 9043 *q++ = ch; 9044 ch = *p++; 9045 } 9046 } 9047 *q = '\0'; 9048 t = toup(ch); 9049 errno = 0; 9050 if (t == 'F') { 9051 ch = *p++; 9052 tok = TOK_CFLOAT; 9053 tokc.f = strtof(token_buf, NULL); 9054 } else if (t == 'L') { 9055 ch = *p++; 9056 tok = TOK_CLDOUBLE; 9057 tokc.ld = strtold(token_buf, NULL); 9058 } else { 9059 tok = TOK_CDOUBLE; 9060 tokc.d = strtod(token_buf, NULL); 9061 } 9062 } 9063 } else { 9064 unsigned long long n, n1; 9065 int lcount, ucount; 9066 9067 /* integer number */ 9068 *q = '\0'; 9069 q = token_buf; 9070 if (b == 10 && *q == '0') { 9071 b = 8; 9072 q++; 9073 } 9074 n = 0; 9075 while(1) { 9076 t = *q++; 9077 /* no need for checks except for base 10 / 8 errors */ 9078 if (t == '\0') { 9079 break; 9080 } else if (t >= 'a') { 9081 t = t - 'a' + 10; 9082 } else if (t >= 'A') { 9083 t = t - 'A' + 10; 9084 } else { 9085 t = t - '0'; 9086 if (t >= b) 9087 error("invalid digit"); 9088 } 9089 n1 = n; 9090 n = n * b + t; 9091 /* detect overflow */ 9092 /* XXX: this test is not reliable */ 9093 if (n < n1) 9094 error("integer constant overflow"); 9095 } 9096 9097 /* XXX: not exactly ANSI compliant */ 9098 if ((n & 0xffffffff00000000LL) != 0) { 9099 if ((n >> 63) != 0) 9100 tok = TOK_CULLONG; 9101 else 9102 tok = TOK_CLLONG; 9103 } else if (n > 0x7fffffff) { 9104 tok = TOK_CUINT; 9105 } else { 9106 tok = TOK_CINT; 9107 } 9108 lcount = 0; 9109 ucount = 0; 9110 for(;;) { 9111 t = toup(ch); 9112 if (t == 'L') { 9113 if (lcount >= 2) 9114 error("three 'l's in integer constant"); 9115 lcount++; 9116 if (lcount == 2) { 9117 if (tok == TOK_CINT) 9118 tok = TOK_CLLONG; 9119 else if (tok == TOK_CUINT) 9120 tok = TOK_CULLONG; 9121 } 9122 ch = *p++; 9123 } else if (t == 'U') { 9124 if (ucount >= 1) 9125 error("two 'u's in integer constant"); 9126 ucount++; 9127 if (tok == TOK_CINT) 9128 tok = TOK_CUINT; 9129 else if (tok == TOK_CLLONG) 9130 tok = TOK_CULLONG; 9131 ch = *p++; 9132 } else { 9133 break; 9134 } 9135 } 9136 if (tok == TOK_CINT || tok == TOK_CUINT) 9137 tokc.ui = n; 9138 else 9139 tokc.ull = n; 9140 } 9141 } 9142 9143 9144 #define PARSE2(c1, tok1, c2, tok2) \ 9145 case c1: \ 9146 PEEKC(c, p); \ 9147 if (c == c2) { \ 9148 p++; \ 9149 tok = tok2; \ 9150 } else { \ 9151 tok = tok1; \ 9152 } \ 9153 break; 9154 9155 /* return next token without macro substitution */ 9156 static /*inline*/ void next_nomacro1(void) 9157 { 9158 int t, c, is_long; 9159 TokenSym *ts; 9160 uint8_t *p, *p1; 9161 unsigned int h; 9162 9163 p = file->buf_ptr; 9164 redo_no_start: 9165 c = *p; 9166 switch(c) { 9167 case ' ': 9168 case '\t': 9169 case '\f': 9170 case '\v': 9171 case '\r': 9172 p++; 9173 goto redo_no_start; 9174 9175 case '\\': 9176 /* first look if it is in fact an end of buffer */ 9177 if (p >= file->buf_end) { 9178 file->buf_ptr = p; 9179 handle_eob(); 9180 p = file->buf_ptr; 9181 if (p >= file->buf_end) 9182 goto parse_eof; 9183 else 9184 goto redo_no_start; 9185 } else { 9186 file->buf_ptr = p; 9187 ch = *p; 9188 handle_stray(); 9189 p = file->buf_ptr; 9190 goto redo_no_start; 9191 } 9192 parse_eof: 9193 { 9194 TCCState *s1 = tcc_state; 9195 if (parse_flags & PARSE_FLAG_LINEFEED) { 9196 tok = TOK_LINEFEED; 9197 } else if (s1->include_stack_ptr == s1->include_stack || 9198 !(parse_flags & PARSE_FLAG_PREPROCESS)) { 9199 /* no include left : end of file. */ 9200 tok = TOK_EOF; 9201 } else { 9202 /* pop include file */ 9203 9204 /* test if previous '#endif' was after a #ifdef at 9205 start of file */ 9206 if (tok_flags & TOK_FLAG_ENDIF) { 9207 #ifdef INC_DEBUG 9208 printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL)); 9209 #endif 9210 add_cached_include(s1, file->inc_type, file->inc_filename, 9211 file->ifndef_macro_saved); 9212 } 9213 9214 /* add end of include file debug info */ 9215 if (do_debug) { 9216 put_stabd(N_EINCL, 0, 0); 9217 } 9218 /* pop include stack */ 9219 tcc_close(file); 9220 s1->include_stack_ptr--; 9221 file = *s1->include_stack_ptr; 9222 p = file->buf_ptr; 9223 goto redo_no_start; 9224 } 9225 } 9226 break; 9227 9228 case '\n': 9229 if (parse_flags & PARSE_FLAG_LINEFEED) { 9230 tok = TOK_LINEFEED; 9231 } else { 9232 file->line_num++; 9233 tok_flags |= TOK_FLAG_BOL; 9234 p++; 9235 goto redo_no_start; 9236 } 9237 break; 9238 9239 case '#': 9240 /* XXX: simplify */ 9241 PEEKC(c, p); 9242 if ((tok_flags & TOK_FLAG_BOL) && 9243 (parse_flags & PARSE_FLAG_PREPROCESS)) { 9244 file->buf_ptr = p; 9245 preprocess(tok_flags & TOK_FLAG_BOF); 9246 p = file->buf_ptr; 9247 goto redo_no_start; 9248 } else { 9249 if (c == '#') { 9250 p++; 9251 tok = TOK_TWOSHARPS; 9252 } else { 9253 if (parse_flags & PARSE_FLAG_ASM_COMMENTS) { 9254 p = parse_line_comment(p - 1); 9255 goto redo_no_start; 9256 } else { 9257 tok = '#'; 9258 } 9259 } 9260 } 9261 break; 9262 9263 case 'a': case 'b': case 'c': case 'd': 9264 case 'e': case 'f': case 'g': case 'h': 9265 case 'i': case 'j': case 'k': case 'l': 9266 case 'm': case 'n': case 'o': case 'p': 9267 case 'q': case 'r': case 's': case 't': 9268 case 'u': case 'v': case 'w': case 'x': 9269 case 'y': case 'z': 9270 case 'A': case 'B': case 'C': case 'D': 9271 case 'E': case 'F': case 'G': case 'H': 9272 case 'I': case 'J': case 'K': 9273 case 'M': case 'N': case 'O': case 'P': 9274 case 'Q': case 'R': case 'S': case 'T': 9275 case 'U': case 'V': case 'W': case 'X': 9276 case 'Y': case 'Z': 9277 case '_': 9278 parse_ident_fast: 9279 p1 = p; 9280 h = TOK_HASH_INIT; 9281 h = TOK_HASH_FUNC(h, c); 9282 p++; 9283 for(;;) { 9284 c = *p; 9285 if (!isidnum_table[c]) 9286 break; 9287 h = TOK_HASH_FUNC(h, c); 9288 p++; 9289 } 9290 if (c != '\\') { 9291 TokenSym **pts; 9292 int len; 9293 9294 /* fast case : no stray found, so we have the full token 9295 and we have already hashed it */ 9296 len = p - p1; 9297 h &= (TOK_HASH_SIZE - 1); 9298 pts = &hash_ident[h]; 9299 for(;;) { 9300 ts = *pts; 9301 if (!ts) 9302 break; 9303 if (ts->len == len && !memcmp(ts->str, p1, len)) 9304 goto token_found; 9305 pts = &(ts->hash_next); 9306 } 9307 ts = tok_alloc_new(pts, p1, len); 9308 token_found: ; 9309 } else { 9310 /* slower case */ 9311 cstr_reset(&tokcstr); 9312 9313 while (p1 < p) { 9314 cstr_ccat(&tokcstr, *p1); 9315 p1++; 9316 } 9317 p--; 9318 PEEKC(c, p); 9319 parse_ident_slow: 9320 while (isidnum_table[c]) { 9321 cstr_ccat(&tokcstr, c); 9322 PEEKC(c, p); 9323 } 9324 ts = tok_alloc(tokcstr.data, tokcstr.size); 9325 } 9326 tok = ts->tok; 9327 break; 9328 case 'L': 9329 t = p[1]; 9330 if (t != '\\' && t != '\'' && t != '\"') { 9331 /* fast case */ 9332 goto parse_ident_fast; 9333 } else { 9334 PEEKC(c, p); 9335 if (c == '\'' || c == '\"') { 9336 is_long = 1; 9337 goto str_const; 9338 } else { 9339 cstr_reset(&tokcstr); 9340 cstr_ccat(&tokcstr, 'L'); 9341 goto parse_ident_slow; 9342 } 9343 } 9344 break; 9345 case '0': case '1': case '2': case '3': 9346 case '4': case '5': case '6': case '7': 9347 case '8': case '9': 9348 9349 cstr_reset(&tokcstr); 9350 /* after the first digit, accept digits, alpha, '.' or sign if 9351 prefixed by 'eEpP' */ 9352 parse_num: 9353 for(;;) { 9354 t = c; 9355 cstr_ccat(&tokcstr, c); 9356 PEEKC(c, p); 9357 if (!(isnum(c) || isid(c) || c == '.' || 9358 ((c == '+' || c == '-') && 9359 (t == 'e' || t == 'E' || t == 'p' || t == 'P')))) 9360 break; 9361 } 9362 /* We add a trailing '\0' to ease parsing */ 9363 cstr_ccat(&tokcstr, '\0'); 9364 tokc.cstr = &tokcstr; 9365 tok = TOK_PPNUM; 9366 break; 9367 case '.': 9368 /* special dot handling because it can also start a number */ 9369 PEEKC(c, p); 9370 if (isnum(c)) { 9371 cstr_reset(&tokcstr); 9372 cstr_ccat(&tokcstr, '.'); 9373 goto parse_num; 9374 } else if (c == '.') { 9375 PEEKC(c, p); 9376 if (c != '.') 9377 expect("'.'"); 9378 PEEKC(c, p); 9379 tok = TOK_DOTS; 9380 } else { 9381 tok = '.'; 9382 } 9383 break; 9384 case '\'': 9385 case '\"': 9386 is_long = 0; 9387 str_const: 9388 { 9389 CString str; 9390 int sep; 9391 9392 sep = c; 9393 9394 /* parse the string */ 9395 cstr_new(&str); 9396 p = parse_pp_string(p, sep, &str); 9397 cstr_ccat(&str, '\0'); 9398 9399 /* eval the escape (should be done as TOK_PPNUM) */ 9400 cstr_reset(&tokcstr); 9401 parse_escape_string(&tokcstr, str.data, is_long); 9402 cstr_free(&str); 9403 9404 if (sep == '\'') { 9405 int char_size; 9406 /* XXX: make it portable */ 9407 if (!is_long) 9408 char_size = 1; 9409 else 9410 char_size = sizeof(int); 9411 if (tokcstr.size <= char_size) 9412 error("empty character constant"); 9413 if (tokcstr.size > 2 * char_size) 9414 warning("multi-character character constant"); 9415 if (!is_long) { 9416 tokc.i = *(int8_t *)tokcstr.data; 9417 tok = TOK_CCHAR; 9418 } else { 9419 tokc.i = *(int *)tokcstr.data; 9420 tok = TOK_LCHAR; 9421 } 9422 } else { 9423 tokc.cstr = &tokcstr; 9424 if (!is_long) 9425 tok = TOK_STR; 9426 else 9427 tok = TOK_LSTR; 9428 } 9429 } 9430 break; 9431 9432 case '<': 9433 PEEKC(c, p); 9434 if (c == '=') { 9435 p++; 9436 tok = TOK_LE; 9437 } else if (c == '<') { 9438 PEEKC(c, p); 9439 if (c == '=') { 9440 p++; 9441 tok = TOK_A_SHL; 9442 } else { 9443 tok = TOK_SHL; 9444 } 9445 } else { 9446 tok = TOK_LT; 9447 } 9448 break; 9449 9450 case '>': 9451 PEEKC(c, p); 9452 if (c == '=') { 9453 p++; 9454 tok = TOK_GE; 9455 } else if (c == '>') { 9456 PEEKC(c, p); 9457 if (c == '=') { 9458 p++; 9459 tok = TOK_A_SAR; 9460 } else { 9461 tok = TOK_SAR; 9462 } 9463 } else { 9464 tok = TOK_GT; 9465 } 9466 break; 9467 9468 case '&': 9469 PEEKC(c, p); 9470 if (c == '&') { 9471 p++; 9472 tok = TOK_LAND; 9473 } else if (c == '=') { 9474 p++; 9475 tok = TOK_A_AND; 9476 } else { 9477 tok = '&'; 9478 } 9479 break; 9480 9481 case '|': 9482 PEEKC(c, p); 9483 if (c == '|') { 9484 p++; 9485 tok = TOK_LOR; 9486 } else if (c == '=') { 9487 p++; 9488 tok = TOK_A_OR; 9489 } else { 9490 tok = '|'; 9491 } 9492 break; 9493 9494 case '+': 9495 PEEKC(c, p); 9496 if (c == '+') { 9497 p++; 9498 tok = TOK_INC; 9499 } else if (c == '=') { 9500 p++; 9501 tok = TOK_A_ADD; 9502 } else { 9503 tok = '+'; 9504 } 9505 break; 9506 9507 case '-': 9508 PEEKC(c, p); 9509 if (c == '-') { 9510 p++; 9511 tok = TOK_DEC; 9512 } else if (c == '=') { 9513 p++; 9514 tok = TOK_A_SUB; 9515 } else if (c == '>') { 9516 p++; 9517 tok = TOK_ARROW; 9518 } else { 9519 tok = '-'; 9520 } 9521 break; 9522 9523 PARSE2('!', '!', '=', TOK_NE) 9524 PARSE2('=', '=', '=', TOK_EQ) 9525 PARSE2('*', '*', '=', TOK_A_MUL) 9526 PARSE2('%', '%', '=', TOK_A_MOD) 9527 PARSE2('^', '^', '=', TOK_A_XOR) 9528 9529 /* comments or operator */ 9530 case '/': 9531 PEEKC(c, p); 9532 if (c == '*') { 9533 p = parse_comment(p); 9534 goto redo_no_start; 9535 } else if (c == '/') { 9536 p = parse_line_comment(p); 9537 goto redo_no_start; 9538 } else if (c == '=') { 9539 p++; 9540 tok = TOK_A_DIV; 9541 } else { 9542 tok = '/'; 9543 } 9544 break; 9545 9546 /* simple tokens */ 9547 case '(': 9548 case ')': 9549 case '[': 9550 case ']': 9551 case '{': 9552 case '}': 9553 case ',': 9554 case ';': 9555 case ':': 9556 case '?': 9557 case '~': 9558 case '$': /* only used in assembler */ 9559 case '@': /* dito */ 9560 tok = c; 9561 p++; 9562 break; 9563 default: 9564 error("unrecognized character \\x%02x", c); 9565 break; 9566 } 9567 file->buf_ptr = p; 9568 tok_flags = 0; 9569 #if defined(PARSE_DEBUG) 9570 printf("token = %s\n", get_tok_str(tok, &tokc)); 9571 #endif 9572 } 9573 9574 /* return next token without macro substitution. Can read input from 9575 macro_ptr buffer */ 9576 static void next_nomacro(void) 9577 { 9578 if (macro_ptr) { 9579 redo: 9580 tok = *macro_ptr; 9581 if (tok) { 9582 TOK_GET(tok, macro_ptr, tokc); 9583 if (tok == TOK_LINENUM) { 9584 file->line_num = tokc.i; 9585 goto redo; 9586 } 9587 } 9588 } else { 9589 next_nomacro1(); 9590 } 9591 } 9592 9593 /* substitute args in macro_str and return allocated string */ 9594 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) 9595 { 9596 int *st, last_tok, t, notfirst; 9597 Sym *s; 9598 CValue cval; 9599 TokenString str; 9600 CString cstr; 9601 9602 tok_str_new(&str); 9603 last_tok = 0; 9604 while(1) { 9605 TOK_GET(t, macro_str, cval); 9606 if (!t) 9607 break; 9608 if (t == '#') { 9609 /* stringize */ 9610 TOK_GET(t, macro_str, cval); 9611 if (!t) 9612 break; 9613 s = sym_find2(args, t); 9614 if (s) { 9615 cstr_new(&cstr); 9616 st = (int *)s->c; 9617 notfirst = 0; 9618 while (*st) { 9619 if (notfirst) 9620 cstr_ccat(&cstr, ' '); 9621 TOK_GET(t, st, cval); 9622 cstr_cat(&cstr, get_tok_str(t, &cval)); 9623 notfirst = 1; 9624 } 9625 cstr_ccat(&cstr, '\0'); 9626 #ifdef PP_DEBUG 9627 printf("stringize: %s\n", (char *)cstr.data); 9628 #endif 9629 /* add string */ 9630 cval.cstr = &cstr; 9631 tok_str_add2(&str, TOK_STR, &cval); 9632 cstr_free(&cstr); 9633 } else { 9634 tok_str_add2(&str, t, &cval); 9635 } 9636 } else if (t >= TOK_IDENT) { 9637 s = sym_find2(args, t); 9638 if (s) { 9639 st = (int *)s->c; 9640 /* if '##' is present before or after, no arg substitution */ 9641 if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) { 9642 /* special case for var arg macros : ## eats the 9643 ',' if empty VA_ARGS variable. */ 9644 /* XXX: test of the ',' is not 100% 9645 reliable. should fix it to avoid security 9646 problems */ 9647 if (gnu_ext && s->type.t && 9648 last_tok == TOK_TWOSHARPS && 9649 str.len >= 2 && str.str[str.len - 2] == ',') { 9650 if (*st == 0) { 9651 /* suppress ',' '##' */ 9652 str.len -= 2; 9653 } else { 9654 /* suppress '##' and add variable */ 9655 str.len--; 9656 goto add_var; 9657 } 9658 } else { 9659 int t1; 9660 add_var: 9661 for(;;) { 9662 TOK_GET(t1, st, cval); 9663 if (!t1) 9664 break; 9665 tok_str_add2(&str, t1, &cval); 9666 } 9667 } 9668 } else { 9669 /* NOTE: the stream cannot be read when macro 9670 substituing an argument */ 9671 macro_subst(&str, nested_list, st, NULL); 9672 } 9673 } else { 9674 tok_str_add(&str, t); 9675 } 9676 } else { 9677 tok_str_add2(&str, t, &cval); 9678 } 9679 last_tok = t; 9680 } 9681 tok_str_add(&str, 0); 9682 return str.str; 9683 } 9684 9685 static char const ab_month_name[12][4] = 9686 { 9687 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 9688 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 9689 }; 9690 9691 /* do macro substitution of current token with macro 's' and add 9692 result to (tok_str,tok_len). 'nested_list' is the list of all 9693 macros we got inside to avoid recursing. Return non zero if no 9694 substitution needs to be done */ 9695 static int macro_subst_tok(TokenString *tok_str, 9696 Sym **nested_list, Sym *s, struct macro_level **can_read_stream) 9697 { 9698 Sym *args, *sa, *sa1; 9699 int mstr_allocated, parlevel, *mstr, t, t1; 9700 TokenString str; 9701 char *cstrval; 9702 CValue cval; 9703 CString cstr; 9704 char buf[32]; 9705 9706 /* if symbol is a macro, prepare substitution */ 9707 /* special macros */ 9708 if (tok == TOK___LINE__) { 9709 snprintf(buf, sizeof(buf), "%d", file->line_num); 9710 cstrval = buf; 9711 t1 = TOK_PPNUM; 9712 goto add_cstr1; 9713 } else if (tok == TOK___FILE__) { 9714 cstrval = file->filename; 9715 goto add_cstr; 9716 } else if (tok == TOK___DATE__ || tok == TOK___TIME__) { 9717 time_t ti; 9718 struct tm *tm; 9719 9720 time(&ti); 9721 tm = localtime(&ti); 9722 if (tok == TOK___DATE__) { 9723 snprintf(buf, sizeof(buf), "%s %2d %d", 9724 ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900); 9725 } else { 9726 snprintf(buf, sizeof(buf), "%02d:%02d:%02d", 9727 tm->tm_hour, tm->tm_min, tm->tm_sec); 9728 } 9729 cstrval = buf; 9730 add_cstr: 9731 t1 = TOK_STR; 9732 add_cstr1: 9733 cstr_new(&cstr); 9734 cstr_cat(&cstr, cstrval); 9735 cstr_ccat(&cstr, '\0'); 9736 cval.cstr = &cstr; 9737 tok_str_add2(tok_str, t1, &cval); 9738 cstr_free(&cstr); 9739 } else { 9740 mstr = (int *)s->c; 9741 mstr_allocated = 0; 9742 if (s->type.t == MACRO_FUNC) { 9743 /* NOTE: we do not use next_nomacro to avoid eating the 9744 next token. XXX: find better solution */ 9745 redo: 9746 if (macro_ptr) { 9747 t = *macro_ptr; 9748 if (t == 0 && can_read_stream) { 9749 /* end of macro stream: we must look at the token 9750 after in the file */ 9751 struct macro_level *ml = *can_read_stream; 9752 macro_ptr = NULL; 9753 if (ml) 9754 { 9755 macro_ptr = ml->p; 9756 ml->p = NULL; 9757 *can_read_stream = ml -> prev; 9758 } 9759 goto redo; 9760 } 9761 } else { 9762 /* XXX: incorrect with comments */ 9763 ch = file->buf_ptr[0]; 9764 while (is_space(ch) || ch == '\n') 9765 cinp(); 9766 t = ch; 9767 } 9768 if (t != '(') /* no macro subst */ 9769 return -1; 9770 9771 /* argument macro */ 9772 next_nomacro(); 9773 next_nomacro(); 9774 args = NULL; 9775 sa = s->next; 9776 /* NOTE: empty args are allowed, except if no args */ 9777 for(;;) { 9778 /* handle '()' case */ 9779 if (!args && !sa && tok == ')') 9780 break; 9781 if (!sa) 9782 error("macro '%s' used with too many args", 9783 get_tok_str(s->v, 0)); 9784 tok_str_new(&str); 9785 parlevel = 0; 9786 /* NOTE: non zero sa->t indicates VA_ARGS */ 9787 while ((parlevel > 0 || 9788 (tok != ')' && 9789 (tok != ',' || sa->type.t))) && 9790 tok != -1) { 9791 if (tok == '(') 9792 parlevel++; 9793 else if (tok == ')') 9794 parlevel--; 9795 tok_str_add2(&str, tok, &tokc); 9796 next_nomacro(); 9797 } 9798 tok_str_add(&str, 0); 9799 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str); 9800 sa = sa->next; 9801 if (tok == ')') { 9802 /* special case for gcc var args: add an empty 9803 var arg argument if it is omitted */ 9804 if (sa && sa->type.t && gnu_ext) 9805 continue; 9806 else 9807 break; 9808 } 9809 if (tok != ',') 9810 expect(","); 9811 next_nomacro(); 9812 } 9813 if (sa) { 9814 error("macro '%s' used with too few args", 9815 get_tok_str(s->v, 0)); 9816 } 9817 9818 /* now subst each arg */ 9819 mstr = macro_arg_subst(nested_list, mstr, args); 9820 /* free memory */ 9821 sa = args; 9822 while (sa) { 9823 sa1 = sa->prev; 9824 tok_str_free((int *)sa->c); 9825 sym_free(sa); 9826 sa = sa1; 9827 } 9828 mstr_allocated = 1; 9829 } 9830 sym_push2(nested_list, s->v, 0, 0); 9831 macro_subst(tok_str, nested_list, mstr, can_read_stream); 9832 /* pop nested defined symbol */ 9833 sa1 = *nested_list; 9834 *nested_list = sa1->prev; 9835 sym_free(sa1); 9836 if (mstr_allocated) 9837 tok_str_free(mstr); 9838 } 9839 return 0; 9840 } 9841 9842 /* handle the '##' operator. Return NULL if no '##' seen. Otherwise 9843 return the resulting string (which must be freed). */ 9844 static /*inline*/ int *macro_twosharps(const int *macro_str) 9845 { 9846 TokenSym *ts; 9847 const int *macro_ptr1, *start_macro_ptr, *ptr, *saved_macro_ptr; 9848 int t; 9849 const char *p1, *p2; 9850 CValue cval; 9851 TokenString macro_str1; 9852 CString cstr; 9853 memset(&cval, 0, sizeof(cval)); 9854 start_macro_ptr = macro_str; 9855 /* we search the first '##' */ 9856 for(;;) { 9857 macro_ptr1 = macro_str; 9858 TOK_GET(t, macro_str, cval); 9859 /* nothing more to do if end of string */ 9860 if (t == 0) 9861 return NULL; 9862 if (*macro_str == TOK_TWOSHARPS) 9863 break; 9864 } 9865 9866 /* we saw '##', so we need more processing to handle it */ 9867 cstr_new(&cstr); 9868 tok_str_new(¯o_str1); 9869 tok = t; 9870 tokc = cval; 9871 9872 /* add all tokens seen so far */ 9873 for(ptr = start_macro_ptr; ptr < macro_ptr1;) { 9874 TOK_GET(t, ptr, cval); 9875 tok_str_add2(¯o_str1, t, &cval); 9876 } 9877 saved_macro_ptr = macro_ptr; 9878 /* XXX: get rid of the use of macro_ptr here */ 9879 macro_ptr = (int *)macro_str; 9880 for(;;) { 9881 while (*macro_ptr == TOK_TWOSHARPS) { 9882 macro_ptr++; 9883 macro_ptr1 = macro_ptr; 9884 t = *macro_ptr; 9885 if (t) { 9886 TOK_GET(t, macro_ptr, cval); 9887 /* We concatenate the two tokens if we have an 9888 identifier or a preprocessing number */ 9889 cstr_reset(&cstr); 9890 p1 = get_tok_str(tok, &tokc); 9891 cstr_cat(&cstr, p1); 9892 p2 = get_tok_str(t, &cval); 9893 cstr_cat(&cstr, p2); 9894 cstr_ccat(&cstr, '\0'); 9895 9896 if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && 9897 (t >= TOK_IDENT || t == TOK_PPNUM)) { 9898 if (tok == TOK_PPNUM) { 9899 /* if number, then create a number token */ 9900 /* NOTE: no need to allocate because 9901 tok_str_add2() does it */ 9902 tokc.cstr = &cstr; 9903 } else { 9904 /* if identifier, we must do a test to 9905 validate we have a correct identifier */ 9906 if (t == TOK_PPNUM) { 9907 const char *p; 9908 int c; 9909 9910 p = p2; 9911 for(;;) { 9912 c = *p; 9913 if (c == '\0') 9914 break; 9915 p++; 9916 if (!isnum(c) && !isid(c)) 9917 goto error_pasting; 9918 } 9919 } 9920 ts = tok_alloc(cstr.data, strlen(cstr.data)); 9921 tok = ts->tok; /* modify current token */ 9922 } 9923 } else { 9924 const char *str = cstr.data; 9925 const unsigned char *q; 9926 9927 /* we look for a valid token */ 9928 /* XXX: do more extensive checks */ 9929 if (!strcmp(str, ">>=")) { 9930 tok = TOK_A_SAR; 9931 } else if (!strcmp(str, "<<=")) { 9932 tok = TOK_A_SHL; 9933 } else if (strlen(str) == 2) { 9934 /* search in two bytes table */ 9935 q = tok_two_chars; 9936 for(;;) { 9937 if (!*q) 9938 goto error_pasting; 9939 if (q[0] == str[0] && q[1] == str[1]) 9940 break; 9941 q += 3; 9942 } 9943 tok = q[2]; 9944 } else { 9945 error_pasting: 9946 /* NOTE: because get_tok_str use a static buffer, 9947 we must save it */ 9948 cstr_reset(&cstr); 9949 p1 = get_tok_str(tok, &tokc); 9950 cstr_cat(&cstr, p1); 9951 cstr_ccat(&cstr, '\0'); 9952 p2 = get_tok_str(t, &cval); 9953 warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2); 9954 /* cannot merge tokens: just add them separately */ 9955 tok_str_add2(¯o_str1, tok, &tokc); 9956 /* XXX: free associated memory ? */ 9957 tok = t; 9958 tokc = cval; 9959 } 9960 } 9961 } 9962 } 9963 tok_str_add2(¯o_str1, tok, &tokc); 9964 next_nomacro(); 9965 if (tok == 0) 9966 break; 9967 } 9968 macro_ptr = (int *)saved_macro_ptr; 9969 cstr_free(&cstr); 9970 tok_str_add(¯o_str1, 0); 9971 return macro_str1.str; 9972 } 9973 9974 9975 /* do macro substitution of macro_str and add result to 9976 (tok_str,tok_len). 'nested_list' is the list of all macros we got 9977 inside to avoid recursing. */ 9978 static void macro_subst(TokenString *tok_str, Sym **nested_list, 9979 const int *macro_str, struct macro_level ** can_read_stream) 9980 { 9981 Sym *s; 9982 int *macro_str1; 9983 const int *ptr; 9984 int t, ret; 9985 CValue cval; 9986 struct macro_level ml; 9987 9988 /* first scan for '##' operator handling */ 9989 ptr = macro_str; 9990 macro_str1 = macro_twosharps(ptr); 9991 if (macro_str1) 9992 ptr = macro_str1; 9993 while (1) { 9994 /* NOTE: ptr == NULL can only happen if tokens are read from 9995 file stream due to a macro function call */ 9996 if (ptr == NULL) 9997 break; 9998 TOK_GET(t, ptr, cval); 9999 if (t == 0) 10000 break; 10001 s = define_find(t); 10002 if (s != NULL) { 10003 /* if nested substitution, do nothing */ 10004 if (sym_find2(*nested_list, t)) 10005 goto no_subst; 10006 ml.p = macro_ptr; 10007 if (can_read_stream) 10008 ml.prev = *can_read_stream, *can_read_stream = &ml; 10009 macro_ptr = (int *)ptr; 10010 tok = t; 10011 ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream); 10012 ptr = (int *)macro_ptr; 10013 macro_ptr = ml.p; 10014 if (can_read_stream && *can_read_stream == &ml) 10015 *can_read_stream = ml.prev; 10016 if (ret != 0) 10017 goto no_subst; 10018 } else { 10019 no_subst: 10020 tok_str_add2(tok_str, t, &cval); 10021 } 10022 } 10023 if (macro_str1) 10024 tok_str_free(macro_str1); 10025 } 10026 10027 /* return next token with macro substitution */ 10028 static void next(void) 10029 { 10030 Sym *nested_list, *s; 10031 TokenString str; 10032 struct macro_level *ml; 10033 10034 redo: 10035 next_nomacro(); 10036 if (!macro_ptr) { 10037 /* if not reading from macro substituted string, then try 10038 to substitute macros */ 10039 if (tok >= TOK_IDENT && 10040 (parse_flags & PARSE_FLAG_PREPROCESS)) { 10041 s = define_find(tok); 10042 if (s) { 10043 /* we have a macro: we try to substitute */ 10044 tok_str_new(&str); 10045 nested_list = NULL; 10046 ml = NULL; 10047 if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) { 10048 /* substitution done, NOTE: maybe empty */ 10049 tok_str_add(&str, 0); 10050 macro_ptr = str.str; 10051 macro_ptr_allocated = str.str; 10052 goto redo; 10053 } 10054 } 10055 } 10056 } else { 10057 if (tok == 0) { 10058 /* end of macro or end of unget buffer */ 10059 if (unget_buffer_enabled) { 10060 macro_ptr = unget_saved_macro_ptr; 10061 unget_buffer_enabled = 0; 10062 } else { 10063 /* end of macro string: free it */ 10064 tok_str_free(macro_ptr_allocated); 10065 macro_ptr = NULL; 10066 } 10067 goto redo; 10068 } 10069 } 10070 10071 /* convert preprocessor tokens into C tokens */ 10072 if (tok == TOK_PPNUM && 10073 (parse_flags & PARSE_FLAG_TOK_NUM)) { 10074 parse_number((char *)tokc.cstr->data); 10075 } 10076 } 10077 10078 /* push back current token and set current token to 'last_tok'. Only 10079 identifier case handled for labels. */ 10080 static inline void unget_tok(int last_tok) 10081 { 10082 int i, n; 10083 int *q; 10084 unget_saved_macro_ptr = macro_ptr; 10085 unget_buffer_enabled = 1; 10086 q = unget_saved_buffer; 10087 macro_ptr = q; 10088 *q++ = tok; 10089 n = tok_ext_size(tok) - 1; 10090 for(i=0;i<n;i++) 10091 *q++ = tokc.tab[i]; 10092 *q = 0; /* end of token string */ 10093 tok = last_tok; 10094 } 10095 10096 10097 void swap(int *p, int *q) 10098 { 10099 int t; 10100 t = *p; 10101 *p = *q; 10102 *q = t; 10103 } 10104 10105 void vsetc(CType *type, int r, CValue *vc) 10106 { 10107 int v; 10108 10109 if (vtop >= vstack + (VSTACK_SIZE - 1)) 10110 error("memory full"); 10111 /* cannot let cpu flags if other instruction are generated. Also 10112 avoid leaving VT_JMP anywhere except on the top of the stack 10113 because it would complicate the code generator. */ 10114 if (vtop >= vstack) { 10115 v = vtop->r & VT_VALMASK; 10116 if (v == VT_CMP || (v & ~1) == VT_JMP) 10117 gv(RC_INT); 10118 } 10119 vtop++; 10120 vtop->type = *type; 10121 vtop->r = r; 10122 vtop->r2 = VT_CONST; 10123 vtop->c = *vc; 10124 } 10125 10126 /* push integer constant */ 10127 void vpushi(int v) 10128 { 10129 CValue cval; 10130 cval.i = v; 10131 vsetc(&int_type, VT_CONST, &cval); 10132 } 10133 10134 /* Return a static symbol pointing to a section */ 10135 static Sym *get_sym_ref(CType *type, Section *sec, 10136 unsigned long offset, unsigned long size) 10137 { 10138 int v; 10139 Sym *sym; 10140 10141 v = anon_sym++; 10142 sym = global_identifier_push(v, type->t | VT_STATIC, 0); 10143 sym->type.ref = type->ref; 10144 sym->r = VT_CONST | VT_SYM; 10145 put_extern_sym(sym, sec, offset, size); 10146 return sym; 10147 } 10148 10149 /* push a reference to a section offset by adding a dummy symbol */ 10150 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) 10151 { 10152 CValue cval; 10153 10154 cval.ul = 0; 10155 vsetc(type, VT_CONST | VT_SYM, &cval); 10156 vtop->sym = get_sym_ref(type, sec, offset, size); 10157 } 10158 10159 /* define a new external reference to a symbol 'v' of type 'u' */ 10160 static Sym *external_global_sym(int v, CType *type, int r) 10161 { 10162 Sym *s; 10163 10164 s = sym_find(v); 10165 if (!s) { 10166 /* push forward reference */ 10167 s = global_identifier_push(v, type->t | VT_EXTERN, 0); 10168 s->type.ref = type->ref; 10169 s->r = r | VT_CONST | VT_SYM; 10170 } 10171 return s; 10172 } 10173 10174 /* define a new external reference to a symbol 'v' of type 'u' */ 10175 static Sym *external_sym(int v, CType *type, int r) 10176 { 10177 Sym *s; 10178 10179 s = sym_find(v); 10180 if (!s) { 10181 /* push forward reference */ 10182 s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); 10183 s->type.t |= VT_EXTERN; 10184 } else { 10185 if (!is_compatible_types(&s->type, type)) 10186 error("incompatible types for redefinition of '%s'", 10187 get_tok_str(v, NULL)); 10188 } 10189 return s; 10190 } 10191 10192 /* push a reference to global symbol v */ 10193 static void vpush_global_sym(CType *type, int v) 10194 { 10195 Sym *sym; 10196 CValue cval; 10197 10198 sym = external_global_sym(v, type, 0); 10199 cval.ul = 0; 10200 vsetc(type, VT_CONST | VT_SYM, &cval); 10201 vtop->sym = sym; 10202 } 10203 10204 void vset(CType *type, int r, int v) 10205 { 10206 CValue cval; 10207 10208 cval.i = v; 10209 vsetc(type, r, &cval); 10210 } 10211 10212 void vseti(int r, int v) 10213 { 10214 CType type; 10215 type.t = VT_INT; 10216 vset(&type, r, v); 10217 } 10218 10219 void vswap(void) 10220 { 10221 SValue tmp; 10222 10223 tmp = vtop[0]; 10224 vtop[0] = vtop[-1]; 10225 vtop[-1] = tmp; 10226 } 10227 10228 void vpushv(SValue *v) 10229 { 10230 if (vtop >= vstack + (VSTACK_SIZE - 1)) 10231 error("memory full"); 10232 vtop++; 10233 *vtop = *v; 10234 } 10235 10236 void vdup(void) 10237 { 10238 vpushv(vtop); 10239 } 10240 10241 /* save r to the memory stack, and mark it as being free */ 10242 void save_reg(int r) 10243 { 10244 int l, saved, size, align; 10245 SValue *p, sv; 10246 CType *type; 10247 10248 /* modify all stack values */ 10249 saved = 0; 10250 l = 0; 10251 for(p=vstack;p<=vtop;p++) { 10252 if ((p->r & VT_VALMASK) == r || 10253 (p->r2 & VT_VALMASK) == r) { 10254 /* must save value on stack if not already done */ 10255 if (!saved) { 10256 /* NOTE: must reload 'r' because r might be equal to r2 */ 10257 r = p->r & VT_VALMASK; 10258 /* store register in the stack */ 10259 type = &p->type; 10260 if ((p->r & VT_LVAL) || 10261 (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG)) 10262 type = &int_type; 10263 size = type_size(type, &align); 10264 loc = (loc - size) & -align; 10265 sv.type.t = type->t; 10266 sv.r = VT_LOCAL | VT_LVAL; 10267 sv.c.ul = loc; 10268 store(r, &sv); 10269 #ifdef TCC_TARGET_I386 10270 /* x86 specific: need to pop fp register ST0 if saved */ 10271 if (r == TREG_ST0) { 10272 o(0xd9dd); /* fstp %st(1) */ 10273 } 10274 #endif 10275 /* special long long case */ 10276 if ((type->t & VT_BTYPE) == VT_LLONG) { 10277 sv.c.ul += 4; 10278 store(p->r2, &sv); 10279 } 10280 l = loc; 10281 saved = 1; 10282 } 10283 /* mark that stack entry as being saved on the stack */ 10284 if (p->r & VT_LVAL) { 10285 /* also clear the bounded flag because the 10286 relocation address of the function was stored in 10287 p->c.ul */ 10288 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL; 10289 } else { 10290 p->r = lvalue_type(p->type.t) | VT_LOCAL; 10291 } 10292 p->r2 = VT_CONST; 10293 p->c.ul = l; 10294 } 10295 } 10296 } 10297 10298 /* find a register of class 'rc2' with at most one reference on stack. 10299 * If none, call get_reg(rc) */ 10300 int get_reg_ex(int rc, int rc2) 10301 { 10302 int r; 10303 SValue *p; 10304 10305 for(r=0;r<NB_REGS;r++) { 10306 if (reg_classes[r] & rc2) { 10307 int n; 10308 n=0; 10309 for(p = vstack; p <= vtop; p++) { 10310 if ((p->r & VT_VALMASK) == r || 10311 (p->r2 & VT_VALMASK) == r) 10312 n++; 10313 } 10314 if (n <= 1) 10315 return r; 10316 } 10317 } 10318 return get_reg(rc); 10319 } 10320 10321 /* find a free register of class 'rc'. If none, save one register */ 10322 int get_reg(int rc) 10323 { 10324 int r; 10325 SValue *p; 10326 10327 /* find a free register */ 10328 for(r=0;r<NB_REGS;r++) { 10329 if (reg_classes[r] & rc) { 10330 for(p=vstack;p<=vtop;p++) { 10331 if ((p->r & VT_VALMASK) == r || 10332 (p->r2 & VT_VALMASK) == r) 10333 goto notfound; 10334 } 10335 return r; 10336 } 10337 notfound: ; 10338 } 10339 10340 /* no register left : free the first one on the stack (VERY 10341 IMPORTANT to start from the bottom to ensure that we don't 10342 spill registers used in gen_opi()) */ 10343 for(p=vstack;p<=vtop;p++) { 10344 r = p->r & VT_VALMASK; 10345 if (r < VT_CONST && (reg_classes[r] & rc)) 10346 goto save_found; 10347 /* also look at second register (if long long) */ 10348 r = p->r2 & VT_VALMASK; 10349 if (r < VT_CONST && (reg_classes[r] & rc)) { 10350 save_found: 10351 save_reg(r); 10352 return r; 10353 } 10354 } 10355 /* Should never comes here */ 10356 return -1; 10357 } 10358 10359 /* save registers up to (vtop - n) stack entry */ 10360 void save_regs(int n) 10361 { 10362 int r; 10363 SValue *p, *p1; 10364 p1 = vtop - n; 10365 for(p = vstack;p <= p1; p++) { 10366 r = p->r & VT_VALMASK; 10367 if (r < VT_CONST) { 10368 save_reg(r); 10369 } 10370 } 10371 } 10372 10373 /* move register 's' to 'r', and flush previous value of r to memory 10374 if needed */ 10375 void move_reg(int r, int s) 10376 { 10377 SValue sv; 10378 10379 if (r != s) { 10380 save_reg(r); 10381 sv.type.t = VT_INT; 10382 sv.r = s; 10383 sv.c.ul = 0; 10384 load(r, &sv); 10385 } 10386 } 10387 10388 /* get address of vtop (vtop MUST BE an lvalue) */ 10389 void gaddrof(void) 10390 { 10391 vtop->r &= ~VT_LVAL; 10392 /* tricky: if saved lvalue, then we can go back to lvalue */ 10393 if ((vtop->r & VT_VALMASK) == VT_LLOCAL) 10394 vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL; 10395 } 10396 10397 #ifdef CONFIG_TCC_BCHECK 10398 /* generate lvalue bound code */ 10399 void gbound(void) 10400 { 10401 int lval_type; 10402 CType type1; 10403 10404 vtop->r &= ~VT_MUSTBOUND; 10405 /* if lvalue, then use checking code before dereferencing */ 10406 if (vtop->r & VT_LVAL) { 10407 /* if not VT_BOUNDED value, then make one */ 10408 if (!(vtop->r & VT_BOUNDED)) { 10409 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL); 10410 /* must save type because we must set it to int to get pointer */ 10411 type1 = vtop->type; 10412 vtop->type.t = VT_INT; 10413 gaddrof(); 10414 vpushi(0); 10415 gen_bounded_ptr_add(); 10416 vtop->r |= lval_type; 10417 vtop->type = type1; 10418 } 10419 /* then check for dereferencing */ 10420 gen_bounded_ptr_deref(); 10421 } 10422 } 10423 #endif 10424 10425 /* store vtop a register belonging to class 'rc'. lvalues are 10426 converted to values. Cannot be used if cannot be converted to 10427 register value (such as structures). */ 10428 int gv(int rc) 10429 { 10430 int r, r2, rc2, bit_pos, bit_size, size, align, i; 10431 unsigned long long ll; 10432 10433 /* NOTE: get_reg can modify vstack[] */ 10434 if (vtop->type.t & VT_BITFIELD) { 10435 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; 10436 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; 10437 /* remove bit field info to avoid loops */ 10438 vtop->type.t &= ~(VT_BITFIELD | (~0U << VT_STRUCT_SHIFT)); 10439 /* generate shifts */ 10440 vpushi(32 - (bit_pos + bit_size)); 10441 gen_op(TOK_SHL); 10442 vpushi(32 - bit_size); 10443 /* NOTE: transformed to SHR if unsigned */ 10444 gen_op(TOK_SAR); 10445 r = gv(rc); 10446 } else { 10447 if (is_float(vtop->type.t) && 10448 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { 10449 Sym *sym; 10450 int *ptr; 10451 unsigned long offset; 10452 10453 /* XXX: unify with initializers handling ? */ 10454 /* CPUs usually cannot use float constants, so we store them 10455 generically in data segment */ 10456 size = type_size(&vtop->type, &align); 10457 offset = (data_section->data_offset + align - 1) & -align; 10458 data_section->data_offset = offset; 10459 /* XXX: not portable yet */ 10460 ptr = section_ptr_add(data_section, size); 10461 size = size >> 2; 10462 for(i=0;i<size;i++) 10463 ptr[i] = vtop->c.tab[i]; 10464 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2); 10465 vtop->r |= VT_LVAL | VT_SYM; 10466 vtop->sym = sym; 10467 vtop->c.ul = 0; 10468 } 10469 #ifdef CONFIG_TCC_BCHECK 10470 if (vtop->r & VT_MUSTBOUND) 10471 gbound(); 10472 #endif 10473 10474 r = vtop->r & VT_VALMASK; 10475 /* need to reload if: 10476 - constant 10477 - lvalue (need to dereference pointer) 10478 - already a register, but not in the right class */ 10479 if (r >= VT_CONST || 10480 (vtop->r & VT_LVAL) || 10481 !(reg_classes[r] & rc) || 10482 ((vtop->type.t & VT_BTYPE) == VT_LLONG && 10483 !(reg_classes[vtop->r2] & rc))) { 10484 r = get_reg(rc); 10485 if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { 10486 /* two register type load : expand to two words 10487 temporarily */ 10488 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { 10489 /* load constant */ 10490 ll = vtop->c.ull; 10491 vtop->c.ui = ll; /* first word */ 10492 load(r, vtop); 10493 vtop->r = r; /* save register value */ 10494 vpushi(ll >> 32); /* second word */ 10495 } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ 10496 (vtop->r & VT_LVAL)) { 10497 /* We do not want to modifier the long long 10498 pointer here, so the safest (and less 10499 efficient) is to save all the other registers 10500 in the stack. XXX: totally inefficient. */ 10501 save_regs(1); 10502 /* load from memory */ 10503 load(r, vtop); 10504 vdup(); 10505 vtop[-1].r = r; /* save register value */ 10506 /* increment pointer to get second word */ 10507 vtop->type.t = VT_INT; 10508 gaddrof(); 10509 vpushi(4); 10510 gen_op('+'); 10511 vtop->r |= VT_LVAL; 10512 } else { 10513 /* move registers */ 10514 load(r, vtop); 10515 vdup(); 10516 vtop[-1].r = r; /* save register value */ 10517 vtop->r = vtop[-1].r2; 10518 } 10519 /* allocate second register */ 10520 rc2 = RC_INT; 10521 if (rc == RC_IRET) 10522 rc2 = RC_LRET; 10523 r2 = get_reg(rc2); 10524 load(r2, vtop); 10525 vpop(); 10526 /* write second register */ 10527 vtop->r2 = r2; 10528 } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) { 10529 int t1, t; 10530 /* lvalue of scalar type : need to use lvalue type 10531 because of possible cast */ 10532 t = vtop->type.t; 10533 t1 = t; 10534 /* compute memory access type */ 10535 if (vtop->r & VT_LVAL_BYTE) 10536 t = VT_BYTE; 10537 else if (vtop->r & VT_LVAL_SHORT) 10538 t = VT_SHORT; 10539 if (vtop->r & VT_LVAL_UNSIGNED) 10540 t |= VT_UNSIGNED; 10541 vtop->type.t = t; 10542 load(r, vtop); 10543 /* restore wanted type */ 10544 vtop->type.t = t1; 10545 } else { 10546 /* one register type load */ 10547 load(r, vtop); 10548 } 10549 } 10550 vtop->r = r; 10551 #ifdef TCC_TARGET_C67 10552 /* uses register pairs for doubles */ 10553 if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 10554 vtop->r2 = r+1; 10555 #endif 10556 } 10557 return r; 10558 } 10559 10560 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */ 10561 void gv2(int rc1, int rc2) 10562 { 10563 int v; 10564 10565 /* generate more generic register first. But VT_JMP or VT_CMP 10566 values must be generated first in all cases to avoid possible 10567 reload errors */ 10568 v = vtop[0].r & VT_VALMASK; 10569 if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) { 10570 vswap(); 10571 gv(rc1); 10572 vswap(); 10573 gv(rc2); 10574 /* test if reload is needed for first register */ 10575 if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) { 10576 vswap(); 10577 gv(rc1); 10578 vswap(); 10579 } 10580 } else { 10581 gv(rc2); 10582 vswap(); 10583 gv(rc1); 10584 vswap(); 10585 /* test if reload is needed for first register */ 10586 if ((vtop[0].r & VT_VALMASK) >= VT_CONST) { 10587 gv(rc2); 10588 } 10589 } 10590 } 10591 10592 /* expand long long on stack in two int registers */ 10593 void lexpand(void) 10594 { 10595 int u; 10596 10597 u = vtop->type.t & VT_UNSIGNED; 10598 gv(RC_INT); 10599 vdup(); 10600 vtop[0].r = vtop[-1].r2; 10601 vtop[0].r2 = VT_CONST; 10602 vtop[-1].r2 = VT_CONST; 10603 vtop[0].type.t = VT_INT | u; 10604 vtop[-1].type.t = VT_INT | u; 10605 } 10606 10607 #ifdef TCC_TARGET_ARM 10608 /* expand long long on stack */ 10609 void lexpand_nr(void) 10610 { 10611 int u,v; 10612 10613 u = vtop->type.t & VT_UNSIGNED; 10614 vdup(); 10615 vtop->r2 = VT_CONST; 10616 vtop->type.t = VT_INT | u; 10617 v=vtop[-1].r & (VT_VALMASK | VT_LVAL); 10618 if (v == VT_CONST) { 10619 vtop[-1].c.ui = vtop->c.ull; 10620 vtop->c.ui = vtop->c.ull >> 32; 10621 vtop->r = VT_CONST; 10622 } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) { 10623 vtop->c.ui += 4; 10624 vtop->r = vtop[-1].r; 10625 } else if (v > VT_CONST) { 10626 vtop--; 10627 lexpand(); 10628 } else 10629 vtop->r = vtop[-1].r2; 10630 vtop[-1].r2 = VT_CONST; 10631 vtop[-1].type.t = VT_INT | u; 10632 } 10633 #endif 10634 10635 /* build a long long from two ints */ 10636 void lbuild(int t) 10637 { 10638 gv2(RC_INT, RC_INT); 10639 vtop[-1].r2 = vtop[0].r; 10640 vtop[-1].type.t = t; 10641 vpop(); 10642 } 10643 10644 /* rotate n first stack elements to the bottom 10645 I1 ... In -> I2 ... In I1 [top is right] 10646 */ 10647 void vrotb(int n) 10648 { 10649 int i; 10650 SValue tmp; 10651 10652 tmp = vtop[-n + 1]; 10653 for(i=-n+1;i!=0;i++) 10654 vtop[i] = vtop[i+1]; 10655 vtop[0] = tmp; 10656 } 10657 10658 /* rotate n first stack elements to the top 10659 I1 ... In -> In I1 ... I(n-1) [top is right] 10660 */ 10661 void vrott(int n) 10662 { 10663 int i; 10664 SValue tmp; 10665 10666 tmp = vtop[0]; 10667 for(i = 0;i < n - 1; i++) 10668 vtop[-i] = vtop[-i - 1]; 10669 vtop[-n + 1] = tmp; 10670 } 10671 10672 #ifdef TCC_TARGET_ARM 10673 /* like vrott but in other direction 10674 In ... I1 -> I(n-1) ... I1 In [top is right] 10675 */ 10676 void vnrott(int n) 10677 { 10678 int i; 10679 SValue tmp; 10680 10681 tmp = vtop[-n + 1]; 10682 for(i = n - 1; i > 0; i--) 10683 vtop[-i] = vtop[-i + 1]; 10684 vtop[0] = tmp; 10685 } 10686 #endif 10687 10688 /* pop stack value */ 10689 void vpop(void) 10690 { 10691 int v; 10692 v = vtop->r & VT_VALMASK; 10693 #ifdef TCC_TARGET_I386 10694 /* for x86, we need to pop the FP stack */ 10695 if (v == TREG_ST0 && !nocode_wanted) { 10696 o(0xd9dd); /* fstp %st(1) */ 10697 } else 10698 #endif 10699 if (v == VT_JMP || v == VT_JMPI) { 10700 /* need to put correct jump if && or || without test */ 10701 gsym(vtop->c.ul); 10702 } 10703 vtop--; 10704 } 10705 10706 /* convert stack entry to register and duplicate its value in another 10707 register */ 10708 void gv_dup(void) 10709 { 10710 int rc, t, r, r1; 10711 SValue sv; 10712 10713 t = vtop->type.t; 10714 if ((t & VT_BTYPE) == VT_LLONG) { 10715 lexpand(); 10716 gv_dup(); 10717 vswap(); 10718 vrotb(3); 10719 gv_dup(); 10720 vrotb(4); 10721 /* stack: H L L1 H1 */ 10722 lbuild(t); 10723 vrotb(3); 10724 vrotb(3); 10725 vswap(); 10726 lbuild(t); 10727 vswap(); 10728 } else { 10729 /* duplicate value */ 10730 rc = RC_INT; 10731 sv.type.t = VT_INT; 10732 if (is_float(t)) { 10733 rc = RC_FLOAT; 10734 sv.type.t = t; 10735 } 10736 r = gv(rc); 10737 r1 = get_reg(rc); 10738 sv.r = r; 10739 sv.c.ul = 0; 10740 load(r1, &sv); /* move r to r1 */ 10741 vdup(); 10742 /* duplicates value */ 10743 vtop->r = r1; 10744 } 10745 } 10746 10747 /* generate CPU independent (unsigned) long long operations */ 10748 void gen_opl(int op) 10749 { 10750 int t, a, b, op1, c, i; 10751 int func; 10752 SValue tmp; 10753 10754 switch(op) { 10755 case '/': 10756 case TOK_PDIV: 10757 func = TOK___divdi3; 10758 goto gen_func; 10759 case TOK_UDIV: 10760 func = TOK___udivdi3; 10761 goto gen_func; 10762 case '%': 10763 func = TOK___moddi3; 10764 goto gen_func; 10765 case TOK_UMOD: 10766 func = TOK___umoddi3; 10767 gen_func: 10768 /* call generic long long function */ 10769 vpush_global_sym(&func_old_type, func); 10770 vrott(3); 10771 gfunc_call(2); 10772 vpushi(0); 10773 vtop->r = REG_IRET; 10774 vtop->r2 = REG_LRET; 10775 break; 10776 case '^': 10777 case '&': 10778 case '|': 10779 case '*': 10780 case '+': 10781 case '-': 10782 t = vtop->type.t; 10783 vswap(); 10784 lexpand(); 10785 vrotb(3); 10786 lexpand(); 10787 /* stack: L1 H1 L2 H2 */ 10788 tmp = vtop[0]; 10789 vtop[0] = vtop[-3]; 10790 vtop[-3] = tmp; 10791 tmp = vtop[-2]; 10792 vtop[-2] = vtop[-3]; 10793 vtop[-3] = tmp; 10794 vswap(); 10795 /* stack: H1 H2 L1 L2 */ 10796 if (op == '*') { 10797 vpushv(vtop - 1); 10798 vpushv(vtop - 1); 10799 gen_op(TOK_UMULL); 10800 lexpand(); 10801 /* stack: H1 H2 L1 L2 ML MH */ 10802 for(i=0;i<4;i++) 10803 vrotb(6); 10804 /* stack: ML MH H1 H2 L1 L2 */ 10805 tmp = vtop[0]; 10806 vtop[0] = vtop[-2]; 10807 vtop[-2] = tmp; 10808 /* stack: ML MH H1 L2 H2 L1 */ 10809 gen_op('*'); 10810 vrotb(3); 10811 vrotb(3); 10812 gen_op('*'); 10813 /* stack: ML MH M1 M2 */ 10814 gen_op('+'); 10815 gen_op('+'); 10816 } else if (op == '+' || op == '-') { 10817 /* XXX: add non carry method too (for MIPS or alpha) */ 10818 if (op == '+') 10819 op1 = TOK_ADDC1; 10820 else 10821 op1 = TOK_SUBC1; 10822 gen_op(op1); 10823 /* stack: H1 H2 (L1 op L2) */ 10824 vrotb(3); 10825 vrotb(3); 10826 gen_op(op1 + 1); /* TOK_xxxC2 */ 10827 } else { 10828 gen_op(op); 10829 /* stack: H1 H2 (L1 op L2) */ 10830 vrotb(3); 10831 vrotb(3); 10832 /* stack: (L1 op L2) H1 H2 */ 10833 gen_op(op); 10834 /* stack: (L1 op L2) (H1 op H2) */ 10835 } 10836 /* stack: L H */ 10837 lbuild(t); 10838 break; 10839 case TOK_SAR: 10840 case TOK_SHR: 10841 case TOK_SHL: 10842 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { 10843 t = vtop[-1].type.t; 10844 vswap(); 10845 lexpand(); 10846 vrotb(3); 10847 /* stack: L H shift */ 10848 c = (int)vtop->c.i; 10849 /* constant: simpler */ 10850 /* NOTE: all comments are for SHL. the other cases are 10851 done by swaping words */ 10852 vpop(); 10853 if (op != TOK_SHL) 10854 vswap(); 10855 if (c >= 32) { 10856 /* stack: L H */ 10857 vpop(); 10858 if (c > 32) { 10859 vpushi(c - 32); 10860 gen_op(op); 10861 } 10862 if (op != TOK_SAR) { 10863 vpushi(0); 10864 } else { 10865 gv_dup(); 10866 vpushi(31); 10867 gen_op(TOK_SAR); 10868 } 10869 vswap(); 10870 } else { 10871 vswap(); 10872 gv_dup(); 10873 /* stack: H L L */ 10874 vpushi(c); 10875 gen_op(op); 10876 vswap(); 10877 vpushi(32 - c); 10878 if (op == TOK_SHL) 10879 gen_op(TOK_SHR); 10880 else 10881 gen_op(TOK_SHL); 10882 vrotb(3); 10883 /* stack: L L H */ 10884 vpushi(c); 10885 if (op == TOK_SHL) 10886 gen_op(TOK_SHL); 10887 else 10888 gen_op(TOK_SHR); 10889 gen_op('|'); 10890 } 10891 if (op != TOK_SHL) 10892 vswap(); 10893 lbuild(t); 10894 } else { 10895 /* XXX: should provide a faster fallback on x86 ? */ 10896 switch(op) { 10897 case TOK_SAR: 10898 func = TOK___sardi3; 10899 goto gen_func; 10900 case TOK_SHR: 10901 func = TOK___shrdi3; 10902 goto gen_func; 10903 case TOK_SHL: 10904 func = TOK___shldi3; 10905 goto gen_func; 10906 } 10907 } 10908 break; 10909 default: 10910 /* compare operations */ 10911 t = vtop->type.t; 10912 vswap(); 10913 lexpand(); 10914 vrotb(3); 10915 lexpand(); 10916 /* stack: L1 H1 L2 H2 */ 10917 tmp = vtop[-1]; 10918 vtop[-1] = vtop[-2]; 10919 vtop[-2] = tmp; 10920 /* stack: L1 L2 H1 H2 */ 10921 /* compare high */ 10922 op1 = op; 10923 /* when values are equal, we need to compare low words. since 10924 the jump is inverted, we invert the test too. */ 10925 if (op1 == TOK_LT) 10926 op1 = TOK_LE; 10927 else if (op1 == TOK_GT) 10928 op1 = TOK_GE; 10929 else if (op1 == TOK_ULT) 10930 op1 = TOK_ULE; 10931 else if (op1 == TOK_UGT) 10932 op1 = TOK_UGE; 10933 a = 0; 10934 b = 0; 10935 gen_op(op1); 10936 if (op1 != TOK_NE) { 10937 a = gtst(1, 0); 10938 } 10939 if (op != TOK_EQ) { 10940 /* generate non equal test */ 10941 /* XXX: NOT PORTABLE yet */ 10942 if (a == 0) { 10943 b = gtst(0, 0); 10944 } else { 10945 #if defined(TCC_TARGET_I386) 10946 b = psym(0x850f, 0); 10947 #elif defined(TCC_TARGET_ARM) 10948 b = ind; 10949 o(0x1A000000 | encbranch(ind, 0, 1)); 10950 #elif defined(TCC_TARGET_C67) 10951 error("not implemented"); 10952 #else 10953 #error not supported 10954 #endif 10955 } 10956 } 10957 /* compare low. Always unsigned */ 10958 op1 = op; 10959 if (op1 == TOK_LT) 10960 op1 = TOK_ULT; 10961 else if (op1 == TOK_LE) 10962 op1 = TOK_ULE; 10963 else if (op1 == TOK_GT) 10964 op1 = TOK_UGT; 10965 else if (op1 == TOK_GE) 10966 op1 = TOK_UGE; 10967 gen_op(op1); 10968 a = gtst(1, a); 10969 gsym(b); 10970 vseti(VT_JMPI, a); 10971 break; 10972 } 10973 } 10974 10975 /* handle integer constant optimizations and various machine 10976 independent opt */ 10977 void gen_opic(int op) 10978 { 10979 int fc, c1, c2, n; 10980 SValue *v1, *v2; 10981 10982 v1 = vtop - 1; 10983 v2 = vtop; 10984 /* currently, we cannot do computations with forward symbols */ 10985 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 10986 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 10987 if (c1 && c2) { 10988 fc = v2->c.i; 10989 switch(op) { 10990 case '+': v1->c.i += fc; break; 10991 case '-': v1->c.i -= fc; break; 10992 case '&': v1->c.i &= fc; break; 10993 case '^': v1->c.i ^= fc; break; 10994 case '|': v1->c.i |= fc; break; 10995 case '*': v1->c.i *= fc; break; 10996 10997 case TOK_PDIV: 10998 case '/': 10999 case '%': 11000 case TOK_UDIV: 11001 case TOK_UMOD: 11002 /* if division by zero, generate explicit division */ 11003 if (fc == 0) { 11004 if (const_wanted) 11005 error("division by zero in constant"); 11006 goto general_case; 11007 } 11008 switch(op) { 11009 default: v1->c.i /= fc; break; 11010 case '%': v1->c.i %= fc; break; 11011 case TOK_UDIV: v1->c.i = (unsigned)v1->c.i / fc; break; 11012 case TOK_UMOD: v1->c.i = (unsigned)v1->c.i % fc; break; 11013 } 11014 break; 11015 case TOK_SHL: v1->c.i <<= fc; break; 11016 case TOK_SHR: v1->c.i = (unsigned)v1->c.i >> fc; break; 11017 case TOK_SAR: v1->c.i >>= fc; break; 11018 /* tests */ 11019 case TOK_ULT: v1->c.i = (unsigned)v1->c.i < (unsigned)fc; break; 11020 case TOK_UGE: v1->c.i = (unsigned)v1->c.i >= (unsigned)fc; break; 11021 case TOK_EQ: v1->c.i = v1->c.i == fc; break; 11022 case TOK_NE: v1->c.i = v1->c.i != fc; break; 11023 case TOK_ULE: v1->c.i = (unsigned)v1->c.i <= (unsigned)fc; break; 11024 case TOK_UGT: v1->c.i = (unsigned)v1->c.i > (unsigned)fc; break; 11025 case TOK_LT: v1->c.i = v1->c.i < fc; break; 11026 case TOK_GE: v1->c.i = v1->c.i >= fc; break; 11027 case TOK_LE: v1->c.i = v1->c.i <= fc; break; 11028 case TOK_GT: v1->c.i = v1->c.i > fc; break; 11029 /* logical */ 11030 case TOK_LAND: v1->c.i = v1->c.i && fc; break; 11031 case TOK_LOR: v1->c.i = v1->c.i || fc; break; 11032 default: 11033 goto general_case; 11034 } 11035 vtop--; 11036 } else { 11037 /* if commutative ops, put c2 as constant */ 11038 if (c1 && (op == '+' || op == '&' || op == '^' || 11039 op == '|' || op == '*')) { 11040 vswap(); 11041 swap(&c1, &c2); 11042 } 11043 fc = vtop->c.i; 11044 if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 11045 op == TOK_PDIV) && 11046 fc == 1) || 11047 ((op == '+' || op == '-' || op == '|' || op == '^' || 11048 op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 11049 fc == 0) || 11050 (op == '&' && 11051 fc == -1))) { 11052 /* nothing to do */ 11053 vtop--; 11054 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) { 11055 /* try to use shifts instead of muls or divs */ 11056 if (fc > 0 && (fc & (fc - 1)) == 0) { 11057 n = -1; 11058 while (fc) { 11059 fc >>= 1; 11060 n++; 11061 } 11062 vtop->c.i = n; 11063 if (op == '*') 11064 op = TOK_SHL; 11065 else if (op == TOK_PDIV) 11066 op = TOK_SAR; 11067 else 11068 op = TOK_SHR; 11069 } 11070 goto general_case; 11071 } else if (c2 && (op == '+' || op == '-') && 11072 (vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == 11073 (VT_CONST | VT_SYM)) { 11074 /* symbol + constant case */ 11075 if (op == '-') 11076 fc = -fc; 11077 vtop--; 11078 vtop->c.i += fc; 11079 } else { 11080 general_case: 11081 if (!nocode_wanted) { 11082 /* call low level op generator */ 11083 gen_opi(op); 11084 } else { 11085 vtop--; 11086 } 11087 } 11088 } 11089 } 11090 11091 /* generate a floating point operation with constant propagation */ 11092 void gen_opif(int op) 11093 { 11094 int c1, c2; 11095 SValue *v1, *v2; 11096 long double f1, f2; 11097 11098 v1 = vtop - 1; 11099 v2 = vtop; 11100 /* currently, we cannot do computations with forward symbols */ 11101 c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 11102 c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 11103 if (c1 && c2) { 11104 if (v1->type.t == VT_FLOAT) { 11105 f1 = v1->c.f; 11106 f2 = v2->c.f; 11107 } else if (v1->type.t == VT_DOUBLE) { 11108 f1 = v1->c.d; 11109 f2 = v2->c.d; 11110 } else { 11111 f1 = v1->c.ld; 11112 f2 = v2->c.ld; 11113 } 11114 11115 /* NOTE: we only do constant propagation if finite number (not 11116 NaN or infinity) (ANSI spec) */ 11117 if (!ieee_finite(f1) || !ieee_finite(f2)) 11118 goto general_case; 11119 11120 switch(op) { 11121 case '+': f1 += f2; break; 11122 case '-': f1 -= f2; break; 11123 case '*': f1 *= f2; break; 11124 case '/': 11125 if (f2 == 0.0) { 11126 if (const_wanted) 11127 error("division by zero in constant"); 11128 goto general_case; 11129 } 11130 f1 /= f2; 11131 break; 11132 /* XXX: also handles tests ? */ 11133 default: 11134 goto general_case; 11135 } 11136 /* XXX: overflow test ? */ 11137 if (v1->type.t == VT_FLOAT) { 11138 v1->c.f = f1; 11139 } else if (v1->type.t == VT_DOUBLE) { 11140 v1->c.d = f1; 11141 } else { 11142 v1->c.ld = f1; 11143 } 11144 vtop--; 11145 } else { 11146 general_case: 11147 if (!nocode_wanted) { 11148 gen_opf(op); 11149 } else { 11150 vtop--; 11151 } 11152 } 11153 } 11154 11155 /* return the pointed type of t */ 11156 static inline CType *pointed_type(CType *type) 11157 { 11158 return &type->ref->type; 11159 } 11160 11161 static int pointed_size(CType *type) 11162 { 11163 int align; 11164 return type_size(pointed_type(type), &align); 11165 } 11166 11167 static inline int is_null_pointer(SValue *p) 11168 { 11169 if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) 11170 return 0; 11171 return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || 11172 ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0); 11173 } 11174 11175 static inline int is_integer_btype(int bt) 11176 { 11177 return (bt == VT_BYTE || bt == VT_SHORT || 11178 bt == VT_INT || bt == VT_LLONG); 11179 } 11180 11181 /* check types for comparison or substraction of pointers */ 11182 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op) 11183 { 11184 CType *type1, *type2, tmp_type1, tmp_type2; 11185 int bt1, bt2; 11186 11187 /* null pointers are accepted for all comparisons as gcc */ 11188 if (is_null_pointer(p1) || is_null_pointer(p2)) 11189 return; 11190 type1 = &p1->type; 11191 type2 = &p2->type; 11192 bt1 = type1->t & VT_BTYPE; 11193 bt2 = type2->t & VT_BTYPE; 11194 /* accept comparison between pointer and integer with a warning */ 11195 if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') { 11196 warning("comparison between pointer and integer"); 11197 return; 11198 } 11199 11200 /* both must be pointers or implicit function pointers */ 11201 if (bt1 == VT_PTR) { 11202 type1 = pointed_type(type1); 11203 } else if (bt1 != VT_FUNC) 11204 goto invalid_operands; 11205 11206 if (bt2 == VT_PTR) { 11207 type2 = pointed_type(type2); 11208 } else if (bt2 != VT_FUNC) { 11209 invalid_operands: 11210 error("invalid operands to binary %s", get_tok_str(op, NULL)); 11211 } 11212 if ((type1->t & VT_BTYPE) == VT_VOID || 11213 (type2->t & VT_BTYPE) == VT_VOID) 11214 return; 11215 tmp_type1 = *type1; 11216 tmp_type2 = *type2; 11217 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 11218 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 11219 if (!is_compatible_types(&tmp_type1, &tmp_type2)) { 11220 /* gcc-like error if '-' is used */ 11221 if (op == '-') 11222 goto invalid_operands; 11223 else 11224 warning("comparison of distinct pointer types lacks a cast"); 11225 } 11226 } 11227 11228 /* generic gen_op: handles types problems */ 11229 void gen_op(int op) 11230 { 11231 int u, t1, t2, bt1, bt2, t; 11232 CType type1; 11233 11234 t1 = vtop[-1].type.t; 11235 t2 = vtop[0].type.t; 11236 bt1 = t1 & VT_BTYPE; 11237 bt2 = t2 & VT_BTYPE; 11238 11239 if (bt1 == VT_PTR || bt2 == VT_PTR) { 11240 /* at least one operand is a pointer */ 11241 /* relationnal op: must be both pointers */ 11242 if (op >= TOK_ULT && op <= TOK_GT) { 11243 check_comparison_pointer_types(vtop - 1, vtop, op); 11244 /* pointers are handled are unsigned */ 11245 t = VT_INT | VT_UNSIGNED; 11246 goto std_op; 11247 } 11248 /* if both pointers, then it must be the '-' op */ 11249 if (bt1 == VT_PTR && bt2 == VT_PTR) { 11250 if (op != '-') 11251 error("cannot use pointers here"); 11252 check_comparison_pointer_types(vtop - 1, vtop, op); 11253 /* XXX: check that types are compatible */ 11254 u = pointed_size(&vtop[-1].type); 11255 gen_opic(op); 11256 /* set to integer type */ 11257 vtop->type.t = VT_INT; 11258 vpushi(u); 11259 gen_op(TOK_PDIV); 11260 } else { 11261 /* exactly one pointer : must be '+' or '-'. */ 11262 if (op != '-' && op != '+') 11263 error("cannot use pointers here"); 11264 /* Put pointer as first operand */ 11265 if (bt2 == VT_PTR) { 11266 vswap(); 11267 swap(&t1, &t2); 11268 } 11269 type1 = vtop[-1].type; 11270 /* XXX: cast to int ? (long long case) */ 11271 vpushi(pointed_size(&vtop[-1].type)); 11272 gen_op('*'); 11273 #ifdef CONFIG_TCC_BCHECK 11274 /* if evaluating constant expression, no code should be 11275 generated, so no bound check */ 11276 if (do_bounds_check && !const_wanted) { 11277 /* if bounded pointers, we generate a special code to 11278 test bounds */ 11279 if (op == '-') { 11280 vpushi(0); 11281 vswap(); 11282 gen_op('-'); 11283 } 11284 gen_bounded_ptr_add(); 11285 } else 11286 #endif 11287 { 11288 gen_opic(op); 11289 } 11290 /* put again type if gen_opic() swaped operands */ 11291 vtop->type = type1; 11292 } 11293 } else if (is_float(bt1) || is_float(bt2)) { 11294 /* compute bigger type and do implicit casts */ 11295 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { 11296 t = VT_LDOUBLE; 11297 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { 11298 t = VT_DOUBLE; 11299 } else { 11300 t = VT_FLOAT; 11301 } 11302 /* floats can only be used for a few operations */ 11303 if (op != '+' && op != '-' && op != '*' && op != '/' && 11304 (op < TOK_ULT || op > TOK_GT)) 11305 error("invalid operands for binary operation"); 11306 goto std_op; 11307 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { 11308 /* cast to biggest op */ 11309 t = VT_LLONG; 11310 /* convert to unsigned if it does not fit in a long long */ 11311 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || 11312 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) 11313 t |= VT_UNSIGNED; 11314 goto std_op; 11315 } else { 11316 /* integer operations */ 11317 t = VT_INT; 11318 /* convert to unsigned if it does not fit in an integer */ 11319 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || 11320 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) 11321 t |= VT_UNSIGNED; 11322 std_op: 11323 /* XXX: currently, some unsigned operations are explicit, so 11324 we modify them here */ 11325 if (t & VT_UNSIGNED) { 11326 if (op == TOK_SAR) 11327 op = TOK_SHR; 11328 else if (op == '/') 11329 op = TOK_UDIV; 11330 else if (op == '%') 11331 op = TOK_UMOD; 11332 else if (op == TOK_LT) 11333 op = TOK_ULT; 11334 else if (op == TOK_GT) 11335 op = TOK_UGT; 11336 else if (op == TOK_LE) 11337 op = TOK_ULE; 11338 else if (op == TOK_GE) 11339 op = TOK_UGE; 11340 } 11341 vswap(); 11342 type1.t = t; 11343 gen_cast(&type1); 11344 vswap(); 11345 /* special case for shifts and long long: we keep the shift as 11346 an integer */ 11347 if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) 11348 type1.t = VT_INT; 11349 gen_cast(&type1); 11350 if (is_float(t)) 11351 gen_opif(op); 11352 else if ((t & VT_BTYPE) == VT_LLONG) 11353 gen_opl(op); 11354 else 11355 gen_opic(op); 11356 if (op >= TOK_ULT && op <= TOK_GT) { 11357 /* relationnal op: the result is an int */ 11358 vtop->type.t = VT_INT; 11359 } else { 11360 vtop->type.t = t; 11361 } 11362 } 11363 } 11364 11365 /* generic itof for unsigned long long case */ 11366 void gen_cvt_itof1(int t) 11367 { 11368 if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 11369 (VT_LLONG | VT_UNSIGNED)) { 11370 11371 if (t == VT_FLOAT) 11372 vpush_global_sym(&func_old_type, TOK___ulltof); 11373 else if (t == VT_DOUBLE) 11374 vpush_global_sym(&func_old_type, TOK___ulltod); 11375 else 11376 vpush_global_sym(&func_old_type, TOK___ulltold); 11377 vrott(2); 11378 gfunc_call(1); 11379 vpushi(0); 11380 vtop->r = REG_FRET; 11381 } else { 11382 gen_cvt_itof(t); 11383 } 11384 } 11385 11386 /* generic ftoi for unsigned long long case */ 11387 void gen_cvt_ftoi1(int t) 11388 { 11389 int st; 11390 11391 if (t == (VT_LLONG | VT_UNSIGNED)) { 11392 /* not handled natively */ 11393 st = vtop->type.t & VT_BTYPE; 11394 if (st == VT_FLOAT) 11395 vpush_global_sym(&func_old_type, TOK___fixunssfdi); 11396 else if (st == VT_DOUBLE) 11397 vpush_global_sym(&func_old_type, TOK___fixunsdfdi); 11398 else 11399 vpush_global_sym(&func_old_type, TOK___fixunsxfdi); 11400 vrott(2); 11401 gfunc_call(1); 11402 vpushi(0); 11403 vtop->r = REG_IRET; 11404 vtop->r2 = REG_LRET; 11405 } else { 11406 gen_cvt_ftoi(t); 11407 } 11408 } 11409 11410 /* force char or short cast */ 11411 void force_charshort_cast(int t) 11412 { 11413 int bits, dbt; 11414 dbt = t & VT_BTYPE; 11415 /* XXX: add optimization if lvalue : just change type and offset */ 11416 if (dbt == VT_BYTE) 11417 bits = 8; 11418 else 11419 bits = 16; 11420 if (t & VT_UNSIGNED) { 11421 vpushi((1 << bits) - 1); 11422 gen_op('&'); 11423 } else { 11424 bits = 32 - bits; 11425 vpushi(bits); 11426 gen_op(TOK_SHL); 11427 vpushi(bits); 11428 gen_op(TOK_SAR); 11429 } 11430 } 11431 11432 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */ 11433 static void gen_cast(CType *type) 11434 { 11435 int sbt, dbt, sf, df, c; 11436 11437 /* special delayed cast for char/short */ 11438 /* XXX: in some cases (multiple cascaded casts), it may still 11439 be incorrect */ 11440 if (vtop->r & VT_MUSTCAST) { 11441 vtop->r &= ~VT_MUSTCAST; 11442 force_charshort_cast(vtop->type.t); 11443 } 11444 11445 /* bitfields first get cast to ints */ 11446 if (vtop->type.t & VT_BITFIELD) { 11447 gv(RC_INT); 11448 } 11449 11450 dbt = type->t & (VT_BTYPE | VT_UNSIGNED); 11451 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED); 11452 11453 if (sbt != dbt && !nocode_wanted) { 11454 sf = is_float(sbt); 11455 df = is_float(dbt); 11456 c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 11457 if (sf && df) { 11458 /* convert from fp to fp */ 11459 if (c) { 11460 /* constant case: we can do it now */ 11461 /* XXX: in ISOC, cannot do it if error in convert */ 11462 if (dbt == VT_FLOAT && sbt == VT_DOUBLE) 11463 vtop->c.f = (float)vtop->c.d; 11464 else if (dbt == VT_FLOAT && sbt == VT_LDOUBLE) 11465 vtop->c.f = (float)vtop->c.ld; 11466 else if (dbt == VT_DOUBLE && sbt == VT_FLOAT) 11467 vtop->c.d = (double)vtop->c.f; 11468 else if (dbt == VT_DOUBLE && sbt == VT_LDOUBLE) 11469 vtop->c.d = (double)vtop->c.ld; 11470 else if (dbt == VT_LDOUBLE && sbt == VT_FLOAT) 11471 vtop->c.ld = (long double)vtop->c.f; 11472 else if (dbt == VT_LDOUBLE && sbt == VT_DOUBLE) 11473 vtop->c.ld = (long double)vtop->c.d; 11474 } else { 11475 /* non constant case: generate code */ 11476 gen_cvt_ftof(dbt); 11477 } 11478 } else if (df) { 11479 /* convert int to fp */ 11480 if (c) { 11481 switch(sbt) { 11482 case VT_LLONG | VT_UNSIGNED: 11483 case VT_LLONG: 11484 /* XXX: add const cases for long long */ 11485 goto do_itof; 11486 case VT_INT | VT_UNSIGNED: 11487 switch(dbt) { 11488 case VT_FLOAT: vtop->c.f = (float)vtop->c.ui; break; 11489 case VT_DOUBLE: vtop->c.d = (double)vtop->c.ui; break; 11490 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.ui; break; 11491 } 11492 break; 11493 default: 11494 switch(dbt) { 11495 case VT_FLOAT: vtop->c.f = (float)vtop->c.i; break; 11496 case VT_DOUBLE: vtop->c.d = (double)vtop->c.i; break; 11497 case VT_LDOUBLE: vtop->c.ld = (long double)vtop->c.i; break; 11498 } 11499 break; 11500 } 11501 } else { 11502 do_itof: 11503 #if !defined(TCC_TARGET_ARM) 11504 gen_cvt_itof1(dbt); 11505 #else 11506 gen_cvt_itof(dbt); 11507 #endif 11508 } 11509 } else if (sf) { 11510 /* convert fp to int */ 11511 /* we handle char/short/etc... with generic code */ 11512 if (dbt != (VT_INT | VT_UNSIGNED) && 11513 dbt != (VT_LLONG | VT_UNSIGNED) && 11514 dbt != VT_LLONG) 11515 dbt = VT_INT; 11516 if (c) { 11517 switch(dbt) { 11518 case VT_LLONG | VT_UNSIGNED: 11519 case VT_LLONG: 11520 /* XXX: add const cases for long long */ 11521 goto do_ftoi; 11522 case VT_INT | VT_UNSIGNED: 11523 switch(sbt) { 11524 case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break; 11525 case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; 11526 case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; 11527 } 11528 break; 11529 default: 11530 /* int case */ 11531 switch(sbt) { 11532 case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break; 11533 case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break; 11534 case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break; 11535 } 11536 break; 11537 } 11538 } else { 11539 do_ftoi: 11540 gen_cvt_ftoi1(dbt); 11541 } 11542 if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { 11543 /* additional cast for char/short/bool... */ 11544 vtop->type.t = dbt; 11545 gen_cast(type); 11546 } 11547 } else if ((dbt & VT_BTYPE) == VT_LLONG) { 11548 if ((sbt & VT_BTYPE) != VT_LLONG) { 11549 /* scalar to long long */ 11550 if (c) { 11551 if (sbt == (VT_INT | VT_UNSIGNED)) 11552 vtop->c.ll = vtop->c.ui; 11553 else 11554 vtop->c.ll = vtop->c.i; 11555 } else { 11556 /* machine independent conversion */ 11557 gv(RC_INT); 11558 /* generate high word */ 11559 if (sbt == (VT_INT | VT_UNSIGNED)) { 11560 vpushi(0); 11561 gv(RC_INT); 11562 } else { 11563 gv_dup(); 11564 vpushi(31); 11565 gen_op(TOK_SAR); 11566 } 11567 /* patch second register */ 11568 vtop[-1].r2 = vtop->r; 11569 vpop(); 11570 } 11571 } 11572 } else if (dbt == VT_BOOL) { 11573 /* scalar to bool */ 11574 vpushi(0); 11575 gen_op(TOK_NE); 11576 } else if ((dbt & VT_BTYPE) == VT_BYTE || 11577 (dbt & VT_BTYPE) == VT_SHORT) { 11578 force_charshort_cast(dbt); 11579 } else if ((dbt & VT_BTYPE) == VT_INT) { 11580 /* scalar to int */ 11581 if (sbt == VT_LLONG) { 11582 /* from long long: just take low order word */ 11583 lexpand(); 11584 vpop(); 11585 } 11586 /* if lvalue and single word type, nothing to do because 11587 the lvalue already contains the real type size (see 11588 VT_LVAL_xxx constants) */ 11589 } 11590 } 11591 vtop->type = *type; 11592 } 11593 11594 /* return type size. Put alignment at 'a' */ 11595 static int type_size(CType *type, int *a) 11596 { 11597 Sym *s; 11598 int bt; 11599 11600 bt = type->t & VT_BTYPE; 11601 if (bt == VT_STRUCT) { 11602 /* struct/union */ 11603 s = type->ref; 11604 *a = s->r; 11605 return s->c; 11606 } else if (bt == VT_PTR) { 11607 if (type->t & VT_ARRAY) { 11608 s = type->ref; 11609 return type_size(&s->type, a) * s->c; 11610 } else { 11611 *a = PTR_SIZE; 11612 return PTR_SIZE; 11613 } 11614 } else if (bt == VT_LDOUBLE) { 11615 *a = LDOUBLE_ALIGN; 11616 return LDOUBLE_SIZE; 11617 } else if (bt == VT_DOUBLE || bt == VT_LLONG) { 11618 #ifdef TCC_TARGET_I386 11619 *a = 4; 11620 #else 11621 *a = 8; 11622 #endif 11623 return 8; 11624 } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) { 11625 *a = 4; 11626 return 4; 11627 } else if (bt == VT_SHORT) { 11628 *a = 2; 11629 return 2; 11630 } else { 11631 /* char, void, function, _Bool */ 11632 *a = 1; 11633 return 1; 11634 } 11635 } 11636 11637 /* modify type so that its it is a pointer to type. */ 11638 static void mk_pointer(CType *type) 11639 { 11640 Sym *s; 11641 s = sym_push(SYM_FIELD, type, 0, -1); 11642 type->t = VT_PTR | (type->t & ~VT_TYPE); 11643 type->ref = s; 11644 } 11645 11646 /* compare function types. OLD functions match any new functions */ 11647 static int is_compatible_func(CType *type1, CType *type2) 11648 { 11649 Sym *s1, *s2; 11650 11651 s1 = type1->ref; 11652 s2 = type2->ref; 11653 if (!is_compatible_types(&s1->type, &s2->type)) 11654 return 0; 11655 /* check func_call */ 11656 if (s1->r != s2->r) 11657 return 0; 11658 /* XXX: not complete */ 11659 if (s1->c == FUNC_OLD || s2->c == FUNC_OLD) 11660 return 1; 11661 if (s1->c != s2->c) 11662 return 0; 11663 while (s1 != NULL) { 11664 if (s2 == NULL) 11665 return 0; 11666 if (!is_compatible_types(&s1->type, &s2->type)) 11667 return 0; 11668 s1 = s1->next; 11669 s2 = s2->next; 11670 } 11671 if (s2) 11672 return 0; 11673 return 1; 11674 } 11675 11676 /* return true if type1 and type2 are exactly the same (including 11677 qualifiers). 11678 11679 - enums are not checked as gcc __builtin_types_compatible_p () 11680 */ 11681 static int is_compatible_types(CType *type1, CType *type2) 11682 { 11683 int bt1, t1, t2; 11684 11685 t1 = type1->t & VT_TYPE; 11686 t2 = type2->t & VT_TYPE; 11687 /* XXX: bitfields ? */ 11688 if (t1 != t2) 11689 return 0; 11690 /* test more complicated cases */ 11691 bt1 = t1 & VT_BTYPE; 11692 if (bt1 == VT_PTR) { 11693 type1 = pointed_type(type1); 11694 type2 = pointed_type(type2); 11695 return is_compatible_types(type1, type2); 11696 } else if (bt1 == VT_STRUCT) { 11697 return (type1->ref == type2->ref); 11698 } else if (bt1 == VT_FUNC) { 11699 return is_compatible_func(type1, type2); 11700 } else { 11701 return 1; 11702 } 11703 } 11704 11705 /* print a type. If 'varstr' is not NULL, then the variable is also 11706 printed in the type */ 11707 /* XXX: union */ 11708 /* XXX: add array and function pointers */ 11709 void type_to_str(char *buf, int buf_size, 11710 CType *type, const char *varstr) 11711 { 11712 int bt, v, t; 11713 Sym *s, *sa; 11714 char buf1[256]; 11715 const char *tstr; 11716 11717 t = type->t & VT_TYPE; 11718 bt = t & VT_BTYPE; 11719 buf[0] = '\0'; 11720 if (t & VT_CONSTANT) 11721 pstrcat(buf, buf_size, "const "); 11722 if (t & VT_VOLATILE) 11723 pstrcat(buf, buf_size, "volatile "); 11724 if (t & VT_UNSIGNED) 11725 pstrcat(buf, buf_size, "unsigned "); 11726 switch(bt) { 11727 case VT_VOID: 11728 tstr = "void"; 11729 goto add_tstr; 11730 case VT_BOOL: 11731 tstr = "_Bool"; 11732 goto add_tstr; 11733 case VT_BYTE: 11734 tstr = "char"; 11735 goto add_tstr; 11736 case VT_SHORT: 11737 tstr = "short"; 11738 goto add_tstr; 11739 case VT_INT: 11740 tstr = "int"; 11741 goto add_tstr; 11742 case VT_LONG: 11743 tstr = "long"; 11744 goto add_tstr; 11745 case VT_LLONG: 11746 tstr = "long long"; 11747 goto add_tstr; 11748 case VT_FLOAT: 11749 tstr = "float"; 11750 goto add_tstr; 11751 case VT_DOUBLE: 11752 tstr = "double"; 11753 goto add_tstr; 11754 case VT_LDOUBLE: 11755 tstr = "long double"; 11756 add_tstr: 11757 pstrcat(buf, buf_size, tstr); 11758 break; 11759 case VT_ENUM: 11760 case VT_STRUCT: 11761 if (bt == VT_STRUCT) 11762 tstr = "struct "; 11763 else 11764 tstr = "enum "; 11765 pstrcat(buf, buf_size, tstr); 11766 v = type->ref->v & ~SYM_STRUCT; 11767 if (v >= SYM_FIRST_ANOM) 11768 pstrcat(buf, buf_size, "<anonymous>"); 11769 else 11770 pstrcat(buf, buf_size, get_tok_str(v, NULL)); 11771 break; 11772 case VT_FUNC: 11773 s = type->ref; 11774 type_to_str(buf, buf_size, &s->type, varstr); 11775 pstrcat(buf, buf_size, "("); 11776 sa = s->next; 11777 while (sa != NULL) { 11778 type_to_str(buf1, sizeof(buf1), &sa->type, NULL); 11779 pstrcat(buf, buf_size, buf1); 11780 sa = sa->next; 11781 if (sa) 11782 pstrcat(buf, buf_size, ", "); 11783 } 11784 pstrcat(buf, buf_size, ")"); 11785 goto no_var; 11786 case VT_PTR: 11787 s = type->ref; 11788 pstrcpy(buf1, sizeof(buf1), "*"); 11789 if (varstr) 11790 pstrcat(buf1, sizeof(buf1), varstr); 11791 type_to_str(buf, buf_size, &s->type, buf1); 11792 goto no_var; 11793 } 11794 if (varstr) { 11795 pstrcat(buf, buf_size, " "); 11796 pstrcat(buf, buf_size, varstr); 11797 } 11798 no_var: ; 11799 } 11800 11801 /* verify type compatibility to store vtop in 'dt' type, and generate 11802 casts if needed. */ 11803 static void gen_assign_cast(CType *dt) 11804 { 11805 CType *st, *type1, *type2, tmp_type1, tmp_type2; 11806 char buf1[256], buf2[256]; 11807 int dbt, sbt; 11808 11809 st = &vtop->type; /* source type */ 11810 dbt = dt->t & VT_BTYPE; 11811 sbt = st->t & VT_BTYPE; 11812 if (dt->t & VT_CONSTANT) 11813 warning("assignment of read-only location"); 11814 switch(dbt) { 11815 case VT_PTR: 11816 /* special cases for pointers */ 11817 /* '0' can also be a pointer */ 11818 if (is_null_pointer(vtop)) 11819 goto type_ok; 11820 /* accept implicit pointer to integer cast with warning */ 11821 if (is_integer_btype(sbt)) { 11822 warning("assignment makes pointer from integer without a cast"); 11823 goto type_ok; 11824 } 11825 type1 = pointed_type(dt); 11826 /* a function is implicitely a function pointer */ 11827 if (sbt == VT_FUNC) { 11828 if ((type1->t & VT_BTYPE) != VT_VOID && 11829 !is_compatible_types(pointed_type(dt), st)) 11830 goto error; 11831 else 11832 goto type_ok; 11833 } 11834 if (sbt != VT_PTR) 11835 goto error; 11836 type2 = pointed_type(st); 11837 if ((type1->t & VT_BTYPE) == VT_VOID || 11838 (type2->t & VT_BTYPE) == VT_VOID) { 11839 /* void * can match anything */ 11840 } else { 11841 /* exact type match, except for unsigned */ 11842 tmp_type1 = *type1; 11843 tmp_type2 = *type2; 11844 tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 11845 tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); 11846 if (!is_compatible_types(&tmp_type1, &tmp_type2)) 11847 goto error; 11848 } 11849 /* check const and volatile */ 11850 if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || 11851 (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE))) 11852 warning("assignment discards qualifiers from pointer target type"); 11853 break; 11854 case VT_BYTE: 11855 case VT_SHORT: 11856 case VT_INT: 11857 case VT_LLONG: 11858 if (sbt == VT_PTR || sbt == VT_FUNC) { 11859 warning("assignment makes integer from pointer without a cast"); 11860 } 11861 /* XXX: more tests */ 11862 break; 11863 case VT_STRUCT: 11864 tmp_type1 = *dt; 11865 tmp_type2 = *st; 11866 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); 11867 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); 11868 if (!is_compatible_types(&tmp_type1, &tmp_type2)) { 11869 error: 11870 type_to_str(buf1, sizeof(buf1), st, NULL); 11871 type_to_str(buf2, sizeof(buf2), dt, NULL); 11872 error("cannot cast '%s' to '%s'", buf1, buf2); 11873 } 11874 break; 11875 } 11876 type_ok: 11877 gen_cast(dt); 11878 } 11879 11880 /* store vtop in lvalue pushed on stack */ 11881 void vstore(void) 11882 { 11883 int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast; 11884 11885 ft = vtop[-1].type.t; 11886 sbt = vtop->type.t & VT_BTYPE; 11887 dbt = ft & VT_BTYPE; 11888 if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || 11889 (sbt == VT_INT && dbt == VT_SHORT)) { 11890 /* optimize char/short casts */ 11891 delayed_cast = VT_MUSTCAST; 11892 vtop->type.t = ft & VT_TYPE; 11893 /* XXX: factorize */ 11894 if (ft & VT_CONSTANT) 11895 warning("assignment of read-only location"); 11896 } else { 11897 delayed_cast = 0; 11898 if (!(ft & VT_BITFIELD)) 11899 gen_assign_cast(&vtop[-1].type); 11900 } 11901 11902 if (sbt == VT_STRUCT) { 11903 /* if structure, only generate pointer */ 11904 /* structure assignment : generate memcpy */ 11905 /* XXX: optimize if small size */ 11906 if (!nocode_wanted) { 11907 size = type_size(&vtop->type, &align); 11908 11909 vpush_global_sym(&func_old_type, TOK_memcpy); 11910 11911 /* destination */ 11912 vpushv(vtop - 2); 11913 vtop->type.t = VT_INT; 11914 gaddrof(); 11915 /* source */ 11916 vpushv(vtop - 2); 11917 vtop->type.t = VT_INT; 11918 gaddrof(); 11919 /* type size */ 11920 vpushi(size); 11921 gfunc_call(3); 11922 11923 vswap(); 11924 vpop(); 11925 } else { 11926 vswap(); 11927 vpop(); 11928 } 11929 /* leave source on stack */ 11930 } else if (ft & VT_BITFIELD) { 11931 /* bitfield store handling */ 11932 bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f; 11933 bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f; 11934 /* remove bit field info to avoid loops */ 11935 vtop[-1].type.t = ft & ~(VT_BITFIELD | (~0U << VT_STRUCT_SHIFT)); 11936 11937 /* duplicate destination */ 11938 vdup(); 11939 vtop[-1] = vtop[-2]; 11940 11941 /* mask and shift source */ 11942 vpushi((1 << bit_size) - 1); 11943 gen_op('&'); 11944 vpushi(bit_pos); 11945 gen_op(TOK_SHL); 11946 /* load destination, mask and or with source */ 11947 vswap(); 11948 vpushi(~(((1 << bit_size) - 1) << bit_pos)); 11949 gen_op('&'); 11950 gen_op('|'); 11951 /* store result */ 11952 vstore(); 11953 } else { 11954 #ifdef CONFIG_TCC_BCHECK 11955 /* bound check case */ 11956 if (vtop[-1].r & VT_MUSTBOUND) { 11957 vswap(); 11958 gbound(); 11959 vswap(); 11960 } 11961 #endif 11962 if (!nocode_wanted) { 11963 rc = RC_INT; 11964 if (is_float(ft)) 11965 rc = RC_FLOAT; 11966 r = gv(rc); /* generate value */ 11967 /* if lvalue was saved on stack, must read it */ 11968 if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) { 11969 SValue sv; 11970 t = get_reg(RC_INT); 11971 sv.type.t = VT_INT; 11972 sv.r = VT_LOCAL | VT_LVAL; 11973 sv.c.ul = vtop[-1].c.ul; 11974 load(t, &sv); 11975 vtop[-1].r = t | VT_LVAL; 11976 } 11977 store(r, vtop - 1); 11978 /* two word case handling : store second register at word + 4 */ 11979 if ((ft & VT_BTYPE) == VT_LLONG) { 11980 vswap(); 11981 /* convert to int to increment easily */ 11982 vtop->type.t = VT_INT; 11983 gaddrof(); 11984 vpushi(4); 11985 gen_op('+'); 11986 vtop->r |= VT_LVAL; 11987 vswap(); 11988 /* XXX: it works because r2 is spilled last ! */ 11989 store(vtop->r2, vtop - 1); 11990 } 11991 } 11992 vswap(); 11993 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ 11994 vtop->r |= delayed_cast; 11995 } 11996 } 11997 11998 /* post defines POST/PRE add. c is the token ++ or -- */ 11999 void inc(int post, int c) 12000 { 12001 test_lvalue(); 12002 vdup(); /* save lvalue */ 12003 if (post) { 12004 gv_dup(); /* duplicate value */ 12005 vrotb(3); 12006 vrotb(3); 12007 } 12008 /* add constant */ 12009 vpushi(c - TOK_MID); 12010 gen_op('+'); 12011 vstore(); /* store value */ 12012 if (post) 12013 vpop(); /* if post op, return saved value */ 12014 } 12015 12016 /* Parse GNUC __attribute__ extension. Currently, the following 12017 extensions are recognized: 12018 - aligned(n) : set data/function alignment. 12019 - packed : force data alignment to 1 12020 - section(x) : generate data/code in this section. 12021 - unused : currently ignored, but may be used someday. 12022 - regparm(n) : pass function parameters in registers (i386 only) 12023 */ 12024 static void parse_attribute(AttributeDef *ad) 12025 { 12026 int t, n; 12027 12028 while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { 12029 next(); 12030 skip('('); 12031 skip('('); 12032 while (tok != ')') { 12033 if (tok < TOK_IDENT) 12034 expect("attribute name"); 12035 t = tok; 12036 next(); 12037 switch(t) { 12038 case TOK_SECTION1: 12039 case TOK_SECTION2: 12040 skip('('); 12041 if (tok != TOK_STR) 12042 expect("section name"); 12043 ad->section = find_section(tcc_state, (char *)tokc.cstr->data); 12044 next(); 12045 skip(')'); 12046 break; 12047 case TOK_ALIGNED1: 12048 case TOK_ALIGNED2: 12049 if (tok == '(') { 12050 next(); 12051 n = expr_const(); 12052 if (n <= 0 || (n & (n - 1)) != 0) 12053 error("alignment must be a positive power of two"); 12054 skip(')'); 12055 } else { 12056 n = MAX_ALIGN; 12057 } 12058 ad->aligned = n; 12059 break; 12060 case TOK_PACKED1: 12061 case TOK_PACKED2: 12062 ad->packed = 1; 12063 break; 12064 case TOK_UNUSED1: 12065 case TOK_UNUSED2: 12066 /* currently, no need to handle it because tcc does not 12067 track unused objects */ 12068 break; 12069 case TOK_NORETURN1: 12070 case TOK_NORETURN2: 12071 /* currently, no need to handle it because tcc does not 12072 track unused objects */ 12073 break; 12074 case TOK_CDECL1: 12075 case TOK_CDECL2: 12076 case TOK_CDECL3: 12077 ad->func_call = FUNC_CDECL; 12078 break; 12079 case TOK_STDCALL1: 12080 case TOK_STDCALL2: 12081 case TOK_STDCALL3: 12082 ad->func_call = FUNC_STDCALL; 12083 break; 12084 #ifdef TCC_TARGET_I386 12085 case TOK_REGPARM1: 12086 case TOK_REGPARM2: 12087 skip('('); 12088 n = expr_const(); 12089 if (n > 3) 12090 n = 3; 12091 else if (n < 0) 12092 n = 0; 12093 if (n > 0) 12094 ad->func_call = FUNC_FASTCALL1 + n - 1; 12095 skip(')'); 12096 break; 12097 #endif 12098 case TOK_DLLEXPORT: 12099 ad->dllexport = 1; 12100 break; 12101 default: 12102 if (tcc_state->warn_unsupported) 12103 warning("'%s' attribute ignored", get_tok_str(t, NULL)); 12104 /* skip parameters */ 12105 /* XXX: skip parenthesis too */ 12106 if (tok == '(') { 12107 next(); 12108 while (tok != ')' && tok != -1) 12109 next(); 12110 next(); 12111 } 12112 break; 12113 } 12114 if (tok != ',') 12115 break; 12116 next(); 12117 } 12118 skip(')'); 12119 skip(')'); 12120 } 12121 } 12122 12123 /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ 12124 static void struct_decl(CType *type, int u) 12125 { 12126 int a, v, size, align, maxalign, c, offset; 12127 int bit_size, bit_pos, bsize, bt, lbit_pos; 12128 Sym *s, *ss, **ps; 12129 AttributeDef ad; 12130 CType type1, btype; 12131 12132 a = tok; /* save decl type */ 12133 next(); 12134 if (tok != '{') { 12135 v = tok; 12136 next(); 12137 /* struct already defined ? return it */ 12138 if (v < TOK_IDENT) 12139 expect("struct/union/enum name"); 12140 s = struct_find(v); 12141 if (s) { 12142 if (s->type.t != a) 12143 error("invalid type"); 12144 goto do_decl; 12145 } 12146 } else { 12147 v = anon_sym++; 12148 } 12149 type1.t = a; 12150 /* we put an undefined size for struct/union */ 12151 s = sym_push(v | SYM_STRUCT, &type1, 0, -1); 12152 s->r = 0; /* default alignment is zero as gcc */ 12153 /* put struct/union/enum name in type */ 12154 do_decl: 12155 type->t = u; 12156 type->ref = s; 12157 12158 if (tok == '{') { 12159 next(); 12160 if (s->c != -1) 12161 error("struct/union/enum already defined"); 12162 /* cannot be empty */ 12163 c = 0; 12164 /* non empty enums are not allowed */ 12165 if (a == TOK_ENUM) { 12166 for(;;) { 12167 v = tok; 12168 if (v < TOK_UIDENT) 12169 expect("identifier"); 12170 next(); 12171 if (tok == '=') { 12172 next(); 12173 c = expr_const(); 12174 } 12175 /* enum symbols have static storage */ 12176 ss = sym_push(v, &int_type, VT_CONST, c); 12177 ss->type.t |= VT_STATIC; 12178 if (tok != ',') 12179 break; 12180 next(); 12181 c++; 12182 /* NOTE: we accept a trailing comma */ 12183 if (tok == '}') 12184 break; 12185 } 12186 skip('}'); 12187 } else { 12188 maxalign = 1; 12189 ps = &s->next; 12190 bit_pos = 0; 12191 offset = 0; 12192 while (tok != '}') { 12193 parse_btype(&btype, &ad); 12194 while (1) { 12195 bit_size = -1; 12196 v = 0; 12197 type1 = btype; 12198 if (tok != ':') { 12199 type_decl(&type1, &ad, &v, TYPE_DIRECT); 12200 if ((type1.t & VT_BTYPE) == VT_FUNC || 12201 (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) 12202 error("invalid type for '%s'", 12203 get_tok_str(v, NULL)); 12204 } 12205 if (tok == ':') { 12206 next(); 12207 bit_size = expr_const(); 12208 /* XXX: handle v = 0 case for messages */ 12209 if (bit_size < 0) 12210 error("negative width in bit-field '%s'", 12211 get_tok_str(v, NULL)); 12212 if (v && bit_size == 0) 12213 error("zero width for bit-field '%s'", 12214 get_tok_str(v, NULL)); 12215 } 12216 size = type_size(&type1, &align); 12217 if (ad.aligned) { 12218 if (align < ad.aligned) 12219 align = ad.aligned; 12220 } else if (ad.packed) { 12221 align = 1; 12222 } else if (*tcc_state->pack_stack_ptr) { 12223 if (align > *tcc_state->pack_stack_ptr) 12224 align = *tcc_state->pack_stack_ptr; 12225 } 12226 lbit_pos = 0; 12227 if (bit_size >= 0) { 12228 bt = type1.t & VT_BTYPE; 12229 if (bt != VT_INT && 12230 bt != VT_BYTE && 12231 bt != VT_SHORT && 12232 bt != VT_BOOL && 12233 bt != VT_ENUM) 12234 error("bitfields must have scalar type"); 12235 bsize = size * 8; 12236 if (bit_size > bsize) { 12237 error("width of '%s' exceeds its type", 12238 get_tok_str(v, NULL)); 12239 } else if (bit_size == bsize) { 12240 /* no need for bit fields */ 12241 bit_pos = 0; 12242 } else if (bit_size == 0) { 12243 /* XXX: what to do if only padding in a 12244 structure ? */ 12245 /* zero size: means to pad */ 12246 if (bit_pos > 0) 12247 bit_pos = bsize; 12248 } else { 12249 /* we do not have enough room ? */ 12250 if ((bit_pos + bit_size) > bsize) 12251 bit_pos = 0; 12252 lbit_pos = bit_pos; 12253 /* XXX: handle LSB first */ 12254 type1.t |= VT_BITFIELD | 12255 (bit_pos << VT_STRUCT_SHIFT) | 12256 (bit_size << (VT_STRUCT_SHIFT + 6)); 12257 bit_pos += bit_size; 12258 } 12259 } else { 12260 bit_pos = 0; 12261 } 12262 if (v) { 12263 /* add new memory data only if starting 12264 bit field */ 12265 if (lbit_pos == 0) { 12266 if (a == TOK_STRUCT) { 12267 c = (c + align - 1) & -align; 12268 offset = c; 12269 c += size; 12270 } else { 12271 offset = 0; 12272 if (size > c) 12273 c = size; 12274 } 12275 if (align > maxalign) 12276 maxalign = align; 12277 } 12278 #if 0 12279 printf("add field %s offset=%d", 12280 get_tok_str(v, NULL), offset); 12281 if (type1.t & VT_BITFIELD) { 12282 printf(" pos=%d size=%d", 12283 (type1.t >> VT_STRUCT_SHIFT) & 0x3f, 12284 (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); 12285 } 12286 printf("\n"); 12287 #endif 12288 ss = sym_push(v | SYM_FIELD, &type1, 0, offset); 12289 *ps = ss; 12290 ps = &ss->next; 12291 } 12292 if (tok == ';' || tok == TOK_EOF) 12293 break; 12294 skip(','); 12295 } 12296 skip(';'); 12297 } 12298 skip('}'); 12299 /* store size and alignment */ 12300 s->c = (c + maxalign - 1) & -maxalign; 12301 s->r = maxalign; 12302 } 12303 } 12304 } 12305 12306 /* return 0 if no type declaration. otherwise, return the basic type 12307 and skip it. 12308 */ 12309 static int parse_btype(CType *type, AttributeDef *ad) 12310 { 12311 int t, u, type_found, typespec_found; 12312 Sym *s; 12313 CType type1; 12314 12315 memset(ad, 0, sizeof(AttributeDef)); 12316 type_found = 0; 12317 typespec_found = 0; 12318 t = 0; 12319 while(1) { 12320 switch(tok) { 12321 case TOK_EXTENSION: 12322 /* currently, we really ignore extension */ 12323 next(); 12324 continue; 12325 12326 /* basic types */ 12327 case TOK_CHAR: 12328 u = VT_BYTE; 12329 basic_type: 12330 next(); 12331 basic_type1: 12332 if ((t & VT_BTYPE) != 0) 12333 error("too many basic types"); 12334 t |= u; 12335 typespec_found = 1; 12336 break; 12337 case TOK_VOID: 12338 u = VT_VOID; 12339 goto basic_type; 12340 case TOK_SHORT: 12341 u = VT_SHORT; 12342 goto basic_type; 12343 case TOK_INT: 12344 next(); 12345 typespec_found = 1; 12346 break; 12347 case TOK_LONG: 12348 next(); 12349 if ((t & VT_BTYPE) == VT_DOUBLE) { 12350 t = (t & ~VT_BTYPE) | VT_LDOUBLE; 12351 } else if ((t & VT_BTYPE) == VT_LONG) { 12352 t = (t & ~VT_BTYPE) | VT_LLONG; 12353 } else { 12354 u = VT_LONG; 12355 goto basic_type1; 12356 } 12357 break; 12358 case TOK_BOOL: 12359 u = VT_BOOL; 12360 goto basic_type; 12361 case TOK_FLOAT: 12362 u = VT_FLOAT; 12363 goto basic_type; 12364 case TOK_DOUBLE: 12365 next(); 12366 if ((t & VT_BTYPE) == VT_LONG) { 12367 t = (t & ~VT_BTYPE) | VT_LDOUBLE; 12368 } else { 12369 u = VT_DOUBLE; 12370 goto basic_type1; 12371 } 12372 break; 12373 case TOK_ENUM: 12374 struct_decl(&type1, VT_ENUM); 12375 basic_type2: 12376 u = type1.t; 12377 type->ref = type1.ref; 12378 goto basic_type1; 12379 case TOK_STRUCT: 12380 case TOK_UNION: 12381 struct_decl(&type1, VT_STRUCT); 12382 goto basic_type2; 12383 12384 /* type modifiers */ 12385 case TOK_CONST1: 12386 case TOK_CONST2: 12387 case TOK_CONST3: 12388 t |= VT_CONSTANT; 12389 next(); 12390 break; 12391 case TOK_VOLATILE1: 12392 case TOK_VOLATILE2: 12393 case TOK_VOLATILE3: 12394 t |= VT_VOLATILE; 12395 next(); 12396 break; 12397 case TOK_SIGNED1: 12398 case TOK_SIGNED2: 12399 case TOK_SIGNED3: 12400 typespec_found = 1; 12401 t |= VT_SIGNED; 12402 next(); 12403 break; 12404 case TOK_REGISTER: 12405 case TOK_AUTO: 12406 case TOK_RESTRICT1: 12407 case TOK_RESTRICT2: 12408 case TOK_RESTRICT3: 12409 next(); 12410 break; 12411 case TOK_UNSIGNED: 12412 t |= VT_UNSIGNED; 12413 next(); 12414 typespec_found = 1; 12415 break; 12416 12417 /* storage */ 12418 case TOK_EXTERN: 12419 t |= VT_EXTERN; 12420 next(); 12421 break; 12422 case TOK_STATIC: 12423 t |= VT_STATIC; 12424 next(); 12425 break; 12426 case TOK_TYPEDEF: 12427 t |= VT_TYPEDEF; 12428 next(); 12429 break; 12430 case TOK_INLINE1: 12431 case TOK_INLINE2: 12432 case TOK_INLINE3: 12433 t |= VT_INLINE; 12434 next(); 12435 break; 12436 12437 /* GNUC attribute */ 12438 case TOK_ATTRIBUTE1: 12439 case TOK_ATTRIBUTE2: 12440 parse_attribute(ad); 12441 break; 12442 /* GNUC typeof */ 12443 case TOK_TYPEOF1: 12444 case TOK_TYPEOF2: 12445 case TOK_TYPEOF3: 12446 next(); 12447 parse_expr_type(&type1); 12448 goto basic_type2; 12449 default: 12450 if (typespec_found) 12451 goto the_end; 12452 s = sym_find(tok); 12453 if (!s || !(s->type.t & VT_TYPEDEF)) 12454 goto the_end; 12455 t |= (s->type.t & ~VT_TYPEDEF); 12456 type->ref = s->type.ref; 12457 next(); 12458 break; 12459 } 12460 type_found = 1; 12461 } 12462 the_end: 12463 if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED)) 12464 error("signed and unsigned modifier"); 12465 if (tcc_state->char_is_unsigned) { 12466 if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE) 12467 t |= VT_UNSIGNED; 12468 } 12469 t &= ~VT_SIGNED; 12470 12471 /* long is never used as type */ 12472 if ((t & VT_BTYPE) == VT_LONG) 12473 t = (t & ~VT_BTYPE) | VT_INT; 12474 type->t = t; 12475 return type_found; 12476 } 12477 12478 /* convert a function parameter type (array to pointer and function to 12479 function pointer) */ 12480 static inline void convert_parameter_type(CType *pt) 12481 { 12482 /* remove const and volatile qualifiers (XXX: const could be used 12483 to indicate a const function parameter */ 12484 pt->t &= ~(VT_CONSTANT | VT_VOLATILE); 12485 /* array must be transformed to pointer according to ANSI C */ 12486 pt->t &= ~VT_ARRAY; 12487 if ((pt->t & VT_BTYPE) == VT_FUNC) { 12488 mk_pointer(pt); 12489 } 12490 } 12491 12492 static void post_type(CType *type, AttributeDef *ad) 12493 { 12494 int n, l, t1; 12495 Sym **plast, *s, *first; 12496 AttributeDef ad1; 12497 CType pt; 12498 12499 if (tok == '(') { 12500 /* function declaration */ 12501 next(); 12502 l = 0; 12503 first = NULL; 12504 plast = &first; 12505 while (tok != ')') { 12506 /* read param name and compute offset */ 12507 if (l != FUNC_OLD) { 12508 if (!parse_btype(&pt, &ad1)) { 12509 if (l) { 12510 error("invalid type"); 12511 } else { 12512 l = FUNC_OLD; 12513 goto old_proto; 12514 } 12515 } 12516 l = FUNC_NEW; 12517 if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')') 12518 break; 12519 type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT); 12520 if ((pt.t & VT_BTYPE) == VT_VOID) 12521 error("parameter declared as void"); 12522 } else { 12523 old_proto: 12524 n = tok; 12525 pt.t = VT_INT; 12526 next(); 12527 } 12528 convert_parameter_type(&pt); 12529 s = sym_push(n | SYM_FIELD, &pt, 0, 0); 12530 *plast = s; 12531 plast = &s->next; 12532 if (tok == ',') { 12533 next(); 12534 if (l == FUNC_NEW && tok == TOK_DOTS) { 12535 l = FUNC_ELLIPSIS; 12536 next(); 12537 break; 12538 } 12539 } 12540 } 12541 /* if no parameters, then old type prototype */ 12542 if (l == 0) 12543 l = FUNC_OLD; 12544 skip(')'); 12545 t1 = type->t & VT_STORAGE; 12546 /* NOTE: const is ignored in returned type as it has a special 12547 meaning in gcc / C++ */ 12548 type->t &= ~(VT_STORAGE | VT_CONSTANT); 12549 post_type(type, ad); 12550 /* we push a anonymous symbol which will contain the function prototype */ 12551 s = sym_push(SYM_FIELD, type, ad->func_call, l); 12552 s->next = first; 12553 type->t = t1 | VT_FUNC; 12554 type->ref = s; 12555 } else if (tok == '[') { 12556 /* array definition */ 12557 next(); 12558 n = -1; 12559 if (tok != ']') { 12560 n = expr_const(); 12561 if (n < 0) 12562 error("invalid array size"); 12563 } 12564 skip(']'); 12565 /* parse next post type */ 12566 t1 = type->t & VT_STORAGE; 12567 type->t &= ~VT_STORAGE; 12568 post_type(type, ad); 12569 12570 /* we push a anonymous symbol which will contain the array 12571 element type */ 12572 s = sym_push(SYM_FIELD, type, 0, n); 12573 type->t = t1 | VT_ARRAY | VT_PTR; 12574 type->ref = s; 12575 } 12576 } 12577 12578 /* Parse a type declaration (except basic type), and return the type 12579 in 'type'. 'td' is a bitmask indicating which kind of type decl is 12580 expected. 'type' should contain the basic type. 'ad' is the 12581 attribute definition of the basic type. It can be modified by 12582 type_decl(). 12583 */ 12584 static void type_decl(CType *type, AttributeDef *ad, int *v, int td) 12585 { 12586 Sym *s; 12587 CType type1, *type2; 12588 int qualifiers; 12589 12590 while (tok == '*') { 12591 qualifiers = 0; 12592 redo: 12593 next(); 12594 switch(tok) { 12595 case TOK_CONST1: 12596 case TOK_CONST2: 12597 case TOK_CONST3: 12598 qualifiers |= VT_CONSTANT; 12599 goto redo; 12600 case TOK_VOLATILE1: 12601 case TOK_VOLATILE2: 12602 case TOK_VOLATILE3: 12603 qualifiers |= VT_VOLATILE; 12604 goto redo; 12605 case TOK_RESTRICT1: 12606 case TOK_RESTRICT2: 12607 case TOK_RESTRICT3: 12608 goto redo; 12609 } 12610 mk_pointer(type); 12611 type->t |= qualifiers; 12612 } 12613 12614 /* XXX: clarify attribute handling */ 12615 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) 12616 parse_attribute(ad); 12617 12618 /* recursive type */ 12619 /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */ 12620 type1.t = 0; /* XXX: same as int */ 12621 if (tok == '(') { 12622 next(); 12623 /* XXX: this is not correct to modify 'ad' at this point, but 12624 the syntax is not clear */ 12625 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) 12626 parse_attribute(ad); 12627 type_decl(&type1, ad, v, td); 12628 skip(')'); 12629 } else { 12630 /* type identifier */ 12631 if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) { 12632 *v = tok; 12633 next(); 12634 } else { 12635 if (!(td & TYPE_ABSTRACT)) 12636 expect("identifier"); 12637 *v = 0; 12638 } 12639 } 12640 post_type(type, ad); 12641 if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) 12642 parse_attribute(ad); 12643 if (!type1.t) 12644 return; 12645 /* append type at the end of type1 */ 12646 type2 = &type1; 12647 for(;;) { 12648 s = type2->ref; 12649 type2 = &s->type; 12650 if (!type2->t) { 12651 *type2 = *type; 12652 break; 12653 } 12654 } 12655 *type = type1; 12656 } 12657 12658 /* compute the lvalue VT_LVAL_xxx needed to match type t. */ 12659 static int lvalue_type(int t) 12660 { 12661 int bt, r; 12662 r = VT_LVAL; 12663 bt = t & VT_BTYPE; 12664 if (bt == VT_BYTE || bt == VT_BOOL) 12665 r |= VT_LVAL_BYTE; 12666 else if (bt == VT_SHORT) 12667 r |= VT_LVAL_SHORT; 12668 else 12669 return r; 12670 if (t & VT_UNSIGNED) 12671 r |= VT_LVAL_UNSIGNED; 12672 return r; 12673 } 12674 12675 /* indirection with full error checking and bound check */ 12676 static void indir(void) 12677 { 12678 if ((vtop->type.t & VT_BTYPE) != VT_PTR) 12679 expect("pointer"); 12680 if ((vtop->r & VT_LVAL) && !nocode_wanted) 12681 gv(RC_INT); 12682 vtop->type = *pointed_type(&vtop->type); 12683 /* an array is never an lvalue */ 12684 if (!(vtop->type.t & VT_ARRAY)) { 12685 vtop->r |= lvalue_type(vtop->type.t); 12686 /* if bound checking, the referenced pointer must be checked */ 12687 if (do_bounds_check) 12688 vtop->r |= VT_MUSTBOUND; 12689 } 12690 } 12691 12692 /* pass a parameter to a function and do type checking and casting */ 12693 static void gfunc_param_typed(Sym *func, Sym *arg) 12694 { 12695 int func_type; 12696 CType type; 12697 12698 func_type = func->c; 12699 if (func_type == FUNC_OLD || 12700 (func_type == FUNC_ELLIPSIS && arg == NULL)) { 12701 /* default casting : only need to convert float to double */ 12702 if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) { 12703 type.t = VT_DOUBLE; 12704 gen_cast(&type); 12705 } 12706 } else if (arg == NULL) { 12707 error("too many arguments to function"); 12708 } else { 12709 type = arg->type; 12710 type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ 12711 gen_assign_cast(&type); 12712 } 12713 } 12714 12715 /* parse an expression of the form '(type)' or '(expr)' and return its 12716 type */ 12717 static void parse_expr_type(CType *type) 12718 { 12719 int n; 12720 AttributeDef ad; 12721 12722 skip('('); 12723 if (parse_btype(type, &ad)) { 12724 type_decl(type, &ad, &n, TYPE_ABSTRACT); 12725 } else { 12726 expr_type(type); 12727 } 12728 skip(')'); 12729 } 12730 12731 static void parse_type(CType *type) 12732 { 12733 AttributeDef ad; 12734 int n; 12735 12736 if (!parse_btype(type, &ad)) { 12737 expect("type"); 12738 } 12739 type_decl(type, &ad, &n, TYPE_ABSTRACT); 12740 } 12741 12742 static void vpush_tokc(int t) 12743 { 12744 CType type; 12745 type.t = t; 12746 vsetc(&type, VT_CONST, &tokc); 12747 } 12748 12749 static void unary(void) 12750 { 12751 int n, t, align, size, r; 12752 CType type; 12753 Sym *s; 12754 AttributeDef ad; 12755 12756 /* XXX: GCC 2.95.3 does not generate a table although it should be 12757 better here */ 12758 tok_next: 12759 switch(tok) { 12760 case TOK_EXTENSION: 12761 next(); 12762 goto tok_next; 12763 case TOK_CINT: 12764 case TOK_CCHAR: 12765 case TOK_LCHAR: 12766 vpushi(tokc.i); 12767 next(); 12768 break; 12769 case TOK_CUINT: 12770 vpush_tokc(VT_INT | VT_UNSIGNED); 12771 next(); 12772 break; 12773 case TOK_CLLONG: 12774 vpush_tokc(VT_LLONG); 12775 next(); 12776 break; 12777 case TOK_CULLONG: 12778 vpush_tokc(VT_LLONG | VT_UNSIGNED); 12779 next(); 12780 break; 12781 case TOK_CFLOAT: 12782 vpush_tokc(VT_FLOAT); 12783 next(); 12784 break; 12785 case TOK_CDOUBLE: 12786 vpush_tokc(VT_DOUBLE); 12787 next(); 12788 break; 12789 case TOK_CLDOUBLE: 12790 vpush_tokc(VT_LDOUBLE); 12791 next(); 12792 break; 12793 case TOK___FUNCTION__: 12794 if (!gnu_ext) 12795 goto tok_identifier; 12796 /* fall thru */ 12797 case TOK___FUNC__: 12798 { 12799 void *ptr; 12800 int len; 12801 /* special function name identifier */ 12802 len = strlen(funcname) + 1; 12803 /* generate char[len] type */ 12804 type.t = VT_BYTE; 12805 mk_pointer(&type); 12806 type.t |= VT_ARRAY; 12807 type.ref->c = len; 12808 vpush_ref(&type, data_section, data_section->data_offset, len); 12809 ptr = section_ptr_add(data_section, len); 12810 memcpy(ptr, funcname, len); 12811 next(); 12812 } 12813 break; 12814 case TOK_LSTR: 12815 t = VT_INT; 12816 goto str_init; 12817 case TOK_STR: 12818 /* string parsing */ 12819 t = VT_BYTE; 12820 str_init: 12821 if (tcc_state->warn_write_strings) 12822 t |= VT_CONSTANT; 12823 type.t = t; 12824 mk_pointer(&type); 12825 type.t |= VT_ARRAY; 12826 memset(&ad, 0, sizeof(AttributeDef)); 12827 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0); 12828 break; 12829 case '(': 12830 next(); 12831 /* cast ? */ 12832 if (parse_btype(&type, &ad)) { 12833 type_decl(&type, &ad, &n, TYPE_ABSTRACT); 12834 skip(')'); 12835 /* check ISOC99 compound literal */ 12836 if (tok == '{') { 12837 /* data is allocated locally by default */ 12838 if (global_expr) 12839 r = VT_CONST; 12840 else 12841 r = VT_LOCAL; 12842 /* all except arrays are lvalues */ 12843 if (!(type.t & VT_ARRAY)) 12844 r |= lvalue_type(type.t); 12845 memset(&ad, 0, sizeof(AttributeDef)); 12846 decl_initializer_alloc(&type, &ad, r, 1, 0, 0); 12847 } else { 12848 unary(); 12849 gen_cast(&type); 12850 } 12851 } else if (tok == '{') { 12852 /* save all registers */ 12853 save_regs(0); 12854 /* statement expression : we do not accept break/continue 12855 inside as GCC does */ 12856 block(NULL, NULL, NULL, NULL, 0, 1); 12857 skip(')'); 12858 } else { 12859 gexpr(); 12860 skip(')'); 12861 } 12862 break; 12863 case '*': 12864 next(); 12865 unary(); 12866 indir(); 12867 break; 12868 case '&': 12869 next(); 12870 unary(); 12871 /* functions names must be treated as function pointers, 12872 except for unary '&' and sizeof. Since we consider that 12873 functions are not lvalues, we only have to handle it 12874 there and in function calls. */ 12875 /* arrays can also be used although they are not lvalues */ 12876 if ((vtop->type.t & VT_BTYPE) != VT_FUNC && 12877 !(vtop->type.t & VT_ARRAY)) 12878 test_lvalue(); 12879 mk_pointer(&vtop->type); 12880 gaddrof(); 12881 break; 12882 case '!': 12883 next(); 12884 unary(); 12885 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) 12886 vtop->c.i = !vtop->c.i; 12887 else if ((vtop->r & VT_VALMASK) == VT_CMP) 12888 vtop->c.i = vtop->c.i ^ 1; 12889 else 12890 vseti(VT_JMP, gtst(1, 0)); 12891 break; 12892 case '~': 12893 next(); 12894 unary(); 12895 vpushi(-1); 12896 gen_op('^'); 12897 break; 12898 case '+': 12899 next(); 12900 /* in order to force cast, we add zero */ 12901 unary(); 12902 if ((vtop->type.t & VT_BTYPE) == VT_PTR) 12903 error("pointer not accepted for unary plus"); 12904 vpushi(0); 12905 gen_op('+'); 12906 break; 12907 case TOK_SIZEOF: 12908 case TOK_ALIGNOF1: 12909 case TOK_ALIGNOF2: 12910 t = tok; 12911 next(); 12912 if (tok == '(') { 12913 parse_expr_type(&type); 12914 } else { 12915 unary_type(&type); 12916 } 12917 size = type_size(&type, &align); 12918 if (t == TOK_SIZEOF) { 12919 if (size < 0) 12920 error("sizeof applied to an incomplete type"); 12921 vpushi(size); 12922 } else { 12923 vpushi(align); 12924 } 12925 break; 12926 12927 case TOK_builtin_types_compatible_p: 12928 { 12929 CType type1, type2; 12930 next(); 12931 skip('('); 12932 parse_type(&type1); 12933 skip(','); 12934 parse_type(&type2); 12935 skip(')'); 12936 type1.t &= ~(VT_CONSTANT | VT_VOLATILE); 12937 type2.t &= ~(VT_CONSTANT | VT_VOLATILE); 12938 vpushi(is_compatible_types(&type1, &type2)); 12939 } 12940 break; 12941 case TOK_builtin_constant_p: 12942 { 12943 int saved_nocode_wanted, res; 12944 next(); 12945 skip('('); 12946 saved_nocode_wanted = nocode_wanted; 12947 nocode_wanted = 1; 12948 gexpr(); 12949 res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; 12950 vpop(); 12951 nocode_wanted = saved_nocode_wanted; 12952 skip(')'); 12953 vpushi(res); 12954 } 12955 break; 12956 case TOK_INC: 12957 case TOK_DEC: 12958 t = tok; 12959 next(); 12960 unary(); 12961 inc(0, t); 12962 break; 12963 case '-': 12964 next(); 12965 vpushi(0); 12966 unary(); 12967 gen_op('-'); 12968 break; 12969 case TOK_LAND: 12970 if (!gnu_ext) 12971 goto tok_identifier; 12972 next(); 12973 /* allow to take the address of a label */ 12974 if (tok < TOK_UIDENT) 12975 expect("label identifier"); 12976 s = label_find(tok); 12977 if (!s) { 12978 s = label_push(&global_label_stack, tok, LABEL_FORWARD); 12979 } else { 12980 if (s->r == LABEL_DECLARED) 12981 s->r = LABEL_FORWARD; 12982 } 12983 if (!s->type.t) { 12984 s->type.t = VT_VOID; 12985 mk_pointer(&s->type); 12986 s->type.t |= VT_STATIC; 12987 } 12988 vset(&s->type, VT_CONST | VT_SYM, 0); 12989 vtop->sym = s; 12990 next(); 12991 break; 12992 default: 12993 tok_identifier: 12994 t = tok; 12995 next(); 12996 if (t < TOK_UIDENT) 12997 expect("identifier"); 12998 s = sym_find(t); 12999 if (!s) { 13000 if (tok != '(') 13001 error("'%s' undeclared", get_tok_str(t, NULL)); 13002 /* for simple function calls, we tolerate undeclared 13003 external reference to int() function */ 13004 if (tcc_state->warn_implicit_function_declaration) 13005 warning("implicit declaration of function '%s'", 13006 get_tok_str(t, NULL)); 13007 s = external_global_sym(t, &func_old_type, 0); 13008 } 13009 if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == 13010 (VT_STATIC | VT_INLINE | VT_FUNC)) { 13011 /* if referencing an inline function, then we generate a 13012 symbol to it if not already done. It will have the 13013 effect to generate code for it at the end of the 13014 compilation unit. Inline function as always 13015 generated in the text section. */ 13016 if (!s->c) 13017 put_extern_sym(s, text_section, 0, 0); 13018 r = VT_SYM | VT_CONST; 13019 } else { 13020 r = s->r; 13021 } 13022 vset(&s->type, r, s->c); 13023 /* if forward reference, we must point to s */ 13024 if (vtop->r & VT_SYM) { 13025 vtop->sym = s; 13026 vtop->c.ul = 0; 13027 } 13028 break; 13029 } 13030 13031 /* post operations */ 13032 while (1) { 13033 if (tok == TOK_INC || tok == TOK_DEC) { 13034 inc(1, tok); 13035 next(); 13036 } else if (tok == '.' || tok == TOK_ARROW) { 13037 /* field */ 13038 if (tok == TOK_ARROW) 13039 indir(); 13040 test_lvalue(); 13041 gaddrof(); 13042 next(); 13043 /* expect pointer on structure */ 13044 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT) 13045 expect("struct or union"); 13046 s = vtop->type.ref; 13047 /* find field */ 13048 tok |= SYM_FIELD; 13049 while ((s = s->next) != NULL) { 13050 if (s->v == tok) 13051 break; 13052 } 13053 if (!s) 13054 error("field not found"); 13055 /* add field offset to pointer */ 13056 vtop->type = char_pointer_type; /* change type to 'char *' */ 13057 vpushi(s->c); 13058 gen_op('+'); 13059 /* change type to field type, and set to lvalue */ 13060 vtop->type = s->type; 13061 /* an array is never an lvalue */ 13062 if (!(vtop->type.t & VT_ARRAY)) { 13063 vtop->r |= lvalue_type(vtop->type.t); 13064 /* if bound checking, the referenced pointer must be checked */ 13065 if (do_bounds_check) 13066 vtop->r |= VT_MUSTBOUND; 13067 } 13068 next(); 13069 } else if (tok == '[') { 13070 next(); 13071 gexpr(); 13072 gen_op('+'); 13073 indir(); 13074 skip(']'); 13075 } else if (tok == '(') { 13076 SValue ret; 13077 Sym *sa; 13078 int nb_args; 13079 13080 /* function call */ 13081 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) { 13082 /* pointer test (no array accepted) */ 13083 if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) { 13084 vtop->type = *pointed_type(&vtop->type); 13085 if ((vtop->type.t & VT_BTYPE) != VT_FUNC) 13086 goto error_func; 13087 } else { 13088 error_func: 13089 expect("function pointer"); 13090 } 13091 } else { 13092 vtop->r &= ~VT_LVAL; /* no lvalue */ 13093 } 13094 /* get return type */ 13095 s = vtop->type.ref; 13096 next(); 13097 sa = s->next; /* first parameter */ 13098 nb_args = 0; 13099 /* compute first implicit argument if a structure is returned */ 13100 if ((s->type.t & VT_BTYPE) == VT_STRUCT) { 13101 /* get some space for the returned structure */ 13102 size = type_size(&s->type, &align); 13103 loc = (loc - size) & -align; 13104 ret.type = s->type; 13105 ret.r = VT_LOCAL | VT_LVAL; 13106 /* pass it as 'int' to avoid structure arg passing 13107 problems */ 13108 vseti(VT_LOCAL, loc); 13109 ret.c = vtop->c; 13110 nb_args++; 13111 } else { 13112 ret.type = s->type; 13113 ret.r2 = VT_CONST; 13114 /* return in register */ 13115 if (is_float(ret.type.t)) { 13116 ret.r = REG_FRET; 13117 } else { 13118 if ((ret.type.t & VT_BTYPE) == VT_LLONG) 13119 ret.r2 = REG_LRET; 13120 ret.r = REG_IRET; 13121 } 13122 ret.c.i = 0; 13123 } 13124 if (tok != ')') { 13125 for(;;) { 13126 expr_eq(); 13127 gfunc_param_typed(s, sa); 13128 nb_args++; 13129 if (sa) 13130 sa = sa->next; 13131 if (tok == ')') 13132 break; 13133 skip(','); 13134 } 13135 } 13136 if (sa) 13137 error("too few arguments to function"); 13138 skip(')'); 13139 if (!nocode_wanted) { 13140 gfunc_call(nb_args); 13141 } else { 13142 vtop -= (nb_args + 1); 13143 } 13144 /* return value */ 13145 vsetc(&ret.type, ret.r, &ret.c); 13146 vtop->r2 = ret.r2; 13147 } else { 13148 break; 13149 } 13150 } 13151 } 13152 13153 static void uneq(void) 13154 { 13155 int t; 13156 13157 unary(); 13158 if (tok == '=' || 13159 (tok >= TOK_A_MOD && tok <= TOK_A_DIV) || 13160 tok == TOK_A_XOR || tok == TOK_A_OR || 13161 tok == TOK_A_SHL || tok == TOK_A_SAR) { 13162 test_lvalue(); 13163 t = tok; 13164 next(); 13165 if (t == '=') { 13166 expr_eq(); 13167 } else { 13168 vdup(); 13169 expr_eq(); 13170 gen_op(t & 0x7f); 13171 } 13172 vstore(); 13173 } 13174 } 13175 13176 static void expr_prod(void) 13177 { 13178 int t; 13179 13180 uneq(); 13181 while (tok == '*' || tok == '/' || tok == '%') { 13182 t = tok; 13183 next(); 13184 uneq(); 13185 gen_op(t); 13186 } 13187 } 13188 13189 static void expr_sum(void) 13190 { 13191 int t; 13192 13193 expr_prod(); 13194 while (tok == '+' || tok == '-') { 13195 t = tok; 13196 next(); 13197 expr_prod(); 13198 gen_op(t); 13199 } 13200 } 13201 13202 static void expr_shift(void) 13203 { 13204 int t; 13205 13206 expr_sum(); 13207 while (tok == TOK_SHL || tok == TOK_SAR) { 13208 t = tok; 13209 next(); 13210 expr_sum(); 13211 gen_op(t); 13212 } 13213 } 13214 13215 static void expr_cmp(void) 13216 { 13217 int t; 13218 13219 expr_shift(); 13220 while ((tok >= TOK_ULE && tok <= TOK_GT) || 13221 tok == TOK_ULT || tok == TOK_UGE) { 13222 t = tok; 13223 next(); 13224 expr_shift(); 13225 gen_op(t); 13226 } 13227 } 13228 13229 static void expr_cmpeq(void) 13230 { 13231 int t; 13232 13233 expr_cmp(); 13234 while (tok == TOK_EQ || tok == TOK_NE) { 13235 t = tok; 13236 next(); 13237 expr_cmp(); 13238 gen_op(t); 13239 } 13240 } 13241 13242 static void expr_and(void) 13243 { 13244 expr_cmpeq(); 13245 while (tok == '&') { 13246 next(); 13247 expr_cmpeq(); 13248 gen_op('&'); 13249 } 13250 } 13251 13252 static void expr_xor(void) 13253 { 13254 expr_and(); 13255 while (tok == '^') { 13256 next(); 13257 expr_and(); 13258 gen_op('^'); 13259 } 13260 } 13261 13262 static void expr_or(void) 13263 { 13264 expr_xor(); 13265 while (tok == '|') { 13266 next(); 13267 expr_xor(); 13268 gen_op('|'); 13269 } 13270 } 13271 13272 /* XXX: fix this mess */ 13273 static void expr_land_const(void) 13274 { 13275 expr_or(); 13276 while (tok == TOK_LAND) { 13277 next(); 13278 expr_or(); 13279 gen_op(TOK_LAND); 13280 } 13281 } 13282 13283 /* XXX: fix this mess */ 13284 static void expr_lor_const(void) 13285 { 13286 expr_land_const(); 13287 while (tok == TOK_LOR) { 13288 next(); 13289 expr_land_const(); 13290 gen_op(TOK_LOR); 13291 } 13292 } 13293 13294 /* only used if non constant */ 13295 static void expr_land(void) 13296 { 13297 int t; 13298 13299 expr_or(); 13300 if (tok == TOK_LAND) { 13301 t = 0; 13302 for(;;) { 13303 t = gtst(1, t); 13304 if (tok != TOK_LAND) { 13305 vseti(VT_JMPI, t); 13306 break; 13307 } 13308 next(); 13309 expr_or(); 13310 } 13311 } 13312 } 13313 13314 static void expr_lor(void) 13315 { 13316 int t; 13317 13318 expr_land(); 13319 if (tok == TOK_LOR) { 13320 t = 0; 13321 for(;;) { 13322 t = gtst(0, t); 13323 if (tok != TOK_LOR) { 13324 vseti(VT_JMP, t); 13325 break; 13326 } 13327 next(); 13328 expr_land(); 13329 } 13330 } 13331 } 13332 13333 /* XXX: better constant handling */ 13334 static void expr_eq(void) 13335 { 13336 int tt, u, r1, r2, rc, t1, t2, bt1, bt2; 13337 SValue sv; 13338 CType type, type1, type2; 13339 13340 if (const_wanted) { 13341 int c1, c; 13342 expr_lor_const(); 13343 if (tok == '?') { 13344 c = vtop->c.i; 13345 vpop(); 13346 next(); 13347 if (tok == ':' && gnu_ext) { 13348 c1 = c; 13349 } else { 13350 gexpr(); 13351 c1 = vtop->c.i; 13352 vpop(); 13353 } 13354 skip(':'); 13355 expr_eq(); 13356 if (c) 13357 vtop->c.i = c1; 13358 } 13359 } else { 13360 expr_lor(); 13361 if (tok == '?') { 13362 next(); 13363 if (vtop != vstack) { 13364 /* needed to avoid having different registers saved in 13365 each branch */ 13366 if (is_float(vtop->type.t)) 13367 rc = RC_FLOAT; 13368 else 13369 rc = RC_INT; 13370 gv(rc); 13371 save_regs(1); 13372 } 13373 if (tok == ':' && gnu_ext) { 13374 gv_dup(); 13375 tt = gtst(1, 0); 13376 } else { 13377 tt = gtst(1, 0); 13378 gexpr(); 13379 } 13380 type1 = vtop->type; 13381 sv = *vtop; /* save value to handle it later */ 13382 vtop--; /* no vpop so that FP stack is not flushed */ 13383 skip(':'); 13384 u = gjmp(0); 13385 gsym(tt); 13386 expr_eq(); 13387 type2 = vtop->type; 13388 13389 t1 = type1.t; 13390 bt1 = t1 & VT_BTYPE; 13391 t2 = type2.t; 13392 bt2 = t2 & VT_BTYPE; 13393 /* cast operands to correct type according to ISOC rules */ 13394 if (is_float(bt1) || is_float(bt2)) { 13395 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { 13396 type.t = VT_LDOUBLE; 13397 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) { 13398 type.t = VT_DOUBLE; 13399 } else { 13400 type.t = VT_FLOAT; 13401 } 13402 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) { 13403 /* cast to biggest op */ 13404 type.t = VT_LLONG; 13405 /* convert to unsigned if it does not fit in a long long */ 13406 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) || 13407 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) 13408 type.t |= VT_UNSIGNED; 13409 } else if (bt1 == VT_PTR || bt2 == VT_PTR) { 13410 /* XXX: test pointer compatibility */ 13411 type = type1; 13412 } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { 13413 /* XXX: test structure compatibility */ 13414 type = type1; 13415 } else if (bt1 == VT_VOID || bt2 == VT_VOID) { 13416 /* NOTE: as an extension, we accept void on only one side */ 13417 type.t = VT_VOID; 13418 } else { 13419 /* integer operations */ 13420 type.t = VT_INT; 13421 /* convert to unsigned if it does not fit in an integer */ 13422 if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) || 13423 (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) 13424 type.t |= VT_UNSIGNED; 13425 } 13426 13427 /* now we convert second operand */ 13428 gen_cast(&type); 13429 rc = RC_INT; 13430 if (is_float(type.t)) { 13431 rc = RC_FLOAT; 13432 } else if ((type.t & VT_BTYPE) == VT_LLONG) { 13433 /* for long longs, we use fixed registers to avoid having 13434 to handle a complicated move */ 13435 rc = RC_IRET; 13436 } 13437 13438 r2 = gv(rc); 13439 /* this is horrible, but we must also convert first 13440 operand */ 13441 tt = gjmp(0); 13442 gsym(u); 13443 /* put again first value and cast it */ 13444 *vtop = sv; 13445 gen_cast(&type); 13446 r1 = gv(rc); 13447 move_reg(r2, r1); 13448 vtop->r = r2; 13449 gsym(tt); 13450 } 13451 } 13452 } 13453 13454 static void gexpr(void) 13455 { 13456 while (1) { 13457 expr_eq(); 13458 if (tok != ',') 13459 break; 13460 vpop(); 13461 next(); 13462 } 13463 } 13464 13465 /* parse an expression and return its type without any side effect. */ 13466 static void expr_type(CType *type) 13467 { 13468 int saved_nocode_wanted; 13469 13470 saved_nocode_wanted = nocode_wanted; 13471 nocode_wanted = 1; 13472 gexpr(); 13473 *type = vtop->type; 13474 vpop(); 13475 nocode_wanted = saved_nocode_wanted; 13476 } 13477 13478 /* parse a unary expression and return its type without any side 13479 effect. */ 13480 static void unary_type(CType *type) 13481 { 13482 int a; 13483 13484 a = nocode_wanted; 13485 nocode_wanted = 1; 13486 unary(); 13487 *type = vtop->type; 13488 vpop(); 13489 nocode_wanted = a; 13490 } 13491 13492 /* parse a constant expression and return value in vtop. */ 13493 static void expr_const1(void) 13494 { 13495 int a; 13496 a = const_wanted; 13497 const_wanted = 1; 13498 expr_eq(); 13499 const_wanted = a; 13500 } 13501 13502 /* parse an integer constant and return its value. */ 13503 static int expr_const(void) 13504 { 13505 int c; 13506 expr_const1(); 13507 if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) 13508 expect("constant expression"); 13509 c = vtop->c.i; 13510 vpop(); 13511 return c; 13512 } 13513 13514 /* return the label token if current token is a label, otherwise 13515 return zero */ 13516 static int is_label(void) 13517 { 13518 int last_tok; 13519 13520 /* fast test first */ 13521 if (tok < TOK_UIDENT) 13522 return 0; 13523 /* no need to save tokc because tok is an identifier */ 13524 last_tok = tok; 13525 next(); 13526 if (tok == ':') { 13527 next(); 13528 return last_tok; 13529 } else { 13530 unget_tok(last_tok); 13531 return 0; 13532 } 13533 } 13534 13535 static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 13536 int case_reg, int is_expr) 13537 { 13538 int a, b, c, d; 13539 Sym *s; 13540 13541 /* generate line number info */ 13542 if (do_debug && 13543 (last_line_num != file->line_num || last_ind != ind)) { 13544 put_stabn(N_SLINE, 0, file->line_num, ind - func_ind); 13545 last_ind = ind; 13546 last_line_num = file->line_num; 13547 } 13548 13549 if (is_expr) { 13550 /* default return value is (void) */ 13551 vpushi(0); 13552 vtop->type.t = VT_VOID; 13553 } 13554 13555 if (tok == TOK_IF) { 13556 /* if test */ 13557 next(); 13558 skip('('); 13559 gexpr(); 13560 skip(')'); 13561 a = gtst(1, 0); 13562 block(bsym, csym, case_sym, def_sym, case_reg, 0); 13563 c = tok; 13564 if (c == TOK_ELSE) { 13565 next(); 13566 d = gjmp(0); 13567 gsym(a); 13568 block(bsym, csym, case_sym, def_sym, case_reg, 0); 13569 gsym(d); /* patch else jmp */ 13570 } else 13571 gsym(a); 13572 } else if (tok == TOK_WHILE) { 13573 next(); 13574 d = ind; 13575 skip('('); 13576 gexpr(); 13577 skip(')'); 13578 a = gtst(1, 0); 13579 b = 0; 13580 block(&a, &b, case_sym, def_sym, case_reg, 0); 13581 gjmp_addr(d); 13582 gsym(a); 13583 gsym_addr(b, d); 13584 } else if (tok == '{') { 13585 Sym *llabel; 13586 13587 next(); 13588 /* record local declaration stack position */ 13589 s = local_stack; 13590 llabel = local_label_stack; 13591 /* handle local labels declarations */ 13592 if (tok == TOK_LABEL) { 13593 next(); 13594 for(;;) { 13595 if (tok < TOK_UIDENT) 13596 expect("label identifier"); 13597 label_push(&local_label_stack, tok, LABEL_DECLARED); 13598 next(); 13599 if (tok == ',') { 13600 next(); 13601 } else { 13602 skip(';'); 13603 break; 13604 } 13605 } 13606 } 13607 while (tok != '}') { 13608 decl(VT_LOCAL); 13609 if (tok != '}') { 13610 if (is_expr) 13611 vpop(); 13612 block(bsym, csym, case_sym, def_sym, case_reg, is_expr); 13613 } 13614 } 13615 /* pop locally defined labels */ 13616 label_pop(&local_label_stack, llabel); 13617 /* pop locally defined symbols */ 13618 sym_pop(&local_stack, s); 13619 next(); 13620 } else if (tok == TOK_RETURN) { 13621 next(); 13622 if (tok != ';') { 13623 gexpr(); 13624 gen_assign_cast(&func_vt); 13625 if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { 13626 CType type; 13627 /* if returning structure, must copy it to implicit 13628 first pointer arg location */ 13629 type = func_vt; 13630 mk_pointer(&type); 13631 vset(&type, VT_LOCAL | VT_LVAL, func_vc); 13632 indir(); 13633 vswap(); 13634 /* copy structure value to pointer */ 13635 vstore(); 13636 } else if (is_float(func_vt.t)) { 13637 gv(RC_FRET); 13638 } else { 13639 gv(RC_IRET); 13640 } 13641 vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ 13642 } 13643 skip(';'); 13644 rsym = gjmp(rsym); /* jmp */ 13645 } else if (tok == TOK_BREAK) { 13646 /* compute jump */ 13647 if (!bsym) 13648 error("cannot break"); 13649 *bsym = gjmp(*bsym); 13650 next(); 13651 skip(';'); 13652 } else if (tok == TOK_CONTINUE) { 13653 /* compute jump */ 13654 if (!csym) 13655 error("cannot continue"); 13656 *csym = gjmp(*csym); 13657 next(); 13658 skip(';'); 13659 } else if (tok == TOK_FOR) { 13660 int e; 13661 next(); 13662 skip('('); 13663 if (tok != ';') { 13664 gexpr(); 13665 vpop(); 13666 } 13667 skip(';'); 13668 d = ind; 13669 c = ind; 13670 a = 0; 13671 b = 0; 13672 if (tok != ';') { 13673 gexpr(); 13674 a = gtst(1, 0); 13675 } 13676 skip(';'); 13677 if (tok != ')') { 13678 e = gjmp(0); 13679 c = ind; 13680 gexpr(); 13681 vpop(); 13682 gjmp_addr(d); 13683 gsym(e); 13684 } 13685 skip(')'); 13686 block(&a, &b, case_sym, def_sym, case_reg, 0); 13687 gjmp_addr(c); 13688 gsym(a); 13689 gsym_addr(b, c); 13690 } else 13691 if (tok == TOK_DO) { 13692 next(); 13693 a = 0; 13694 b = 0; 13695 d = ind; 13696 block(&a, &b, case_sym, def_sym, case_reg, 0); 13697 skip(TOK_WHILE); 13698 skip('('); 13699 gsym(b); 13700 gexpr(); 13701 c = gtst(0, 0); 13702 gsym_addr(c, d); 13703 skip(')'); 13704 gsym(a); 13705 skip(';'); 13706 } else 13707 if (tok == TOK_SWITCH) { 13708 next(); 13709 skip('('); 13710 gexpr(); 13711 /* XXX: other types than integer */ 13712 case_reg = gv(RC_INT); 13713 vpop(); 13714 skip(')'); 13715 a = 0; 13716 b = gjmp(0); /* jump to first case */ 13717 c = 0; 13718 block(&a, csym, &b, &c, case_reg, 0); 13719 /* if no default, jmp after switch */ 13720 if (c == 0) 13721 c = ind; 13722 /* default label */ 13723 gsym_addr(b, c); 13724 /* break label */ 13725 gsym(a); 13726 } else 13727 if (tok == TOK_CASE) { 13728 int v1, v2; 13729 if (!case_sym) 13730 expect("switch"); 13731 next(); 13732 v1 = expr_const(); 13733 v2 = v1; 13734 if (gnu_ext && tok == TOK_DOTS) { 13735 next(); 13736 v2 = expr_const(); 13737 if (v2 < v1) 13738 warning("empty case range"); 13739 } 13740 /* since a case is like a label, we must skip it with a jmp */ 13741 b = gjmp(0); 13742 gsym(*case_sym); 13743 vseti(case_reg, 0); 13744 vpushi(v1); 13745 if (v1 == v2) { 13746 gen_op(TOK_EQ); 13747 *case_sym = gtst(1, 0); 13748 } else { 13749 gen_op(TOK_GE); 13750 *case_sym = gtst(1, 0); 13751 vseti(case_reg, 0); 13752 vpushi(v2); 13753 gen_op(TOK_LE); 13754 *case_sym = gtst(1, *case_sym); 13755 } 13756 gsym(b); 13757 skip(':'); 13758 is_expr = 0; 13759 goto block_after_label; 13760 } else 13761 if (tok == TOK_DEFAULT) { 13762 next(); 13763 skip(':'); 13764 if (!def_sym) 13765 expect("switch"); 13766 if (*def_sym) 13767 error("too many 'default'"); 13768 *def_sym = ind; 13769 is_expr = 0; 13770 goto block_after_label; 13771 } else 13772 if (tok == TOK_GOTO) { 13773 next(); 13774 if (tok == '*' && gnu_ext) { 13775 /* computed goto */ 13776 next(); 13777 gexpr(); 13778 if ((vtop->type.t & VT_BTYPE) != VT_PTR) 13779 expect("pointer"); 13780 ggoto(); 13781 } else if (tok >= TOK_UIDENT) { 13782 s = label_find(tok); 13783 /* put forward definition if needed */ 13784 if (!s) { 13785 s = label_push(&global_label_stack, tok, LABEL_FORWARD); 13786 } else { 13787 if (s->r == LABEL_DECLARED) 13788 s->r = LABEL_FORWARD; 13789 } 13790 /* label already defined */ 13791 if (s->r & LABEL_FORWARD) 13792 s->next = (void *)gjmp((long)s->next); 13793 else 13794 gjmp_addr((long)s->next); 13795 next(); 13796 } else { 13797 expect("label identifier"); 13798 } 13799 skip(';'); 13800 } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { 13801 asm_instr(); 13802 } else { 13803 b = is_label(); 13804 if (b) { 13805 /* label case */ 13806 s = label_find(b); 13807 if (s) { 13808 if (s->r == LABEL_DEFINED) 13809 error("duplicate label '%s'", get_tok_str(s->v, NULL)); 13810 gsym((long)s->next); 13811 s->r = LABEL_DEFINED; 13812 } else { 13813 s = label_push(&global_label_stack, b, LABEL_DEFINED); 13814 } 13815 s->next = (void *)ind; 13816 /* we accept this, but it is a mistake */ 13817 block_after_label: 13818 if (tok == '}') { 13819 warning("deprecated use of label at end of compound statement"); 13820 } else { 13821 if (is_expr) 13822 vpop(); 13823 block(bsym, csym, case_sym, def_sym, case_reg, is_expr); 13824 } 13825 } else { 13826 /* expression case */ 13827 if (tok != ';') { 13828 if (is_expr) { 13829 vpop(); 13830 gexpr(); 13831 } else { 13832 gexpr(); 13833 vpop(); 13834 } 13835 } 13836 skip(';'); 13837 } 13838 } 13839 } 13840 13841 /* t is the array or struct type. c is the array or struct 13842 address. cur_index/cur_field is the pointer to the current 13843 value. 'size_only' is true if only size info is needed (only used 13844 in arrays) */ 13845 static void decl_designator(CType *type, Section *sec, unsigned long c, 13846 int *cur_index, Sym **cur_field, 13847 int size_only) 13848 { 13849 Sym *s, *f; 13850 int notfirst, index, index_last, align, l, nb_elems, elem_size; 13851 CType type1; 13852 13853 notfirst = 0; 13854 elem_size = 0; 13855 nb_elems = 1; 13856 if (gnu_ext && (l = is_label()) != 0) 13857 goto struct_field; 13858 while (tok == '[' || tok == '.') { 13859 if (tok == '[') { 13860 if (!(type->t & VT_ARRAY)) 13861 expect("array type"); 13862 s = type->ref; 13863 next(); 13864 index = expr_const(); 13865 if (index < 0 || (s->c >= 0 && index >= s->c)) 13866 expect("invalid index"); 13867 if (tok == TOK_DOTS && gnu_ext) { 13868 next(); 13869 index_last = expr_const(); 13870 if (index_last < 0 || 13871 (s->c >= 0 && index_last >= s->c) || 13872 index_last < index) 13873 expect("invalid index"); 13874 } else { 13875 index_last = index; 13876 } 13877 skip(']'); 13878 if (!notfirst) 13879 *cur_index = index_last; 13880 type = pointed_type(type); 13881 elem_size = type_size(type, &align); 13882 c += index * elem_size; 13883 /* NOTE: we only support ranges for last designator */ 13884 nb_elems = index_last - index + 1; 13885 if (nb_elems != 1) { 13886 notfirst = 1; 13887 break; 13888 } 13889 } else { 13890 next(); 13891 l = tok; 13892 next(); 13893 struct_field: 13894 if ((type->t & VT_BTYPE) != VT_STRUCT) 13895 expect("struct/union type"); 13896 s = type->ref; 13897 l |= SYM_FIELD; 13898 f = s->next; 13899 while (f) { 13900 if (f->v == l) 13901 break; 13902 f = f->next; 13903 } 13904 if (!f) 13905 expect("field"); 13906 if (!notfirst) 13907 *cur_field = f; 13908 /* XXX: fix this mess by using explicit storage field */ 13909 type1 = f->type; 13910 type1.t |= (type->t & ~VT_TYPE); 13911 type = &type1; 13912 c += f->c; 13913 } 13914 notfirst = 1; 13915 } 13916 if (notfirst) { 13917 if (tok == '=') { 13918 next(); 13919 } else { 13920 if (!gnu_ext) 13921 expect("="); 13922 } 13923 } else { 13924 if (type->t & VT_ARRAY) { 13925 index = *cur_index; 13926 type = pointed_type(type); 13927 c += index * type_size(type, &align); 13928 } else { 13929 f = *cur_field; 13930 if (!f) 13931 error("too many field init"); 13932 /* XXX: fix this mess by using explicit storage field */ 13933 type1 = f->type; 13934 type1.t |= (type->t & ~VT_TYPE); 13935 type = &type1; 13936 c += f->c; 13937 } 13938 } 13939 decl_initializer(type, sec, c, 0, size_only); 13940 13941 /* XXX: make it more general */ 13942 if (!size_only && nb_elems > 1) { 13943 unsigned long c_end; 13944 uint8_t *src, *dst; 13945 int i; 13946 13947 if (!sec) 13948 error("range init not supported yet for dynamic storage"); 13949 c_end = c + nb_elems * elem_size; 13950 if (c_end > sec->data_allocated) 13951 section_realloc(sec, c_end); 13952 src = sec->data + c; 13953 dst = src; 13954 for(i = 1; i < nb_elems; i++) { 13955 dst += elem_size; 13956 memcpy(dst, src, elem_size); 13957 } 13958 } 13959 } 13960 13961 #define EXPR_VAL 0 13962 #define EXPR_CONST 1 13963 #define EXPR_ANY 2 13964 13965 /* store a value or an expression directly in global data or in local array */ 13966 static void init_putv(CType *type, Section *sec, unsigned long c, 13967 int v, int expr_type) 13968 { 13969 int saved_global_expr, bt, bit_pos, bit_size; 13970 void *ptr; 13971 unsigned long long bit_mask; 13972 CType dtype; 13973 13974 switch(expr_type) { 13975 case EXPR_VAL: 13976 vpushi(v); 13977 break; 13978 case EXPR_CONST: 13979 /* compound literals must be allocated globally in this case */ 13980 saved_global_expr = global_expr; 13981 global_expr = 1; 13982 expr_const1(); 13983 global_expr = saved_global_expr; 13984 /* NOTE: symbols are accepted */ 13985 if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST) 13986 error("initializer element is not constant"); 13987 break; 13988 case EXPR_ANY: 13989 expr_eq(); 13990 break; 13991 } 13992 13993 dtype = *type; 13994 dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ 13995 13996 if (sec) { 13997 /* XXX: not portable */ 13998 /* XXX: generate error if incorrect relocation */ 13999 gen_assign_cast(&dtype); 14000 bt = type->t & VT_BTYPE; 14001 ptr = sec->data + c; 14002 /* XXX: make code faster ? */ 14003 if (!(type->t & VT_BITFIELD)) { 14004 bit_pos = 0; 14005 bit_size = 32; 14006 bit_mask = -1LL; 14007 } else { 14008 bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f; 14009 bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; 14010 bit_mask = (1LL << bit_size) - 1; 14011 } 14012 if ((vtop->r & VT_SYM) && 14013 (bt == VT_BYTE || 14014 bt == VT_SHORT || 14015 bt == VT_DOUBLE || 14016 bt == VT_LDOUBLE || 14017 bt == VT_LLONG || 14018 (bt == VT_INT && bit_size != 32))) 14019 error("initializer element is not computable at load time"); 14020 switch(bt) { 14021 case VT_BYTE: 14022 *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos; 14023 break; 14024 case VT_SHORT: 14025 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos; 14026 break; 14027 case VT_DOUBLE: 14028 *(double *)ptr = vtop->c.d; 14029 break; 14030 case VT_LDOUBLE: 14031 *(long double *)ptr = vtop->c.ld; 14032 break; 14033 case VT_LLONG: 14034 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos; 14035 break; 14036 default: 14037 if (vtop->r & VT_SYM) { 14038 greloc(sec, vtop->sym, c, R_DATA_32); 14039 } 14040 *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos; 14041 break; 14042 } 14043 vtop--; 14044 } else { 14045 vset(&dtype, VT_LOCAL, c); 14046 vswap(); 14047 vstore(); 14048 vpop(); 14049 } 14050 } 14051 14052 /* put zeros for variable based init */ 14053 static void init_putz(CType *t, Section *sec, unsigned long c, int size) 14054 { 14055 if (sec) { 14056 /* nothing to do because globals are already set to zero */ 14057 } else { 14058 vpush_global_sym(&func_old_type, TOK_memset); 14059 vseti(VT_LOCAL, c); 14060 vpushi(0); 14061 vpushi(size); 14062 gfunc_call(3); 14063 } 14064 } 14065 14066 /* 't' contains the type and storage info. 'c' is the offset of the 14067 object in section 'sec'. If 'sec' is NULL, it means stack based 14068 allocation. 'first' is true if array '{' must be read (multi 14069 dimension implicit array init handling). 'size_only' is true if 14070 size only evaluation is wanted (only for arrays). */ 14071 static void decl_initializer(CType *type, Section *sec, unsigned long c, 14072 int first, int size_only) 14073 { 14074 int index, array_length, n, no_oblock, nb, parlevel, i; 14075 int size1, align1, expr_type; 14076 Sym *s, *f; 14077 CType *t1; 14078 14079 if (type->t & VT_ARRAY) { 14080 s = type->ref; 14081 n = s->c; 14082 array_length = 0; 14083 t1 = pointed_type(type); 14084 size1 = type_size(t1, &align1); 14085 14086 no_oblock = 1; 14087 if ((first && tok != TOK_LSTR && tok != TOK_STR) || 14088 tok == '{') { 14089 skip('{'); 14090 no_oblock = 0; 14091 } 14092 14093 /* only parse strings here if correct type (otherwise: handle 14094 them as ((w)char *) expressions */ 14095 if ((tok == TOK_LSTR && 14096 (t1->t & VT_BTYPE) == VT_INT) || 14097 (tok == TOK_STR && 14098 (t1->t & VT_BTYPE) == VT_BYTE)) { 14099 while (tok == TOK_STR || tok == TOK_LSTR) { 14100 int cstr_len, ch; 14101 CString *cstr; 14102 14103 cstr = tokc.cstr; 14104 /* compute maximum number of chars wanted */ 14105 if (tok == TOK_STR) 14106 cstr_len = cstr->size; 14107 else 14108 cstr_len = cstr->size / sizeof(int); 14109 cstr_len--; 14110 nb = cstr_len; 14111 if (n >= 0 && nb > (n - array_length)) 14112 nb = n - array_length; 14113 if (!size_only) { 14114 if (cstr_len > nb) 14115 warning("initializer-string for array is too long"); 14116 /* in order to go faster for common case (char 14117 string in global variable, we handle it 14118 specifically */ 14119 if (sec && tok == TOK_STR && size1 == 1) { 14120 memcpy(sec->data + c + array_length, cstr->data, nb); 14121 } else { 14122 for(i=0;i<nb;i++) { 14123 if (tok == TOK_STR) 14124 ch = ((unsigned char *)cstr->data)[i]; 14125 else 14126 ch = ((int *)cstr->data)[i]; 14127 init_putv(t1, sec, c + (array_length + i) * size1, 14128 ch, EXPR_VAL); 14129 } 14130 } 14131 } 14132 array_length += nb; 14133 next(); 14134 } 14135 /* only add trailing zero if enough storage (no 14136 warning in this case since it is standard) */ 14137 if (n < 0 || array_length < n) { 14138 if (!size_only) { 14139 init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL); 14140 } 14141 array_length++; 14142 } 14143 } else { 14144 index = 0; 14145 while (tok != '}') { 14146 decl_designator(type, sec, c, &index, NULL, size_only); 14147 if (n >= 0 && index >= n) 14148 error("index too large"); 14149 /* must put zero in holes (note that doing it that way 14150 ensures that it even works with designators) */ 14151 if (!size_only && array_length < index) { 14152 init_putz(t1, sec, c + array_length * size1, 14153 (index - array_length) * size1); 14154 } 14155 index++; 14156 if (index > array_length) 14157 array_length = index; 14158 /* special test for multi dimensional arrays (may not 14159 be strictly correct if designators are used at the 14160 same time) */ 14161 if (index >= n && no_oblock) 14162 break; 14163 if (tok == '}') 14164 break; 14165 skip(','); 14166 } 14167 } 14168 if (!no_oblock) 14169 skip('}'); 14170 /* put zeros at the end */ 14171 if (!size_only && n >= 0 && array_length < n) { 14172 init_putz(t1, sec, c + array_length * size1, 14173 (n - array_length) * size1); 14174 } 14175 /* patch type size if needed */ 14176 if (n < 0) 14177 s->c = array_length; 14178 } else if ((type->t & VT_BTYPE) == VT_STRUCT && 14179 (sec || !first || tok == '{')) { 14180 int par_count; 14181 14182 /* NOTE: the previous test is a specific case for automatic 14183 struct/union init */ 14184 /* XXX: union needs only one init */ 14185 14186 /* XXX: this test is incorrect for local initializers 14187 beginning with ( without {. It would be much more difficult 14188 to do it correctly (ideally, the expression parser should 14189 be used in all cases) */ 14190 par_count = 0; 14191 if (tok == '(') { 14192 AttributeDef ad1; 14193 CType type1; 14194 next(); 14195 while (tok == '(') { 14196 par_count++; 14197 next(); 14198 } 14199 if (!parse_btype(&type1, &ad1)) 14200 expect("cast"); 14201 type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); 14202 #if 0 14203 if (!is_assignable_types(type, &type1)) 14204 error("invalid type for cast"); 14205 #endif 14206 skip(')'); 14207 } 14208 no_oblock = 1; 14209 if (first || tok == '{') { 14210 skip('{'); 14211 no_oblock = 0; 14212 } 14213 s = type->ref; 14214 f = s->next; 14215 array_length = 0; 14216 index = 0; 14217 n = s->c; 14218 while (tok != '}') { 14219 decl_designator(type, sec, c, NULL, &f, size_only); 14220 index = f->c; 14221 if (!size_only && array_length < index) { 14222 init_putz(type, sec, c + array_length, 14223 index - array_length); 14224 } 14225 index = index + type_size(&f->type, &align1); 14226 if (index > array_length) 14227 array_length = index; 14228 f = f->next; 14229 if (no_oblock && f == NULL) 14230 break; 14231 if (tok == '}') 14232 break; 14233 skip(','); 14234 } 14235 /* put zeros at the end */ 14236 if (!size_only && array_length < n) { 14237 init_putz(type, sec, c + array_length, 14238 n - array_length); 14239 } 14240 if (!no_oblock) 14241 skip('}'); 14242 while (par_count) { 14243 skip(')'); 14244 par_count--; 14245 } 14246 } else if (tok == '{') { 14247 next(); 14248 decl_initializer(type, sec, c, first, size_only); 14249 skip('}'); 14250 } else if (size_only) { 14251 /* just skip expression */ 14252 parlevel = 0; 14253 while ((parlevel > 0 || (tok != '}' && tok != ',')) && 14254 tok != -1) { 14255 if (tok == '(') 14256 parlevel++; 14257 else if (tok == ')') 14258 parlevel--; 14259 next(); 14260 } 14261 } else { 14262 /* currently, we always use constant expression for globals 14263 (may change for scripting case) */ 14264 expr_type = EXPR_CONST; 14265 if (!sec) 14266 expr_type = EXPR_ANY; 14267 init_putv(type, sec, c, 0, expr_type); 14268 } 14269 } 14270 14271 /* parse an initializer for type 't' if 'has_init' is non zero, and 14272 allocate space in local or global data space ('r' is either 14273 VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated 14274 variable 'v' of scope 'scope' is declared before initializers are 14275 parsed. If 'v' is zero, then a reference to the new object is put 14276 in the value stack. If 'has_init' is 2, a special parsing is done 14277 to handle string constants. */ 14278 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 14279 int has_init, int v, int scope) 14280 { 14281 int size, align, addr, data_offset; 14282 int level; 14283 ParseState saved_parse_state; 14284 TokenString init_str; 14285 Section *sec; 14286 14287 size = type_size(type, &align); 14288 /* If unknown size, we must evaluate it before 14289 evaluating initializers because 14290 initializers can generate global data too 14291 (e.g. string pointers or ISOC99 compound 14292 literals). It also simplifies local 14293 initializers handling */ 14294 tok_str_new(&init_str); 14295 if (size < 0) { 14296 if (!has_init) 14297 error("unknown type size"); 14298 /* get all init string */ 14299 if (has_init == 2) { 14300 /* only get strings */ 14301 while (tok == TOK_STR || tok == TOK_LSTR) { 14302 tok_str_add_tok(&init_str); 14303 next(); 14304 } 14305 } else { 14306 level = 0; 14307 while (level > 0 || (tok != ',' && tok != ';')) { 14308 if (tok < 0) 14309 error("unexpected end of file in initializer"); 14310 tok_str_add_tok(&init_str); 14311 if (tok == '{') 14312 level++; 14313 else if (tok == '}') { 14314 if (level == 0) 14315 break; 14316 level--; 14317 } 14318 next(); 14319 } 14320 } 14321 tok_str_add(&init_str, -1); 14322 tok_str_add(&init_str, 0); 14323 14324 /* compute size */ 14325 save_parse_state(&saved_parse_state); 14326 14327 macro_ptr = init_str.str; 14328 next(); 14329 decl_initializer(type, NULL, 0, 1, 1); 14330 /* prepare second initializer parsing */ 14331 macro_ptr = init_str.str; 14332 next(); 14333 14334 /* if still unknown size, error */ 14335 size = type_size(type, &align); 14336 if (size < 0) 14337 error("unknown type size"); 14338 } 14339 /* take into account specified alignment if bigger */ 14340 if (ad->aligned) { 14341 if (ad->aligned > align) 14342 align = ad->aligned; 14343 } else if (ad->packed) { 14344 align = 1; 14345 } 14346 if ((r & VT_VALMASK) == VT_LOCAL) { 14347 sec = NULL; 14348 if (do_bounds_check && (type->t & VT_ARRAY)) 14349 loc--; 14350 loc = (loc - size) & -align; 14351 addr = loc; 14352 /* handles bounds */ 14353 /* XXX: currently, since we do only one pass, we cannot track 14354 '&' operators, so we add only arrays */ 14355 if (do_bounds_check && (type->t & VT_ARRAY)) { 14356 unsigned long *bounds_ptr; 14357 /* add padding between regions */ 14358 loc--; 14359 /* then add local bound info */ 14360 bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long)); 14361 bounds_ptr[0] = addr; 14362 bounds_ptr[1] = size; 14363 } 14364 if (v) { 14365 /* local variable */ 14366 sym_push(v, type, r, addr); 14367 } else { 14368 /* push local reference */ 14369 vset(type, r, addr); 14370 } 14371 } else { 14372 Sym *sym; 14373 14374 sym = NULL; 14375 if (v && scope == VT_CONST) { 14376 /* see if the symbol was already defined */ 14377 sym = sym_find(v); 14378 if (sym) { 14379 if (!is_compatible_types(&sym->type, type)) 14380 error("incompatible types for redefinition of '%s'", 14381 get_tok_str(v, NULL)); 14382 if (sym->type.t & VT_EXTERN) { 14383 /* if the variable is extern, it was not allocated */ 14384 sym->type.t &= ~VT_EXTERN; 14385 /* set array size if it was ommited in extern 14386 declaration */ 14387 if ((sym->type.t & VT_ARRAY) && 14388 sym->type.ref->c < 0 && 14389 type->ref->c >= 0) 14390 sym->type.ref->c = type->ref->c; 14391 } else { 14392 /* we accept several definitions of the same 14393 global variable. this is tricky, because we 14394 must play with the SHN_COMMON type of the symbol */ 14395 /* XXX: should check if the variable was already 14396 initialized. It is incorrect to initialized it 14397 twice */ 14398 /* no init data, we won't add more to the symbol */ 14399 if (!has_init) 14400 goto no_alloc; 14401 } 14402 } 14403 } 14404 14405 /* allocate symbol in corresponding section */ 14406 sec = ad->section; 14407 if (!sec) { 14408 if (has_init) 14409 sec = data_section; 14410 else if (tcc_state->nocommon) 14411 sec = bss_section; 14412 } 14413 if (sec) { 14414 data_offset = sec->data_offset; 14415 data_offset = (data_offset + align - 1) & -align; 14416 addr = data_offset; 14417 /* very important to increment global pointer at this time 14418 because initializers themselves can create new initializers */ 14419 data_offset += size; 14420 /* add padding if bound check */ 14421 if (do_bounds_check) 14422 data_offset++; 14423 sec->data_offset = data_offset; 14424 /* allocate section space to put the data */ 14425 if (sec->sh_type != SHT_NOBITS && 14426 data_offset > sec->data_allocated) 14427 section_realloc(sec, data_offset); 14428 /* align section if needed */ 14429 if (align > sec->sh_addralign) 14430 sec->sh_addralign = align; 14431 } else { 14432 addr = 0; /* avoid warning */ 14433 } 14434 14435 if (v) { 14436 if (scope == VT_CONST) { 14437 if (!sym) 14438 goto do_def; 14439 } else { 14440 do_def: 14441 sym = sym_push(v, type, r | VT_SYM, 0); 14442 } 14443 /* update symbol definition */ 14444 if (sec) { 14445 put_extern_sym(sym, sec, addr, size); 14446 } else { 14447 Elf32_Sym *esym; 14448 /* put a common area */ 14449 put_extern_sym(sym, NULL, align, size); 14450 /* XXX: find a nicer way */ 14451 esym = &((Elf32_Sym *)symtab_section->data)[sym->c]; 14452 esym->st_shndx = SHN_COMMON; 14453 } 14454 } else { 14455 CValue cval; 14456 14457 /* push global reference */ 14458 sym = get_sym_ref(type, sec, addr, size); 14459 cval.ul = 0; 14460 vsetc(type, VT_CONST | VT_SYM, &cval); 14461 vtop->sym = sym; 14462 } 14463 14464 /* handles bounds now because the symbol must be defined 14465 before for the relocation */ 14466 if (do_bounds_check) { 14467 unsigned long *bounds_ptr; 14468 14469 greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32); 14470 /* then add global bound info */ 14471 bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long)); 14472 bounds_ptr[0] = 0; /* relocated */ 14473 bounds_ptr[1] = size; 14474 } 14475 } 14476 if (has_init) { 14477 decl_initializer(type, sec, addr, 1, 0); 14478 /* restore parse state if needed */ 14479 if (init_str.str) { 14480 tok_str_free(init_str.str); 14481 restore_parse_state(&saved_parse_state); 14482 } 14483 } 14484 no_alloc: ; 14485 } 14486 14487 void put_func_debug(Sym *sym) 14488 { 14489 char buf[512]; 14490 14491 /* stabs info */ 14492 /* XXX: we put here a dummy type */ 14493 snprintf(buf, sizeof(buf), "%s:%c1", 14494 funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); 14495 put_stabs_r(buf, N_FUN, 0, file->line_num, 0, 14496 cur_text_section, sym->c); 14497 last_ind = 0; 14498 last_line_num = 0; 14499 } 14500 14501 /* parse an old style function declaration list */ 14502 /* XXX: check multiple parameter */ 14503 static void func_decl_list(Sym *func_sym) 14504 { 14505 AttributeDef ad; 14506 int v; 14507 Sym *s; 14508 CType btype, type; 14509 14510 /* parse each declaration */ 14511 while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) { 14512 if (!parse_btype(&btype, &ad)) 14513 expect("declaration list"); 14514 if (((btype.t & VT_BTYPE) == VT_ENUM || 14515 (btype.t & VT_BTYPE) == VT_STRUCT) && 14516 tok == ';') { 14517 /* we accept no variable after */ 14518 } else { 14519 for(;;) { 14520 type = btype; 14521 type_decl(&type, &ad, &v, TYPE_DIRECT); 14522 /* find parameter in function parameter list */ 14523 s = func_sym->next; 14524 while (s != NULL) { 14525 if ((s->v & ~SYM_FIELD) == v) 14526 goto found; 14527 s = s->next; 14528 } 14529 error("declaration for parameter '%s' but no such parameter", 14530 get_tok_str(v, NULL)); 14531 found: 14532 /* check that no storage specifier except 'register' was given */ 14533 if (type.t & VT_STORAGE) 14534 error("storage class specified for '%s'", get_tok_str(v, NULL)); 14535 convert_parameter_type(&type); 14536 /* we can add the type (NOTE: it could be local to the function) */ 14537 s->type = type; 14538 /* accept other parameters */ 14539 if (tok == ',') 14540 next(); 14541 else 14542 break; 14543 } 14544 } 14545 skip(';'); 14546 } 14547 } 14548 14549 /* parse a function defined by symbol 'sym' and generate its code in 14550 'cur_text_section' */ 14551 static void gen_function(Sym *sym) 14552 { 14553 ind = cur_text_section->data_offset; 14554 /* NOTE: we patch the symbol size later */ 14555 put_extern_sym(sym, cur_text_section, ind, 0); 14556 funcname = get_tok_str(sym->v, NULL); 14557 func_ind = ind; 14558 /* put debug symbol */ 14559 if (do_debug) 14560 put_func_debug(sym); 14561 /* push a dummy symbol to enable local sym storage */ 14562 sym_push2(&local_stack, SYM_FIELD, 0, 0); 14563 gfunc_prolog(&sym->type); 14564 rsym = 0; 14565 block(NULL, NULL, NULL, NULL, 0, 0); 14566 gsym(rsym); 14567 gfunc_epilog(); 14568 cur_text_section->data_offset = ind; 14569 label_pop(&global_label_stack, NULL); 14570 sym_pop(&local_stack, NULL); /* reset local stack */ 14571 /* end of function */ 14572 /* patch symbol size */ 14573 ((Elf32_Sym *)symtab_section->data)[sym->c].st_size = 14574 ind - func_ind; 14575 if (do_debug) { 14576 put_stabn(N_FUN, 0, 0, ind - func_ind); 14577 } 14578 funcname = ""; /* for safety */ 14579 func_vt.t = VT_VOID; /* for safety */ 14580 ind = 0; /* for safety */ 14581 } 14582 14583 static void gen_inline_functions(void) 14584 { 14585 Sym *sym; 14586 CType *type; 14587 int *str, inline_generated; 14588 14589 /* iterate while inline function are referenced */ 14590 for(;;) { 14591 inline_generated = 0; 14592 for(sym = global_stack; sym != NULL; sym = sym->prev) { 14593 type = &sym->type; 14594 if (((type->t & VT_BTYPE) == VT_FUNC) && 14595 (type->t & (VT_STATIC | VT_INLINE)) == 14596 (VT_STATIC | VT_INLINE) && 14597 sym->c != 0) { 14598 /* the function was used: generate its code and 14599 convert it to a normal function */ 14600 str = (int *)sym->r; 14601 sym->r = VT_SYM | VT_CONST; 14602 type->t &= ~VT_INLINE; 14603 14604 macro_ptr = str; 14605 next(); 14606 cur_text_section = text_section; 14607 gen_function(sym); 14608 macro_ptr = NULL; /* fail safe */ 14609 14610 tok_str_free(str); 14611 inline_generated = 1; 14612 } 14613 } 14614 if (!inline_generated) 14615 break; 14616 } 14617 14618 /* free all remaining inline function tokens */ 14619 for(sym = global_stack; sym != NULL; sym = sym->prev) { 14620 type = &sym->type; 14621 if (((type->t & VT_BTYPE) == VT_FUNC) && 14622 (type->t & (VT_STATIC | VT_INLINE)) == 14623 (VT_STATIC | VT_INLINE)) { 14624 str = (int *)sym->r; 14625 tok_str_free(str); 14626 sym->r = 0; /* fail safe */ 14627 } 14628 } 14629 } 14630 14631 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */ 14632 static void decl(int l) 14633 { 14634 int v, has_init, r; 14635 CType type, btype; 14636 Sym *sym; 14637 AttributeDef ad; 14638 14639 while (1) { 14640 if (!parse_btype(&btype, &ad)) { 14641 /* skip redundant ';' */ 14642 /* XXX: find more elegant solution */ 14643 if (tok == ';') { 14644 next(); 14645 continue; 14646 } 14647 if (l == VT_CONST && 14648 (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { 14649 /* global asm block */ 14650 asm_global_instr(); 14651 continue; 14652 } 14653 /* special test for old K&R protos without explicit int 14654 type. Only accepted when defining global data */ 14655 if (l == VT_LOCAL || tok < TOK_DEFINE) 14656 break; 14657 btype.t = VT_INT; 14658 } 14659 if (((btype.t & VT_BTYPE) == VT_ENUM || 14660 (btype.t & VT_BTYPE) == VT_STRUCT) && 14661 tok == ';') { 14662 /* we accept no variable after */ 14663 next(); 14664 continue; 14665 } 14666 while (1) { /* iterate thru each declaration */ 14667 type = btype; 14668 type_decl(&type, &ad, &v, TYPE_DIRECT); 14669 #if 0 14670 { 14671 char buf[500]; 14672 type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL)); 14673 printf("type = '%s'\n", buf); 14674 } 14675 #endif 14676 if ((type.t & VT_BTYPE) == VT_FUNC) { 14677 /* if old style function prototype, we accept a 14678 declaration list */ 14679 sym = type.ref; 14680 if (sym->c == FUNC_OLD) 14681 func_decl_list(sym); 14682 } 14683 14684 if (tok == '{') { 14685 if (l == VT_LOCAL) 14686 error("cannot use local functions"); 14687 if (!(type.t & VT_FUNC)) 14688 expect("function definition"); 14689 14690 /* reject abstract declarators in function definition */ 14691 sym = type.ref; 14692 while ((sym = sym->next) != NULL) 14693 if (!(sym->v & ~SYM_FIELD)) 14694 expect("identifier"); 14695 14696 /* XXX: cannot do better now: convert extern line to static inline */ 14697 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE)) 14698 type.t = (type.t & ~VT_EXTERN) | VT_STATIC; 14699 14700 sym = sym_find(v); 14701 if (sym) { 14702 if ((sym->type.t & VT_BTYPE) != VT_FUNC) 14703 goto func_error1; 14704 /* specific case: if not func_call defined, we put 14705 the one of the prototype */ 14706 /* XXX: should have default value */ 14707 if (sym->type.ref->r != FUNC_CDECL && 14708 type.ref->r == FUNC_CDECL) 14709 type.ref->r = sym->type.ref->r; 14710 if (!is_compatible_types(&sym->type, &type)) { 14711 func_error1: 14712 error("incompatible types for redefinition of '%s'", 14713 get_tok_str(v, NULL)); 14714 } 14715 /* if symbol is already defined, then put complete type */ 14716 sym->type = type; 14717 } else { 14718 /* put function symbol */ 14719 sym = global_identifier_push(v, type.t, 0); 14720 sym->type.ref = type.ref; 14721 } 14722 14723 /* static inline functions are just recorded as a kind 14724 of macro. Their code will be emitted at the end of 14725 the compilation unit only if they are used */ 14726 if ((type.t & (VT_INLINE | VT_STATIC)) == 14727 (VT_INLINE | VT_STATIC)) { 14728 TokenString func_str; 14729 int block_level; 14730 14731 tok_str_new(&func_str); 14732 14733 block_level = 0; 14734 for(;;) { 14735 int t; 14736 if (tok == TOK_EOF) 14737 error("unexpected end of file"); 14738 tok_str_add_tok(&func_str); 14739 t = tok; 14740 next(); 14741 if (t == '{') { 14742 block_level++; 14743 } else if (t == '}') { 14744 block_level--; 14745 if (block_level == 0) 14746 break; 14747 } 14748 } 14749 tok_str_add(&func_str, -1); 14750 tok_str_add(&func_str, 0); 14751 sym->r = (long)func_str.str; 14752 } else { 14753 /* compute text section */ 14754 cur_text_section = ad.section; 14755 if (!cur_text_section) 14756 cur_text_section = text_section; 14757 sym->r = VT_SYM | VT_CONST; 14758 gen_function(sym); 14759 #ifdef TCC_TARGET_PE 14760 if (ad.dllexport) { 14761 ((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1; 14762 } 14763 #endif 14764 } 14765 break; 14766 } else { 14767 if (btype.t & VT_TYPEDEF) { 14768 /* save typedefed type */ 14769 /* XXX: test storage specifiers ? */ 14770 sym = sym_push(v, &type, 0, 0); 14771 sym->type.t |= VT_TYPEDEF; 14772 } else if ((type.t & VT_BTYPE) == VT_FUNC) { 14773 /* external function definition */ 14774 /* specific case for func_call attribute */ 14775 if (ad.func_call) 14776 type.ref->r = ad.func_call; 14777 external_sym(v, &type, 0); 14778 } else { 14779 /* not lvalue if array */ 14780 r = 0; 14781 if (!(type.t & VT_ARRAY)) 14782 r |= lvalue_type(type.t); 14783 has_init = (tok == '='); 14784 if ((btype.t & VT_EXTERN) || 14785 ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && 14786 !has_init && l == VT_CONST && type.ref->c < 0)) { 14787 /* external variable */ 14788 /* NOTE: as GCC, uninitialized global static 14789 arrays of null size are considered as 14790 extern */ 14791 external_sym(v, &type, r); 14792 } else { 14793 if (type.t & VT_STATIC) 14794 r |= VT_CONST; 14795 else 14796 r |= l; 14797 if (has_init) 14798 next(); 14799 decl_initializer_alloc(&type, &ad, r, 14800 has_init, v, l); 14801 } 14802 } 14803 if (tok != ',') { 14804 skip(';'); 14805 break; 14806 } 14807 next(); 14808 } 14809 } 14810 } 14811 } 14812 14813 /* better than nothing, but needs extension to handle '-E' option 14814 correctly too */ 14815 static void preprocess_init(TCCState *s1) 14816 { 14817 s1->include_stack_ptr = s1->include_stack; 14818 /* XXX: move that before to avoid having to initialize 14819 file->ifdef_stack_ptr ? */ 14820 s1->ifdef_stack_ptr = s1->ifdef_stack; 14821 file->ifdef_stack_ptr = s1->ifdef_stack_ptr; 14822 14823 /* XXX: not ANSI compliant: bound checking says error */ 14824 vtop = vstack - 1; 14825 s1->pack_stack[0] = 0; 14826 s1->pack_stack_ptr = s1->pack_stack; 14827 } 14828 14829 /* compile the C file opened in 'file'. Return non zero if errors. */ 14830 static int tcc_compile(TCCState *s1) 14831 { 14832 Sym *define_start; 14833 char buf[512]; 14834 volatile int section_sym; 14835 14836 #ifdef INC_DEBUG 14837 printf("%s: **** new file\n", file->filename); 14838 #endif 14839 preprocess_init(s1); 14840 14841 funcname = ""; 14842 anon_sym = SYM_FIRST_ANOM; 14843 14844 /* file info: full path + filename */ 14845 section_sym = 0; /* avoid warning */ 14846 if (do_debug) { 14847 section_sym = put_elf_sym(symtab_section, 0, 0, 14848 ELF32_ST_INFO(STB_LOCAL, STT_SECTION), 0, 14849 text_section->sh_num, NULL); 14850 dummy_char_star = getcwd(buf, sizeof(buf)); 14851 pstrcat(buf, sizeof(buf), "/"); 14852 put_stabs_r(buf, N_SO, 0, 0, 14853 text_section->data_offset, text_section, section_sym); 14854 put_stabs_r(file->filename, N_SO, 0, 0, 14855 text_section->data_offset, text_section, section_sym); 14856 } 14857 /* an elf symbol of type STT_FILE must be put so that STB_LOCAL 14858 symbols can be safely used */ 14859 put_elf_sym(symtab_section, 0, 0, 14860 ELF32_ST_INFO(STB_LOCAL, STT_FILE), 0, 14861 SHN_ABS, file->filename); 14862 14863 /* define some often used types */ 14864 int_type.t = VT_INT; 14865 14866 char_pointer_type.t = VT_BYTE; 14867 mk_pointer(&char_pointer_type); 14868 14869 func_old_type.t = VT_FUNC; 14870 func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD); 14871 14872 #if 0 14873 /* define 'void *alloca(unsigned int)' builtin function */ 14874 { 14875 Sym *s1; 14876 14877 p = anon_sym++; 14878 sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW); 14879 s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0); 14880 s1->next = NULL; 14881 sym->next = s1; 14882 sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0); 14883 } 14884 #endif 14885 14886 define_start = define_stack; 14887 14888 if (setjmp(s1->error_jmp_buf) == 0) { 14889 s1->nb_errors = 0; 14890 s1->error_set_jmp_enabled = 1; 14891 14892 ch = file->buf_ptr[0]; 14893 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; 14894 parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM; 14895 next(); 14896 decl(VT_CONST); 14897 if (tok != TOK_EOF) 14898 expect("declaration"); 14899 14900 /* end of translation unit info */ 14901 if (do_debug) { 14902 put_stabs_r(NULL, N_SO, 0, 0, 14903 text_section->data_offset, text_section, section_sym); 14904 } 14905 } 14906 s1->error_set_jmp_enabled = 0; 14907 14908 /* reset define stack, but leave -Dsymbols (may be incorrect if 14909 they are undefined) */ 14910 free_defines(define_start); 14911 14912 gen_inline_functions(); 14913 14914 sym_pop(&global_stack, NULL); 14915 14916 return s1->nb_errors != 0 ? -1 : 0; 14917 } 14918 14919 #ifdef LIBTCC 14920 int tcc_compile_string(TCCState *s, const char *str) 14921 { 14922 BufferedFile bf1, *bf = &bf1; 14923 int ret, len; 14924 char *buf; 14925 14926 /* init file structure */ 14927 bf->fd = -1; 14928 /* XXX: avoid copying */ 14929 len = strlen(str); 14930 buf = tcc_malloc(len + 1); 14931 if (!buf) 14932 return -1; 14933 memcpy(buf, str, len); 14934 buf[len] = CH_EOB; 14935 bf->buf_ptr = buf; 14936 bf->buf_end = buf + len; 14937 pstrcpy(bf->filename, sizeof(bf->filename), "<string>"); 14938 bf->line_num = 1; 14939 file = bf; 14940 14941 ret = tcc_compile(s); 14942 14943 tcc_free(buf); 14944 14945 /* currently, no need to close */ 14946 return ret; 14947 } 14948 #endif 14949 14950 /* define a preprocessor symbol. A value can also be provided with the '=' operator */ 14951 void tcc_define_symbol(TCCState *s1, const char *sym, const char *value) 14952 { 14953 BufferedFile bf1, *bf = &bf1; 14954 14955 pstrcpy(bf->buffer, IO_BUF_SIZE, sym); 14956 pstrcat(bf->buffer, IO_BUF_SIZE, " "); 14957 /* default value */ 14958 if (!value) 14959 value = "1"; 14960 pstrcat(bf->buffer, IO_BUF_SIZE, value); 14961 14962 /* init file structure */ 14963 bf->fd = -1; 14964 bf->buf_ptr = bf->buffer; 14965 bf->buf_end = bf->buffer + strlen(bf->buffer); 14966 *bf->buf_end = CH_EOB; 14967 bf->filename[0] = '\0'; 14968 bf->line_num = 1; 14969 file = bf; 14970 14971 s1->include_stack_ptr = s1->include_stack; 14972 14973 /* parse with define parser */ 14974 ch = file->buf_ptr[0]; 14975 next_nomacro(); 14976 parse_define(); 14977 file = NULL; 14978 } 14979 14980 /* undefine a preprocessor symbol */ 14981 void tcc_undefine_symbol(TCCState *s1, const char *sym) 14982 { 14983 TokenSym *ts; 14984 Sym *s; 14985 ts = tok_alloc(sym, strlen(sym)); 14986 s = define_find(ts->tok); 14987 /* undefine symbol by putting an invalid name */ 14988 if (s) 14989 define_undef(s); 14990 } 14991 14992 #ifdef CONFIG_TCC_ASM 14993 14994 #ifdef TCC_TARGET_I386 14995 // njn: inlined i386-asm.c 14996 //#include "i386-asm.c" 14997 //--------------------------------------------------------------------------- 14998 /* 14999 * i386 specific functions for TCC assembler 15000 * 15001 * Copyright (c) 2001, 2002 Fabrice Bellard 15002 * 15003 * This library is free software; you can redistribute it and/or 15004 * modify it under the terms of the GNU Lesser General Public 15005 * License as published by the Free Software Foundation; either 15006 * version 2 of the License, or (at your option) any later version. 15007 * 15008 * This library is distributed in the hope that it will be useful, 15009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15011 * Lesser General Public License for more details. 15012 * 15013 * You should have received a copy of the GNU Lesser General Public 15014 * License along with this library; if not, write to the Free Software 15015 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 15016 */ 15017 15018 #define MAX_OPERANDS 3 15019 15020 typedef struct ASMInstr { 15021 uint16_t sym; 15022 uint16_t opcode; 15023 uint16_t instr_type; 15024 #define OPC_JMP 0x01 /* jmp operand */ 15025 #define OPC_B 0x02 /* only used zith OPC_WL */ 15026 #define OPC_WL 0x04 /* accepts w, l or no suffix */ 15027 #define OPC_BWL (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */ 15028 #define OPC_REG 0x08 /* register is added to opcode */ 15029 #define OPC_MODRM 0x10 /* modrm encoding */ 15030 #define OPC_FWAIT 0x20 /* add fwait opcode */ 15031 #define OPC_TEST 0x40 /* test opcodes */ 15032 #define OPC_SHIFT 0x80 /* shift opcodes */ 15033 #define OPC_D16 0x0100 /* generate data16 prefix */ 15034 #define OPC_ARITH 0x0200 /* arithmetic opcodes */ 15035 #define OPC_SHORTJMP 0x0400 /* short jmp operand */ 15036 #define OPC_FARITH 0x0800 /* FPU arithmetic opcodes */ 15037 #define OPC_GROUP_SHIFT 13 15038 15039 /* in order to compress the operand type, we use specific operands and 15040 we or only with EA */ 15041 #define OPT_REG8 0 /* warning: value is hardcoded from TOK_ASM_xxx */ 15042 #define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */ 15043 #define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */ 15044 #define OPT_MMX 3 /* warning: value is hardcoded from TOK_ASM_xxx */ 15045 #define OPT_SSE 4 /* warning: value is hardcoded from TOK_ASM_xxx */ 15046 #define OPT_CR 5 /* warning: value is hardcoded from TOK_ASM_xxx */ 15047 #define OPT_TR 6 /* warning: value is hardcoded from TOK_ASM_xxx */ 15048 #define OPT_DB 7 /* warning: value is hardcoded from TOK_ASM_xxx */ 15049 #define OPT_SEG 8 15050 #define OPT_ST 9 15051 #define OPT_IM8 10 15052 #define OPT_IM8S 11 15053 #define OPT_IM16 12 15054 #define OPT_IM32 13 15055 #define OPT_EAX 14 /* %al, %ax or %eax register */ 15056 #define OPT_ST0 15 /* %st(0) register */ 15057 #define OPT_CL 16 /* %cl register */ 15058 #define OPT_DX 17 /* %dx register */ 15059 #define OPT_ADDR 18 /* OP_EA with only offset */ 15060 #define OPT_INDIR 19 /* *(expr) */ 15061 15062 /* composite types */ 15063 #define OPT_COMPOSITE_FIRST 20 15064 #define OPT_IM 20 /* IM8 | IM16 | IM32 */ 15065 #define OPT_REG 21 /* REG8 | REG16 | REG32 */ 15066 #define OPT_REGW 22 /* REG16 | REG32 */ 15067 #define OPT_IMW 23 /* IM16 | IM32 */ 15068 15069 /* can be ored with any OPT_xxx */ 15070 #define OPT_EA 0x80 15071 15072 uint8_t nb_ops; 15073 uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */ 15074 } ASMInstr; 15075 15076 typedef struct Operand { 15077 uint32_t type; 15078 #define OP_REG8 (1 << OPT_REG8) 15079 #define OP_REG16 (1 << OPT_REG16) 15080 #define OP_REG32 (1 << OPT_REG32) 15081 #define OP_MMX (1 << OPT_MMX) 15082 #define OP_SSE (1 << OPT_SSE) 15083 #define OP_CR (1 << OPT_CR) 15084 #define OP_TR (1 << OPT_TR) 15085 #define OP_DB (1 << OPT_DB) 15086 #define OP_SEG (1 << OPT_SEG) 15087 #define OP_ST (1 << OPT_ST) 15088 #define OP_IM8 (1 << OPT_IM8) 15089 #define OP_IM8S (1 << OPT_IM8S) 15090 #define OP_IM16 (1 << OPT_IM16) 15091 #define OP_IM32 (1 << OPT_IM32) 15092 #define OP_EAX (1 << OPT_EAX) 15093 #define OP_ST0 (1 << OPT_ST0) 15094 #define OP_CL (1 << OPT_CL) 15095 #define OP_DX (1 << OPT_DX) 15096 #define OP_ADDR (1 << OPT_ADDR) 15097 #define OP_INDIR (1 << OPT_INDIR) 15098 15099 #define OP_EA 0x40000000 15100 #define OP_REG (OP_REG8 | OP_REG16 | OP_REG32) 15101 #define OP_IM OP_IM32 15102 int8_t reg; /* register, -1 if none */ 15103 int8_t reg2; /* second register, -1 if none */ 15104 uint8_t shift; 15105 ExprValue e; 15106 } Operand; 15107 15108 static const uint8_t reg_to_size[5] = { 15109 [OP_REG8] = 0, 15110 [OP_REG16] = 1, 15111 [OP_REG32] = 2, 15112 }; 15113 15114 #define WORD_PREFIX_OPCODE 0x66 15115 15116 #define NB_TEST_OPCODES 30 15117 15118 static const uint8_t test_bits[NB_TEST_OPCODES] = { 15119 0x00, /* o */ 15120 0x01, /* no */ 15121 0x02, /* b */ 15122 0x02, /* c */ 15123 0x02, /* nae */ 15124 0x03, /* nb */ 15125 0x03, /* nc */ 15126 0x03, /* ae */ 15127 0x04, /* e */ 15128 0x04, /* z */ 15129 0x05, /* ne */ 15130 0x05, /* nz */ 15131 0x06, /* be */ 15132 0x06, /* na */ 15133 0x07, /* nbe */ 15134 0x07, /* a */ 15135 0x08, /* s */ 15136 0x09, /* ns */ 15137 0x0a, /* p */ 15138 0x0a, /* pe */ 15139 0x0b, /* np */ 15140 0x0b, /* po */ 15141 0x0c, /* l */ 15142 0x0c, /* nge */ 15143 0x0d, /* nl */ 15144 0x0d, /* ge */ 15145 0x0e, /* le */ 15146 0x0e, /* ng */ 15147 0x0f, /* nle */ 15148 0x0f, /* g */ 15149 }; 15150 15151 static const ASMInstr asm_instrs[] = { 15152 #define ALT(x) x 15153 #define DEF_ASM_OP0(name, opcode) 15154 #define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 }, 15155 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }}, 15156 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }}, 15157 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }}, 15158 // njn: inlined i386-asm.h 15159 //#include "i386-asm.h" 15160 //--------------------------------------------------------------------------- 15161 DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ 15162 DEF_ASM_OP0(popa, 0x61) 15163 DEF_ASM_OP0(clc, 0xf8) 15164 DEF_ASM_OP0(cld, 0xfc) 15165 DEF_ASM_OP0(cli, 0xfa) 15166 DEF_ASM_OP0(clts, 0x0f06) 15167 DEF_ASM_OP0(cmc, 0xf5) 15168 DEF_ASM_OP0(lahf, 0x9f) 15169 DEF_ASM_OP0(sahf, 0x9e) 15170 DEF_ASM_OP0(pushfl, 0x9c) 15171 DEF_ASM_OP0(popfl, 0x9d) 15172 DEF_ASM_OP0(pushf, 0x9c) 15173 DEF_ASM_OP0(popf, 0x9d) 15174 DEF_ASM_OP0(stc, 0xf9) 15175 DEF_ASM_OP0(std, 0xfd) 15176 DEF_ASM_OP0(sti, 0xfb) 15177 DEF_ASM_OP0(aaa, 0x37) 15178 DEF_ASM_OP0(aas, 0x3f) 15179 DEF_ASM_OP0(daa, 0x27) 15180 DEF_ASM_OP0(das, 0x2f) 15181 DEF_ASM_OP0(aad, 0xd50a) 15182 DEF_ASM_OP0(aam, 0xd40a) 15183 DEF_ASM_OP0(cbw, 0x6698) 15184 DEF_ASM_OP0(cwd, 0x6699) 15185 DEF_ASM_OP0(cwde, 0x98) 15186 DEF_ASM_OP0(cdq, 0x99) 15187 DEF_ASM_OP0(cbtw, 0x6698) 15188 DEF_ASM_OP0(cwtl, 0x98) 15189 DEF_ASM_OP0(cwtd, 0x6699) 15190 DEF_ASM_OP0(cltd, 0x99) 15191 DEF_ASM_OP0(int3, 0xcc) 15192 DEF_ASM_OP0(into, 0xce) 15193 DEF_ASM_OP0(iret, 0xcf) 15194 DEF_ASM_OP0(rsm, 0x0faa) 15195 DEF_ASM_OP0(hlt, 0xf4) 15196 DEF_ASM_OP0(wait, 0x9b) 15197 DEF_ASM_OP0(nop, 0x90) 15198 DEF_ASM_OP0(xlat, 0xd7) 15199 15200 /* strings */ 15201 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) 15202 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) 15203 15204 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) 15205 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) 15206 15207 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) 15208 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) 15209 15210 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) 15211 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) 15212 15213 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) 15214 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) 15215 15216 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) 15217 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) 15218 15219 /* bits */ 15220 15221 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 15222 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 15223 15224 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15225 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15226 15227 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15228 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15229 15230 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15231 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15232 15233 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15234 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15235 15236 /* prefixes */ 15237 DEF_ASM_OP0(aword, 0x67) 15238 DEF_ASM_OP0(addr16, 0x67) 15239 DEF_ASM_OP0(word, 0x66) 15240 DEF_ASM_OP0(data16, 0x66) 15241 DEF_ASM_OP0(lock, 0xf0) 15242 DEF_ASM_OP0(rep, 0xf3) 15243 DEF_ASM_OP0(repe, 0xf3) 15244 DEF_ASM_OP0(repz, 0xf3) 15245 DEF_ASM_OP0(repne, 0xf2) 15246 DEF_ASM_OP0(repnz, 0xf2) 15247 15248 DEF_ASM_OP0(invd, 0x0f08) 15249 DEF_ASM_OP0(wbinvd, 0x0f09) 15250 DEF_ASM_OP0(cpuid, 0x0fa2) 15251 DEF_ASM_OP0(wrmsr, 0x0f30) 15252 DEF_ASM_OP0(rdtsc, 0x0f31) 15253 DEF_ASM_OP0(rdmsr, 0x0f32) 15254 DEF_ASM_OP0(rdpmc, 0x0f33) 15255 DEF_ASM_OP0(ud2, 0x0f0b) 15256 15257 /* NOTE: we took the same order as gas opcode definition order */ 15258 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) 15259 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) 15260 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 15261 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15262 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) 15263 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) 15264 15265 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) 15266 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) 15267 15268 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) 15269 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) 15270 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) 15271 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) 15272 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) 15273 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) 15274 15275 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) 15276 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) 15277 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 15278 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) 15279 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 15280 15281 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) 15282 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 15283 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) 15284 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) 15285 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) 15286 15287 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) 15288 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 15289 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) 15290 15291 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) 15292 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) 15293 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 15294 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15295 15296 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) 15297 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) 15298 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) 15299 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) 15300 15301 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) 15302 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) 15303 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) 15304 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) 15305 15306 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) 15307 15308 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15309 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15310 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15311 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15312 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15313 15314 /* arith */ 15315 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ 15316 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15317 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) 15318 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 15319 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) 15320 15321 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15322 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 15323 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) 15324 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 15325 15326 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) 15327 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15328 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) 15329 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15330 15331 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15332 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15333 15334 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15335 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15336 15337 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) 15338 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) 15339 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) 15340 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) 15341 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) 15342 15343 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15344 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 15345 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15346 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 15347 15348 /* shifts */ 15349 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) 15350 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) 15351 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) 15352 15353 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 15354 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 15355 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 15356 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 15357 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 15358 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 15359 15360 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) 15361 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) 15362 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) 15363 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) 15364 15365 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 15366 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) 15367 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) 15368 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) 15369 15370 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) 15371 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) 15372 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) 15373 DEF_ASM_OP0(leave, 0xc9) 15374 DEF_ASM_OP0(ret, 0xc3) 15375 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) 15376 DEF_ASM_OP0(lret, 0xcb) 15377 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) 15378 15379 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) 15380 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 15381 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 15382 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 15383 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 15384 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) 15385 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) 15386 15387 /* float */ 15388 /* specific fcomp handling */ 15389 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) 15390 15391 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 15392 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 15393 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) 15394 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 15395 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 15396 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) 15397 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) 15398 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15399 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15400 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15401 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15402 15403 DEF_ASM_OP0(fucompp, 0xdae9) 15404 DEF_ASM_OP0(ftst, 0xd9e4) 15405 DEF_ASM_OP0(fxam, 0xd9e5) 15406 DEF_ASM_OP0(fld1, 0xd9e8) 15407 DEF_ASM_OP0(fldl2t, 0xd9e9) 15408 DEF_ASM_OP0(fldl2e, 0xd9ea) 15409 DEF_ASM_OP0(fldpi, 0xd9eb) 15410 DEF_ASM_OP0(fldlg2, 0xd9ec) 15411 DEF_ASM_OP0(fldln2, 0xd9ed) 15412 DEF_ASM_OP0(fldz, 0xd9ee) 15413 15414 DEF_ASM_OP0(f2xm1, 0xd9f0) 15415 DEF_ASM_OP0(fyl2x, 0xd9f1) 15416 DEF_ASM_OP0(fptan, 0xd9f2) 15417 DEF_ASM_OP0(fpatan, 0xd9f3) 15418 DEF_ASM_OP0(fxtract, 0xd9f4) 15419 DEF_ASM_OP0(fprem1, 0xd9f5) 15420 DEF_ASM_OP0(fdecstp, 0xd9f6) 15421 DEF_ASM_OP0(fincstp, 0xd9f7) 15422 DEF_ASM_OP0(fprem, 0xd9f8) 15423 DEF_ASM_OP0(fyl2xp1, 0xd9f9) 15424 DEF_ASM_OP0(fsqrt, 0xd9fa) 15425 DEF_ASM_OP0(fsincos, 0xd9fb) 15426 DEF_ASM_OP0(frndint, 0xd9fc) 15427 DEF_ASM_OP0(fscale, 0xd9fd) 15428 DEF_ASM_OP0(fsin, 0xd9fe) 15429 DEF_ASM_OP0(fcos, 0xd9ff) 15430 DEF_ASM_OP0(fchs, 0xd9e0) 15431 DEF_ASM_OP0(fabs, 0xd9e1) 15432 DEF_ASM_OP0(fninit, 0xdbe3) 15433 DEF_ASM_OP0(fnclex, 0xdbe2) 15434 DEF_ASM_OP0(fnop, 0xd9d0) 15435 DEF_ASM_OP0(fwait, 0x9b) 15436 15437 /* fp load */ 15438 DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) 15439 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) 15440 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) 15441 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) 15442 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) 15443 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) 15444 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) 15445 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) 15446 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) 15447 15448 /* fp store */ 15449 DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) 15450 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) 15451 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) 15452 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) 15453 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) 15454 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) 15455 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) 15456 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) 15457 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) 15458 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) 15459 15460 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) 15461 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) 15462 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) 15463 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) 15464 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) 15465 15466 /* exchange */ 15467 DEF_ASM_OP0(fxch, 0xd9c9) 15468 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) 15469 15470 /* misc FPU */ 15471 DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) 15472 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) 15473 15474 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) 15475 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) 15476 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) 15477 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) 15478 DEF_ASM_OP0(fnstsw, 0xdfe0) 15479 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) 15480 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) 15481 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) 15482 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) 15483 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) 15484 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) 15485 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) 15486 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 15487 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) 15488 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) 15489 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 15490 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) 15491 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) 15492 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) 15493 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) 15494 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) 15495 15496 /* segments */ 15497 DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) 15498 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) 15499 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) 15500 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) 15501 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) 15502 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) 15503 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) 15504 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) 15505 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) 15506 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) 15507 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) 15508 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) 15509 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) 15510 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) 15511 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) 15512 15513 /* 486 */ 15514 DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) 15515 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 15516 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 15517 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) 15518 15519 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) 15520 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) 15521 15522 /* pentium */ 15523 DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) 15524 15525 /* pentium pro */ 15526 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) 15527 15528 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15529 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15530 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15531 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15532 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15533 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15534 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15535 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15536 15537 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15538 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15539 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15540 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15541 15542 /* mmx */ 15543 DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ 15544 DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) 15545 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) 15546 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15547 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) 15548 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15549 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15550 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15551 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15552 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15553 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15554 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15555 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15556 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15557 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15558 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15559 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15560 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15561 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15562 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15563 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15564 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15565 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15566 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15567 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15568 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15569 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15570 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15571 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 15572 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15573 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 15574 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15575 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 15576 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15577 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 15578 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15579 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 15580 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15581 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 15582 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15583 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 15584 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15585 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 15586 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15587 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15588 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15589 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15590 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15591 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15592 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15593 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15594 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15595 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15596 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15597 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15598 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15599 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 15600 15601 #undef ALT 15602 #undef DEF_ASM_OP0 15603 #undef DEF_ASM_OP0L 15604 #undef DEF_ASM_OP1 15605 #undef DEF_ASM_OP2 15606 #undef DEF_ASM_OP3 15607 //--------------------------------------------------------------------------- 15608 15609 /* last operation */ 15610 { 0, }, 15611 }; 15612 15613 static const uint16_t op0_codes[] = { 15614 #define ALT(x) 15615 #define DEF_ASM_OP0(x, opcode) opcode, 15616 #define DEF_ASM_OP0L(name, opcode, group, instr_type) 15617 #define DEF_ASM_OP1(name, opcode, group, instr_type, op0) 15618 #define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) 15619 #define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) 15620 // njn: inlined i386-asm.h 15621 //#include "i386-asm.h" 15622 //--------------------------------------------------------------------------- 15623 DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */ 15624 DEF_ASM_OP0(popa, 0x61) 15625 DEF_ASM_OP0(clc, 0xf8) 15626 DEF_ASM_OP0(cld, 0xfc) 15627 DEF_ASM_OP0(cli, 0xfa) 15628 DEF_ASM_OP0(clts, 0x0f06) 15629 DEF_ASM_OP0(cmc, 0xf5) 15630 DEF_ASM_OP0(lahf, 0x9f) 15631 DEF_ASM_OP0(sahf, 0x9e) 15632 DEF_ASM_OP0(pushfl, 0x9c) 15633 DEF_ASM_OP0(popfl, 0x9d) 15634 DEF_ASM_OP0(pushf, 0x9c) 15635 DEF_ASM_OP0(popf, 0x9d) 15636 DEF_ASM_OP0(stc, 0xf9) 15637 DEF_ASM_OP0(std, 0xfd) 15638 DEF_ASM_OP0(sti, 0xfb) 15639 DEF_ASM_OP0(aaa, 0x37) 15640 DEF_ASM_OP0(aas, 0x3f) 15641 DEF_ASM_OP0(daa, 0x27) 15642 DEF_ASM_OP0(das, 0x2f) 15643 DEF_ASM_OP0(aad, 0xd50a) 15644 DEF_ASM_OP0(aam, 0xd40a) 15645 DEF_ASM_OP0(cbw, 0x6698) 15646 DEF_ASM_OP0(cwd, 0x6699) 15647 DEF_ASM_OP0(cwde, 0x98) 15648 DEF_ASM_OP0(cdq, 0x99) 15649 DEF_ASM_OP0(cbtw, 0x6698) 15650 DEF_ASM_OP0(cwtl, 0x98) 15651 DEF_ASM_OP0(cwtd, 0x6699) 15652 DEF_ASM_OP0(cltd, 0x99) 15653 DEF_ASM_OP0(int3, 0xcc) 15654 DEF_ASM_OP0(into, 0xce) 15655 DEF_ASM_OP0(iret, 0xcf) 15656 DEF_ASM_OP0(rsm, 0x0faa) 15657 DEF_ASM_OP0(hlt, 0xf4) 15658 DEF_ASM_OP0(wait, 0x9b) 15659 DEF_ASM_OP0(nop, 0x90) 15660 DEF_ASM_OP0(xlat, 0xd7) 15661 15662 /* strings */ 15663 ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL)) 15664 ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL)) 15665 15666 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL)) 15667 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL)) 15668 15669 ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL)) 15670 ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL)) 15671 15672 ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL)) 15673 ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL)) 15674 15675 ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL)) 15676 ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL)) 15677 15678 ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL)) 15679 ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) 15680 15681 /* bits */ 15682 15683 ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 15684 ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) 15685 15686 ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15687 ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15688 15689 ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15690 ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15691 15692 ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15693 ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15694 15695 ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA)) 15696 ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) 15697 15698 /* prefixes */ 15699 DEF_ASM_OP0(aword, 0x67) 15700 DEF_ASM_OP0(addr16, 0x67) 15701 DEF_ASM_OP0(word, 0x66) 15702 DEF_ASM_OP0(data16, 0x66) 15703 DEF_ASM_OP0(lock, 0xf0) 15704 DEF_ASM_OP0(rep, 0xf3) 15705 DEF_ASM_OP0(repe, 0xf3) 15706 DEF_ASM_OP0(repz, 0xf3) 15707 DEF_ASM_OP0(repne, 0xf2) 15708 DEF_ASM_OP0(repnz, 0xf2) 15709 15710 DEF_ASM_OP0(invd, 0x0f08) 15711 DEF_ASM_OP0(wbinvd, 0x0f09) 15712 DEF_ASM_OP0(cpuid, 0x0fa2) 15713 DEF_ASM_OP0(wrmsr, 0x0f30) 15714 DEF_ASM_OP0(rdtsc, 0x0f31) 15715 DEF_ASM_OP0(rdmsr, 0x0f32) 15716 DEF_ASM_OP0(rdpmc, 0x0f33) 15717 DEF_ASM_OP0(ud2, 0x0f0b) 15718 15719 /* NOTE: we took the same order as gas opcode definition order */ 15720 ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX)) 15721 ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR)) 15722 ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 15723 ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15724 ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG)) 15725 ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA)) 15726 15727 ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG)) 15728 ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG)) 15729 15730 ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32)) 15731 ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32)) 15732 ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32)) 15733 ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR)) 15734 ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB)) 15735 ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR)) 15736 15737 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32)) 15738 ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16)) 15739 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 15740 ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW)) 15741 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32)) 15742 15743 ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW)) 15744 ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 15745 ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S)) 15746 ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32)) 15747 ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG)) 15748 15749 ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW)) 15750 ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA)) 15751 ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG)) 15752 15753 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX)) 15754 ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG)) 15755 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 15756 ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15757 15758 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX)) 15759 ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8)) 15760 ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX)) 15761 ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX)) 15762 15763 ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8)) 15764 ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8)) 15765 ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX)) 15766 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX)) 15767 15768 ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG)) 15769 15770 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15771 ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15772 ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15773 ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15774 ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32)) 15775 15776 /* arith */ 15777 ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */ 15778 ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15779 ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX)) 15780 ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 15781 ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG)) 15782 15783 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG)) 15784 ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) 15785 ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX)) 15786 ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG)) 15787 15788 ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW)) 15789 ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15790 ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW)) 15791 ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15792 15793 ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15794 ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15795 15796 ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15797 ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15798 15799 ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG)) 15800 ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW)) 15801 ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW)) 15802 ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW)) 15803 ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW)) 15804 15805 ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15806 ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 15807 ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA)) 15808 ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX)) 15809 15810 /* shifts */ 15811 ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG)) 15812 ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG)) 15813 ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG)) 15814 15815 ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 15816 ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 15817 ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 15818 ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW)) 15819 ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW)) 15820 ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW)) 15821 15822 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) 15823 ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) 15824 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) 15825 ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) 15826 15827 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 15828 ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA)) 15829 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32)) 15830 ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA)) 15831 15832 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8)) 15833 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA)) 15834 DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8) 15835 DEF_ASM_OP0(leave, 0xc9) 15836 DEF_ASM_OP0(ret, 0xc3) 15837 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) 15838 DEF_ASM_OP0(lret, 0xcb) 15839 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) 15840 15841 ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR)) 15842 DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 15843 DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) 15844 DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 15845 DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) 15846 DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) 15847 DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) 15848 15849 /* float */ 15850 /* specific fcomp handling */ 15851 ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) 15852 15853 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 15854 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 15855 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH)) 15856 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST)) 15857 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0)) 15858 ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST)) 15859 ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH)) 15860 ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15861 ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15862 ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15863 ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA)) 15864 15865 DEF_ASM_OP0(fucompp, 0xdae9) 15866 DEF_ASM_OP0(ftst, 0xd9e4) 15867 DEF_ASM_OP0(fxam, 0xd9e5) 15868 DEF_ASM_OP0(fld1, 0xd9e8) 15869 DEF_ASM_OP0(fldl2t, 0xd9e9) 15870 DEF_ASM_OP0(fldl2e, 0xd9ea) 15871 DEF_ASM_OP0(fldpi, 0xd9eb) 15872 DEF_ASM_OP0(fldlg2, 0xd9ec) 15873 DEF_ASM_OP0(fldln2, 0xd9ed) 15874 DEF_ASM_OP0(fldz, 0xd9ee) 15875 15876 DEF_ASM_OP0(f2xm1, 0xd9f0) 15877 DEF_ASM_OP0(fyl2x, 0xd9f1) 15878 DEF_ASM_OP0(fptan, 0xd9f2) 15879 DEF_ASM_OP0(fpatan, 0xd9f3) 15880 DEF_ASM_OP0(fxtract, 0xd9f4) 15881 DEF_ASM_OP0(fprem1, 0xd9f5) 15882 DEF_ASM_OP0(fdecstp, 0xd9f6) 15883 DEF_ASM_OP0(fincstp, 0xd9f7) 15884 DEF_ASM_OP0(fprem, 0xd9f8) 15885 DEF_ASM_OP0(fyl2xp1, 0xd9f9) 15886 DEF_ASM_OP0(fsqrt, 0xd9fa) 15887 DEF_ASM_OP0(fsincos, 0xd9fb) 15888 DEF_ASM_OP0(frndint, 0xd9fc) 15889 DEF_ASM_OP0(fscale, 0xd9fd) 15890 DEF_ASM_OP0(fsin, 0xd9fe) 15891 DEF_ASM_OP0(fcos, 0xd9ff) 15892 DEF_ASM_OP0(fchs, 0xd9e0) 15893 DEF_ASM_OP0(fabs, 0xd9e1) 15894 DEF_ASM_OP0(fninit, 0xdbe3) 15895 DEF_ASM_OP0(fnclex, 0xdbe2) 15896 DEF_ASM_OP0(fnop, 0xd9d0) 15897 DEF_ASM_OP0(fwait, 0x9b) 15898 15899 /* fp load */ 15900 DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST) 15901 DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST) 15902 DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA) 15903 ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA)) 15904 DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA) 15905 DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA) 15906 DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) 15907 DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) 15908 DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) 15909 15910 /* fp store */ 15911 DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) 15912 DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) 15913 DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA) 15914 DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA) 15915 ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA)) 15916 DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA) 15917 DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA) 15918 DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA) 15919 DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA) 15920 DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA) 15921 15922 DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST) 15923 DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA) 15924 DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA) 15925 DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA) 15926 DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA) 15927 15928 /* exchange */ 15929 DEF_ASM_OP0(fxch, 0xd9c9) 15930 ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST)) 15931 15932 /* misc FPU */ 15933 DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST ) 15934 DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST ) 15935 15936 DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT) 15937 DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA ) 15938 DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA ) 15939 DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ) 15940 DEF_ASM_OP0(fnstsw, 0xdfe0) 15941 ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX )) 15942 ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA )) 15943 DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX ) 15944 ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT)) 15945 ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )) 15946 DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT) 15947 DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA ) 15948 DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 15949 DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA ) 15950 DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA ) 15951 DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA ) 15952 DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA ) 15953 DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST ) 15954 DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST ) 15955 DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA ) 15956 DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA ) 15957 15958 /* segments */ 15959 DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA) 15960 DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32) 15961 DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA) 15962 DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA) 15963 DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG) 15964 DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG) 15965 ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG)) 15966 DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG) 15967 DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA) 15968 DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA) 15969 DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA) 15970 DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA) 15971 DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA) 15972 DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA) 15973 DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA) 15974 15975 /* 486 */ 15976 DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 ) 15977 ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 15978 ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA )) 15979 DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA ) 15980 15981 DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA) 15982 DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA) 15983 15984 /* pentium */ 15985 DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) 15986 15987 /* pentium pro */ 15988 ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) 15989 15990 DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15991 DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15992 DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15993 DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15994 DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15995 DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15996 DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15997 DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 15998 15999 DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 16000 DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 16001 DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 ) 16002 DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 ) 16003 16004 /* mmx */ 16005 DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */ 16006 DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX ) 16007 ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 )) 16008 DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16009 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX )) 16010 DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16011 DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16012 DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16013 DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16014 DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16015 DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16016 DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16017 DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16018 DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16019 DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16020 DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16021 DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16022 DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16023 DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16024 DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16025 DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16026 DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16027 DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16028 DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16029 DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16030 DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16031 DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16032 DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16033 ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 16034 DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16035 ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 16036 DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16037 ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX )) 16038 DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16039 ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 16040 DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16041 ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX )) 16042 DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16043 ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 16044 DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16045 ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 16046 DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16047 ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX )) 16048 DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16049 DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16050 DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16051 DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16052 DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16053 DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16054 DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16055 DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16056 DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16057 DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16058 DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16059 DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16060 DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16061 DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ) 16062 16063 #undef ALT 16064 #undef DEF_ASM_OP0 16065 #undef DEF_ASM_OP0L 16066 #undef DEF_ASM_OP1 16067 #undef DEF_ASM_OP2 16068 #undef DEF_ASM_OP3 16069 //--------------------------------------------------------------------------- 16070 }; 16071 16072 static inline int get_reg_shift(TCCState *s1) 16073 { 16074 int shift, v; 16075 16076 v = asm_int_expr(s1); 16077 switch(v) { 16078 case 1: 16079 shift = 0; 16080 break; 16081 case 2: 16082 shift = 1; 16083 break; 16084 case 4: 16085 shift = 2; 16086 break; 16087 case 8: 16088 shift = 3; 16089 break; 16090 default: 16091 expect("1, 2, 4 or 8 constant"); 16092 shift = 0; 16093 break; 16094 } 16095 return shift; 16096 } 16097 16098 static int asm_parse_reg(void) 16099 { 16100 int reg; 16101 if (tok != '%') 16102 goto error_32; 16103 next(); 16104 if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) { 16105 reg = tok - TOK_ASM_eax; 16106 next(); 16107 return reg; 16108 } else { 16109 error_32: 16110 expect("32 bit register"); 16111 return 0; 16112 } 16113 } 16114 16115 static void parse_operand(TCCState *s1, Operand *op) 16116 { 16117 ExprValue e; 16118 int reg, indir; 16119 const char *p; 16120 16121 indir = 0; 16122 if (tok == '*') { 16123 next(); 16124 indir = OP_INDIR; 16125 } 16126 16127 if (tok == '%') { 16128 next(); 16129 if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) { 16130 reg = tok - TOK_ASM_al; 16131 op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ 16132 op->reg = reg & 7; 16133 if ((op->type & OP_REG) && op->reg == TREG_EAX) 16134 op->type |= OP_EAX; 16135 else if (op->type == OP_REG8 && op->reg == TREG_ECX) 16136 op->type |= OP_CL; 16137 else if (op->type == OP_REG16 && op->reg == TREG_EDX) 16138 op->type |= OP_DX; 16139 } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) { 16140 op->type = OP_DB; 16141 op->reg = tok - TOK_ASM_dr0; 16142 } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) { 16143 op->type = OP_SEG; 16144 op->reg = tok - TOK_ASM_es; 16145 } else if (tok == TOK_ASM_st) { 16146 op->type = OP_ST; 16147 op->reg = 0; 16148 next(); 16149 if (tok == '(') { 16150 next(); 16151 if (tok != TOK_PPNUM) 16152 goto reg_error; 16153 p = tokc.cstr->data; 16154 reg = p[0] - '0'; 16155 if ((unsigned)reg >= 8 || p[1] != '\0') 16156 goto reg_error; 16157 op->reg = reg; 16158 next(); 16159 skip(')'); 16160 } 16161 if (op->reg == 0) 16162 op->type |= OP_ST0; 16163 goto no_skip; 16164 } else { 16165 reg_error: 16166 error("unknown register"); 16167 } 16168 next(); 16169 no_skip: ; 16170 } else if (tok == '$') { 16171 /* constant value */ 16172 next(); 16173 asm_expr(s1, &e); 16174 op->type = OP_IM32; 16175 op->e.v = e.v; 16176 op->e.sym = e.sym; 16177 if (!op->e.sym) { 16178 if (op->e.v == (uint8_t)op->e.v) 16179 op->type |= OP_IM8; 16180 if (op->e.v == (int8_t)op->e.v) 16181 op->type |= OP_IM8S; 16182 if (op->e.v == (uint16_t)op->e.v) 16183 op->type |= OP_IM16; 16184 } 16185 } else { 16186 /* address(reg,reg2,shift) with all variants */ 16187 op->type = OP_EA; 16188 op->reg = -1; 16189 op->reg2 = -1; 16190 op->shift = 0; 16191 if (tok != '(') { 16192 asm_expr(s1, &e); 16193 op->e.v = e.v; 16194 op->e.sym = e.sym; 16195 } else { 16196 op->e.v = 0; 16197 op->e.sym = NULL; 16198 } 16199 if (tok == '(') { 16200 next(); 16201 if (tok != ',') { 16202 op->reg = asm_parse_reg(); 16203 } 16204 if (tok == ',') { 16205 next(); 16206 if (tok != ',') { 16207 op->reg2 = asm_parse_reg(); 16208 } 16209 skip(','); 16210 op->shift = get_reg_shift(s1); 16211 } 16212 skip(')'); 16213 } 16214 if (op->reg == -1 && op->reg2 == -1) 16215 op->type |= OP_ADDR; 16216 } 16217 op->type |= indir; 16218 } 16219 16220 /* XXX: unify with C code output ? */ 16221 static void gen_expr32(ExprValue *pe) 16222 { 16223 if (pe->sym) 16224 greloc(cur_text_section, pe->sym, ind, R_386_32); 16225 gen_le32(pe->v); 16226 } 16227 16228 /* XXX: unify with C code output ? */ 16229 static void gen_disp32(ExprValue *pe) 16230 { 16231 Sym *sym; 16232 sym = pe->sym; 16233 if (sym) { 16234 if (sym->r == cur_text_section->sh_num) { 16235 /* same section: we can output an absolute value. Note 16236 that the TCC compiler behaves differently here because 16237 it always outputs a relocation to ease (future) code 16238 elimination in the linker */ 16239 gen_le32(pe->v + (long)sym->next - ind - 4); 16240 } else { 16241 greloc(cur_text_section, sym, ind, R_386_PC32); 16242 gen_le32(pe->v - 4); 16243 } 16244 } else { 16245 /* put an empty PC32 relocation */ 16246 put_elf_reloc(symtab_section, cur_text_section, 16247 ind, R_386_PC32, 0); 16248 gen_le32(pe->v - 4); 16249 } 16250 } 16251 16252 16253 static void gen_le16(int v) 16254 { 16255 g(v); 16256 g(v >> 8); 16257 } 16258 16259 /* generate the modrm operand */ 16260 static inline void asm_modrm(int reg, Operand *op) 16261 { 16262 int mod, reg1, reg2, sib_reg1; 16263 16264 if (op->type & (OP_REG | OP_MMX | OP_SSE)) { 16265 g(0xc0 + (reg << 3) + op->reg); 16266 } else if (op->reg == -1 && op->reg2 == -1) { 16267 /* displacement only */ 16268 g(0x05 + (reg << 3)); 16269 gen_expr32(&op->e); 16270 } else { 16271 sib_reg1 = op->reg; 16272 /* fist compute displacement encoding */ 16273 if (sib_reg1 == -1) { 16274 sib_reg1 = 5; 16275 mod = 0x00; 16276 } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) { 16277 mod = 0x00; 16278 } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) { 16279 mod = 0x40; 16280 } else { 16281 mod = 0x80; 16282 } 16283 /* compute if sib byte needed */ 16284 reg1 = op->reg; 16285 if (op->reg2 != -1) 16286 reg1 = 4; 16287 g(mod + (reg << 3) + reg1); 16288 if (reg1 == 4) { 16289 /* add sib byte */ 16290 reg2 = op->reg2; 16291 if (reg2 == -1) 16292 reg2 = 4; /* indicate no index */ 16293 g((op->shift << 6) + (reg2 << 3) + sib_reg1); 16294 } 16295 16296 /* add offset */ 16297 if (mod == 0x40) { 16298 g(op->e.v); 16299 } else if (mod == 0x80 || op->reg == -1) { 16300 gen_expr32(&op->e); 16301 } 16302 } 16303 } 16304 16305 static void asm_opcode(TCCState *s1, int opcode) 16306 { 16307 const ASMInstr *pa; 16308 int i, modrm_index, reg, v, op1, is_short_jmp; 16309 int nb_ops, s, ss; 16310 Operand ops[MAX_OPERANDS], *pop; 16311 int op_type[3]; /* decoded op type */ 16312 16313 /* get operands */ 16314 pop = ops; 16315 nb_ops = 0; 16316 for(;;) { 16317 if (tok == ';' || tok == TOK_LINEFEED) 16318 break; 16319 if (nb_ops >= MAX_OPERANDS) { 16320 error("incorrect number of operands"); 16321 } 16322 parse_operand(s1, pop); 16323 pop++; 16324 nb_ops++; 16325 if (tok != ',') 16326 break; 16327 next(); 16328 } 16329 16330 is_short_jmp = 0; 16331 s = 0; /* avoid warning */ 16332 16333 /* optimize matching by using a lookup table (no hashing is needed 16334 !) */ 16335 for(pa = asm_instrs; pa->sym != 0; pa++) { 16336 s = 0; 16337 if (pa->instr_type & OPC_FARITH) { 16338 v = opcode - pa->sym; 16339 if (!((unsigned)v < 8 * 6 && (v % 6) == 0)) 16340 continue; 16341 } else if (pa->instr_type & OPC_ARITH) { 16342 if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4)) 16343 continue; 16344 goto compute_size; 16345 } else if (pa->instr_type & OPC_SHIFT) { 16346 if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4)) 16347 continue; 16348 goto compute_size; 16349 } else if (pa->instr_type & OPC_TEST) { 16350 if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) 16351 continue; 16352 } else if (pa->instr_type & OPC_B) { 16353 if (!(opcode >= pa->sym && opcode <= pa->sym + 3)) 16354 continue; 16355 compute_size: 16356 s = (opcode - pa->sym) & 3; 16357 } else if (pa->instr_type & OPC_WL) { 16358 if (!(opcode >= pa->sym && opcode <= pa->sym + 2)) 16359 continue; 16360 s = opcode - pa->sym + 1; 16361 } else { 16362 if (pa->sym != opcode) 16363 continue; 16364 } 16365 if (pa->nb_ops != nb_ops) 16366 continue; 16367 /* now decode and check each operand */ 16368 for(i = 0; i < nb_ops; i++) { 16369 int op1, op2; 16370 op1 = pa->op_type[i]; 16371 op2 = op1 & 0x1f; 16372 switch(op2) { 16373 case OPT_IM: 16374 v = OP_IM8 | OP_IM16 | OP_IM32; 16375 break; 16376 case OPT_REG: 16377 v = OP_REG8 | OP_REG16 | OP_REG32; 16378 break; 16379 case OPT_REGW: 16380 v = OP_REG16 | OP_REG32; 16381 break; 16382 case OPT_IMW: 16383 v = OP_IM16 | OP_IM32; 16384 break; 16385 default: 16386 v = 1 << op2; 16387 break; 16388 } 16389 if (op1 & OPT_EA) 16390 v |= OP_EA; 16391 op_type[i] = v; 16392 if ((ops[i].type & v) == 0) 16393 goto next; 16394 } 16395 /* all is matching ! */ 16396 break; 16397 next: ; 16398 } 16399 if (pa->sym == 0) { 16400 if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) { 16401 int b; 16402 b = op0_codes[opcode - TOK_ASM_pusha]; 16403 if (b & 0xff00) 16404 g(b >> 8); 16405 g(b); 16406 return; 16407 } else { 16408 error("unknown opcode '%s'", 16409 get_tok_str(opcode, NULL)); 16410 } 16411 } 16412 /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */ 16413 if (s == 3) { 16414 for(i = 0; s == 3 && i < nb_ops; i++) { 16415 if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX))) 16416 s = reg_to_size[ops[i].type & OP_REG]; 16417 } 16418 if (s == 3) { 16419 if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && 16420 (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32))) 16421 s = 2; 16422 else 16423 error("cannot infer opcode suffix"); 16424 } 16425 } 16426 16427 /* generate data16 prefix if needed */ 16428 ss = s; 16429 if (s == 1 || (pa->instr_type & OPC_D16)) 16430 g(WORD_PREFIX_OPCODE); 16431 else if (s == 2) 16432 s = 1; 16433 /* now generates the operation */ 16434 if (pa->instr_type & OPC_FWAIT) 16435 g(0x9b); 16436 16437 v = pa->opcode; 16438 if (v == 0x69 || v == 0x69) { 16439 /* kludge for imul $im, %reg */ 16440 nb_ops = 3; 16441 ops[2] = ops[1]; 16442 } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) { 16443 v--; /* int $3 case */ 16444 nb_ops = 0; 16445 } else if ((v == 0x06 || v == 0x07)) { 16446 if (ops[0].reg >= 4) { 16447 /* push/pop %fs or %gs */ 16448 v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3); 16449 } else { 16450 v += ops[0].reg << 3; 16451 } 16452 nb_ops = 0; 16453 } else if (v <= 0x05) { 16454 /* arith case */ 16455 v += ((opcode - TOK_ASM_addb) >> 2) << 3; 16456 } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) { 16457 /* fpu arith case */ 16458 v += ((opcode - pa->sym) / 6) << 3; 16459 } 16460 if (pa->instr_type & OPC_REG) { 16461 for(i = 0; i < nb_ops; i++) { 16462 if (op_type[i] & (OP_REG | OP_ST)) { 16463 v += ops[i].reg; 16464 break; 16465 } 16466 } 16467 /* mov $im, %reg case */ 16468 if (pa->opcode == 0xb0 && s >= 1) 16469 v += 7; 16470 } 16471 if (pa->instr_type & OPC_B) 16472 v += s; 16473 if (pa->instr_type & OPC_TEST) 16474 v += test_bits[opcode - pa->sym]; 16475 if (pa->instr_type & OPC_SHORTJMP) { 16476 Sym *sym; 16477 int jmp_disp; 16478 16479 /* see if we can really generate the jump with a byte offset */ 16480 sym = ops[0].e.sym; 16481 if (!sym) 16482 goto no_short_jump; 16483 if (sym->r != cur_text_section->sh_num) 16484 goto no_short_jump; 16485 jmp_disp = ops[0].e.v + (long)sym->next - ind - 2; 16486 if (jmp_disp == (int8_t)jmp_disp) { 16487 /* OK to generate jump */ 16488 is_short_jmp = 1; 16489 ops[0].e.v = jmp_disp; 16490 } else { 16491 no_short_jump: 16492 if (pa->instr_type & OPC_JMP) { 16493 /* long jump will be allowed. need to modify the 16494 opcode slightly */ 16495 if (v == 0xeb) 16496 v = 0xe9; 16497 else 16498 v += 0x0f10; 16499 } else { 16500 error("invalid displacement"); 16501 } 16502 } 16503 } 16504 op1 = v >> 8; 16505 if (op1) 16506 g(op1); 16507 g(v); 16508 16509 /* search which operand will used for modrm */ 16510 modrm_index = 0; 16511 if (pa->instr_type & OPC_SHIFT) { 16512 reg = (opcode - pa->sym) >> 2; 16513 if (reg == 6) 16514 reg = 7; 16515 } else if (pa->instr_type & OPC_ARITH) { 16516 reg = (opcode - pa->sym) >> 2; 16517 } else if (pa->instr_type & OPC_FARITH) { 16518 reg = (opcode - pa->sym) / 6; 16519 } else { 16520 reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7; 16521 } 16522 if (pa->instr_type & OPC_MODRM) { 16523 /* first look for an ea operand */ 16524 for(i = 0;i < nb_ops; i++) { 16525 if (op_type[i] & OP_EA) 16526 goto modrm_found; 16527 } 16528 /* then if not found, a register or indirection (shift instructions) */ 16529 for(i = 0;i < nb_ops; i++) { 16530 if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR)) 16531 goto modrm_found; 16532 } 16533 #ifdef ASM_DEBUG 16534 error("bad op table"); 16535 #endif 16536 modrm_found: 16537 modrm_index = i; 16538 /* if a register is used in another operand then it is 16539 used instead of group */ 16540 for(i = 0;i < nb_ops; i++) { 16541 v = op_type[i]; 16542 if (i != modrm_index && 16543 (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) { 16544 reg = ops[i].reg; 16545 break; 16546 } 16547 } 16548 16549 asm_modrm(reg, &ops[modrm_index]); 16550 } 16551 16552 /* emit constants */ 16553 if (pa->opcode == 0x9a || pa->opcode == 0xea) { 16554 /* ljmp or lcall kludge */ 16555 gen_expr32(&ops[1].e); 16556 if (ops[0].e.sym) 16557 error("cannot relocate"); 16558 gen_le16(ops[0].e.v); 16559 } else { 16560 for(i = 0;i < nb_ops; i++) { 16561 v = op_type[i]; 16562 if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) { 16563 /* if multiple sizes are given it means we must look 16564 at the op size */ 16565 if (v == (OP_IM8 | OP_IM16 | OP_IM32) || 16566 v == (OP_IM16 | OP_IM32)) { 16567 if (ss == 0) 16568 v = OP_IM8; 16569 else if (ss == 1) 16570 v = OP_IM16; 16571 else 16572 v = OP_IM32; 16573 } 16574 if (v & (OP_IM8 | OP_IM8S)) { 16575 if (ops[i].e.sym) 16576 goto error_relocate; 16577 g(ops[i].e.v); 16578 } else if (v & OP_IM16) { 16579 if (ops[i].e.sym) { 16580 error_relocate: 16581 error("cannot relocate"); 16582 } 16583 gen_le16(ops[i].e.v); 16584 } else { 16585 if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) { 16586 if (is_short_jmp) 16587 g(ops[i].e.v); 16588 else 16589 gen_disp32(&ops[i].e); 16590 } else { 16591 gen_expr32(&ops[i].e); 16592 } 16593 } 16594 } 16595 } 16596 } 16597 } 16598 16599 #define NB_SAVED_REGS 3 16600 #define NB_ASM_REGS 8 16601 16602 /* return the constraint priority (we allocate first the lowest 16603 numbered constraints) */ 16604 static inline int constraint_priority(const char *str) 16605 { 16606 int priority, c, pr; 16607 16608 /* we take the lowest priority */ 16609 priority = 0; 16610 for(;;) { 16611 c = *str; 16612 if (c == '\0') 16613 break; 16614 str++; 16615 switch(c) { 16616 case 'A': 16617 pr = 0; 16618 break; 16619 case 'a': 16620 case 'b': 16621 case 'c': 16622 case 'd': 16623 case 'S': 16624 case 'D': 16625 pr = 1; 16626 break; 16627 case 'q': 16628 pr = 2; 16629 break; 16630 case 'r': 16631 pr = 3; 16632 break; 16633 case 'N': 16634 case 'M': 16635 case 'I': 16636 case 'i': 16637 case 'm': 16638 case 'g': 16639 pr = 4; 16640 break; 16641 default: 16642 error("unknown constraint '%c'", c); 16643 pr = 0; 16644 } 16645 if (pr > priority) 16646 priority = pr; 16647 } 16648 return priority; 16649 } 16650 16651 static const char *skip_constraint_modifiers(const char *p) 16652 { 16653 while (*p == '=' || *p == '&' || *p == '+' || *p == '%') 16654 p++; 16655 return p; 16656 } 16657 16658 #define REG_OUT_MASK 0x01 16659 #define REG_IN_MASK 0x02 16660 16661 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) 16662 16663 static void asm_compute_constraints(ASMOperand *operands, 16664 int nb_operands, int nb_outputs, 16665 const uint8_t *clobber_regs, 16666 int *pout_reg) 16667 { 16668 ASMOperand *op; 16669 int sorted_op[MAX_ASM_OPERANDS]; 16670 int i, j, k, p1, p2, tmp, reg, c, reg_mask; 16671 const char *str; 16672 uint8_t regs_allocated[NB_ASM_REGS]; 16673 16674 /* init fields */ 16675 for(i=0;i<nb_operands;i++) { 16676 op = &operands[i]; 16677 op->input_index = -1; 16678 op->ref_index = -1; 16679 op->reg = -1; 16680 op->is_memory = 0; 16681 op->is_rw = 0; 16682 } 16683 /* compute constraint priority and evaluate references to output 16684 constraints if input constraints */ 16685 for(i=0;i<nb_operands;i++) { 16686 op = &operands[i]; 16687 str = op->constraint; 16688 str = skip_constraint_modifiers(str); 16689 if (isnum(*str) || *str == '[') { 16690 /* this is a reference to another constraint */ 16691 k = find_constraint(operands, nb_operands, str, NULL); 16692 if ((unsigned)k >= i || i < nb_outputs) 16693 error("invalid reference in constraint %d ('%s')", 16694 i, str); 16695 op->ref_index = k; 16696 if (operands[k].input_index >= 0) 16697 error("cannot reference twice the same operand"); 16698 operands[k].input_index = i; 16699 op->priority = 5; 16700 } else { 16701 op->priority = constraint_priority(str); 16702 } 16703 } 16704 16705 /* sort operands according to their priority */ 16706 for(i=0;i<nb_operands;i++) 16707 sorted_op[i] = i; 16708 for(i=0;i<nb_operands - 1;i++) { 16709 for(j=i+1;j<nb_operands;j++) { 16710 p1 = operands[sorted_op[i]].priority; 16711 p2 = operands[sorted_op[j]].priority; 16712 if (p2 < p1) { 16713 tmp = sorted_op[i]; 16714 sorted_op[i] = sorted_op[j]; 16715 sorted_op[j] = tmp; 16716 } 16717 } 16718 } 16719 16720 for(i = 0;i < NB_ASM_REGS; i++) { 16721 if (clobber_regs[i]) 16722 regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK; 16723 else 16724 regs_allocated[i] = 0; 16725 } 16726 /* esp cannot be used */ 16727 regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK; 16728 /* ebp cannot be used yet */ 16729 regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK; 16730 16731 /* allocate registers and generate corresponding asm moves */ 16732 for(i=0;i<nb_operands;i++) { 16733 j = sorted_op[i]; 16734 op = &operands[j]; 16735 str = op->constraint; 16736 /* no need to allocate references */ 16737 if (op->ref_index >= 0) 16738 continue; 16739 /* select if register is used for output, input or both */ 16740 if (op->input_index >= 0) { 16741 reg_mask = REG_IN_MASK | REG_OUT_MASK; 16742 } else if (j < nb_outputs) { 16743 reg_mask = REG_OUT_MASK; 16744 } else { 16745 reg_mask = REG_IN_MASK; 16746 } 16747 try_next: 16748 c = *str++; 16749 switch(c) { 16750 case '=': 16751 goto try_next; 16752 case '+': 16753 op->is_rw = 1; 16754 /* FALL THRU */ 16755 case '&': 16756 if (j >= nb_outputs) 16757 error("'%c' modifier can only be applied to outputs", c); 16758 reg_mask = REG_IN_MASK | REG_OUT_MASK; 16759 goto try_next; 16760 case 'A': 16761 /* allocate both eax and edx */ 16762 if (is_reg_allocated(TREG_EAX) || 16763 is_reg_allocated(TREG_EDX)) 16764 goto try_next; 16765 op->is_llong = 1; 16766 op->reg = TREG_EAX; 16767 regs_allocated[TREG_EAX] |= reg_mask; 16768 regs_allocated[TREG_EDX] |= reg_mask; 16769 break; 16770 case 'a': 16771 reg = TREG_EAX; 16772 goto alloc_reg; 16773 case 'b': 16774 reg = 3; 16775 goto alloc_reg; 16776 case 'c': 16777 reg = TREG_ECX; 16778 goto alloc_reg; 16779 case 'd': 16780 reg = TREG_EDX; 16781 goto alloc_reg; 16782 case 'S': 16783 reg = 6; 16784 goto alloc_reg; 16785 case 'D': 16786 reg = 7; 16787 alloc_reg: 16788 if (is_reg_allocated(reg)) 16789 goto try_next; 16790 goto reg_found; 16791 case 'q': 16792 /* eax, ebx, ecx or edx */ 16793 for(reg = 0; reg < 4; reg++) { 16794 if (!is_reg_allocated(reg)) 16795 goto reg_found; 16796 } 16797 goto try_next; 16798 case 'r': 16799 /* any general register */ 16800 for(reg = 0; reg < 8; reg++) { 16801 if (!is_reg_allocated(reg)) 16802 goto reg_found; 16803 } 16804 goto try_next; 16805 reg_found: 16806 /* now we can reload in the register */ 16807 op->is_llong = 0; 16808 op->reg = reg; 16809 regs_allocated[reg] |= reg_mask; 16810 break; 16811 case 'i': 16812 if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST)) 16813 goto try_next; 16814 break; 16815 case 'I': 16816 case 'N': 16817 case 'M': 16818 if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST)) 16819 goto try_next; 16820 break; 16821 case 'm': 16822 case 'g': 16823 /* nothing special to do because the operand is already in 16824 memory, except if the pointer itself is stored in a 16825 memory variable (VT_LLOCAL case) */ 16826 /* XXX: fix constant case */ 16827 /* if it is a reference to a memory zone, it must lie 16828 in a register, so we reserve the register in the 16829 input registers and a load will be generated 16830 later */ 16831 if (j < nb_outputs || c == 'm') { 16832 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) { 16833 /* any general register */ 16834 for(reg = 0; reg < 8; reg++) { 16835 if (!(regs_allocated[reg] & REG_IN_MASK)) 16836 goto reg_found1; 16837 } 16838 goto try_next; 16839 reg_found1: 16840 /* now we can reload in the register */ 16841 regs_allocated[reg] |= REG_IN_MASK; 16842 op->reg = reg; 16843 op->is_memory = 1; 16844 } 16845 } 16846 break; 16847 default: 16848 error("asm constraint %d ('%s') could not be satisfied", 16849 j, op->constraint); 16850 break; 16851 } 16852 /* if a reference is present for that operand, we assign it too */ 16853 if (op->input_index >= 0) { 16854 operands[op->input_index].reg = op->reg; 16855 operands[op->input_index].is_llong = op->is_llong; 16856 } 16857 } 16858 16859 /* compute out_reg. It is used to store outputs registers to memory 16860 locations references by pointers (VT_LLOCAL case) */ 16861 *pout_reg = -1; 16862 for(i=0;i<nb_operands;i++) { 16863 op = &operands[i]; 16864 if (op->reg >= 0 && 16865 (op->vt->r & VT_VALMASK) == VT_LLOCAL && 16866 !op->is_memory) { 16867 for(reg = 0; reg < 8; reg++) { 16868 if (!(regs_allocated[reg] & REG_OUT_MASK)) 16869 goto reg_found2; 16870 } 16871 error("could not find free output register for reloading"); 16872 reg_found2: 16873 *pout_reg = reg; 16874 break; 16875 } 16876 } 16877 16878 /* print sorted constraints */ 16879 #ifdef ASM_DEBUG 16880 for(i=0;i<nb_operands;i++) { 16881 j = sorted_op[i]; 16882 op = &operands[j]; 16883 printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", 16884 j, 16885 op->id ? get_tok_str(op->id, NULL) : "", 16886 op->constraint, 16887 op->vt->r, 16888 op->reg); 16889 } 16890 if (*pout_reg >= 0) 16891 printf("out_reg=%d\n", *pout_reg); 16892 #endif 16893 } 16894 16895 static void subst_asm_operand(CString *add_str, 16896 SValue *sv, int modifier) 16897 { 16898 int r, reg, size, val; 16899 char buf[64]; 16900 16901 r = sv->r; 16902 if ((r & VT_VALMASK) == VT_CONST) { 16903 if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n') 16904 cstr_ccat(add_str, '$'); 16905 if (r & VT_SYM) { 16906 cstr_cat(add_str, get_tok_str(sv->sym->v, NULL)); 16907 if (sv->c.i != 0) { 16908 cstr_ccat(add_str, '+'); 16909 } else { 16910 return; 16911 } 16912 } 16913 val = sv->c.i; 16914 if (modifier == 'n') 16915 val = -val; 16916 snprintf(buf, sizeof(buf), "%d", sv->c.i); 16917 cstr_cat(add_str, buf); 16918 } else if ((r & VT_VALMASK) == VT_LOCAL) { 16919 snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i); 16920 cstr_cat(add_str, buf); 16921 } else if (r & VT_LVAL) { 16922 reg = r & VT_VALMASK; 16923 if (reg >= VT_CONST) 16924 error("internal compiler error"); 16925 snprintf(buf, sizeof(buf), "(%%%s)", 16926 get_tok_str(TOK_ASM_eax + reg, NULL)); 16927 cstr_cat(add_str, buf); 16928 } else { 16929 /* register case */ 16930 reg = r & VT_VALMASK; 16931 if (reg >= VT_CONST) 16932 error("internal compiler error"); 16933 16934 /* choose register operand size */ 16935 if ((sv->type.t & VT_BTYPE) == VT_BYTE) 16936 size = 1; 16937 else if ((sv->type.t & VT_BTYPE) == VT_SHORT) 16938 size = 2; 16939 else 16940 size = 4; 16941 if (size == 1 && reg >= 4) 16942 size = 4; 16943 16944 if (modifier == 'b') { 16945 if (reg >= 4) 16946 error("cannot use byte register"); 16947 size = 1; 16948 } else if (modifier == 'h') { 16949 if (reg >= 4) 16950 error("cannot use byte register"); 16951 size = -1; 16952 } else if (modifier == 'w') { 16953 size = 2; 16954 } 16955 16956 switch(size) { 16957 case -1: 16958 reg = TOK_ASM_ah + reg; 16959 break; 16960 case 1: 16961 reg = TOK_ASM_al + reg; 16962 break; 16963 case 2: 16964 reg = TOK_ASM_ax + reg; 16965 break; 16966 default: 16967 reg = TOK_ASM_eax + reg; 16968 break; 16969 } 16970 snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL)); 16971 cstr_cat(add_str, buf); 16972 } 16973 } 16974 16975 /* generate prolog and epilog code for asm statement */ 16976 static void asm_gen_code(ASMOperand *operands, int nb_operands, 16977 int nb_outputs, int is_output, 16978 uint8_t *clobber_regs, 16979 int out_reg) 16980 { 16981 uint8_t regs_allocated[NB_ASM_REGS]; 16982 ASMOperand *op; 16983 int i, reg; 16984 static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 }; 16985 16986 /* mark all used registers */ 16987 memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated)); 16988 for(i = 0; i < nb_operands;i++) { 16989 op = &operands[i]; 16990 if (op->reg >= 0) 16991 regs_allocated[op->reg] = 1; 16992 } 16993 if (!is_output) { 16994 /* generate reg save code */ 16995 for(i = 0; i < NB_SAVED_REGS; i++) { 16996 reg = reg_saved[i]; 16997 if (regs_allocated[reg]) 16998 g(0x50 + reg); 16999 } 17000 17001 /* generate load code */ 17002 for(i = 0; i < nb_operands; i++) { 17003 op = &operands[i]; 17004 if (op->reg >= 0) { 17005 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && 17006 op->is_memory) { 17007 /* memory reference case (for both input and 17008 output cases) */ 17009 SValue sv; 17010 sv = *op->vt; 17011 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; 17012 load(op->reg, &sv); 17013 } else if (i >= nb_outputs || op->is_rw) { 17014 /* load value in register */ 17015 load(op->reg, op->vt); 17016 if (op->is_llong) { 17017 SValue sv; 17018 sv = *op->vt; 17019 sv.c.ul += 4; 17020 load(TREG_EDX, &sv); 17021 } 17022 } 17023 } 17024 } 17025 } else { 17026 /* generate save code */ 17027 for(i = 0 ; i < nb_outputs; i++) { 17028 op = &operands[i]; 17029 if (op->reg >= 0) { 17030 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) { 17031 if (!op->is_memory) { 17032 SValue sv; 17033 sv = *op->vt; 17034 sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL; 17035 load(out_reg, &sv); 17036 17037 sv.r = (sv.r & ~VT_VALMASK) | out_reg; 17038 store(op->reg, &sv); 17039 } 17040 } else { 17041 store(op->reg, op->vt); 17042 if (op->is_llong) { 17043 SValue sv; 17044 sv = *op->vt; 17045 sv.c.ul += 4; 17046 store(TREG_EDX, &sv); 17047 } 17048 } 17049 } 17050 } 17051 /* generate reg restore code */ 17052 for(i = NB_SAVED_REGS - 1; i >= 0; i--) { 17053 reg = reg_saved[i]; 17054 if (regs_allocated[reg]) 17055 g(0x58 + reg); 17056 } 17057 } 17058 } 17059 17060 static void asm_clobber(uint8_t *clobber_regs, const char *str) 17061 { 17062 int reg; 17063 TokenSym *ts; 17064 17065 if (!strcmp(str, "memory") || 17066 !strcmp(str, "cc")) 17067 return; 17068 ts = tok_alloc(str, strlen(str)); 17069 reg = ts->tok; 17070 if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) { 17071 reg -= TOK_ASM_eax; 17072 } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) { 17073 reg -= TOK_ASM_ax; 17074 } else { 17075 error("invalid clobber register '%s'", str); 17076 } 17077 clobber_regs[reg] = 1; 17078 } 17079 //--------------------------------------------------------------------------- 17080 #endif 17081 // njn: inlined tccasm.c 17082 //#include "tccasm.c" 17083 //--------------------------------------------------------------------------- 17084 /* 17085 * GAS like assembler for TCC 17086 * 17087 * Copyright (c) 2001-2004 Fabrice Bellard 17088 * 17089 * This library is free software; you can redistribute it and/or 17090 * modify it under the terms of the GNU Lesser General Public 17091 * License as published by the Free Software Foundation; either 17092 * version 2 of the License, or (at your option) any later version. 17093 * 17094 * This library is distributed in the hope that it will be useful, 17095 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17096 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17097 * Lesser General Public License for more details. 17098 * 17099 * You should have received a copy of the GNU Lesser General Public 17100 * License along with this library; if not, write to the Free Software 17101 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17102 */ 17103 17104 static int asm_get_local_label_name(TCCState *s1, unsigned int n) 17105 { 17106 char buf[64]; 17107 TokenSym *ts; 17108 17109 snprintf(buf, sizeof(buf), "L..%u", n); 17110 ts = tok_alloc(buf, strlen(buf)); 17111 return ts->tok; 17112 } 17113 17114 static void asm_expr(TCCState *s1, ExprValue *pe); 17115 17116 /* We do not use the C expression parser to handle symbols. Maybe the 17117 C expression parser could be tweaked to do so. */ 17118 17119 static void asm_expr_unary(TCCState *s1, ExprValue *pe) 17120 { 17121 Sym *sym; 17122 int op, n, label; 17123 const char *p; 17124 17125 switch(tok) { 17126 case TOK_PPNUM: 17127 p = tokc.cstr->data; 17128 n = strtoul(p, (char **)&p, 0); 17129 if (*p == 'b' || *p == 'f') { 17130 /* backward or forward label */ 17131 label = asm_get_local_label_name(s1, n); 17132 sym = label_find(label); 17133 if (*p == 'b') { 17134 /* backward : find the last corresponding defined label */ 17135 if (sym && sym->r == 0) 17136 sym = sym->prev_tok; 17137 if (!sym) 17138 error("local label '%d' not found backward", n); 17139 } else { 17140 /* forward */ 17141 if (!sym || sym->r) { 17142 /* if the last label is defined, then define a new one */ 17143 sym = label_push(&s1->asm_labels, label, 0); 17144 sym->type.t = VT_STATIC | VT_VOID; 17145 } 17146 } 17147 pe->v = 0; 17148 pe->sym = sym; 17149 } else if (*p == '\0') { 17150 pe->v = n; 17151 pe->sym = NULL; 17152 } else { 17153 error("invalid number syntax"); 17154 } 17155 next(); 17156 break; 17157 case '+': 17158 next(); 17159 asm_expr_unary(s1, pe); 17160 break; 17161 case '-': 17162 case '~': 17163 op = tok; 17164 next(); 17165 asm_expr_unary(s1, pe); 17166 if (pe->sym) 17167 error("invalid operation with label"); 17168 if (op == '-') 17169 pe->v = -pe->v; 17170 else 17171 pe->v = ~pe->v; 17172 break; 17173 case TOK_CCHAR: 17174 case TOK_LCHAR: 17175 pe->v = tokc.i; 17176 pe->sym = NULL; 17177 next(); 17178 break; 17179 case '(': 17180 next(); 17181 asm_expr(s1, pe); 17182 skip(')'); 17183 break; 17184 default: 17185 if (tok >= TOK_IDENT) { 17186 /* label case : if the label was not found, add one */ 17187 sym = label_find(tok); 17188 if (!sym) { 17189 sym = label_push(&s1->asm_labels, tok, 0); 17190 /* NOTE: by default, the symbol is global */ 17191 sym->type.t = VT_VOID; 17192 } 17193 if (sym->r == SHN_ABS) { 17194 /* if absolute symbol, no need to put a symbol value */ 17195 pe->v = (long)sym->next; 17196 pe->sym = NULL; 17197 } else { 17198 pe->v = 0; 17199 pe->sym = sym; 17200 } 17201 next(); 17202 } else { 17203 error("bad expression syntax [%s]", get_tok_str(tok, &tokc)); 17204 } 17205 break; 17206 } 17207 } 17208 17209 static void asm_expr_prod(TCCState *s1, ExprValue *pe) 17210 { 17211 int op; 17212 ExprValue e2; 17213 17214 asm_expr_unary(s1, pe); 17215 for(;;) { 17216 op = tok; 17217 if (op != '*' && op != '/' && op != '%' && 17218 op != TOK_SHL && op != TOK_SAR) 17219 break; 17220 next(); 17221 asm_expr_unary(s1, &e2); 17222 if (pe->sym || e2.sym) 17223 error("invalid operation with label"); 17224 switch(op) { 17225 case '*': 17226 pe->v *= e2.v; 17227 break; 17228 case '/': 17229 if (e2.v == 0) { 17230 div_error: 17231 error("division by zero"); 17232 } 17233 pe->v /= e2.v; 17234 break; 17235 case '%': 17236 if (e2.v == 0) 17237 goto div_error; 17238 pe->v %= e2.v; 17239 break; 17240 case TOK_SHL: 17241 pe->v <<= e2.v; 17242 break; 17243 default: 17244 case TOK_SAR: 17245 pe->v >>= e2.v; 17246 break; 17247 } 17248 } 17249 } 17250 17251 static void asm_expr_logic(TCCState *s1, ExprValue *pe) 17252 { 17253 int op; 17254 ExprValue e2; 17255 17256 asm_expr_prod(s1, pe); 17257 for(;;) { 17258 op = tok; 17259 if (op != '&' && op != '|' && op != '^') 17260 break; 17261 next(); 17262 asm_expr_prod(s1, &e2); 17263 if (pe->sym || e2.sym) 17264 error("invalid operation with label"); 17265 switch(op) { 17266 case '&': 17267 pe->v &= e2.v; 17268 break; 17269 case '|': 17270 pe->v |= e2.v; 17271 break; 17272 default: 17273 case '^': 17274 pe->v ^= e2.v; 17275 break; 17276 } 17277 } 17278 } 17279 17280 static inline void asm_expr_sum(TCCState *s1, ExprValue *pe) 17281 { 17282 int op; 17283 ExprValue e2; 17284 17285 asm_expr_logic(s1, pe); 17286 for(;;) { 17287 op = tok; 17288 if (op != '+' && op != '-') 17289 break; 17290 next(); 17291 asm_expr_logic(s1, &e2); 17292 if (op == '+') { 17293 if (pe->sym != NULL && e2.sym != NULL) 17294 goto cannot_relocate; 17295 pe->v += e2.v; 17296 if (pe->sym == NULL && e2.sym != NULL) 17297 pe->sym = e2.sym; 17298 } else { 17299 pe->v -= e2.v; 17300 /* NOTE: we are less powerful than gas in that case 17301 because we store only one symbol in the expression */ 17302 if (!pe->sym && !e2.sym) { 17303 /* OK */ 17304 } else if (pe->sym && !e2.sym) { 17305 /* OK */ 17306 } else if (pe->sym && e2.sym) { 17307 if (pe->sym == e2.sym) { 17308 /* OK */ 17309 } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) { 17310 /* we also accept defined symbols in the same section */ 17311 pe->v += (long)pe->sym->next - (long)e2.sym->next; 17312 } else { 17313 goto cannot_relocate; 17314 } 17315 pe->sym = NULL; /* same symbols can be substracted to NULL */ 17316 } else { 17317 cannot_relocate: 17318 error("invalid operation with label"); 17319 } 17320 } 17321 } 17322 } 17323 17324 static void asm_expr(TCCState *s1, ExprValue *pe) 17325 { 17326 asm_expr_sum(s1, pe); 17327 } 17328 17329 static int asm_int_expr(TCCState *s1) 17330 { 17331 ExprValue e; 17332 asm_expr(s1, &e); 17333 if (e.sym) 17334 expect("constant"); 17335 return e.v; 17336 } 17337 17338 /* NOTE: the same name space as C labels is used to avoid using too 17339 much memory when storing labels in TokenStrings */ 17340 static void asm_new_label1(TCCState *s1, int label, int is_local, 17341 int sh_num, long value) 17342 { 17343 Sym *sym; 17344 17345 sym = label_find(label); 17346 if (sym) { 17347 if (sym->r) { 17348 /* the label is already defined */ 17349 if (!is_local) { 17350 error("assembler label '%s' already defined", 17351 get_tok_str(label, NULL)); 17352 } else { 17353 /* redefinition of local labels is possible */ 17354 goto new_label; 17355 } 17356 } 17357 } else { 17358 new_label: 17359 sym = label_push(&s1->asm_labels, label, 0); 17360 sym->type.t = VT_STATIC | VT_VOID; 17361 } 17362 sym->r = sh_num; 17363 sym->next = (void *)value; 17364 } 17365 17366 static void asm_new_label(TCCState *s1, int label, int is_local) 17367 { 17368 asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind); 17369 } 17370 17371 static void asm_free_labels(TCCState *st) 17372 { 17373 Sym *s, *s1; 17374 Section *sec; 17375 17376 for(s = st->asm_labels; s != NULL; s = s1) { 17377 s1 = s->prev; 17378 /* define symbol value in object file */ 17379 if (s->r) { 17380 if (s->r == SHN_ABS) 17381 sec = SECTION_ABS; 17382 else 17383 sec = st->sections[s->r]; 17384 put_extern_sym2(s, sec, (long)s->next, 0, 0); 17385 } 17386 /* remove label */ 17387 table_ident[s->v - TOK_IDENT]->sym_label = NULL; 17388 sym_free(s); 17389 } 17390 st->asm_labels = NULL; 17391 } 17392 17393 static void use_section1(TCCState *s1, Section *sec) 17394 { 17395 cur_text_section->data_offset = ind; 17396 cur_text_section = sec; 17397 ind = cur_text_section->data_offset; 17398 } 17399 17400 static void use_section(TCCState *s1, const char *name) 17401 { 17402 Section *sec; 17403 sec = find_section(s1, name); 17404 use_section1(s1, sec); 17405 } 17406 17407 static void asm_parse_directive(TCCState *s1) 17408 { 17409 int n, offset, v, size, tok1; 17410 Section *sec; 17411 uint8_t *ptr; 17412 17413 /* assembler directive */ 17414 next(); 17415 sec = cur_text_section; 17416 switch(tok) { 17417 case TOK_ASM_align: 17418 case TOK_ASM_skip: 17419 case TOK_ASM_space: 17420 tok1 = tok; 17421 next(); 17422 n = asm_int_expr(s1); 17423 if (tok1 == TOK_ASM_align) { 17424 if (n < 0 || (n & (n-1)) != 0) 17425 error("alignment must be a positive power of two"); 17426 offset = (ind + n - 1) & -n; 17427 size = offset - ind; 17428 /* the section must have a compatible alignment */ 17429 if (sec->sh_addralign < n) 17430 sec->sh_addralign = n; 17431 } else { 17432 size = n; 17433 } 17434 v = 0; 17435 if (tok == ',') { 17436 next(); 17437 v = asm_int_expr(s1); 17438 } 17439 zero_pad: 17440 if (sec->sh_type != SHT_NOBITS) { 17441 sec->data_offset = ind; 17442 ptr = section_ptr_add(sec, size); 17443 memset(ptr, v, size); 17444 } 17445 ind += size; 17446 break; 17447 case TOK_ASM_quad: 17448 next(); 17449 for(;;) { 17450 uint64_t vl; 17451 const char *p; 17452 17453 p = tokc.cstr->data; 17454 if (tok != TOK_PPNUM) { 17455 error_constant: 17456 error("64 bit constant"); 17457 } 17458 vl = strtoll(p, (char **)&p, 0); 17459 if (*p != '\0') 17460 goto error_constant; 17461 next(); 17462 if (sec->sh_type != SHT_NOBITS) { 17463 /* XXX: endianness */ 17464 gen_le32(vl); 17465 gen_le32(vl >> 32); 17466 } else { 17467 ind += 8; 17468 } 17469 if (tok != ',') 17470 break; 17471 next(); 17472 } 17473 break; 17474 case TOK_ASM_byte: 17475 size = 1; 17476 goto asm_data; 17477 case TOK_ASM_word: 17478 case TOK_SHORT: 17479 size = 2; 17480 goto asm_data; 17481 case TOK_LONG: 17482 case TOK_INT: 17483 size = 4; 17484 asm_data: 17485 next(); 17486 for(;;) { 17487 ExprValue e; 17488 asm_expr(s1, &e); 17489 if (sec->sh_type != SHT_NOBITS) { 17490 if (size == 4) { 17491 gen_expr32(&e); 17492 } else { 17493 if (e.sym) 17494 expect("constant"); 17495 if (size == 1) 17496 g(e.v); 17497 else 17498 gen_le16(e.v); 17499 } 17500 } else { 17501 ind += size; 17502 } 17503 if (tok != ',') 17504 break; 17505 next(); 17506 } 17507 break; 17508 case TOK_ASM_fill: 17509 { 17510 int repeat, size, val, i, j; 17511 uint8_t repeat_buf[8]; 17512 next(); 17513 repeat = asm_int_expr(s1); 17514 if (repeat < 0) { 17515 error("repeat < 0; .fill ignored"); 17516 break; 17517 } 17518 size = 1; 17519 val = 0; 17520 if (tok == ',') { 17521 next(); 17522 size = asm_int_expr(s1); 17523 if (size < 0) { 17524 error("size < 0; .fill ignored"); 17525 break; 17526 } 17527 if (size > 8) 17528 size = 8; 17529 if (tok == ',') { 17530 next(); 17531 val = asm_int_expr(s1); 17532 } 17533 } 17534 /* XXX: endianness */ 17535 repeat_buf[0] = val; 17536 repeat_buf[1] = val >> 8; 17537 repeat_buf[2] = val >> 16; 17538 repeat_buf[3] = val >> 24; 17539 repeat_buf[4] = 0; 17540 repeat_buf[5] = 0; 17541 repeat_buf[6] = 0; 17542 repeat_buf[7] = 0; 17543 for(i = 0; i < repeat; i++) { 17544 for(j = 0; j < size; j++) { 17545 g(repeat_buf[j]); 17546 } 17547 } 17548 } 17549 break; 17550 case TOK_ASM_org: 17551 { 17552 unsigned long n; 17553 next(); 17554 /* XXX: handle section symbols too */ 17555 n = asm_int_expr(s1); 17556 if (n < ind) 17557 error("attempt to .org backwards"); 17558 v = 0; 17559 size = n - ind; 17560 goto zero_pad; 17561 } 17562 break; 17563 case TOK_ASM_globl: 17564 case TOK_ASM_global: 17565 { 17566 Sym *sym; 17567 17568 next(); 17569 sym = label_find(tok); 17570 if (!sym) { 17571 sym = label_push(&s1->asm_labels, tok, 0); 17572 sym->type.t = VT_VOID; 17573 } 17574 sym->type.t &= ~VT_STATIC; 17575 next(); 17576 } 17577 break; 17578 case TOK_ASM_string: 17579 case TOK_ASM_ascii: 17580 case TOK_ASM_asciz: 17581 { 17582 const uint8_t *p; 17583 int i, size, t; 17584 17585 t = tok; 17586 next(); 17587 for(;;) { 17588 if (tok != TOK_STR) 17589 expect("string constant"); 17590 p = tokc.cstr->data; 17591 size = tokc.cstr->size; 17592 if (t == TOK_ASM_ascii && size > 0) 17593 size--; 17594 for(i = 0; i < size; i++) 17595 g(p[i]); 17596 next(); 17597 if (tok == ',') { 17598 next(); 17599 } else if (tok != TOK_STR) { 17600 break; 17601 } 17602 } 17603 } 17604 break; 17605 case TOK_ASM_text: 17606 case TOK_ASM_data: 17607 case TOK_ASM_bss: 17608 { 17609 char sname[64]; 17610 tok1 = tok; 17611 n = 0; 17612 next(); 17613 if (tok != ';' && tok != TOK_LINEFEED) { 17614 n = asm_int_expr(s1); 17615 next(); 17616 } 17617 sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); 17618 use_section(s1, sname); 17619 } 17620 break; 17621 case TOK_SECTION1: 17622 { 17623 char sname[256]; 17624 17625 /* XXX: support more options */ 17626 next(); 17627 sname[0] = '\0'; 17628 while (tok != ';' && tok != TOK_LINEFEED && tok != ',') { 17629 if (tok == TOK_STR) 17630 pstrcat(sname, sizeof(sname), tokc.cstr->data); 17631 else 17632 pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL)); 17633 next(); 17634 } 17635 if (tok == ',') { 17636 /* skip section options */ 17637 next(); 17638 if (tok != TOK_STR) 17639 expect("string constant"); 17640 next(); 17641 } 17642 last_text_section = cur_text_section; 17643 use_section(s1, sname); 17644 } 17645 break; 17646 case TOK_ASM_previous: 17647 { 17648 Section *sec; 17649 next(); 17650 if (!last_text_section) 17651 error("no previous section referenced"); 17652 sec = cur_text_section; 17653 use_section1(s1, last_text_section); 17654 last_text_section = sec; 17655 } 17656 break; 17657 default: 17658 error("unknown assembler directive '.%s'", get_tok_str(tok, NULL)); 17659 break; 17660 } 17661 } 17662 17663 17664 /* assemble a file */ 17665 static int tcc_assemble_internal(TCCState *s1, int do_preprocess) 17666 { 17667 int opcode; 17668 17669 #if 0 17670 /* print stats about opcodes */ 17671 { 17672 const ASMInstr *pa; 17673 int freq[4]; 17674 int op_vals[500]; 17675 int nb_op_vals, i, j; 17676 17677 nb_op_vals = 0; 17678 memset(freq, 0, sizeof(freq)); 17679 for(pa = asm_instrs; pa->sym != 0; pa++) { 17680 freq[pa->nb_ops]++; 17681 for(i=0;i<pa->nb_ops;i++) { 17682 for(j=0;j<nb_op_vals;j++) { 17683 if (pa->op_type[i] == op_vals[j]) 17684 goto found; 17685 } 17686 op_vals[nb_op_vals++] = pa->op_type[i]; 17687 found: ; 17688 } 17689 } 17690 for(i=0;i<nb_op_vals;i++) { 17691 int v = op_vals[i]; 17692 if ((v & (v - 1)) != 0) 17693 printf("%3d: %08x\n", i, v); 17694 } 17695 printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n", 17696 sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr), 17697 freq[0], freq[1], freq[2], freq[3]); 17698 } 17699 #endif 17700 17701 /* XXX: undefine C labels */ 17702 17703 ch = file->buf_ptr[0]; 17704 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; 17705 parse_flags = PARSE_FLAG_ASM_COMMENTS; 17706 if (do_preprocess) 17707 parse_flags |= PARSE_FLAG_PREPROCESS; 17708 next(); 17709 for(;;) { 17710 if (tok == TOK_EOF) 17711 break; 17712 parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ 17713 redo: 17714 if (tok == '#') { 17715 /* horrible gas comment */ 17716 while (tok != TOK_LINEFEED) 17717 next(); 17718 } else if (tok == '.') { 17719 asm_parse_directive(s1); 17720 } else if (tok == TOK_PPNUM) { 17721 const char *p; 17722 int n; 17723 p = tokc.cstr->data; 17724 n = strtoul(p, (char **)&p, 10); 17725 if (*p != '\0') 17726 expect("':'"); 17727 /* new local label */ 17728 asm_new_label(s1, asm_get_local_label_name(s1, n), 1); 17729 next(); 17730 skip(':'); 17731 goto redo; 17732 } else if (tok >= TOK_IDENT) { 17733 /* instruction or label */ 17734 opcode = tok; 17735 next(); 17736 if (tok == ':') { 17737 /* new label */ 17738 asm_new_label(s1, opcode, 0); 17739 next(); 17740 goto redo; 17741 } else if (tok == '=') { 17742 int n; 17743 next(); 17744 n = asm_int_expr(s1); 17745 asm_new_label1(s1, opcode, 0, SHN_ABS, n); 17746 goto redo; 17747 } else { 17748 asm_opcode(s1, opcode); 17749 } 17750 } 17751 /* end of line */ 17752 if (tok != ';' && tok != TOK_LINEFEED){ 17753 expect("end of line"); 17754 } 17755 parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ 17756 next(); 17757 } 17758 17759 asm_free_labels(s1); 17760 17761 return 0; 17762 } 17763 17764 /* Assemble the current file */ 17765 static int tcc_assemble(TCCState *s1, int do_preprocess) 17766 { 17767 Sym *define_start; 17768 int ret; 17769 17770 preprocess_init(s1); 17771 17772 /* default section is text */ 17773 cur_text_section = text_section; 17774 ind = cur_text_section->data_offset; 17775 17776 define_start = define_stack; 17777 17778 ret = tcc_assemble_internal(s1, do_preprocess); 17779 17780 cur_text_section->data_offset = ind; 17781 17782 free_defines(define_start); 17783 17784 return ret; 17785 } 17786 17787 /********************************************************************/ 17788 /* GCC inline asm support */ 17789 17790 /* assemble the string 'str' in the current C compilation unit without 17791 C preprocessing. NOTE: str is modified by modifying the '\0' at the 17792 end */ 17793 static void tcc_assemble_inline(TCCState *s1, char *str, int len) 17794 { 17795 BufferedFile *bf, *saved_file; 17796 int saved_parse_flags, *saved_macro_ptr; 17797 17798 bf = tcc_malloc(sizeof(BufferedFile)); 17799 memset(bf, 0, sizeof(BufferedFile)); 17800 bf->fd = -1; 17801 bf->buf_ptr = str; 17802 bf->buf_end = str + len; 17803 str[len] = CH_EOB; 17804 /* same name as current file so that errors are correctly 17805 reported */ 17806 pstrcpy(bf->filename, sizeof(bf->filename), file->filename); 17807 bf->line_num = file->line_num; 17808 saved_file = file; 17809 file = bf; 17810 saved_parse_flags = parse_flags; 17811 saved_macro_ptr = macro_ptr; 17812 macro_ptr = NULL; 17813 17814 tcc_assemble_internal(s1, 0); 17815 17816 parse_flags = saved_parse_flags; 17817 macro_ptr = saved_macro_ptr; 17818 file = saved_file; 17819 tcc_free(bf); 17820 } 17821 17822 /* find a constraint by its number or id (gcc 3 extended 17823 syntax). return -1 if not found. Return in *pp in char after the 17824 constraint */ 17825 static int find_constraint(ASMOperand *operands, int nb_operands, 17826 const char *name, const char **pp) 17827 { 17828 int index; 17829 TokenSym *ts; 17830 const char *p; 17831 17832 if (isnum(*name)) { 17833 index = 0; 17834 while (isnum(*name)) { 17835 index = (index * 10) + (*name) - '0'; 17836 name++; 17837 } 17838 if ((unsigned)index >= nb_operands) 17839 index = -1; 17840 } else if (*name == '[') { 17841 name++; 17842 p = strchr(name, ']'); 17843 if (p) { 17844 ts = tok_alloc(name, p - name); 17845 for(index = 0; index < nb_operands; index++) { 17846 if (operands[index].id == ts->tok) 17847 goto found; 17848 } 17849 index = -1; 17850 found: 17851 name = p + 1; 17852 } else { 17853 index = -1; 17854 } 17855 } else { 17856 index = -1; 17857 } 17858 if (pp) 17859 *pp = name; 17860 return index; 17861 } 17862 17863 static void subst_asm_operands(ASMOperand *operands, int nb_operands, 17864 int nb_outputs, 17865 CString *out_str, CString *in_str) 17866 { 17867 int c, index, modifier; 17868 const char *str; 17869 ASMOperand *op; 17870 SValue sv; 17871 17872 cstr_new(out_str); 17873 str = in_str->data; 17874 for(;;) { 17875 c = *str++; 17876 if (c == '%') { 17877 if (*str == '%') { 17878 str++; 17879 goto add_char; 17880 } 17881 modifier = 0; 17882 if (*str == 'c' || *str == 'n' || 17883 *str == 'b' || *str == 'w' || *str == 'h') 17884 modifier = *str++; 17885 index = find_constraint(operands, nb_operands, str, &str); 17886 if (index < 0) 17887 error("invalid operand reference after %%"); 17888 op = &operands[index]; 17889 sv = *op->vt; 17890 if (op->reg >= 0) { 17891 sv.r = op->reg; 17892 if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) 17893 sv.r |= VT_LVAL; 17894 } 17895 subst_asm_operand(out_str, &sv, modifier); 17896 } else { 17897 add_char: 17898 cstr_ccat(out_str, c); 17899 if (c == '\0') 17900 break; 17901 } 17902 } 17903 } 17904 17905 17906 static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr, 17907 int is_output) 17908 { 17909 ASMOperand *op; 17910 int nb_operands; 17911 17912 if (tok != ':') { 17913 nb_operands = *nb_operands_ptr; 17914 for(;;) { 17915 if (nb_operands >= MAX_ASM_OPERANDS) 17916 error("too many asm operands"); 17917 op = &operands[nb_operands++]; 17918 op->id = 0; 17919 if (tok == '[') { 17920 next(); 17921 if (tok < TOK_IDENT) 17922 expect("identifier"); 17923 op->id = tok; 17924 next(); 17925 skip(']'); 17926 } 17927 if (tok != TOK_STR) 17928 expect("string constant"); 17929 op->constraint = tcc_malloc(tokc.cstr->size); 17930 strcpy(op->constraint, tokc.cstr->data); 17931 next(); 17932 skip('('); 17933 gexpr(); 17934 if (is_output) { 17935 test_lvalue(); 17936 } else { 17937 /* we want to avoid LLOCAL case, except when the 'm' 17938 constraint is used. Note that it may come from 17939 register storage, so we need to convert (reg) 17940 case */ 17941 if ((vtop->r & VT_LVAL) && 17942 ((vtop->r & VT_VALMASK) == VT_LLOCAL || 17943 (vtop->r & VT_VALMASK) < VT_CONST) && 17944 !strchr(op->constraint, 'm')) { 17945 gv(RC_INT); 17946 } 17947 } 17948 op->vt = vtop; 17949 skip(')'); 17950 if (tok == ',') { 17951 next(); 17952 } else { 17953 break; 17954 } 17955 } 17956 *nb_operands_ptr = nb_operands; 17957 } 17958 } 17959 17960 static void parse_asm_str(CString *astr) 17961 { 17962 skip('('); 17963 /* read the string */ 17964 if (tok != TOK_STR) 17965 expect("string constant"); 17966 cstr_new(astr); 17967 while (tok == TOK_STR) { 17968 /* XXX: add \0 handling too ? */ 17969 cstr_cat(astr, tokc.cstr->data); 17970 next(); 17971 } 17972 cstr_ccat(astr, '\0'); 17973 } 17974 17975 /* parse the GCC asm() instruction */ 17976 static void asm_instr(void) 17977 { 17978 CString astr, astr1; 17979 ASMOperand operands[MAX_ASM_OPERANDS]; 17980 int nb_inputs __attribute__((unused)); 17981 int nb_outputs, nb_operands, i, must_subst, out_reg; 17982 uint8_t clobber_regs[NB_ASM_REGS]; 17983 17984 next(); 17985 /* since we always generate the asm() instruction, we can ignore 17986 volatile */ 17987 if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) { 17988 next(); 17989 } 17990 parse_asm_str(&astr); 17991 nb_operands = 0; 17992 nb_outputs = 0; 17993 must_subst = 0; 17994 memset(clobber_regs, 0, sizeof(clobber_regs)); 17995 if (tok == ':') { 17996 next(); 17997 must_subst = 1; 17998 /* output args */ 17999 parse_asm_operands(operands, &nb_operands, 1); 18000 nb_outputs = nb_operands; 18001 if (tok == ':') { 18002 next(); 18003 /* input args */ 18004 parse_asm_operands(operands, &nb_operands, 0); 18005 if (tok == ':') { 18006 /* clobber list */ 18007 /* XXX: handle registers */ 18008 next(); 18009 for(;;) { 18010 if (tok != TOK_STR) 18011 expect("string constant"); 18012 asm_clobber(clobber_regs, tokc.cstr->data); 18013 next(); 18014 if (tok == ',') { 18015 next(); 18016 } else { 18017 break; 18018 } 18019 } 18020 } 18021 } 18022 } 18023 skip(')'); 18024 /* NOTE: we do not eat the ';' so that we can restore the current 18025 token after the assembler parsing */ 18026 if (tok != ';') 18027 expect("';'"); 18028 nb_inputs = nb_operands - nb_outputs; 18029 18030 /* save all values in the memory */ 18031 save_regs(0); 18032 18033 /* compute constraints */ 18034 asm_compute_constraints(operands, nb_operands, nb_outputs, 18035 clobber_regs, &out_reg); 18036 18037 /* substitute the operands in the asm string. No substitution is 18038 done if no operands (GCC behaviour) */ 18039 #ifdef ASM_DEBUG 18040 printf("asm: \"%s\"\n", (char *)astr.data); 18041 #endif 18042 if (must_subst) { 18043 subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr); 18044 cstr_free(&astr); 18045 } else { 18046 astr1 = astr; 18047 } 18048 #ifdef ASM_DEBUG 18049 printf("subst_asm: \"%s\"\n", (char *)astr1.data); 18050 #endif 18051 18052 /* generate loads */ 18053 asm_gen_code(operands, nb_operands, nb_outputs, 0, 18054 clobber_regs, out_reg); 18055 18056 /* assemble the string with tcc internal assembler */ 18057 tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1); 18058 18059 /* restore the current C token */ 18060 next(); 18061 18062 /* store the output values if needed */ 18063 asm_gen_code(operands, nb_operands, nb_outputs, 1, 18064 clobber_regs, out_reg); 18065 18066 /* free everything */ 18067 for(i=0;i<nb_operands;i++) { 18068 ASMOperand *op; 18069 op = &operands[i]; 18070 tcc_free(op->constraint); 18071 vpop(); 18072 } 18073 cstr_free(&astr1); 18074 } 18075 18076 static void asm_global_instr(void) 18077 { 18078 CString astr; 18079 18080 next(); 18081 parse_asm_str(&astr); 18082 skip(')'); 18083 /* NOTE: we do not eat the ';' so that we can restore the current 18084 token after the assembler parsing */ 18085 if (tok != ';') 18086 expect("';'"); 18087 18088 #ifdef ASM_DEBUG 18089 printf("asm_global: \"%s\"\n", (char *)astr.data); 18090 #endif 18091 cur_text_section = text_section; 18092 ind = cur_text_section->data_offset; 18093 18094 /* assemble the string with tcc internal assembler */ 18095 tcc_assemble_inline(tcc_state, astr.data, astr.size - 1); 18096 18097 cur_text_section->data_offset = ind; 18098 18099 /* restore the current C token */ 18100 next(); 18101 18102 cstr_free(&astr); 18103 } 18104 //--------------------------------------------------------------------------- 18105 18106 #else 18107 static void asm_instr(void) 18108 { 18109 error("inline asm() not supported"); 18110 } 18111 static void asm_global_instr(void) 18112 { 18113 error("inline asm() not supported"); 18114 } 18115 #endif 18116 18117 // njn: inlined tccelf.c 18118 //#include "tccelf.c" 18119 //--------------------------------------------------------------------------- 18120 /* 18121 * ELF file handling for TCC 18122 * 18123 * Copyright (c) 2001-2004 Fabrice Bellard 18124 * 18125 * This library is free software; you can redistribute it and/or 18126 * modify it under the terms of the GNU Lesser General Public 18127 * License as published by the Free Software Foundation; either 18128 * version 2 of the License, or (at your option) any later version. 18129 * 18130 * This library is distributed in the hope that it will be useful, 18131 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18132 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18133 * Lesser General Public License for more details. 18134 * 18135 * You should have received a copy of the GNU Lesser General Public 18136 * License along with this library; if not, write to the Free Software 18137 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18138 */ 18139 18140 static int put_elf_str(Section *s, const char *sym) 18141 { 18142 int offset, len; 18143 char *ptr; 18144 18145 len = strlen(sym) + 1; 18146 offset = s->data_offset; 18147 ptr = section_ptr_add(s, len); 18148 memcpy(ptr, sym, len); 18149 return offset; 18150 } 18151 18152 /* elf symbol hashing function */ 18153 static unsigned long elf_hash(const unsigned char *name) 18154 { 18155 unsigned long h = 0, g; 18156 18157 while (*name) { 18158 h = (h << 4) + *name++; 18159 g = h & 0xf0000000; 18160 if (g) 18161 h ^= g >> 24; 18162 h &= ~g; 18163 } 18164 return h; 18165 } 18166 18167 /* rebuild hash table of section s */ 18168 /* NOTE: we do factorize the hash table code to go faster */ 18169 static void rebuild_hash(Section *s, unsigned int nb_buckets) 18170 { 18171 Elf32_Sym *sym; 18172 int *ptr, *hash, nb_syms, sym_index, h; 18173 char *strtab; 18174 18175 strtab = s->link->data; 18176 nb_syms = s->data_offset / sizeof(Elf32_Sym); 18177 18178 s->hash->data_offset = 0; 18179 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int)); 18180 ptr[0] = nb_buckets; 18181 ptr[1] = nb_syms; 18182 ptr += 2; 18183 hash = ptr; 18184 memset(hash, 0, (nb_buckets + 1) * sizeof(int)); 18185 ptr += nb_buckets + 1; 18186 18187 sym = (Elf32_Sym *)s->data + 1; 18188 for(sym_index = 1; sym_index < nb_syms; sym_index++) { 18189 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { 18190 h = elf_hash(strtab + sym->st_name) % nb_buckets; 18191 *ptr = hash[h]; 18192 hash[h] = sym_index; 18193 } else { 18194 *ptr = 0; 18195 } 18196 ptr++; 18197 sym++; 18198 } 18199 } 18200 18201 /* return the symbol number */ 18202 static int put_elf_sym(Section *s, 18203 unsigned long value, unsigned long size, 18204 int info, int other, int shndx, const char *name) 18205 { 18206 int name_offset, sym_index; 18207 int nbuckets, h; 18208 Elf32_Sym *sym; 18209 Section *hs; 18210 18211 sym = section_ptr_add(s, sizeof(Elf32_Sym)); 18212 if (name) 18213 name_offset = put_elf_str(s->link, name); 18214 else 18215 name_offset = 0; 18216 /* XXX: endianness */ 18217 sym->st_name = name_offset; 18218 sym->st_value = value; 18219 sym->st_size = size; 18220 sym->st_info = info; 18221 sym->st_other = other; 18222 sym->st_shndx = shndx; 18223 sym_index = sym - (Elf32_Sym *)s->data; 18224 hs = s->hash; 18225 if (hs) { 18226 int *ptr, *base; 18227 ptr = section_ptr_add(hs, sizeof(int)); 18228 base = (int *)hs->data; 18229 /* only add global or weak symbols */ 18230 if (ELF32_ST_BIND(info) != STB_LOCAL) { 18231 /* add another hashing entry */ 18232 nbuckets = base[0]; 18233 h = elf_hash(name) % nbuckets; 18234 *ptr = base[2 + h]; 18235 base[2 + h] = sym_index; 18236 base[1]++; 18237 /* we resize the hash table */ 18238 hs->nb_hashed_syms++; 18239 if (hs->nb_hashed_syms > 2 * nbuckets) { 18240 rebuild_hash(s, 2 * nbuckets); 18241 } 18242 } else { 18243 *ptr = 0; 18244 base[1]++; 18245 } 18246 } 18247 return sym_index; 18248 } 18249 18250 /* find global ELF symbol 'name' and return its index. Return 0 if not 18251 found. */ 18252 static int find_elf_sym(Section *s, const char *name) 18253 { 18254 Elf32_Sym *sym; 18255 Section *hs; 18256 int nbuckets, sym_index, h; 18257 const char *name1; 18258 18259 hs = s->hash; 18260 if (!hs) 18261 return 0; 18262 nbuckets = ((int *)hs->data)[0]; 18263 h = elf_hash(name) % nbuckets; 18264 sym_index = ((int *)hs->data)[2 + h]; 18265 while (sym_index != 0) { 18266 sym = &((Elf32_Sym *)s->data)[sym_index]; 18267 name1 = s->link->data + sym->st_name; 18268 if (!strcmp(name, name1)) 18269 return sym_index; 18270 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; 18271 } 18272 return 0; 18273 } 18274 18275 /* return elf symbol value or error */ 18276 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name) 18277 { 18278 int sym_index; 18279 Elf32_Sym *sym; 18280 18281 sym_index = find_elf_sym(symtab_section, name); 18282 if (!sym_index) 18283 return -1; 18284 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 18285 *pval = sym->st_value; 18286 return 0; 18287 } 18288 18289 void *tcc_get_symbol_err(TCCState *s, const char *name) 18290 { 18291 unsigned long val; 18292 if (tcc_get_symbol(s, &val, name) < 0) 18293 error("%s not defined", name); 18294 return (void *)val; 18295 } 18296 18297 /* add an elf symbol : check if it is already defined and patch 18298 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ 18299 static int add_elf_sym(Section *s, unsigned long value, unsigned long size, 18300 int info, int other, int sh_num, const char *name) 18301 { 18302 Elf32_Sym *esym; 18303 int sym_bind, sym_index, sym_type, esym_bind; 18304 18305 sym_bind = ELF32_ST_BIND(info); 18306 sym_type = ELF32_ST_TYPE(info); 18307 18308 if (sym_bind != STB_LOCAL) { 18309 /* we search global or weak symbols */ 18310 sym_index = find_elf_sym(s, name); 18311 if (!sym_index) 18312 goto do_def; 18313 esym = &((Elf32_Sym *)s->data)[sym_index]; 18314 if (esym->st_shndx != SHN_UNDEF) { 18315 esym_bind = ELF32_ST_BIND(esym->st_info); 18316 if (sh_num == SHN_UNDEF) { 18317 /* ignore adding of undefined symbol if the 18318 corresponding symbol is already defined */ 18319 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) { 18320 /* global overrides weak, so patch */ 18321 goto do_patch; 18322 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) { 18323 /* weak is ignored if already global */ 18324 } else { 18325 #if 0 18326 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n", 18327 sym_bind, sh_num, esym_bind, esym->st_shndx); 18328 #endif 18329 /* NOTE: we accept that two DLL define the same symbol */ 18330 if (s != tcc_state->dynsymtab_section) 18331 error_noabort("'%s' defined twice", name); 18332 } 18333 } else { 18334 do_patch: 18335 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type); 18336 esym->st_shndx = sh_num; 18337 esym->st_value = value; 18338 esym->st_size = size; 18339 esym->st_other = other; 18340 } 18341 } else { 18342 do_def: 18343 sym_index = put_elf_sym(s, value, size, 18344 ELF32_ST_INFO(sym_bind, sym_type), other, 18345 sh_num, name); 18346 } 18347 return sym_index; 18348 } 18349 18350 /* put relocation */ 18351 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, 18352 int type, int symbol) 18353 { 18354 char buf[256]; 18355 Section *sr; 18356 Elf32_Rel *rel; 18357 18358 sr = s->reloc; 18359 if (!sr) { 18360 /* if no relocation section, create it */ 18361 snprintf(buf, sizeof(buf), ".rel%s", s->name); 18362 /* if the symtab is allocated, then we consider the relocation 18363 are also */ 18364 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags); 18365 sr->sh_entsize = sizeof(Elf32_Rel); 18366 sr->link = symtab; 18367 sr->sh_info = s->sh_num; 18368 s->reloc = sr; 18369 } 18370 rel = section_ptr_add(sr, sizeof(Elf32_Rel)); 18371 rel->r_offset = offset; 18372 rel->r_info = ELF32_R_INFO(symbol, type); 18373 } 18374 18375 /* put stab debug information */ 18376 18377 typedef struct { 18378 unsigned long n_strx; /* index into string table of name */ 18379 unsigned char n_type; /* type of symbol */ 18380 unsigned char n_other; /* misc info (usually empty) */ 18381 unsigned short n_desc; /* description field */ 18382 unsigned long n_value; /* value of symbol */ 18383 } Stab_Sym; 18384 18385 static void put_stabs(const char *str, int type, int other, int desc, 18386 unsigned long value) 18387 { 18388 Stab_Sym *sym; 18389 18390 sym = section_ptr_add(stab_section, sizeof(Stab_Sym)); 18391 if (str) { 18392 sym->n_strx = put_elf_str(stabstr_section, str); 18393 } else { 18394 sym->n_strx = 0; 18395 } 18396 sym->n_type = type; 18397 sym->n_other = other; 18398 sym->n_desc = desc; 18399 sym->n_value = value; 18400 } 18401 18402 static void put_stabs_r(const char *str, int type, int other, int desc, 18403 unsigned long value, Section *sec, int sym_index) 18404 { 18405 put_stabs(str, type, other, desc, value); 18406 put_elf_reloc(symtab_section, stab_section, 18407 stab_section->data_offset - sizeof(unsigned long), 18408 R_DATA_32, sym_index); 18409 } 18410 18411 static void put_stabn(int type, int other, int desc, int value) 18412 { 18413 put_stabs(NULL, type, other, desc, value); 18414 } 18415 18416 static void put_stabd(int type, int other, int desc) 18417 { 18418 put_stabs(NULL, type, other, desc, 0); 18419 } 18420 18421 /* In an ELF file symbol table, the local symbols must appear below 18422 the global and weak ones. Since TCC cannot sort it while generating 18423 the code, we must do it after. All the relocation tables are also 18424 modified to take into account the symbol table sorting */ 18425 static void sort_syms(TCCState *s1, Section *s) 18426 { 18427 int *old_to_new_syms; 18428 Elf32_Sym *new_syms; 18429 int nb_syms, i; 18430 Elf32_Sym *p, *q; 18431 Elf32_Rel *rel, *rel_end; 18432 Section *sr; 18433 int type, sym_index; 18434 18435 nb_syms = s->data_offset / sizeof(Elf32_Sym); 18436 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym)); 18437 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int)); 18438 18439 /* first pass for local symbols */ 18440 p = (Elf32_Sym *)s->data; 18441 q = new_syms; 18442 for(i = 0; i < nb_syms; i++) { 18443 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) { 18444 old_to_new_syms[i] = q - new_syms; 18445 *q++ = *p; 18446 } 18447 p++; 18448 } 18449 /* save the number of local symbols in section header */ 18450 s->sh_info = q - new_syms; 18451 18452 /* then second pass for non local symbols */ 18453 p = (Elf32_Sym *)s->data; 18454 for(i = 0; i < nb_syms; i++) { 18455 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) { 18456 old_to_new_syms[i] = q - new_syms; 18457 *q++ = *p; 18458 } 18459 p++; 18460 } 18461 18462 /* we copy the new symbols to the old */ 18463 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym)); 18464 tcc_free(new_syms); 18465 18466 /* now we modify all the relocations */ 18467 for(i = 1; i < s1->nb_sections; i++) { 18468 sr = s1->sections[i]; 18469 if (sr->sh_type == SHT_REL && sr->link == s) { 18470 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); 18471 for(rel = (Elf32_Rel *)sr->data; 18472 rel < rel_end; 18473 rel++) { 18474 sym_index = ELF32_R_SYM(rel->r_info); 18475 type = ELF32_R_TYPE(rel->r_info); 18476 sym_index = old_to_new_syms[sym_index]; 18477 rel->r_info = ELF32_R_INFO(sym_index, type); 18478 } 18479 } 18480 } 18481 18482 tcc_free(old_to_new_syms); 18483 } 18484 18485 /* relocate common symbols in the .bss section */ 18486 static void relocate_common_syms(void) 18487 { 18488 Elf32_Sym *sym, *sym_end; 18489 unsigned long offset, align; 18490 18491 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset); 18492 for(sym = (Elf32_Sym *)symtab_section->data + 1; 18493 sym < sym_end; 18494 sym++) { 18495 if (sym->st_shndx == SHN_COMMON) { 18496 /* align symbol */ 18497 align = sym->st_value; 18498 offset = bss_section->data_offset; 18499 offset = (offset + align - 1) & -align; 18500 sym->st_value = offset; 18501 sym->st_shndx = bss_section->sh_num; 18502 offset += sym->st_size; 18503 bss_section->data_offset = offset; 18504 } 18505 } 18506 } 18507 18508 /* relocate symbol table, resolve undefined symbols if do_resolve is 18509 true and output error if undefined symbol. */ 18510 static void relocate_syms(TCCState *s1, int do_resolve) 18511 { 18512 Elf32_Sym *sym, *esym, *sym_end; 18513 int sym_bind, sh_num, sym_index; 18514 const char *name; 18515 unsigned long addr; 18516 18517 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset); 18518 for(sym = (Elf32_Sym *)symtab_section->data + 1; 18519 sym < sym_end; 18520 sym++) { 18521 sh_num = sym->st_shndx; 18522 if (sh_num == SHN_UNDEF) { 18523 name = strtab_section->data + sym->st_name; 18524 if (do_resolve) { 18525 name = symtab_section->link->data + sym->st_name; 18526 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info)); 18527 if (addr) { 18528 sym->st_value = addr; 18529 goto found; 18530 } 18531 } else if (s1->dynsym) { 18532 /* if dynamic symbol exist, then use it */ 18533 sym_index = find_elf_sym(s1->dynsym, name); 18534 if (sym_index) { 18535 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index]; 18536 sym->st_value = esym->st_value; 18537 goto found; 18538 } 18539 } 18540 /* XXX: _fp_hw seems to be part of the ABI, so we ignore 18541 it */ 18542 if (!strcmp(name, "_fp_hw")) 18543 goto found; 18544 /* only weak symbols are accepted to be undefined. Their 18545 value is zero */ 18546 sym_bind = ELF32_ST_BIND(sym->st_info); 18547 if (sym_bind == STB_WEAK) { 18548 sym->st_value = 0; 18549 } else { 18550 error_noabort("undefined symbol '%s'", name); 18551 } 18552 } else if (sh_num < SHN_LORESERVE) { 18553 /* add section base */ 18554 sym->st_value += s1->sections[sym->st_shndx]->sh_addr; 18555 } 18556 found: ; 18557 } 18558 } 18559 18560 /* relocate a given section (CPU dependent) */ 18561 static void relocate_section(TCCState *s1, Section *s) 18562 { 18563 Section *sr; 18564 Elf32_Rel *rel, *rel_end, *qrel; 18565 Elf32_Sym *sym; 18566 int type, sym_index; 18567 unsigned char *ptr; 18568 unsigned long val, addr; 18569 #if defined(TCC_TARGET_I386) 18570 int esym_index; 18571 #endif 18572 18573 sr = s->reloc; 18574 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); 18575 qrel = (Elf32_Rel *)sr->data; 18576 for(rel = qrel; 18577 rel < rel_end; 18578 rel++) { 18579 ptr = s->data + rel->r_offset; 18580 18581 sym_index = ELF32_R_SYM(rel->r_info); 18582 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 18583 val = sym->st_value; 18584 type = ELF32_R_TYPE(rel->r_info); 18585 addr = s->sh_addr + rel->r_offset; 18586 18587 /* CPU specific */ 18588 switch(type) { 18589 #if defined(TCC_TARGET_I386) 18590 case R_386_32: 18591 if (s1->output_type == TCC_OUTPUT_DLL) { 18592 esym_index = s1->symtab_to_dynsym[sym_index]; 18593 qrel->r_offset = rel->r_offset; 18594 if (esym_index) { 18595 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32); 18596 qrel++; 18597 break; 18598 } else { 18599 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE); 18600 qrel++; 18601 } 18602 } 18603 *(int *)ptr += val; 18604 break; 18605 case R_386_PC32: 18606 if (s1->output_type == TCC_OUTPUT_DLL) { 18607 /* DLL relocation */ 18608 esym_index = s1->symtab_to_dynsym[sym_index]; 18609 if (esym_index) { 18610 qrel->r_offset = rel->r_offset; 18611 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32); 18612 qrel++; 18613 break; 18614 } 18615 } 18616 *(int *)ptr += val - addr; 18617 break; 18618 case R_386_PLT32: 18619 *(int *)ptr += val - addr; 18620 break; 18621 case R_386_GLOB_DAT: 18622 case R_386_JMP_SLOT: 18623 *(int *)ptr = val; 18624 break; 18625 case R_386_GOTPC: 18626 *(int *)ptr += s1->got->sh_addr - addr; 18627 break; 18628 case R_386_GOTOFF: 18629 *(int *)ptr += val - s1->got->sh_addr; 18630 break; 18631 case R_386_GOT32: 18632 /* we load the got offset */ 18633 *(int *)ptr += s1->got_offsets[sym_index]; 18634 break; 18635 #elif defined(TCC_TARGET_ARM) 18636 case R_ARM_PC24: 18637 case R_ARM_PLT32: 18638 { 18639 int x; 18640 x = (*(int *)ptr)&0xffffff; 18641 (*(int *)ptr) &= 0xff000000; 18642 if (x & 0x800000) 18643 x -= 0x1000000; 18644 x *= 4; 18645 x += val - addr; 18646 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000) 18647 error("can't relocate value at %x",addr); 18648 x >>= 2; 18649 x &= 0xffffff; 18650 (*(int *)ptr) |= x; 18651 } 18652 break; 18653 case R_ARM_ABS32: 18654 *(int *)ptr += val; 18655 break; 18656 case R_ARM_GOTPC: 18657 *(int *)ptr += s1->got->sh_addr - addr; 18658 break; 18659 case R_ARM_GOT32: 18660 /* we load the got offset */ 18661 *(int *)ptr += s1->got_offsets[sym_index]; 18662 break; 18663 case R_ARM_COPY: 18664 break; 18665 default: 18666 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n", 18667 type,addr,(unsigned int )ptr,val); 18668 break; 18669 #elif defined(TCC_TARGET_C67) 18670 case R_C60_32: 18671 *(int *)ptr += val; 18672 break; 18673 case R_C60LO16: 18674 { 18675 uint32_t orig; 18676 18677 /* put the low 16 bits of the absolute address */ 18678 // add to what is already there 18679 18680 orig = ((*(int *)(ptr )) >> 7) & 0xffff; 18681 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16; 18682 18683 //patch both at once - assumes always in pairs Low - High 18684 18685 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7); 18686 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7); 18687 } 18688 break; 18689 case R_C60HI16: 18690 break; 18691 default: 18692 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n", 18693 type,addr,(unsigned int )ptr,val); 18694 break; 18695 #else 18696 #error unsupported processor 18697 #endif 18698 } 18699 } 18700 /* if the relocation is allocated, we change its symbol table */ 18701 if (sr->sh_flags & SHF_ALLOC) 18702 sr->link = s1->dynsym; 18703 } 18704 18705 /* relocate relocation table in 'sr' */ 18706 static void relocate_rel(TCCState *s1, Section *sr) 18707 { 18708 Section *s; 18709 Elf32_Rel *rel, *rel_end; 18710 18711 s = s1->sections[sr->sh_info]; 18712 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); 18713 for(rel = (Elf32_Rel *)sr->data; 18714 rel < rel_end; 18715 rel++) { 18716 rel->r_offset += s->sh_addr; 18717 } 18718 } 18719 18720 /* count the number of dynamic relocations so that we can reserve 18721 their space */ 18722 static int prepare_dynamic_rel(TCCState *s1, Section *sr) 18723 { 18724 Elf32_Rel *rel, *rel_end; 18725 int sym_index, esym_index, type, count; 18726 18727 count = 0; 18728 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset); 18729 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) { 18730 sym_index = ELF32_R_SYM(rel->r_info); 18731 type = ELF32_R_TYPE(rel->r_info); 18732 switch(type) { 18733 case R_386_32: 18734 count++; 18735 break; 18736 case R_386_PC32: 18737 esym_index = s1->symtab_to_dynsym[sym_index]; 18738 if (esym_index) 18739 count++; 18740 break; 18741 default: 18742 break; 18743 } 18744 } 18745 if (count) { 18746 /* allocate the section */ 18747 sr->sh_flags |= SHF_ALLOC; 18748 sr->sh_size = count * sizeof(Elf32_Rel); 18749 } 18750 return count; 18751 } 18752 18753 static void put_got_offset(TCCState *s1, int index, unsigned long val) 18754 { 18755 int n; 18756 unsigned long *tab; 18757 18758 if (index >= s1->nb_got_offsets) { 18759 /* find immediately bigger power of 2 and reallocate array */ 18760 n = 1; 18761 while (index >= n) 18762 n *= 2; 18763 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long)); 18764 if (!tab) 18765 error("memory full"); 18766 s1->got_offsets = tab; 18767 memset(s1->got_offsets + s1->nb_got_offsets, 0, 18768 (n - s1->nb_got_offsets) * sizeof(unsigned long)); 18769 s1->nb_got_offsets = n; 18770 } 18771 s1->got_offsets[index] = val; 18772 } 18773 18774 /* XXX: suppress that */ 18775 static void put32(unsigned char *p, uint32_t val) 18776 { 18777 p[0] = val; 18778 p[1] = val >> 8; 18779 p[2] = val >> 16; 18780 p[3] = val >> 24; 18781 } 18782 18783 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) 18784 static uint32_t get32(unsigned char *p) 18785 { 18786 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 18787 } 18788 #endif 18789 18790 static void build_got(TCCState *s1) 18791 { 18792 unsigned char *ptr; 18793 18794 /* if no got, then create it */ 18795 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 18796 s1->got->sh_entsize = 4; 18797 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), 18798 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); 18799 ptr = section_ptr_add(s1->got, 3 * sizeof(int)); 18800 /* keep space for _DYNAMIC pointer, if present */ 18801 put32(ptr, 0); 18802 /* two dummy got entries */ 18803 put32(ptr + 4, 0); 18804 put32(ptr + 8, 0); 18805 } 18806 18807 /* put a got entry corresponding to a symbol in symtab_section. 'size' 18808 and 'info' can be modifed if more precise info comes from the DLL */ 18809 static void put_got_entry(TCCState *s1, 18810 int reloc_type, unsigned long size, int info, 18811 int sym_index) 18812 { 18813 int index; 18814 const char *name; 18815 Elf32_Sym *sym; 18816 unsigned long offset; 18817 int *ptr; 18818 18819 if (!s1->got) 18820 build_got(s1); 18821 18822 /* if a got entry already exists for that symbol, no need to add one */ 18823 if (sym_index < s1->nb_got_offsets && 18824 s1->got_offsets[sym_index] != 0) 18825 return; 18826 18827 put_got_offset(s1, sym_index, s1->got->data_offset); 18828 18829 if (s1->dynsym) { 18830 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 18831 name = symtab_section->link->data + sym->st_name; 18832 offset = sym->st_value; 18833 #ifdef TCC_TARGET_I386 18834 if (reloc_type == R_386_JMP_SLOT) { 18835 Section *plt; 18836 uint8_t *p; 18837 int modrm; 18838 18839 /* if we build a DLL, we add a %ebx offset */ 18840 if (s1->output_type == TCC_OUTPUT_DLL) 18841 modrm = 0xa3; 18842 else 18843 modrm = 0x25; 18844 18845 /* add a PLT entry */ 18846 plt = s1->plt; 18847 if (plt->data_offset == 0) { 18848 /* first plt entry */ 18849 p = section_ptr_add(plt, 16); 18850 p[0] = 0xff; /* pushl got + 4 */ 18851 p[1] = modrm + 0x10; 18852 put32(p + 2, 4); 18853 p[6] = 0xff; /* jmp *(got + 8) */ 18854 p[7] = modrm; 18855 put32(p + 8, 8); 18856 } 18857 18858 p = section_ptr_add(plt, 16); 18859 p[0] = 0xff; /* jmp *(got + x) */ 18860 p[1] = modrm; 18861 put32(p + 2, s1->got->data_offset); 18862 p[6] = 0x68; /* push $xxx */ 18863 put32(p + 7, (plt->data_offset - 32) >> 1); 18864 p[11] = 0xe9; /* jmp plt_start */ 18865 put32(p + 12, -(plt->data_offset)); 18866 18867 /* the symbol is modified so that it will be relocated to 18868 the PLT */ 18869 if (s1->output_type == TCC_OUTPUT_EXE) 18870 offset = plt->data_offset - 16; 18871 } 18872 #elif defined(TCC_TARGET_ARM) 18873 if (reloc_type == R_ARM_JUMP_SLOT) { 18874 Section *plt; 18875 uint8_t *p; 18876 18877 /* if we build a DLL, we add a %ebx offset */ 18878 if (s1->output_type == TCC_OUTPUT_DLL) 18879 error("DLLs unimplemented!"); 18880 18881 /* add a PLT entry */ 18882 plt = s1->plt; 18883 if (plt->data_offset == 0) { 18884 /* first plt entry */ 18885 p = section_ptr_add(plt, 16); 18886 put32(p , 0xe52de004); 18887 put32(p + 4, 0xe59fe010); 18888 put32(p + 8, 0xe08fe00e); 18889 put32(p + 12, 0xe5bef008); 18890 } 18891 18892 p = section_ptr_add(plt, 16); 18893 put32(p , 0xe59fc004); 18894 put32(p+4, 0xe08fc00c); 18895 put32(p+8, 0xe59cf000); 18896 put32(p+12, s1->got->data_offset); 18897 18898 /* the symbol is modified so that it will be relocated to 18899 the PLT */ 18900 if (s1->output_type == TCC_OUTPUT_EXE) 18901 offset = plt->data_offset - 16; 18902 } 18903 #elif defined(TCC_TARGET_C67) 18904 error("C67 got not implemented"); 18905 #else 18906 #error unsupported CPU 18907 #endif 18908 index = put_elf_sym(s1->dynsym, offset, 18909 size, info, 0, sym->st_shndx, name); 18910 /* put a got entry */ 18911 put_elf_reloc(s1->dynsym, s1->got, 18912 s1->got->data_offset, 18913 reloc_type, index); 18914 } 18915 ptr = section_ptr_add(s1->got, sizeof(int)); 18916 *ptr = 0; 18917 } 18918 18919 /* build GOT and PLT entries */ 18920 static void build_got_entries(TCCState *s1) 18921 { 18922 Section *s, *symtab __attribute__((unused)); 18923 Elf32_Rel *rel, *rel_end; 18924 Elf32_Sym *sym; 18925 int i, type, reloc_type, sym_index; 18926 18927 for(i = 1; i < s1->nb_sections; i++) { 18928 s = s1->sections[i]; 18929 if (s->sh_type != SHT_REL) 18930 continue; 18931 /* no need to handle got relocations */ 18932 if (s->link != symtab_section) 18933 continue; 18934 symtab = s->link; 18935 rel_end = (Elf32_Rel *)(s->data + s->data_offset); 18936 for(rel = (Elf32_Rel *)s->data; 18937 rel < rel_end; 18938 rel++) { 18939 type = ELF32_R_TYPE(rel->r_info); 18940 switch(type) { 18941 #if defined(TCC_TARGET_I386) 18942 case R_386_GOT32: 18943 case R_386_GOTOFF: 18944 case R_386_GOTPC: 18945 case R_386_PLT32: 18946 if (!s1->got) 18947 build_got(s1); 18948 if (type == R_386_GOT32 || type == R_386_PLT32) { 18949 sym_index = ELF32_R_SYM(rel->r_info); 18950 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 18951 /* look at the symbol got offset. If none, then add one */ 18952 if (type == R_386_GOT32) 18953 reloc_type = R_386_GLOB_DAT; 18954 else 18955 reloc_type = R_386_JMP_SLOT; 18956 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 18957 sym_index); 18958 } 18959 break; 18960 #elif defined(TCC_TARGET_ARM) 18961 case R_ARM_GOT32: 18962 case R_ARM_GOTOFF: 18963 case R_ARM_GOTPC: 18964 case R_ARM_PLT32: 18965 if (!s1->got) 18966 build_got(s1); 18967 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) { 18968 sym_index = ELF32_R_SYM(rel->r_info); 18969 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 18970 /* look at the symbol got offset. If none, then add one */ 18971 if (type == R_ARM_GOT32) 18972 reloc_type = R_ARM_GLOB_DAT; 18973 else 18974 reloc_type = R_ARM_JUMP_SLOT; 18975 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 18976 sym_index); 18977 } 18978 break; 18979 #elif defined(TCC_TARGET_C67) 18980 case R_C60_GOT32: 18981 case R_C60_GOTOFF: 18982 case R_C60_GOTPC: 18983 case R_C60_PLT32: 18984 if (!s1->got) 18985 build_got(s1); 18986 if (type == R_C60_GOT32 || type == R_C60_PLT32) { 18987 sym_index = ELF32_R_SYM(rel->r_info); 18988 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 18989 /* look at the symbol got offset. If none, then add one */ 18990 if (type == R_C60_GOT32) 18991 reloc_type = R_C60_GLOB_DAT; 18992 else 18993 reloc_type = R_C60_JMP_SLOT; 18994 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 18995 sym_index); 18996 } 18997 break; 18998 #else 18999 #error unsupported CPU 19000 #endif 19001 default: 19002 break; 19003 } 19004 } 19005 } 19006 } 19007 19008 static Section *new_symtab(TCCState *s1, 19009 const char *symtab_name, int sh_type, int sh_flags, 19010 const char *strtab_name, 19011 const char *hash_name, int hash_sh_flags) 19012 { 19013 Section *symtab, *strtab, *hash; 19014 int *ptr, nb_buckets; 19015 19016 symtab = new_section(s1, symtab_name, sh_type, sh_flags); 19017 symtab->sh_entsize = sizeof(Elf32_Sym); 19018 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags); 19019 put_elf_str(strtab, ""); 19020 symtab->link = strtab; 19021 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL); 19022 19023 nb_buckets = 1; 19024 19025 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags); 19026 hash->sh_entsize = sizeof(int); 19027 symtab->hash = hash; 19028 hash->link = symtab; 19029 19030 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int)); 19031 ptr[0] = nb_buckets; 19032 ptr[1] = 1; 19033 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int)); 19034 return symtab; 19035 } 19036 19037 /* put dynamic tag */ 19038 static void put_dt(Section *dynamic, int dt, unsigned long val) 19039 { 19040 Elf32_Dyn *dyn; 19041 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn)); 19042 dyn->d_tag = dt; 19043 dyn->d_un.d_val = val; 19044 } 19045 19046 static void add_init_array_defines(TCCState *s1, const char *section_name) 19047 { 19048 Section *s; 19049 long end_offset; 19050 char sym_start[1024]; 19051 char sym_end[1024]; 19052 19053 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1); 19054 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1); 19055 19056 s = find_section(s1, section_name); 19057 if (!s) { 19058 end_offset = 0; 19059 s = data_section; 19060 } else { 19061 end_offset = s->data_offset; 19062 } 19063 19064 add_elf_sym(symtab_section, 19065 0, 0, 19066 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19067 s->sh_num, sym_start); 19068 add_elf_sym(symtab_section, 19069 end_offset, 0, 19070 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19071 s->sh_num, sym_end); 19072 } 19073 19074 /* add tcc runtime libraries */ 19075 static void tcc_add_runtime(TCCState *s1) 19076 { 19077 char buf[1024]; 19078 19079 #ifdef CONFIG_TCC_BCHECK 19080 if (do_bounds_check) { 19081 unsigned long *ptr; 19082 Section *init_section; 19083 unsigned char *pinit; 19084 int sym_index; 19085 19086 /* XXX: add an object file to do that */ 19087 ptr = section_ptr_add(bounds_section, sizeof(unsigned long)); 19088 *ptr = 0; 19089 add_elf_sym(symtab_section, 0, 0, 19090 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19091 bounds_section->sh_num, "__bounds_start"); 19092 /* add bound check code */ 19093 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o"); 19094 tcc_add_file(s1, buf); 19095 #ifdef TCC_TARGET_I386 19096 if (s1->output_type != TCC_OUTPUT_MEMORY) { 19097 /* add 'call __bound_init()' in .init section */ 19098 init_section = find_section(s1, ".init"); 19099 pinit = section_ptr_add(init_section, 5); 19100 pinit[0] = 0xe8; 19101 put32(pinit + 1, -4); 19102 sym_index = find_elf_sym(symtab_section, "__bound_init"); 19103 put_elf_reloc(symtab_section, init_section, 19104 init_section->data_offset - 4, R_386_PC32, sym_index); 19105 } 19106 #endif 19107 } 19108 #endif 19109 /* add libc */ 19110 if (!s1->nostdlib) { 19111 tcc_add_library(s1, "c"); 19112 19113 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a"); 19114 tcc_add_file(s1, buf); 19115 } 19116 /* add crt end if not memory output */ 19117 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) { 19118 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o"); 19119 } 19120 } 19121 19122 /* add various standard linker symbols (must be done after the 19123 sections are filled (for example after allocating common 19124 symbols)) */ 19125 static void tcc_add_linker_symbols(TCCState *s1) 19126 { 19127 char buf[1024]; 19128 int i; 19129 Section *s; 19130 19131 add_elf_sym(symtab_section, 19132 text_section->data_offset, 0, 19133 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19134 text_section->sh_num, "_etext"); 19135 add_elf_sym(symtab_section, 19136 data_section->data_offset, 0, 19137 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19138 data_section->sh_num, "_edata"); 19139 add_elf_sym(symtab_section, 19140 bss_section->data_offset, 0, 19141 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19142 bss_section->sh_num, "_end"); 19143 /* horrible new standard ldscript defines */ 19144 add_init_array_defines(s1, ".preinit_array"); 19145 add_init_array_defines(s1, ".init_array"); 19146 add_init_array_defines(s1, ".fini_array"); 19147 19148 /* add start and stop symbols for sections whose name can be 19149 expressed in C */ 19150 for(i = 1; i < s1->nb_sections; i++) { 19151 s = s1->sections[i]; 19152 if (s->sh_type == SHT_PROGBITS && 19153 (s->sh_flags & SHF_ALLOC)) { 19154 const char *p; 19155 int ch; 19156 19157 /* check if section name can be expressed in C */ 19158 p = s->name; 19159 for(;;) { 19160 ch = *p; 19161 if (!ch) 19162 break; 19163 if (!isid(ch) && !isnum(ch)) 19164 goto next_sec; 19165 p++; 19166 } 19167 snprintf(buf, sizeof(buf), "__start_%s", s->name); 19168 add_elf_sym(symtab_section, 19169 0, 0, 19170 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19171 s->sh_num, buf); 19172 snprintf(buf, sizeof(buf), "__stop_%s", s->name); 19173 add_elf_sym(symtab_section, 19174 s->data_offset, 0, 19175 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 19176 s->sh_num, buf); 19177 } 19178 next_sec: ; 19179 } 19180 } 19181 19182 /* name of ELF interpreter */ 19183 #ifdef __FreeBSD__ 19184 static char elf_interp[] = "/usr/libexec/ld-elf.so.1"; 19185 #else 19186 static char elf_interp[] = "/lib/ld-linux.so.2"; 19187 #endif 19188 19189 static void tcc_output_binary(TCCState *s1, FILE *f, 19190 const int *section_order) 19191 { 19192 Section *s; 19193 int i, offset, size; 19194 19195 offset = 0; 19196 for(i=1;i<s1->nb_sections;i++) { 19197 s = s1->sections[section_order[i]]; 19198 if (s->sh_type != SHT_NOBITS && 19199 (s->sh_flags & SHF_ALLOC)) { 19200 while (offset < s->sh_offset) { 19201 fputc(0, f); 19202 offset++; 19203 } 19204 size = s->sh_size; 19205 dummy_size_t = fwrite(s->data, 1, size, f); 19206 offset += size; 19207 } 19208 } 19209 } 19210 19211 /* output an ELF file */ 19212 /* XXX: suppress unneeded sections */ 19213 int tcc_output_file(TCCState *s1, const char *filename) 19214 { 19215 Elf32_Ehdr ehdr; 19216 FILE *f; 19217 int fd, mode, ret; 19218 int *section_order; 19219 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k; 19220 unsigned long addr; 19221 Section *strsec, *s; 19222 Elf32_Shdr shdr, *sh; 19223 Elf32_Phdr *phdr, *ph; 19224 Section *interp, *dynamic, *dynstr; 19225 unsigned long saved_dynamic_data_offset; 19226 Elf32_Sym *sym; 19227 int type, file_type; 19228 unsigned long rel_addr, rel_size; 19229 19230 file_type = s1->output_type; 19231 s1->nb_errors = 0; 19232 19233 if (file_type != TCC_OUTPUT_OBJ) { 19234 tcc_add_runtime(s1); 19235 } 19236 19237 phdr = NULL; 19238 section_order = NULL; 19239 interp = NULL; 19240 dynamic = NULL; 19241 dynstr = NULL; /* avoid warning */ 19242 saved_dynamic_data_offset = 0; /* avoid warning */ 19243 19244 if (file_type != TCC_OUTPUT_OBJ) { 19245 relocate_common_syms(); 19246 19247 tcc_add_linker_symbols(s1); 19248 19249 if (!s1->static_link) { 19250 const char *name; 19251 int sym_index, index; 19252 Elf32_Sym *esym, *sym_end; 19253 19254 if (file_type == TCC_OUTPUT_EXE) { 19255 char *ptr; 19256 /* add interpreter section only if executable */ 19257 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC); 19258 interp->sh_addralign = 1; 19259 ptr = section_ptr_add(interp, sizeof(elf_interp)); 19260 strcpy(ptr, elf_interp); 19261 } 19262 19263 /* add dynamic symbol table */ 19264 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC, 19265 ".dynstr", 19266 ".hash", SHF_ALLOC); 19267 dynstr = s1->dynsym->link; 19268 19269 /* add dynamic section */ 19270 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 19271 SHF_ALLOC | SHF_WRITE); 19272 dynamic->link = dynstr; 19273 dynamic->sh_entsize = sizeof(Elf32_Dyn); 19274 19275 /* add PLT */ 19276 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 19277 SHF_ALLOC | SHF_EXECINSTR); 19278 s1->plt->sh_entsize = 4; 19279 19280 build_got(s1); 19281 19282 /* scan for undefined symbols and see if they are in the 19283 dynamic symbols. If a symbol STT_FUNC is found, then we 19284 add it in the PLT. If a symbol STT_OBJECT is found, we 19285 add it in the .bss section with a suitable relocation */ 19286 sym_end = (Elf32_Sym *)(symtab_section->data + 19287 symtab_section->data_offset); 19288 if (file_type == TCC_OUTPUT_EXE) { 19289 for(sym = (Elf32_Sym *)symtab_section->data + 1; 19290 sym < sym_end; 19291 sym++) { 19292 if (sym->st_shndx == SHN_UNDEF) { 19293 name = symtab_section->link->data + sym->st_name; 19294 sym_index = find_elf_sym(s1->dynsymtab_section, name); 19295 if (sym_index) { 19296 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index]; 19297 type = ELF32_ST_TYPE(esym->st_info); 19298 if (type == STT_FUNC) { 19299 put_got_entry(s1, R_JMP_SLOT, esym->st_size, 19300 esym->st_info, 19301 sym - (Elf32_Sym *)symtab_section->data); 19302 } else if (type == STT_OBJECT) { 19303 unsigned long offset; 19304 offset = bss_section->data_offset; 19305 /* XXX: which alignment ? */ 19306 offset = (offset + 16 - 1) & -16; 19307 index = put_elf_sym(s1->dynsym, offset, esym->st_size, 19308 esym->st_info, 0, 19309 bss_section->sh_num, name); 19310 put_elf_reloc(s1->dynsym, bss_section, 19311 offset, R_COPY, index); 19312 offset += esym->st_size; 19313 bss_section->data_offset = offset; 19314 } 19315 } else { 19316 /* STB_WEAK undefined symbols are accepted */ 19317 /* XXX: _fp_hw seems to be part of the ABI, so we ignore 19318 it */ 19319 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK || 19320 !strcmp(name, "_fp_hw")) { 19321 } else { 19322 error_noabort("undefined symbol '%s'", name); 19323 } 19324 } 19325 } else if (s1->rdynamic && 19326 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { 19327 /* if -rdynamic option, then export all non 19328 local symbols */ 19329 name = symtab_section->link->data + sym->st_name; 19330 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 19331 sym->st_info, 0, 19332 sym->st_shndx, name); 19333 } 19334 } 19335 19336 if (s1->nb_errors) 19337 goto fail; 19338 19339 /* now look at unresolved dynamic symbols and export 19340 corresponding symbol */ 19341 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data + 19342 s1->dynsymtab_section->data_offset); 19343 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1; 19344 esym < sym_end; 19345 esym++) { 19346 if (esym->st_shndx == SHN_UNDEF) { 19347 name = s1->dynsymtab_section->link->data + esym->st_name; 19348 sym_index = find_elf_sym(symtab_section, name); 19349 if (sym_index) { 19350 /* XXX: avoid adding a symbol if already 19351 present because of -rdynamic ? */ 19352 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 19353 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 19354 sym->st_info, 0, 19355 sym->st_shndx, name); 19356 } else { 19357 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) { 19358 /* weak symbols can stay undefined */ 19359 } else { 19360 warning("undefined dynamic symbol '%s'", name); 19361 } 19362 } 19363 } 19364 } 19365 } else { 19366 int nb_syms; 19367 /* shared library case : we simply export all the global symbols */ 19368 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym); 19369 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); 19370 for(sym = (Elf32_Sym *)symtab_section->data + 1; 19371 sym < sym_end; 19372 sym++) { 19373 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { 19374 name = symtab_section->link->data + sym->st_name; 19375 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 19376 sym->st_info, 0, 19377 sym->st_shndx, name); 19378 s1->symtab_to_dynsym[sym - 19379 (Elf32_Sym *)symtab_section->data] = 19380 index; 19381 } 19382 } 19383 } 19384 19385 build_got_entries(s1); 19386 19387 /* add a list of needed dlls */ 19388 for(i = 0; i < s1->nb_loaded_dlls; i++) { 19389 DLLReference *dllref = s1->loaded_dlls[i]; 19390 if (dllref->level == 0) 19391 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name)); 19392 } 19393 /* XXX: currently, since we do not handle PIC code, we 19394 must relocate the readonly segments */ 19395 if (file_type == TCC_OUTPUT_DLL) 19396 put_dt(dynamic, DT_TEXTREL, 0); 19397 19398 /* add necessary space for other entries */ 19399 saved_dynamic_data_offset = dynamic->data_offset; 19400 dynamic->data_offset += 8 * 9; 19401 } else { 19402 /* still need to build got entries in case of static link */ 19403 build_got_entries(s1); 19404 } 19405 } 19406 19407 memset(&ehdr, 0, sizeof(ehdr)); 19408 19409 /* we add a section for symbols */ 19410 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0); 19411 put_elf_str(strsec, ""); 19412 19413 /* compute number of sections */ 19414 shnum = s1->nb_sections; 19415 19416 /* this array is used to reorder sections in the output file */ 19417 section_order = tcc_malloc(sizeof(int) * shnum); 19418 section_order[0] = 0; 19419 sh_order_index = 1; 19420 19421 /* compute number of program headers */ 19422 switch(file_type) { 19423 default: 19424 case TCC_OUTPUT_OBJ: 19425 phnum = 0; 19426 break; 19427 case TCC_OUTPUT_EXE: 19428 if (!s1->static_link) 19429 phnum = 4; 19430 else 19431 phnum = 2; 19432 break; 19433 case TCC_OUTPUT_DLL: 19434 phnum = 3; 19435 break; 19436 } 19437 19438 /* allocate strings for section names and decide if an unallocated 19439 section should be output */ 19440 /* NOTE: the strsec section comes last, so its size is also 19441 correct ! */ 19442 for(i = 1; i < s1->nb_sections; i++) { 19443 s = s1->sections[i]; 19444 s->sh_name = put_elf_str(strsec, s->name); 19445 /* when generating a DLL, we include relocations but we may 19446 patch them */ 19447 if (file_type == TCC_OUTPUT_DLL && 19448 s->sh_type == SHT_REL && 19449 !(s->sh_flags & SHF_ALLOC)) { 19450 prepare_dynamic_rel(s1, s); 19451 } else if (do_debug || 19452 file_type == TCC_OUTPUT_OBJ || 19453 (s->sh_flags & SHF_ALLOC) || 19454 i == (s1->nb_sections - 1)) { 19455 /* we output all sections if debug or object file */ 19456 s->sh_size = s->data_offset; 19457 } 19458 } 19459 19460 /* allocate program segment headers */ 19461 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr)); 19462 19463 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { 19464 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr); 19465 } else { 19466 file_offset = 0; 19467 } 19468 if (phnum > 0) { 19469 /* compute section to program header mapping */ 19470 if (s1->has_text_addr) { 19471 int a_offset, p_offset; 19472 addr = s1->text_addr; 19473 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % 19474 ELF_PAGE_SIZE */ 19475 a_offset = addr & (ELF_PAGE_SIZE - 1); 19476 p_offset = file_offset & (ELF_PAGE_SIZE - 1); 19477 if (a_offset < p_offset) 19478 a_offset += ELF_PAGE_SIZE; 19479 file_offset += (a_offset - p_offset); 19480 } else { 19481 if (file_type == TCC_OUTPUT_DLL) 19482 addr = 0; 19483 else 19484 addr = ELF_START_ADDR; 19485 /* compute address after headers */ 19486 addr += (file_offset & (ELF_PAGE_SIZE - 1)); 19487 } 19488 19489 /* dynamic relocation table information, for .dynamic section */ 19490 rel_size = 0; 19491 rel_addr = 0; 19492 19493 /* leave one program header for the program interpreter */ 19494 ph = &phdr[0]; 19495 if (interp) 19496 ph++; 19497 19498 for(j = 0; j < 2; j++) { 19499 ph->p_type = PT_LOAD; 19500 if (j == 0) 19501 ph->p_flags = PF_R | PF_X; 19502 else 19503 ph->p_flags = PF_R | PF_W; 19504 ph->p_align = ELF_PAGE_SIZE; 19505 19506 /* we do the following ordering: interp, symbol tables, 19507 relocations, progbits, nobits */ 19508 /* XXX: do faster and simpler sorting */ 19509 for(k = 0; k < 5; k++) { 19510 for(i = 1; i < s1->nb_sections; i++) { 19511 s = s1->sections[i]; 19512 /* compute if section should be included */ 19513 if (j == 0) { 19514 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 19515 SHF_ALLOC) 19516 continue; 19517 } else { 19518 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 19519 (SHF_ALLOC | SHF_WRITE)) 19520 continue; 19521 } 19522 if (s == interp) { 19523 if (k != 0) 19524 continue; 19525 } else if (s->sh_type == SHT_DYNSYM || 19526 s->sh_type == SHT_STRTAB || 19527 s->sh_type == SHT_HASH) { 19528 if (k != 1) 19529 continue; 19530 } else if (s->sh_type == SHT_REL) { 19531 if (k != 2) 19532 continue; 19533 } else if (s->sh_type == SHT_NOBITS) { 19534 if (k != 4) 19535 continue; 19536 } else { 19537 if (k != 3) 19538 continue; 19539 } 19540 section_order[sh_order_index++] = i; 19541 19542 /* section matches: we align it and add its size */ 19543 tmp = addr; 19544 addr = (addr + s->sh_addralign - 1) & 19545 ~(s->sh_addralign - 1); 19546 file_offset += addr - tmp; 19547 s->sh_offset = file_offset; 19548 s->sh_addr = addr; 19549 19550 /* update program header infos */ 19551 if (ph->p_offset == 0) { 19552 ph->p_offset = file_offset; 19553 ph->p_vaddr = addr; 19554 ph->p_paddr = ph->p_vaddr; 19555 } 19556 /* update dynamic relocation infos */ 19557 if (s->sh_type == SHT_REL) { 19558 if (rel_size == 0) 19559 rel_addr = addr; 19560 rel_size += s->sh_size; 19561 } 19562 addr += s->sh_size; 19563 if (s->sh_type != SHT_NOBITS) 19564 file_offset += s->sh_size; 19565 } 19566 } 19567 ph->p_filesz = file_offset - ph->p_offset; 19568 ph->p_memsz = addr - ph->p_vaddr; 19569 ph++; 19570 if (j == 0) { 19571 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { 19572 /* if in the middle of a page, we duplicate the page in 19573 memory so that one copy is RX and the other is RW */ 19574 if ((addr & (ELF_PAGE_SIZE - 1)) != 0) 19575 addr += ELF_PAGE_SIZE; 19576 } else { 19577 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1); 19578 file_offset = (file_offset + ELF_PAGE_SIZE - 1) & 19579 ~(ELF_PAGE_SIZE - 1); 19580 } 19581 } 19582 } 19583 19584 /* if interpreter, then add corresponing program header */ 19585 if (interp) { 19586 ph = &phdr[0]; 19587 19588 ph->p_type = PT_INTERP; 19589 ph->p_offset = interp->sh_offset; 19590 ph->p_vaddr = interp->sh_addr; 19591 ph->p_paddr = ph->p_vaddr; 19592 ph->p_filesz = interp->sh_size; 19593 ph->p_memsz = interp->sh_size; 19594 ph->p_flags = PF_R; 19595 ph->p_align = interp->sh_addralign; 19596 } 19597 19598 /* if dynamic section, then add corresponing program header */ 19599 if (dynamic) { 19600 Elf32_Sym *sym_end; 19601 19602 ph = &phdr[phnum - 1]; 19603 19604 ph->p_type = PT_DYNAMIC; 19605 ph->p_offset = dynamic->sh_offset; 19606 ph->p_vaddr = dynamic->sh_addr; 19607 ph->p_paddr = ph->p_vaddr; 19608 ph->p_filesz = dynamic->sh_size; 19609 ph->p_memsz = dynamic->sh_size; 19610 ph->p_flags = PF_R | PF_W; 19611 ph->p_align = dynamic->sh_addralign; 19612 19613 /* put GOT dynamic section address */ 19614 put32(s1->got->data, dynamic->sh_addr); 19615 19616 /* relocate the PLT */ 19617 if (file_type == TCC_OUTPUT_EXE) { 19618 uint8_t *p, *p_end; 19619 19620 p = s1->plt->data; 19621 p_end = p + s1->plt->data_offset; 19622 if (p < p_end) { 19623 #if defined(TCC_TARGET_I386) 19624 put32(p + 2, get32(p + 2) + s1->got->sh_addr); 19625 put32(p + 8, get32(p + 8) + s1->got->sh_addr); 19626 p += 16; 19627 while (p < p_end) { 19628 put32(p + 2, get32(p + 2) + s1->got->sh_addr); 19629 p += 16; 19630 } 19631 #elif defined(TCC_TARGET_ARM) 19632 int x; 19633 x=s1->got->sh_addr - s1->plt->sh_addr - 12; 19634 p +=16; 19635 while (p < p_end) { 19636 put32(p + 12, x + get32(p + 12) + s1->plt->data - p); 19637 p += 16; 19638 } 19639 #elif defined(TCC_TARGET_C67) 19640 /* XXX: TODO */ 19641 #else 19642 #error unsupported CPU 19643 #endif 19644 } 19645 } 19646 19647 /* relocate symbols in .dynsym */ 19648 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset); 19649 for(sym = (Elf32_Sym *)s1->dynsym->data + 1; 19650 sym < sym_end; 19651 sym++) { 19652 if (sym->st_shndx == SHN_UNDEF) { 19653 /* relocate to the PLT if the symbol corresponds 19654 to a PLT entry */ 19655 if (sym->st_value) 19656 sym->st_value += s1->plt->sh_addr; 19657 } else if (sym->st_shndx < SHN_LORESERVE) { 19658 /* do symbol relocation */ 19659 sym->st_value += s1->sections[sym->st_shndx]->sh_addr; 19660 } 19661 } 19662 19663 /* put dynamic section entries */ 19664 dynamic->data_offset = saved_dynamic_data_offset; 19665 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr); 19666 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr); 19667 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr); 19668 put_dt(dynamic, DT_STRSZ, dynstr->data_offset); 19669 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym)); 19670 put_dt(dynamic, DT_REL, rel_addr); 19671 put_dt(dynamic, DT_RELSZ, rel_size); 19672 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel)); 19673 put_dt(dynamic, DT_NULL, 0); 19674 } 19675 19676 ehdr.e_phentsize = sizeof(Elf32_Phdr); 19677 ehdr.e_phnum = phnum; 19678 ehdr.e_phoff = sizeof(Elf32_Ehdr); 19679 } 19680 19681 /* all other sections come after */ 19682 for(i = 1; i < s1->nb_sections; i++) { 19683 s = s1->sections[i]; 19684 if (phnum > 0 && (s->sh_flags & SHF_ALLOC)) 19685 continue; 19686 section_order[sh_order_index++] = i; 19687 19688 file_offset = (file_offset + s->sh_addralign - 1) & 19689 ~(s->sh_addralign - 1); 19690 s->sh_offset = file_offset; 19691 if (s->sh_type != SHT_NOBITS) 19692 file_offset += s->sh_size; 19693 } 19694 19695 /* if building executable or DLL, then relocate each section 19696 except the GOT which is already relocated */ 19697 if (file_type != TCC_OUTPUT_OBJ) { 19698 relocate_syms(s1, 0); 19699 19700 if (s1->nb_errors != 0) { 19701 fail: 19702 ret = -1; 19703 goto the_end; 19704 } 19705 19706 /* relocate sections */ 19707 /* XXX: ignore sections with allocated relocations ? */ 19708 for(i = 1; i < s1->nb_sections; i++) { 19709 s = s1->sections[i]; 19710 if (s->reloc && s != s1->got) 19711 relocate_section(s1, s); 19712 } 19713 19714 /* relocate relocation entries if the relocation tables are 19715 allocated in the executable */ 19716 for(i = 1; i < s1->nb_sections; i++) { 19717 s = s1->sections[i]; 19718 if ((s->sh_flags & SHF_ALLOC) && 19719 s->sh_type == SHT_REL) { 19720 relocate_rel(s1, s); 19721 } 19722 } 19723 19724 /* get entry point address */ 19725 if (file_type == TCC_OUTPUT_EXE) 19726 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start"); 19727 else 19728 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ 19729 } 19730 19731 /* write elf file */ 19732 if (file_type == TCC_OUTPUT_OBJ) 19733 mode = 0666; 19734 else 19735 mode = 0777; 19736 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 19737 if (fd < 0) { 19738 error_noabort("could not write '%s'", filename); 19739 goto fail; 19740 } 19741 f = fdopen(fd, "wb"); 19742 19743 #ifdef TCC_TARGET_COFF 19744 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) { 19745 tcc_output_coff(s1, f); 19746 } else 19747 #endif 19748 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) { 19749 sort_syms(s1, symtab_section); 19750 19751 /* align to 4 */ 19752 file_offset = (file_offset + 3) & -4; 19753 19754 /* fill header */ 19755 ehdr.e_ident[0] = ELFMAG0; 19756 ehdr.e_ident[1] = ELFMAG1; 19757 ehdr.e_ident[2] = ELFMAG2; 19758 ehdr.e_ident[3] = ELFMAG3; 19759 ehdr.e_ident[4] = ELFCLASS32; 19760 ehdr.e_ident[5] = ELFDATA2LSB; 19761 ehdr.e_ident[6] = EV_CURRENT; 19762 #ifdef __FreeBSD__ 19763 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD; 19764 #endif 19765 #ifdef TCC_TARGET_ARM 19766 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; 19767 #endif 19768 switch(file_type) { 19769 default: 19770 case TCC_OUTPUT_EXE: 19771 ehdr.e_type = ET_EXEC; 19772 break; 19773 case TCC_OUTPUT_DLL: 19774 ehdr.e_type = ET_DYN; 19775 break; 19776 case TCC_OUTPUT_OBJ: 19777 ehdr.e_type = ET_REL; 19778 break; 19779 } 19780 ehdr.e_machine = EM_TCC_TARGET; 19781 ehdr.e_version = EV_CURRENT; 19782 ehdr.e_shoff = file_offset; 19783 ehdr.e_ehsize = sizeof(Elf32_Ehdr); 19784 ehdr.e_shentsize = sizeof(Elf32_Shdr); 19785 ehdr.e_shnum = shnum; 19786 ehdr.e_shstrndx = shnum - 1; 19787 19788 dummy_size_t = fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f); 19789 dummy_size_t = fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f); 19790 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr); 19791 19792 for(i=1;i<s1->nb_sections;i++) { 19793 s = s1->sections[section_order[i]]; 19794 if (s->sh_type != SHT_NOBITS) { 19795 while (offset < s->sh_offset) { 19796 fputc(0, f); 19797 offset++; 19798 } 19799 size = s->sh_size; 19800 dummy_size_t = fwrite(s->data, 1, size, f); 19801 offset += size; 19802 } 19803 } 19804 19805 /* output section headers */ 19806 while (offset < ehdr.e_shoff) { 19807 fputc(0, f); 19808 offset++; 19809 } 19810 19811 for(i=0;i<s1->nb_sections;i++) { 19812 sh = &shdr; 19813 memset(sh, 0, sizeof(Elf32_Shdr)); 19814 s = s1->sections[i]; 19815 if (s) { 19816 sh->sh_name = s->sh_name; 19817 sh->sh_type = s->sh_type; 19818 sh->sh_flags = s->sh_flags; 19819 sh->sh_entsize = s->sh_entsize; 19820 sh->sh_info = s->sh_info; 19821 if (s->link) 19822 sh->sh_link = s->link->sh_num; 19823 sh->sh_addralign = s->sh_addralign; 19824 sh->sh_addr = s->sh_addr; 19825 sh->sh_offset = s->sh_offset; 19826 sh->sh_size = s->sh_size; 19827 } 19828 dummy_size_t = fwrite(sh, 1, sizeof(Elf32_Shdr), f); 19829 } 19830 } else { 19831 tcc_output_binary(s1, f, section_order); 19832 } 19833 fclose(f); 19834 19835 ret = 0; 19836 the_end: 19837 tcc_free(s1->symtab_to_dynsym); 19838 tcc_free(section_order); 19839 tcc_free(phdr); 19840 tcc_free(s1->got_offsets); 19841 return ret; 19842 } 19843 19844 static void *load_data(int fd, unsigned long file_offset, unsigned long size) 19845 { 19846 void *data; 19847 19848 data = tcc_malloc(size); 19849 lseek(fd, file_offset, SEEK_SET); 19850 dummy_size_t = read(fd, data, size); 19851 return data; 19852 } 19853 19854 typedef struct SectionMergeInfo { 19855 Section *s; /* corresponding existing section */ 19856 unsigned long offset; /* offset of the new section in the existing section */ 19857 uint8_t new_section; /* true if section 's' was added */ 19858 uint8_t link_once; /* true if link once section */ 19859 } SectionMergeInfo; 19860 19861 /* load an object file and merge it with current files */ 19862 /* XXX: handle correctly stab (debug) info */ 19863 static int tcc_load_object_file(TCCState *s1, 19864 int fd, unsigned long file_offset) 19865 { 19866 Elf32_Ehdr ehdr; 19867 Elf32_Shdr *shdr, *sh; 19868 int size, i, j, offset, offseti, nb_syms, sym_index, ret; 19869 unsigned char *strsec, *strtab; 19870 int *old_to_new_syms; 19871 char *sh_name, *name; 19872 SectionMergeInfo *sm_table, *sm; 19873 Elf32_Sym *sym, *symtab; 19874 Elf32_Rel *rel, *rel_end; 19875 Section *s; 19876 19877 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) 19878 goto fail1; 19879 if (ehdr.e_ident[0] != ELFMAG0 || 19880 ehdr.e_ident[1] != ELFMAG1 || 19881 ehdr.e_ident[2] != ELFMAG2 || 19882 ehdr.e_ident[3] != ELFMAG3) 19883 goto fail1; 19884 /* test if object file */ 19885 if (ehdr.e_type != ET_REL) 19886 goto fail1; 19887 /* test CPU specific stuff */ 19888 if (ehdr.e_ident[5] != ELFDATA2LSB || 19889 ehdr.e_machine != EM_TCC_TARGET) { 19890 fail1: 19891 error_noabort("invalid object file"); 19892 return -1; 19893 } 19894 /* read sections */ 19895 shdr = load_data(fd, file_offset + ehdr.e_shoff, 19896 sizeof(Elf32_Shdr) * ehdr.e_shnum); 19897 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum); 19898 19899 /* load section names */ 19900 sh = &shdr[ehdr.e_shstrndx]; 19901 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); 19902 19903 /* load symtab and strtab */ 19904 old_to_new_syms = NULL; 19905 symtab = NULL; 19906 strtab = NULL; 19907 nb_syms = 0; 19908 for(i = 1; i < ehdr.e_shnum; i++) { 19909 sh = &shdr[i]; 19910 if (sh->sh_type == SHT_SYMTAB) { 19911 if (symtab) { 19912 error_noabort("object must contain only one symtab"); 19913 fail: 19914 ret = -1; 19915 goto the_end; 19916 } 19917 nb_syms = sh->sh_size / sizeof(Elf32_Sym); 19918 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); 19919 sm_table[i].s = symtab_section; 19920 19921 /* now load strtab */ 19922 sh = &shdr[sh->sh_link]; 19923 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size); 19924 } 19925 } 19926 19927 /* now examine each section and try to merge its content with the 19928 ones in memory */ 19929 for(i = 1; i < ehdr.e_shnum; i++) { 19930 /* no need to examine section name strtab */ 19931 if (i == ehdr.e_shstrndx) 19932 continue; 19933 sh = &shdr[i]; 19934 sh_name = strsec + sh->sh_name; 19935 /* ignore sections types we do not handle */ 19936 if (sh->sh_type != SHT_PROGBITS && 19937 sh->sh_type != SHT_REL && 19938 sh->sh_type != SHT_NOBITS) 19939 continue; 19940 if (sh->sh_addralign < 1) 19941 sh->sh_addralign = 1; 19942 /* find corresponding section, if any */ 19943 for(j = 1; j < s1->nb_sections;j++) { 19944 s = s1->sections[j]; 19945 if (!strcmp(s->name, sh_name)) { 19946 if (!strncmp(sh_name, ".gnu.linkonce", 19947 sizeof(".gnu.linkonce") - 1)) { 19948 /* if a 'linkonce' section is already present, we 19949 do not add it again. It is a little tricky as 19950 symbols can still be defined in 19951 it. */ 19952 sm_table[i].link_once = 1; 19953 goto next; 19954 } else { 19955 goto found; 19956 } 19957 } 19958 } 19959 /* not found: create new section */ 19960 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags); 19961 /* take as much info as possible from the section. sh_link and 19962 sh_info will be updated later */ 19963 s->sh_addralign = sh->sh_addralign; 19964 s->sh_entsize = sh->sh_entsize; 19965 sm_table[i].new_section = 1; 19966 found: 19967 if (sh->sh_type != s->sh_type) { 19968 error_noabort("invalid section type"); 19969 goto fail; 19970 } 19971 19972 /* align start of section */ 19973 offset = s->data_offset; 19974 size = sh->sh_addralign - 1; 19975 offset = (offset + size) & ~size; 19976 if (sh->sh_addralign > s->sh_addralign) 19977 s->sh_addralign = sh->sh_addralign; 19978 s->data_offset = offset; 19979 sm_table[i].offset = offset; 19980 sm_table[i].s = s; 19981 /* concatenate sections */ 19982 size = sh->sh_size; 19983 if (sh->sh_type != SHT_NOBITS) { 19984 unsigned char *ptr; 19985 lseek(fd, file_offset + sh->sh_offset, SEEK_SET); 19986 ptr = section_ptr_add(s, size); 19987 dummy_size_t = read(fd, ptr, size); 19988 } else { 19989 s->data_offset += size; 19990 } 19991 next: ; 19992 } 19993 19994 /* second short pass to update sh_link and sh_info fields of new 19995 sections */ 19996 sm = sm_table; 19997 for(i = 1; i < ehdr.e_shnum; i++) { 19998 s = sm_table[i].s; 19999 if (!s || !sm_table[i].new_section) 20000 continue; 20001 sh = &shdr[i]; 20002 if (sh->sh_link > 0) 20003 s->link = sm_table[sh->sh_link].s; 20004 if (sh->sh_type == SHT_REL) { 20005 s->sh_info = sm_table[sh->sh_info].s->sh_num; 20006 /* update backward link */ 20007 s1->sections[s->sh_info]->reloc = s; 20008 } 20009 } 20010 20011 /* resolve symbols */ 20012 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int)); 20013 20014 sym = symtab + 1; 20015 for(i = 1; i < nb_syms; i++, sym++) { 20016 if (sym->st_shndx != SHN_UNDEF && 20017 sym->st_shndx < SHN_LORESERVE) { 20018 sm = &sm_table[sym->st_shndx]; 20019 if (sm->link_once) { 20020 /* if a symbol is in a link once section, we use the 20021 already defined symbol. It is very important to get 20022 correct relocations */ 20023 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { 20024 name = strtab + sym->st_name; 20025 sym_index = find_elf_sym(symtab_section, name); 20026 if (sym_index) 20027 old_to_new_syms[i] = sym_index; 20028 } 20029 continue; 20030 } 20031 /* if no corresponding section added, no need to add symbol */ 20032 if (!sm->s) 20033 continue; 20034 /* convert section number */ 20035 sym->st_shndx = sm->s->sh_num; 20036 /* offset value */ 20037 sym->st_value += sm->offset; 20038 } 20039 /* add symbol */ 20040 name = strtab + sym->st_name; 20041 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, 20042 sym->st_info, sym->st_other, 20043 sym->st_shndx, name); 20044 old_to_new_syms[i] = sym_index; 20045 } 20046 20047 /* third pass to patch relocation entries */ 20048 for(i = 1; i < ehdr.e_shnum; i++) { 20049 s = sm_table[i].s; 20050 if (!s) 20051 continue; 20052 sh = &shdr[i]; 20053 offset = sm_table[i].offset; 20054 switch(s->sh_type) { 20055 case SHT_REL: 20056 /* take relocation offset information */ 20057 offseti = sm_table[sh->sh_info].offset; 20058 rel_end = (Elf32_Rel *)(s->data + s->data_offset); 20059 for(rel = (Elf32_Rel *)(s->data + offset); 20060 rel < rel_end; 20061 rel++) { 20062 int type; 20063 unsigned sym_index; 20064 /* convert symbol index */ 20065 type = ELF32_R_TYPE(rel->r_info); 20066 sym_index = ELF32_R_SYM(rel->r_info); 20067 /* NOTE: only one symtab assumed */ 20068 if (sym_index >= nb_syms) 20069 goto invalid_reloc; 20070 sym_index = old_to_new_syms[sym_index]; 20071 if (!sym_index) { 20072 invalid_reloc: 20073 error_noabort("Invalid relocation entry"); 20074 goto fail; 20075 } 20076 rel->r_info = ELF32_R_INFO(sym_index, type); 20077 /* offset the relocation offset */ 20078 rel->r_offset += offseti; 20079 } 20080 break; 20081 default: 20082 break; 20083 } 20084 } 20085 20086 ret = 0; 20087 the_end: 20088 tcc_free(symtab); 20089 tcc_free(strtab); 20090 tcc_free(old_to_new_syms); 20091 tcc_free(sm_table); 20092 tcc_free(strsec); 20093 tcc_free(shdr); 20094 return ret; 20095 } 20096 20097 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */ 20098 20099 typedef struct ArchiveHeader { 20100 char ar_name[16]; /* name of this member */ 20101 char ar_date[12]; /* file mtime */ 20102 char ar_uid[6]; /* owner uid; printed as decimal */ 20103 char ar_gid[6]; /* owner gid; printed as decimal */ 20104 char ar_mode[8]; /* file mode, printed as octal */ 20105 char ar_size[10]; /* file size, printed as decimal */ 20106 char ar_fmag[2]; /* should contain ARFMAG */ 20107 } ArchiveHeader; 20108 20109 static int get_be32(const uint8_t *b) 20110 { 20111 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24); 20112 } 20113 20114 /* load only the objects which resolve undefined symbols */ 20115 static int tcc_load_alacarte(TCCState *s1, int fd, int size) 20116 { 20117 int i, bound, nsyms, sym_index, off, ret; 20118 uint8_t *data; 20119 const char *ar_names, *p; 20120 const uint8_t *ar_index; 20121 Elf32_Sym *sym; 20122 20123 data = tcc_malloc(size); 20124 if (read(fd, data, size) != size) 20125 goto fail; 20126 nsyms = get_be32(data); 20127 ar_index = data + 4; 20128 ar_names = ar_index + nsyms * 4; 20129 20130 do { 20131 bound = 0; 20132 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) { 20133 sym_index = find_elf_sym(symtab_section, p); 20134 if(sym_index) { 20135 sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; 20136 if(sym->st_shndx == SHN_UNDEF) { 20137 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); 20138 #if 0 20139 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx); 20140 #endif 20141 ++bound; 20142 lseek(fd, off, SEEK_SET); 20143 if(tcc_load_object_file(s1, fd, off) < 0) { 20144 fail: 20145 ret = -1; 20146 goto the_end; 20147 } 20148 } 20149 } 20150 } 20151 } while(bound); 20152 ret = 0; 20153 the_end: 20154 tcc_free(data); 20155 return ret; 20156 } 20157 20158 /* load a '.a' file */ 20159 static int tcc_load_archive(TCCState *s1, int fd) 20160 { 20161 ArchiveHeader hdr; 20162 char ar_size[11]; 20163 char ar_name[17]; 20164 char magic[8]; 20165 int size, len, i; 20166 unsigned long file_offset; 20167 20168 /* skip magic which was already checked */ 20169 dummy_size_t = read(fd, magic, sizeof(magic)); 20170 20171 for(;;) { 20172 len = read(fd, &hdr, sizeof(hdr)); 20173 if (len == 0) 20174 break; 20175 if (len != sizeof(hdr)) { 20176 error_noabort("invalid archive"); 20177 return -1; 20178 } 20179 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size)); 20180 ar_size[sizeof(hdr.ar_size)] = '\0'; 20181 size = strtol(ar_size, NULL, 0); 20182 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name)); 20183 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) { 20184 if (ar_name[i] != ' ') 20185 break; 20186 } 20187 ar_name[i + 1] = '\0'; 20188 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size); 20189 file_offset = lseek(fd, 0, SEEK_CUR); 20190 /* align to even */ 20191 size = (size + 1) & ~1; 20192 if (!strcmp(ar_name, "/")) { 20193 /* coff symbol table : we handle it */ 20194 if(s1->alacarte_link) 20195 return tcc_load_alacarte(s1, fd, size); 20196 } else if (!strcmp(ar_name, "//") || 20197 !strcmp(ar_name, "__.SYMDEF") || 20198 !strcmp(ar_name, "__.SYMDEF/") || 20199 !strcmp(ar_name, "ARFILENAMES/")) { 20200 /* skip symbol table or archive names */ 20201 } else { 20202 if (tcc_load_object_file(s1, fd, file_offset) < 0) 20203 return -1; 20204 } 20205 lseek(fd, file_offset + size, SEEK_SET); 20206 } 20207 return 0; 20208 } 20209 20210 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL 20211 is referenced by the user (so it should be added as DT_NEEDED in 20212 the generated ELF file) */ 20213 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) 20214 { 20215 Elf32_Ehdr ehdr; 20216 Elf32_Shdr *shdr, *sh, *sh1; 20217 int i, nb_syms, nb_dts, sym_bind, ret; 20218 Elf32_Sym *sym, *dynsym; 20219 Elf32_Dyn *dt, *dynamic; 20220 unsigned char *dynstr; 20221 const char *name, *soname, *p; 20222 DLLReference *dllref; 20223 20224 dummy_size_t = read(fd, &ehdr, sizeof(ehdr)); 20225 20226 /* test CPU specific stuff */ 20227 if (ehdr.e_ident[5] != ELFDATA2LSB || 20228 ehdr.e_machine != EM_TCC_TARGET) { 20229 error_noabort("bad architecture"); 20230 return -1; 20231 } 20232 20233 /* read sections */ 20234 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum); 20235 20236 /* load dynamic section and dynamic symbols */ 20237 nb_syms = 0; 20238 nb_dts = 0; 20239 dynamic = NULL; 20240 dynsym = NULL; /* avoid warning */ 20241 dynstr = NULL; /* avoid warning */ 20242 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) { 20243 switch(sh->sh_type) { 20244 case SHT_DYNAMIC: 20245 nb_dts = sh->sh_size / sizeof(Elf32_Dyn); 20246 dynamic = load_data(fd, sh->sh_offset, sh->sh_size); 20247 break; 20248 case SHT_DYNSYM: 20249 nb_syms = sh->sh_size / sizeof(Elf32_Sym); 20250 dynsym = load_data(fd, sh->sh_offset, sh->sh_size); 20251 sh1 = &shdr[sh->sh_link]; 20252 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size); 20253 break; 20254 default: 20255 break; 20256 } 20257 } 20258 20259 /* compute the real library name */ 20260 soname = filename; 20261 p = strrchr(soname, '/'); 20262 if (p) 20263 soname = p + 1; 20264 20265 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { 20266 if (dt->d_tag == DT_SONAME) { 20267 soname = dynstr + dt->d_un.d_val; 20268 } 20269 } 20270 20271 /* if the dll is already loaded, do not load it */ 20272 for(i = 0; i < s1->nb_loaded_dlls; i++) { 20273 dllref = s1->loaded_dlls[i]; 20274 if (!strcmp(soname, dllref->name)) { 20275 /* but update level if needed */ 20276 if (level < dllref->level) 20277 dllref->level = level; 20278 ret = 0; 20279 goto the_end; 20280 } 20281 } 20282 20283 // printf("loading dll '%s'\n", soname); 20284 20285 /* add the dll and its level */ 20286 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname)); 20287 dllref->level = level; 20288 strcpy(dllref->name, soname); 20289 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref); 20290 20291 /* add dynamic symbols in dynsym_section */ 20292 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) { 20293 sym_bind = ELF32_ST_BIND(sym->st_info); 20294 if (sym_bind == STB_LOCAL) 20295 continue; 20296 name = dynstr + sym->st_name; 20297 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, 20298 sym->st_info, sym->st_other, sym->st_shndx, name); 20299 } 20300 20301 /* load all referenced DLLs */ 20302 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { 20303 switch(dt->d_tag) { 20304 case DT_NEEDED: 20305 name = dynstr + dt->d_un.d_val; 20306 for(i = 0; i < s1->nb_loaded_dlls; i++) { 20307 dllref = s1->loaded_dlls[i]; 20308 if (!strcmp(name, dllref->name)) 20309 goto already_loaded; 20310 } 20311 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { 20312 error_noabort("referenced dll '%s' not found", name); 20313 ret = -1; 20314 goto the_end; 20315 } 20316 already_loaded: 20317 break; 20318 } 20319 } 20320 ret = 0; 20321 the_end: 20322 tcc_free(dynstr); 20323 tcc_free(dynsym); 20324 tcc_free(dynamic); 20325 tcc_free(shdr); 20326 return ret; 20327 } 20328 20329 #define LD_TOK_NAME 256 20330 #define LD_TOK_EOF (-1) 20331 20332 /* return next ld script token */ 20333 static int ld_next(TCCState *s1, char *name, int name_size) 20334 { 20335 int c; 20336 char *q; 20337 20338 redo: 20339 switch(ch) { 20340 case ' ': 20341 case '\t': 20342 case '\f': 20343 case '\v': 20344 case '\r': 20345 case '\n': 20346 inp(); 20347 goto redo; 20348 case '/': 20349 minp(); 20350 if (ch == '*') { 20351 file->buf_ptr = parse_comment(file->buf_ptr); 20352 ch = file->buf_ptr[0]; 20353 goto redo; 20354 } else { 20355 q = name; 20356 *q++ = '/'; 20357 goto parse_name; 20358 } 20359 break; 20360 case 'a' ... 'z': 20361 case 'A' ... 'Z': 20362 case '_': 20363 case '\\': 20364 case '.': 20365 case '$': 20366 case '~': 20367 q = name; 20368 parse_name: 20369 for(;;) { 20370 if (!((ch >= 'a' && ch <= 'z') || 20371 (ch >= 'A' && ch <= 'Z') || 20372 (ch >= '0' && ch <= '9') || 20373 strchr("/.-_+=$:\\,~", ch))) 20374 break; 20375 if ((q - name) < name_size - 1) { 20376 *q++ = ch; 20377 } 20378 minp(); 20379 } 20380 *q = '\0'; 20381 c = LD_TOK_NAME; 20382 break; 20383 case CH_EOF: 20384 c = LD_TOK_EOF; 20385 break; 20386 default: 20387 c = ch; 20388 inp(); 20389 break; 20390 } 20391 #if 0 20392 printf("tok=%c %d\n", c, c); 20393 if (c == LD_TOK_NAME) 20394 printf(" name=%s\n", name); 20395 #endif 20396 return c; 20397 } 20398 20399 /* interpret a subset of GNU ldscripts to handle the dummy libc.so 20400 files */ 20401 static int tcc_load_ldscript(TCCState *s1) 20402 { 20403 char cmd[64]; 20404 char filename[1024]; 20405 int t; 20406 20407 ch = file->buf_ptr[0]; 20408 ch = handle_eob(); 20409 for(;;) { 20410 t = ld_next(s1, cmd, sizeof(cmd)); 20411 if (t == LD_TOK_EOF) 20412 return 0; 20413 else if (t != LD_TOK_NAME) 20414 return -1; 20415 if (!strcmp(cmd, "INPUT") || 20416 !strcmp(cmd, "GROUP")) { 20417 t = ld_next(s1, cmd, sizeof(cmd)); 20418 if (t != '(') 20419 expect("("); 20420 t = ld_next(s1, filename, sizeof(filename)); 20421 for(;;) { 20422 if (t == LD_TOK_EOF) { 20423 error_noabort("unexpected end of file"); 20424 return -1; 20425 } else if (t == ')') { 20426 break; 20427 } else if (t != LD_TOK_NAME) { 20428 error_noabort("filename expected"); 20429 return -1; 20430 } 20431 tcc_add_file(s1, filename); 20432 t = ld_next(s1, filename, sizeof(filename)); 20433 if (t == ',') { 20434 t = ld_next(s1, filename, sizeof(filename)); 20435 } 20436 } 20437 } else if (!strcmp(cmd, "OUTPUT_FORMAT") || 20438 !strcmp(cmd, "TARGET")) { 20439 /* ignore some commands */ 20440 t = ld_next(s1, cmd, sizeof(cmd)); 20441 if (t != '(') 20442 expect("("); 20443 for(;;) { 20444 t = ld_next(s1, filename, sizeof(filename)); 20445 if (t == LD_TOK_EOF) { 20446 error_noabort("unexpected end of file"); 20447 return -1; 20448 } else if (t == ')') { 20449 break; 20450 } 20451 } 20452 } else { 20453 return -1; 20454 } 20455 } 20456 return 0; 20457 } 20458 //--------------------------------------------------------------------------- 20459 20460 #ifdef TCC_TARGET_COFF 20461 #include "tcccoff.c" 20462 #endif 20463 20464 #ifdef TCC_TARGET_PE 20465 #include "tccpe.c" 20466 #endif 20467 20468 /* print the position in the source file of PC value 'pc' by reading 20469 the stabs debug information */ 20470 static void rt_printline(unsigned long wanted_pc) 20471 { 20472 Stab_Sym *sym, *sym_end; 20473 char func_name[128], last_func_name[128]; 20474 unsigned long func_addr, last_pc, pc; 20475 const char *incl_files[INCLUDE_STACK_SIZE]; 20476 int incl_index, len, last_line_num, i; 20477 const char *str, *p; 20478 20479 fprintf(stderr, "0x%08lx:", wanted_pc); 20480 20481 func_name[0] = '\0'; 20482 func_addr = 0; 20483 incl_index = 0; 20484 last_func_name[0] = '\0'; 20485 last_pc = 0xffffffff; 20486 last_line_num = 1; 20487 sym = (Stab_Sym *)stab_section->data + 1; 20488 sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); 20489 while (sym < sym_end) { 20490 switch(sym->n_type) { 20491 /* function start or end */ 20492 case N_FUN: 20493 if (sym->n_strx == 0) { 20494 /* we test if between last line and end of function */ 20495 pc = sym->n_value + func_addr; 20496 if (wanted_pc >= last_pc && wanted_pc < pc) 20497 goto found; 20498 func_name[0] = '\0'; 20499 func_addr = 0; 20500 } else { 20501 str = stabstr_section->data + sym->n_strx; 20502 p = strchr(str, ':'); 20503 if (!p) { 20504 pstrcpy(func_name, sizeof(func_name), str); 20505 } else { 20506 len = p - str; 20507 if (len > sizeof(func_name) - 1) 20508 len = sizeof(func_name) - 1; 20509 memcpy(func_name, str, len); 20510 func_name[len] = '\0'; 20511 } 20512 func_addr = sym->n_value; 20513 } 20514 break; 20515 /* line number info */ 20516 case N_SLINE: 20517 pc = sym->n_value + func_addr; 20518 if (wanted_pc >= last_pc && wanted_pc < pc) 20519 goto found; 20520 last_pc = pc; 20521 last_line_num = sym->n_desc; 20522 /* XXX: slow! */ 20523 strcpy(last_func_name, func_name); 20524 break; 20525 /* include files */ 20526 case N_BINCL: 20527 str = stabstr_section->data + sym->n_strx; 20528 add_incl: 20529 if (incl_index < INCLUDE_STACK_SIZE) { 20530 incl_files[incl_index++] = str; 20531 } 20532 break; 20533 case N_EINCL: 20534 if (incl_index > 1) 20535 incl_index--; 20536 break; 20537 case N_SO: 20538 if (sym->n_strx == 0) { 20539 incl_index = 0; /* end of translation unit */ 20540 } else { 20541 str = stabstr_section->data + sym->n_strx; 20542 /* do not add path */ 20543 len = strlen(str); 20544 if (len > 0 && str[len - 1] != '/') 20545 goto add_incl; 20546 } 20547 break; 20548 } 20549 sym++; 20550 } 20551 20552 /* second pass: we try symtab symbols (no line number info) */ 20553 incl_index = 0; 20554 { 20555 Elf32_Sym *sym, *sym_end; 20556 int type; 20557 20558 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset); 20559 for(sym = (Elf32_Sym *)symtab_section->data + 1; 20560 sym < sym_end; 20561 sym++) { 20562 type = ELF32_ST_TYPE(sym->st_info); 20563 if (type == STT_FUNC) { 20564 if (wanted_pc >= sym->st_value && 20565 wanted_pc < sym->st_value + sym->st_size) { 20566 pstrcpy(last_func_name, sizeof(last_func_name), 20567 strtab_section->data + sym->st_name); 20568 goto found; 20569 } 20570 } 20571 } 20572 } 20573 /* did not find any info: */ 20574 fprintf(stderr, " ???\n"); 20575 return; 20576 found: 20577 if (last_func_name[0] != '\0') { 20578 fprintf(stderr, " %s()", last_func_name); 20579 } 20580 if (incl_index > 0) { 20581 fprintf(stderr, " (%s:%d", 20582 incl_files[incl_index - 1], last_line_num); 20583 for(i = incl_index - 2; i >= 0; i--) 20584 fprintf(stderr, ", included from %s", incl_files[i]); 20585 fprintf(stderr, ")"); 20586 } 20587 fprintf(stderr, "\n"); 20588 } 20589 20590 #if !defined(WIN32) && !defined(CONFIG_TCCBOOT) 20591 20592 /* return the PC at frame level 'level'. Return non zero if not found */ 20593 static int rt_get_caller_pc(unsigned long *paddr, 20594 ucontext_t *uc, int level) 20595 { 20596 unsigned long fp __attribute__((unused)); 20597 //int i; 20598 20599 if (level == 0) { 20600 *paddr = 12345; //uc->uc_mcontext.gregs[REG_EIP]; 20601 return 0; 20602 } else { 20603 fp = 23456; //uc->uc_mcontext.gregs[REG_EBP]; 20604 return 0; 20605 } 20606 } 20607 20608 /* emit a run time error at position 'pc' */ 20609 void rt_error(ucontext_t *uc, const char *fmt, ...) 20610 { 20611 va_list ap; 20612 unsigned long pc = 0; // shut gcc up 20613 int i; 20614 20615 va_start(ap, fmt); 20616 fprintf(stderr, "Runtime error: "); 20617 vfprintf(stderr, fmt, ap); 20618 fprintf(stderr, "\n"); 20619 for(i=0;i<num_callers;i++) { 20620 if (rt_get_caller_pc(&pc, uc, i) < 0) 20621 break; 20622 if (i == 0) 20623 fprintf(stderr, "at "); 20624 else 20625 fprintf(stderr, "by "); 20626 rt_printline(pc); 20627 } 20628 exit(255); 20629 va_end(ap); 20630 } 20631 20632 /* signal handler for fatal errors */ 20633 static void sig_error(int signum, siginfo_t *siginf, void *puc) 20634 { 20635 ucontext_t *uc = puc; 20636 20637 switch(signum) { 20638 case SIGFPE: 20639 switch(siginf->si_code) { 20640 case FPE_INTDIV: 20641 case FPE_FLTDIV: 20642 rt_error(uc, "division by zero"); 20643 break; 20644 default: 20645 rt_error(uc, "floating point exception"); 20646 break; 20647 } 20648 break; 20649 case SIGBUS: 20650 case SIGSEGV: 20651 if (rt_bound_error_msg && *rt_bound_error_msg) 20652 rt_error(uc, *rt_bound_error_msg); 20653 else 20654 rt_error(uc, "dereferencing invalid pointer"); 20655 break; 20656 case SIGILL: 20657 rt_error(uc, "illegal instruction"); 20658 break; 20659 case SIGABRT: 20660 rt_error(uc, "abort() called"); 20661 break; 20662 default: 20663 rt_error(uc, "caught signal %d", signum); 20664 break; 20665 } 20666 exit(255); 20667 } 20668 #endif 20669 20670 /* do all relocations (needed before using tcc_get_symbol()) */ 20671 int tcc_relocate(TCCState *s1) 20672 { 20673 Section *s; 20674 int i; 20675 20676 s1->nb_errors = 0; 20677 20678 #ifdef TCC_TARGET_PE 20679 pe_add_runtime(s1); 20680 #else 20681 tcc_add_runtime(s1); 20682 #endif 20683 20684 relocate_common_syms(); 20685 20686 tcc_add_linker_symbols(s1); 20687 20688 build_got_entries(s1); 20689 20690 /* compute relocation address : section are relocated in place. We 20691 also alloc the bss space */ 20692 for(i = 1; i < s1->nb_sections; i++) { 20693 s = s1->sections[i]; 20694 if (s->sh_flags & SHF_ALLOC) { 20695 if (s->sh_type == SHT_NOBITS) 20696 s->data = tcc_mallocz(s->data_offset); 20697 s->sh_addr = (unsigned long)s->data; 20698 } 20699 } 20700 20701 relocate_syms(s1, 1); 20702 20703 if (s1->nb_errors != 0) 20704 return -1; 20705 20706 /* relocate each section */ 20707 for(i = 1; i < s1->nb_sections; i++) { 20708 s = s1->sections[i]; 20709 if (s->reloc) 20710 relocate_section(s1, s); 20711 } 20712 return 0; 20713 } 20714 20715 /* launch the compiled program with the given arguments */ 20716 int tcc_run(TCCState *s1, int argc, char **argv) 20717 { 20718 int (*prog_main)(int, char **); 20719 20720 if (tcc_relocate(s1) < 0) 20721 return -1; 20722 20723 prog_main = tcc_get_symbol_err(s1, "main"); 20724 20725 if (do_debug) { 20726 #if defined(WIN32) || defined(CONFIG_TCCBOOT) 20727 error("debug mode currently not available for Windows"); 20728 #else 20729 struct sigaction sigact; 20730 /* install TCC signal handlers to print debug info on fatal 20731 runtime errors */ 20732 sigact.sa_flags = SA_SIGINFO | SA_RESETHAND; 20733 sigact.sa_sigaction = sig_error; 20734 sigemptyset(&sigact.sa_mask); 20735 sigaction(SIGFPE, &sigact, NULL); 20736 sigaction(SIGILL, &sigact, NULL); 20737 sigaction(SIGSEGV, &sigact, NULL); 20738 sigaction(SIGBUS, &sigact, NULL); 20739 sigaction(SIGABRT, &sigact, NULL); 20740 #endif 20741 } 20742 20743 #ifdef CONFIG_TCC_BCHECK 20744 if (do_bounds_check) { 20745 void (*bound_init)(void); 20746 20747 /* set error function */ 20748 rt_bound_error_msg = (void *)tcc_get_symbol_err(s1, 20749 "__bound_error_msg"); 20750 20751 /* XXX: use .init section so that it also work in binary ? */ 20752 bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init"); 20753 bound_init(); 20754 } 20755 #endif 20756 return (*prog_main)(argc, argv); 20757 } 20758 20759 TCCState *tcc_new(void) 20760 { 20761 const char *p, *r; 20762 TCCState *s; 20763 TokenSym *ts __attribute__((unused)); 20764 int i, c; 20765 20766 s = tcc_mallocz(sizeof(TCCState)); 20767 if (!s) 20768 return NULL; 20769 tcc_state = s; 20770 s->output_type = TCC_OUTPUT_MEMORY; 20771 20772 /* init isid table */ 20773 for(i=0;i<256;i++) 20774 isidnum_table[i] = isid(i) || isnum(i); 20775 20776 /* add all tokens */ 20777 table_ident = NULL; 20778 memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); 20779 20780 tok_ident = TOK_IDENT; 20781 p = tcc_keywords; 20782 while (*p) { 20783 r = p; 20784 for(;;) { 20785 c = *r++; 20786 if (c == '\0') 20787 break; 20788 } 20789 ts = tok_alloc(p, r - p - 1); 20790 p = r; 20791 } 20792 20793 /* we add dummy defines for some special macros to speed up tests 20794 and to have working defined() */ 20795 define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL); 20796 define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL); 20797 define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL); 20798 define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL); 20799 20800 /* standard defines */ 20801 tcc_define_symbol(s, "__STDC__", NULL); 20802 #if defined(TCC_TARGET_I386) 20803 tcc_define_symbol(s, "__i386__", NULL); 20804 #endif 20805 #if defined(TCC_TARGET_ARM) 20806 tcc_define_symbol(s, "__ARM_ARCH_4__", NULL); 20807 tcc_define_symbol(s, "__arm_elf__", NULL); 20808 tcc_define_symbol(s, "__arm_elf", NULL); 20809 tcc_define_symbol(s, "arm_elf", NULL); 20810 tcc_define_symbol(s, "__arm__", NULL); 20811 tcc_define_symbol(s, "__arm", NULL); 20812 tcc_define_symbol(s, "arm", NULL); 20813 tcc_define_symbol(s, "__APCS_32__", NULL); 20814 #endif 20815 #if defined(linux) 20816 tcc_define_symbol(s, "__linux__", NULL); 20817 tcc_define_symbol(s, "linux", NULL); 20818 #endif 20819 /* tiny C specific defines */ 20820 tcc_define_symbol(s, "__TINYC__", NULL); 20821 20822 /* tiny C & gcc defines */ 20823 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int"); 20824 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int"); 20825 tcc_define_symbol(s, "__WCHAR_TYPE__", "int"); 20826 20827 /* default library paths */ 20828 #ifdef TCC_TARGET_PE 20829 { 20830 char buf[1024]; 20831 snprintf(buf, sizeof(buf), "%s/lib", tcc_lib_path); 20832 tcc_add_library_path(s, buf); 20833 } 20834 #else 20835 tcc_add_library_path(s, "/usr/local/lib"); 20836 tcc_add_library_path(s, "/usr/lib"); 20837 tcc_add_library_path(s, "/lib"); 20838 #endif 20839 20840 /* no section zero */ 20841 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL); 20842 20843 /* create standard sections */ 20844 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); 20845 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); 20846 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); 20847 20848 /* symbols are always generated for linking stage */ 20849 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, 20850 ".strtab", 20851 ".hashtab", SHF_PRIVATE); 20852 strtab_section = symtab_section->link; 20853 20854 /* private symbol table for dynamic symbols */ 20855 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE, 20856 ".dynstrtab", 20857 ".dynhashtab", SHF_PRIVATE); 20858 s->alacarte_link = 1; 20859 20860 #ifdef CHAR_IS_UNSIGNED 20861 s->char_is_unsigned = 1; 20862 #endif 20863 #if defined(TCC_TARGET_PE) && 0 20864 /* XXX: currently the PE linker is not ready to support that */ 20865 s->leading_underscore = 1; 20866 #endif 20867 return s; 20868 } 20869 20870 void tcc_delete(TCCState *s1) 20871 { 20872 int i, n; 20873 20874 /* free -D defines */ 20875 free_defines(NULL); 20876 20877 /* free tokens */ 20878 n = tok_ident - TOK_IDENT; 20879 for(i = 0; i < n; i++) 20880 tcc_free(table_ident[i]); 20881 tcc_free(table_ident); 20882 20883 /* free all sections */ 20884 20885 free_section(symtab_section->hash); 20886 20887 free_section(s1->dynsymtab_section->hash); 20888 free_section(s1->dynsymtab_section->link); 20889 free_section(s1->dynsymtab_section); 20890 20891 for(i = 1; i < s1->nb_sections; i++) 20892 free_section(s1->sections[i]); 20893 tcc_free(s1->sections); 20894 20895 /* free loaded dlls array */ 20896 for(i = 0; i < s1->nb_loaded_dlls; i++) 20897 tcc_free(s1->loaded_dlls[i]); 20898 tcc_free(s1->loaded_dlls); 20899 20900 /* library paths */ 20901 for(i = 0; i < s1->nb_library_paths; i++) 20902 tcc_free(s1->library_paths[i]); 20903 tcc_free(s1->library_paths); 20904 20905 /* cached includes */ 20906 for(i = 0; i < s1->nb_cached_includes; i++) 20907 tcc_free(s1->cached_includes[i]); 20908 tcc_free(s1->cached_includes); 20909 20910 for(i = 0; i < s1->nb_include_paths; i++) 20911 tcc_free(s1->include_paths[i]); 20912 tcc_free(s1->include_paths); 20913 20914 for(i = 0; i < s1->nb_sysinclude_paths; i++) 20915 tcc_free(s1->sysinclude_paths[i]); 20916 tcc_free(s1->sysinclude_paths); 20917 20918 tcc_free(s1); 20919 } 20920 20921 int tcc_add_include_path(TCCState *s1, const char *pathname) 20922 { 20923 char *pathname1; 20924 20925 pathname1 = tcc_strdup(pathname); 20926 dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1); 20927 return 0; 20928 } 20929 20930 int tcc_add_sysinclude_path(TCCState *s1, const char *pathname) 20931 { 20932 char *pathname1; 20933 20934 pathname1 = tcc_strdup(pathname); 20935 dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1); 20936 return 0; 20937 } 20938 20939 static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) 20940 { 20941 const char *ext, *filename1; 20942 Elf32_Ehdr ehdr; 20943 int fd, ret; 20944 BufferedFile *saved_file; 20945 20946 /* find source file type with extension */ 20947 filename1 = strrchr(filename, '/'); 20948 if (filename1) 20949 filename1++; 20950 else 20951 filename1 = filename; 20952 ext = strrchr(filename1, '.'); 20953 if (ext) 20954 ext++; 20955 20956 /* open the file */ 20957 saved_file = file; 20958 file = tcc_open(s1, filename); 20959 if (!file) { 20960 if (flags & AFF_PRINT_ERROR) { 20961 error_noabort("file '%s' not found", filename); 20962 } 20963 ret = -1; 20964 goto fail1; 20965 } 20966 20967 if (!ext || !strcmp(ext, "c")) { 20968 /* C file assumed */ 20969 ret = tcc_compile(s1); 20970 } else 20971 #ifdef CONFIG_TCC_ASM 20972 if (!strcmp(ext, "S")) { 20973 /* preprocessed assembler */ 20974 ret = tcc_assemble(s1, 1); 20975 } else if (!strcmp(ext, "s")) { 20976 /* non preprocessed assembler */ 20977 ret = tcc_assemble(s1, 0); 20978 } else 20979 #endif 20980 #ifdef TCC_TARGET_PE 20981 if (!strcmp(ext, "def")) { 20982 ret = pe_load_def_file(s1, fdopen(file->fd, "rb")); 20983 } else 20984 #endif 20985 { 20986 fd = file->fd; 20987 /* assume executable format: auto guess file type */ 20988 ret = read(fd, &ehdr, sizeof(ehdr)); 20989 lseek(fd, 0, SEEK_SET); 20990 if (ret <= 0) { 20991 error_noabort("could not read header"); 20992 goto fail; 20993 } else if (ret != sizeof(ehdr)) { 20994 goto try_load_script; 20995 } 20996 20997 if (ehdr.e_ident[0] == ELFMAG0 && 20998 ehdr.e_ident[1] == ELFMAG1 && 20999 ehdr.e_ident[2] == ELFMAG2 && 21000 ehdr.e_ident[3] == ELFMAG3) { 21001 file->line_num = 0; /* do not display line number if error */ 21002 if (ehdr.e_type == ET_REL) { 21003 ret = tcc_load_object_file(s1, fd, 0); 21004 } else if (ehdr.e_type == ET_DYN) { 21005 if (s1->output_type == TCC_OUTPUT_MEMORY) { 21006 #ifdef TCC_TARGET_PE 21007 ret = -1; 21008 #else 21009 void *h; 21010 assert(0); 21011 h = 0; 21012 //h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); 21013 // jrs: remove need for dlopen 21014 if (h) 21015 ret = 0; 21016 else 21017 ret = -1; 21018 #endif 21019 } else { 21020 ret = tcc_load_dll(s1, fd, filename, 21021 (flags & AFF_REFERENCED_DLL) != 0); 21022 } 21023 } else { 21024 error_noabort("unrecognized ELF file"); 21025 goto fail; 21026 } 21027 } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) { 21028 file->line_num = 0; /* do not display line number if error */ 21029 ret = tcc_load_archive(s1, fd); 21030 } else 21031 #ifdef TCC_TARGET_COFF 21032 if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) { 21033 ret = tcc_load_coff(s1, fd); 21034 } else 21035 #endif 21036 { 21037 /* as GNU ld, consider it is an ld script if not recognized */ 21038 try_load_script: 21039 ret = tcc_load_ldscript(s1); 21040 if (ret < 0) { 21041 error_noabort("unrecognized file type"); 21042 goto fail; 21043 } 21044 } 21045 } 21046 the_end: 21047 tcc_close(file); 21048 fail1: 21049 file = saved_file; 21050 return ret; 21051 fail: 21052 ret = -1; 21053 goto the_end; 21054 } 21055 21056 int tcc_add_file(TCCState *s, const char *filename) 21057 { 21058 return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR); 21059 } 21060 21061 int tcc_add_library_path(TCCState *s, const char *pathname) 21062 { 21063 char *pathname1; 21064 21065 pathname1 = tcc_strdup(pathname); 21066 dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1); 21067 return 0; 21068 } 21069 21070 /* find and load a dll. Return non zero if not found */ 21071 /* XXX: add '-rpath' option support ? */ 21072 static int tcc_add_dll(TCCState *s, const char *filename, int flags) 21073 { 21074 char buf[1024]; 21075 int i; 21076 21077 for(i = 0; i < s->nb_library_paths; i++) { 21078 snprintf(buf, sizeof(buf), "%s/%s", 21079 s->library_paths[i], filename); 21080 if (tcc_add_file_internal(s, buf, flags) == 0) 21081 return 0; 21082 } 21083 return -1; 21084 } 21085 21086 /* the library name is the same as the argument of the '-l' option */ 21087 int tcc_add_library(TCCState *s, const char *libraryname) 21088 { 21089 char buf[1024]; 21090 int i; 21091 21092 /* first we look for the dynamic library if not static linking */ 21093 if (!s->static_link) { 21094 #ifdef TCC_TARGET_PE 21095 snprintf(buf, sizeof(buf), "%s.def", libraryname); 21096 #else 21097 snprintf(buf, sizeof(buf), "lib%s.so", libraryname); 21098 #endif 21099 if (tcc_add_dll(s, buf, 0) == 0) 21100 return 0; 21101 } 21102 21103 /* then we look for the static library */ 21104 for(i = 0; i < s->nb_library_paths; i++) { 21105 snprintf(buf, sizeof(buf), "%s/lib%s.a", 21106 s->library_paths[i], libraryname); 21107 if (tcc_add_file_internal(s, buf, 0) == 0) 21108 return 0; 21109 } 21110 return -1; 21111 } 21112 21113 int tcc_add_symbol(TCCState *s, const char *name, unsigned long val) 21114 { 21115 add_elf_sym(symtab_section, val, 0, 21116 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 21117 SHN_ABS, name); 21118 return 0; 21119 } 21120 21121 int tcc_set_output_type(TCCState *s, int output_type) 21122 { 21123 s->output_type = output_type; 21124 21125 if (!s->nostdinc) { 21126 char buf[1024]; 21127 21128 /* default include paths */ 21129 /* XXX: reverse order needed if -isystem support */ 21130 #ifndef TCC_TARGET_PE 21131 tcc_add_sysinclude_path(s, "/usr/local/include"); 21132 tcc_add_sysinclude_path(s, "/usr/include"); 21133 #endif 21134 snprintf(buf, sizeof(buf), "%s/include", tcc_lib_path); 21135 tcc_add_sysinclude_path(s, buf); 21136 #ifdef TCC_TARGET_PE 21137 snprintf(buf, sizeof(buf), "%s/include/winapi", tcc_lib_path); 21138 tcc_add_sysinclude_path(s, buf); 21139 #endif 21140 } 21141 21142 /* if bound checking, then add corresponding sections */ 21143 #ifdef CONFIG_TCC_BCHECK 21144 if (do_bounds_check) { 21145 /* define symbol */ 21146 tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL); 21147 /* create bounds sections */ 21148 bounds_section = new_section(s, ".bounds", 21149 SHT_PROGBITS, SHF_ALLOC); 21150 lbounds_section = new_section(s, ".lbounds", 21151 SHT_PROGBITS, SHF_ALLOC); 21152 } 21153 #endif 21154 21155 if (s->char_is_unsigned) { 21156 tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL); 21157 } 21158 21159 /* add debug sections */ 21160 if (do_debug) { 21161 /* stab symbols */ 21162 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0); 21163 stab_section->sh_entsize = sizeof(Stab_Sym); 21164 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0); 21165 put_elf_str(stabstr_section, ""); 21166 stab_section->link = stabstr_section; 21167 /* put first entry */ 21168 put_stabs("", 0, 0, 0, 0); 21169 } 21170 21171 /* add libc crt1/crti objects */ 21172 #ifndef TCC_TARGET_PE 21173 if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) && 21174 !s->nostdlib) { 21175 if (output_type != TCC_OUTPUT_DLL) 21176 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o"); 21177 tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o"); 21178 } 21179 #endif 21180 return 0; 21181 } 21182 21183 #define WD_ALL 0x0001 /* warning is activated when using -Wall */ 21184 #define FD_INVERT 0x0002 /* invert value before storing */ 21185 21186 typedef struct FlagDef { 21187 uint16_t offset; 21188 uint16_t flags; 21189 const char *name; 21190 } FlagDef; 21191 21192 static const FlagDef warning_defs[] = { 21193 { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, 21194 { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, 21195 { offsetof(TCCState, warn_error), 0, "error" }, 21196 { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, 21197 "implicit-function-declaration" }, 21198 }; 21199 21200 static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags, 21201 const char *name, int value) 21202 { 21203 int i; 21204 const FlagDef *p; 21205 const char *r; 21206 21207 r = name; 21208 if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') { 21209 r += 3; 21210 value = !value; 21211 } 21212 for(i = 0, p = flags; i < nb_flags; i++, p++) { 21213 if (!strcmp(r, p->name)) 21214 goto found; 21215 } 21216 return -1; 21217 found: 21218 if (p->flags & FD_INVERT) 21219 value = !value; 21220 *(int *)((uint8_t *)s + p->offset) = value; 21221 return 0; 21222 } 21223 21224 21225 /* set/reset a warning */ 21226 int tcc_set_warning(TCCState *s, const char *warning_name, int value) 21227 { 21228 int i; 21229 const FlagDef *p; 21230 21231 if (!strcmp(warning_name, "all")) { 21232 for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) { 21233 if (p->flags & WD_ALL) 21234 *(int *)((uint8_t *)s + p->offset) = 1; 21235 } 21236 return 0; 21237 } else { 21238 return set_flag(s, warning_defs, countof(warning_defs), 21239 warning_name, value); 21240 } 21241 } 21242 21243 static const FlagDef flag_defs[] = { 21244 { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" }, 21245 { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" }, 21246 { offsetof(TCCState, nocommon), FD_INVERT, "common" }, 21247 { offsetof(TCCState, leading_underscore), 0, "leading-underscore" }, 21248 }; 21249 21250 /* set/reset a flag */ 21251 int tcc_set_flag(TCCState *s, const char *flag_name, int value) 21252 { 21253 return set_flag(s, flag_defs, countof(flag_defs), 21254 flag_name, value); 21255 } 21256 21257 #if !defined(LIBTCC) 21258 21259 /* extract the basename of a file */ 21260 static const char *tcc_basename(const char *name) 21261 { 21262 const char *p; 21263 p = strrchr(name, '/'); 21264 #ifdef WIN32 21265 if (!p) 21266 p = strrchr(name, '\\'); 21267 #endif 21268 if (!p) 21269 p = name; 21270 else 21271 p++; 21272 return p; 21273 } 21274 21275 static int64_t getclock_us(void) 21276 { 21277 #ifdef WIN32 21278 struct _timeb tb; 21279 _ftime(&tb); 21280 return (tb.time * 1000LL + tb.millitm) * 1000LL; 21281 #else 21282 struct timeval tv; 21283 gettimeofday(&tv, NULL); 21284 return tv.tv_sec * 1000000LL + tv.tv_usec; 21285 #endif 21286 } 21287 21288 void help(void) 21289 { 21290 printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2015 Fabrice Bellard\n" 21291 "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n" 21292 " [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-static]\n" 21293 " [infile1 infile2...] [-run infile args...]\n" 21294 "\n" 21295 "General options:\n" 21296 " -v display current version\n" 21297 " -c compile only - generate an object file\n" 21298 " -o outfile set output filename\n" 21299 " -Bdir set tcc internal library path\n" 21300 " -bench output compilation statistics\n" 21301 " -run run compiled source\n" 21302 " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" 21303 " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" 21304 " -w disable all warnings\n" 21305 "Preprocessor options:\n" 21306 " -Idir add include path 'dir'\n" 21307 " -Dsym[=val] define 'sym' with value 'val'\n" 21308 " -Usym undefine 'sym'\n" 21309 "Linker options:\n" 21310 " -Ldir add library path 'dir'\n" 21311 " -llib link with dynamic or static library 'lib'\n" 21312 " -shared generate a shared library\n" 21313 " -static static linking\n" 21314 " -rdynamic export all global symbols to dynamic linker\n" 21315 " -r relocatable output\n" 21316 "Debugger options:\n" 21317 " -g generate runtime debug info\n" 21318 #ifdef CONFIG_TCC_BCHECK 21319 " -b compile with built-in memory and bounds checker (implies -g)\n" 21320 #endif 21321 " -bt N show N callers in stack traces\n" 21322 ); 21323 } 21324 21325 #define TCC_OPTION_HAS_ARG 0x0001 21326 #define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */ 21327 21328 typedef struct TCCOption { 21329 const char *name; 21330 uint16_t index; 21331 uint16_t flags; 21332 } TCCOption; 21333 21334 enum { 21335 TCC_OPTION_HELP, 21336 TCC_OPTION_I, 21337 TCC_OPTION_D, 21338 TCC_OPTION_U, 21339 TCC_OPTION_L, 21340 TCC_OPTION_B, 21341 TCC_OPTION_l, 21342 TCC_OPTION_bench, 21343 TCC_OPTION_bt, 21344 TCC_OPTION_b, 21345 TCC_OPTION_g, 21346 TCC_OPTION_c, 21347 TCC_OPTION_static, 21348 TCC_OPTION_shared, 21349 TCC_OPTION_o, 21350 TCC_OPTION_r, 21351 TCC_OPTION_Wl, 21352 TCC_OPTION_W, 21353 TCC_OPTION_O, 21354 TCC_OPTION_m, 21355 TCC_OPTION_f, 21356 TCC_OPTION_nostdinc, 21357 TCC_OPTION_nostdlib, 21358 TCC_OPTION_print_search_dirs, 21359 TCC_OPTION_rdynamic, 21360 TCC_OPTION_run, 21361 TCC_OPTION_v, 21362 TCC_OPTION_w, 21363 TCC_OPTION_pipe, 21364 }; 21365 21366 static const TCCOption tcc_options[] = { 21367 { "h", TCC_OPTION_HELP, 0 }, 21368 { "?", TCC_OPTION_HELP, 0 }, 21369 { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG }, 21370 { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG }, 21371 { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG }, 21372 { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG }, 21373 { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG }, 21374 { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21375 { "bench", TCC_OPTION_bench, 0 }, 21376 { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG }, 21377 #ifdef CONFIG_TCC_BCHECK 21378 { "b", TCC_OPTION_b, 0 }, 21379 #endif 21380 { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21381 { "c", TCC_OPTION_c, 0 }, 21382 { "static", TCC_OPTION_static, 0 }, 21383 { "shared", TCC_OPTION_shared, 0 }, 21384 { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG }, 21385 { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21386 { "rdynamic", TCC_OPTION_rdynamic, 0 }, 21387 { "r", TCC_OPTION_r, 0 }, 21388 { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21389 { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21390 { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21391 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG }, 21392 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP }, 21393 { "nostdinc", TCC_OPTION_nostdinc, 0 }, 21394 { "nostdlib", TCC_OPTION_nostdlib, 0 }, 21395 { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, 21396 { "v", TCC_OPTION_v, 0 }, 21397 { "w", TCC_OPTION_w, 0 }, 21398 { "pipe", TCC_OPTION_pipe, 0}, 21399 { NULL }, 21400 }; 21401 21402 /* convert 'str' into an array of space separated strings */ 21403 static int expand_args(char ***pargv, const char *str) 21404 { 21405 const char *s1; 21406 char **argv, *arg; 21407 int argc, len; 21408 21409 argc = 0; 21410 argv = NULL; 21411 for(;;) { 21412 while (is_space(*str)) 21413 str++; 21414 if (*str == '\0') 21415 break; 21416 s1 = str; 21417 while (*str != '\0' && !is_space(*str)) 21418 str++; 21419 len = str - s1; 21420 arg = tcc_malloc(len + 1); 21421 memcpy(arg, s1, len); 21422 arg[len] = '\0'; 21423 dynarray_add((void ***)&argv, &argc, arg); 21424 } 21425 *pargv = argv; 21426 return argc; 21427 } 21428 21429 static char **files; 21430 static int nb_files, nb_libraries; 21431 static int multiple_files; 21432 static int print_search_dirs; 21433 static int output_type; 21434 static int reloc_output; 21435 static const char *outfile; 21436 21437 int parse_args(TCCState *s, int argc, char **argv) 21438 { 21439 int optind; 21440 const TCCOption *popt; 21441 const char *optarg, *p1, *r1; 21442 char *r; 21443 21444 optind = 0; 21445 while (1) { 21446 if (optind >= argc) { 21447 if (nb_files == 0 && !print_search_dirs) 21448 goto show_help; 21449 else 21450 break; 21451 } 21452 r = argv[optind++]; 21453 if (r[0] != '-') { 21454 /* add a new file */ 21455 dynarray_add((void ***)&files, &nb_files, r); 21456 if (!multiple_files) { 21457 optind--; 21458 /* argv[0] will be this file */ 21459 break; 21460 } 21461 } else { 21462 /* find option in table (match only the first chars */ 21463 popt = tcc_options; 21464 for(;;) { 21465 p1 = popt->name; 21466 if (p1 == NULL) 21467 error("invalid option -- '%s'", r); 21468 r1 = r + 1; 21469 for(;;) { 21470 if (*p1 == '\0') 21471 goto option_found; 21472 if (*r1 != *p1) 21473 break; 21474 p1++; 21475 r1++; 21476 } 21477 popt++; 21478 } 21479 option_found: 21480 if (popt->flags & TCC_OPTION_HAS_ARG) { 21481 if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) { 21482 optarg = r1; 21483 } else { 21484 if (optind >= argc) 21485 error("argument to '%s' is missing", r); 21486 optarg = argv[optind++]; 21487 } 21488 } else { 21489 if (*r1 != '\0') 21490 goto show_help; 21491 optarg = NULL; 21492 } 21493 21494 switch(popt->index) { 21495 case TCC_OPTION_HELP: 21496 show_help: 21497 help(); 21498 exit(1); 21499 case TCC_OPTION_I: 21500 if (tcc_add_include_path(s, optarg) < 0) 21501 error("too many include paths"); 21502 break; 21503 case TCC_OPTION_D: 21504 { 21505 char *sym, *value; 21506 sym = (char *)optarg; 21507 value = strchr(sym, '='); 21508 if (value) { 21509 *value = '\0'; 21510 value++; 21511 } 21512 tcc_define_symbol(s, sym, value); 21513 } 21514 break; 21515 case TCC_OPTION_U: 21516 tcc_undefine_symbol(s, optarg); 21517 break; 21518 case TCC_OPTION_L: 21519 tcc_add_library_path(s, optarg); 21520 break; 21521 case TCC_OPTION_B: 21522 /* set tcc utilities path (mainly for tcc development) */ 21523 tcc_lib_path = optarg; 21524 break; 21525 case TCC_OPTION_l: 21526 dynarray_add((void ***)&files, &nb_files, r); 21527 nb_libraries++; 21528 break; 21529 case TCC_OPTION_bench: 21530 do_bench = 1; 21531 break; 21532 case TCC_OPTION_bt: 21533 num_callers = atoi(optarg); 21534 break; 21535 #ifdef CONFIG_TCC_BCHECK 21536 case TCC_OPTION_b: 21537 do_bounds_check = 1; 21538 do_debug = 1; 21539 break; 21540 #endif 21541 case TCC_OPTION_g: 21542 do_debug = 1; 21543 break; 21544 case TCC_OPTION_c: 21545 multiple_files = 1; 21546 output_type = TCC_OUTPUT_OBJ; 21547 break; 21548 case TCC_OPTION_static: 21549 s->static_link = 1; 21550 break; 21551 case TCC_OPTION_shared: 21552 output_type = TCC_OUTPUT_DLL; 21553 break; 21554 case TCC_OPTION_o: 21555 multiple_files = 1; 21556 outfile = optarg; 21557 break; 21558 case TCC_OPTION_r: 21559 /* generate a .o merging several output files */ 21560 reloc_output = 1; 21561 output_type = TCC_OUTPUT_OBJ; 21562 break; 21563 case TCC_OPTION_nostdinc: 21564 s->nostdinc = 1; 21565 break; 21566 case TCC_OPTION_nostdlib: 21567 s->nostdlib = 1; 21568 break; 21569 case TCC_OPTION_print_search_dirs: 21570 print_search_dirs = 1; 21571 break; 21572 case TCC_OPTION_run: 21573 { 21574 int argc1; 21575 char **argv1; 21576 argc1 = expand_args(&argv1, optarg); 21577 if (argc1 > 0) { 21578 parse_args(s, argc1, argv1); 21579 } 21580 multiple_files = 0; 21581 output_type = TCC_OUTPUT_MEMORY; 21582 } 21583 break; 21584 case TCC_OPTION_v: 21585 printf("tcc version %s\n", TCC_VERSION); 21586 exit(0); 21587 case TCC_OPTION_f: 21588 if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported) 21589 goto unsupported_option; 21590 break; 21591 case TCC_OPTION_W: 21592 if (tcc_set_warning(s, optarg, 1) < 0 && 21593 s->warn_unsupported) 21594 goto unsupported_option; 21595 break; 21596 case TCC_OPTION_w: 21597 s->warn_none = 1; 21598 break; 21599 case TCC_OPTION_rdynamic: 21600 s->rdynamic = 1; 21601 break; 21602 case TCC_OPTION_Wl: 21603 { 21604 const char *p; 21605 if (strstart(optarg, "-Ttext,", &p)) { 21606 s->text_addr = strtoul(p, NULL, 16); 21607 s->has_text_addr = 1; 21608 } else if (strstart(optarg, "--oformat,", &p)) { 21609 if (strstart(p, "elf32-", NULL)) { 21610 s->output_format = TCC_OUTPUT_FORMAT_ELF; 21611 } else if (!strcmp(p, "binary")) { 21612 s->output_format = TCC_OUTPUT_FORMAT_BINARY; 21613 } else 21614 #ifdef TCC_TARGET_COFF 21615 if (!strcmp(p, "coff")) { 21616 s->output_format = TCC_OUTPUT_FORMAT_COFF; 21617 } else 21618 #endif 21619 { 21620 error("target %s not found", p); 21621 } 21622 } else { 21623 error("unsupported linker option '%s'", optarg); 21624 } 21625 } 21626 break; 21627 default: 21628 if (s->warn_unsupported) { 21629 unsupported_option: 21630 warning("unsupported option '%s'", r); 21631 } 21632 break; 21633 } 21634 } 21635 } 21636 return optind; 21637 } 21638 21639 // njn: renamed main() as main2() in order to repeat it multiple times. 21640 int main2(int argc, char **argv) 21641 { 21642 int i; 21643 TCCState *s; 21644 int nb_objfiles, ret, optind; 21645 char objfilename[1024]; 21646 int64_t start_time = 0; 21647 21648 #ifdef WIN32 21649 /* on win32, we suppose the lib and includes are at the location 21650 of 'tcc.exe' */ 21651 { 21652 static char path[1024]; 21653 char *p, *d; 21654 21655 GetModuleFileNameA(NULL, path, sizeof path); 21656 p = d = strlwr(path); 21657 while (*d) 21658 { 21659 if (*d == '\\') *d = '/', p = d; 21660 ++d; 21661 } 21662 *p = '\0'; 21663 tcc_lib_path = path; 21664 } 21665 #endif 21666 21667 s = tcc_new(); 21668 output_type = TCC_OUTPUT_EXE; 21669 outfile = NULL; 21670 multiple_files = 1; 21671 files = NULL; 21672 nb_files = 0; 21673 nb_libraries = 0; 21674 reloc_output = 0; 21675 print_search_dirs = 0; 21676 21677 optind = parse_args(s, argc - 1, argv + 1) + 1; 21678 21679 if (print_search_dirs) { 21680 /* enough for Linux kernel */ 21681 printf("install: %s/\n", tcc_lib_path); 21682 return 0; 21683 } 21684 21685 nb_objfiles = nb_files - nb_libraries; 21686 21687 /* if outfile provided without other options, we output an 21688 executable */ 21689 if (outfile && output_type == TCC_OUTPUT_MEMORY) 21690 output_type = TCC_OUTPUT_EXE; 21691 21692 /* check -c consistency : only single file handled. XXX: checks file type */ 21693 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { 21694 /* accepts only a single input file */ 21695 if (nb_objfiles != 1) 21696 error("cannot specify multiple files with -c"); 21697 if (nb_libraries != 0) 21698 error("cannot specify libraries with -c"); 21699 } 21700 21701 if (output_type != TCC_OUTPUT_MEMORY) { 21702 if (!outfile) { 21703 /* compute default outfile name */ 21704 pstrcpy(objfilename, sizeof(objfilename) - 1, 21705 /* strip path */ 21706 tcc_basename(files[0])); 21707 #ifdef TCC_TARGET_PE 21708 pe_guess_outfile(objfilename, output_type); 21709 #else 21710 if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { 21711 char *ext = strrchr(objfilename, '.'); 21712 if (!ext) 21713 goto default_outfile; 21714 /* add .o extension */ 21715 strcpy(ext + 1, "o"); 21716 } else { 21717 default_outfile: 21718 pstrcpy(objfilename, sizeof(objfilename), "a.out"); 21719 } 21720 #endif 21721 outfile = objfilename; 21722 } 21723 } 21724 21725 if (do_bench) { 21726 start_time = getclock_us(); 21727 } 21728 21729 tcc_set_output_type(s, output_type); 21730 21731 /* compile or add each files or library */ 21732 for(i = 0;i < nb_files; i++) { 21733 const char *filename; 21734 21735 filename = files[i]; 21736 if (filename[0] == '-') { 21737 if (tcc_add_library(s, filename + 2) < 0) 21738 error("cannot find %s", filename); 21739 } else { 21740 if (tcc_add_file(s, filename) < 0) { 21741 ret = 1; 21742 goto the_end; 21743 } 21744 } 21745 } 21746 21747 /* free all files */ 21748 tcc_free(files); 21749 21750 if (do_bench) { 21751 double total_time; 21752 total_time = (double)(getclock_us() - start_time) / 1000000.0; 21753 if (total_time < 0.001) 21754 total_time = 0.001; 21755 if (total_bytes < 1) 21756 total_bytes = 1; 21757 printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", 21758 tok_ident - TOK_IDENT, total_lines, total_bytes, 21759 total_time, (int)(total_lines / total_time), 21760 total_bytes / total_time / 1000000.0); 21761 } 21762 21763 if (s->output_type == TCC_OUTPUT_MEMORY) { 21764 ret = tcc_run(s, argc - optind, argv + optind); 21765 } else 21766 #ifdef TCC_TARGET_PE 21767 if (s->output_type != TCC_OUTPUT_OBJ) { 21768 ret = tcc_output_pe(s, outfile); 21769 } else 21770 #endif 21771 { 21772 tcc_output_file(s, outfile); 21773 ret = 0; 21774 } 21775 the_end: 21776 /* XXX: cannot do it with bound checking because of the malloc hooks */ 21777 if (!do_bounds_check) 21778 tcc_delete(s); 21779 21780 #ifdef MEM_DEBUG 21781 if (do_bench) { 21782 printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size); 21783 } 21784 #endif 21785 return ret; 21786 } 21787 21788 // njn: created this wrapper main() function to execute compilation multiple 21789 // times. TinyCC is fast! 21790 // Nb: we get a link error, and TinyCC would normally return non-zero. But 21791 // the link error is not a problem for benchmarking purposes, so we return 21792 // zero here (as required by vg_perf). 21793 int main(int argc, char **argv) 21794 { 21795 #define REPS 30 21796 int i; 21797 for (i = 0; i < REPS; i++) { 21798 main2(argc, argv); 21799 } 21800 return 0; 21801 } 21802 21803 #endif 21804 21805 // njn: copied these in from libtcc1.c to avoid link errors when libtcc1.a 21806 // is not present. 21807 unsigned short __tcc_fpu_control = 0x137f; 21808 unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00; 21809 21810 #if 0 21811 long long __shldi3(long long a, int b) 21812 { 21813 #ifdef __TINYC__ 21814 DWunion u; 21815 u.ll = a; 21816 if (b >= 32) { 21817 u.s.high = (unsigned)u.s.low << (b - 32); 21818 u.s.low = 0; 21819 } else if (b != 0) { 21820 u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b)); 21821 u.s.low = (unsigned)u.s.low << b; 21822 } 21823 return u.ll; 21824 #else 21825 return a << b; 21826 #endif 21827 } 21828 #endif 21829