bootstrappable: HAVE_LONG_LONG, part 2.
This commit is contained in:
parent
2556e10583
commit
bdec98dd01
54
elf.h
54
elf.h
|
@ -27,13 +27,17 @@
|
|||
typedef signed char int8_t;
|
||||
typedef short int int16_t;
|
||||
typedef int int32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef long long int int64_t;
|
||||
#endif
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Standard ELF types. */
|
||||
|
||||
|
@ -47,19 +51,25 @@ typedef int32_t Elf32_Sword;
|
|||
typedef uint32_t Elf64_Word;
|
||||
typedef int32_t Elf64_Sword;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* Types for signed and unsigned 64-bit quantities. */
|
||||
typedef uint64_t Elf32_Xword;
|
||||
typedef int64_t Elf32_Sxword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
#endif
|
||||
|
||||
/* Type of addresses. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef uint64_t Elf64_Addr;
|
||||
#endif
|
||||
|
||||
/* Type of file offsets. */
|
||||
typedef uint32_t Elf32_Off;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef uint64_t Elf64_Off;
|
||||
#endif
|
||||
|
||||
/* Type for section indices, which are 16-bit quantities. */
|
||||
typedef uint16_t Elf32_Section;
|
||||
|
@ -67,8 +77,9 @@ typedef uint16_t Elf64_Section;
|
|||
|
||||
/* Type for version symbol information. */
|
||||
typedef Elf32_Half Elf32_Versym;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef Elf64_Half Elf64_Versym;
|
||||
|
||||
#endif
|
||||
|
||||
/* The ELF file header. This appears at the start of every ELF file. */
|
||||
|
||||
|
@ -92,6 +103,7 @@ typedef struct
|
|||
Elf32_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
|
||||
|
@ -109,6 +121,7 @@ typedef struct
|
|||
Elf64_Half e_shnum; /* Section header table entry count */
|
||||
Elf64_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf64_Ehdr;
|
||||
#endif
|
||||
|
||||
/* Fields in the e_ident array. The EI_* macros are indices into the
|
||||
array. The macros under each EI_* macro are the values the byte
|
||||
|
@ -293,6 +306,7 @@ typedef struct
|
|||
Elf32_Word sh_entsize; /* Entry size if section holds table */
|
||||
} Elf32_Shdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||
|
@ -306,6 +320,7 @@ typedef struct
|
|||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
#endif
|
||||
|
||||
/* Special section indices. */
|
||||
|
||||
|
@ -399,6 +414,7 @@ typedef struct
|
|||
Elf32_Section st_shndx; /* Section index */
|
||||
} Elf32_Sym;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word st_name; /* Symbol name (string tbl index) */
|
||||
|
@ -408,6 +424,7 @@ typedef struct
|
|||
Elf64_Addr st_value; /* Symbol value */
|
||||
Elf64_Xword st_size; /* Symbol size */
|
||||
} Elf64_Sym;
|
||||
#endif
|
||||
|
||||
/* The syminfo section if available contains additional information about
|
||||
every dynamic symbol. */
|
||||
|
@ -418,11 +435,13 @@ typedef struct
|
|||
Elf32_Half si_flags; /* Per symbol flags */
|
||||
} Elf32_Syminfo;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
|
||||
Elf64_Half si_flags; /* Per symbol flags */
|
||||
} Elf64_Syminfo;
|
||||
#endif
|
||||
|
||||
/* Possible values for si_boundto. */
|
||||
#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
|
||||
|
@ -510,6 +529,7 @@ typedef struct
|
|||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
} Elf32_Rel;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* I have seen two different definitions of the Elf64_Rel and
|
||||
Elf64_Rela structures, so we'll leave them out until Novell (or
|
||||
whoever) gets their act together. */
|
||||
|
@ -520,6 +540,7 @@ typedef struct
|
|||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
} Elf64_Rel;
|
||||
#endif
|
||||
|
||||
/* Relocation table entry with addend (in section of type SHT_RELA). */
|
||||
|
||||
|
@ -530,12 +551,14 @@ typedef struct
|
|||
Elf32_Sword r_addend; /* Addend */
|
||||
} Elf32_Rela;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
Elf64_Sxword r_addend; /* Addend */
|
||||
} Elf64_Rela;
|
||||
#endif
|
||||
|
||||
/* How to extract and insert information held in the r_info field. */
|
||||
|
||||
|
@ -561,6 +584,7 @@ typedef struct
|
|||
Elf32_Word p_align; /* Segment alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type; /* Segment type */
|
||||
|
@ -572,6 +596,7 @@ typedef struct
|
|||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment */
|
||||
} Elf64_Phdr;
|
||||
#endif
|
||||
|
||||
/* Special value for e_phnum. This indicates that the real number of
|
||||
program headers is too large to fit into e_phnum. Instead the real
|
||||
|
@ -665,6 +690,7 @@ typedef struct
|
|||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Sxword d_tag; /* Dynamic entry type */
|
||||
|
@ -674,6 +700,7 @@ typedef struct
|
|||
Elf64_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
#endif
|
||||
|
||||
/* Legal values for d_tag (dynamic entry type). */
|
||||
|
||||
|
@ -843,6 +870,7 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Verdef;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half vd_version; /* Version revision */
|
||||
|
@ -854,7 +882,7 @@ typedef struct
|
|||
Elf64_Word vd_next; /* Offset in bytes to next verdef
|
||||
entry */
|
||||
} Elf64_Verdef;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for vd_version (version revision). */
|
||||
#define VER_DEF_NONE 0 /* No version */
|
||||
|
@ -880,13 +908,14 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Verdaux;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word vda_name; /* Version or dependency names */
|
||||
Elf64_Word vda_next; /* Offset in bytes to next verdaux
|
||||
entry */
|
||||
} Elf64_Verdaux;
|
||||
|
||||
#endif
|
||||
|
||||
/* Version dependency section. */
|
||||
|
||||
|
@ -901,6 +930,7 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Verneed;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half vn_version; /* Version of structure */
|
||||
|
@ -911,7 +941,7 @@ typedef struct
|
|||
Elf64_Word vn_next; /* Offset in bytes to next verneed
|
||||
entry */
|
||||
} Elf64_Verneed;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for vn_version (version revision). */
|
||||
#define VER_NEED_NONE 0 /* No version */
|
||||
|
@ -930,6 +960,7 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Vernaux;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word vna_hash; /* Hash value of dependency name */
|
||||
|
@ -939,7 +970,7 @@ typedef struct
|
|||
Elf64_Word vna_next; /* Offset in bytes to next vernaux
|
||||
entry */
|
||||
} Elf64_Vernaux;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for vna_flags. */
|
||||
#define VER_FLG_WEAK 0x2 /* Weak version identifier */
|
||||
|
@ -966,6 +997,7 @@ typedef struct
|
|||
} a_un;
|
||||
} Elf32_auxv_t;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
uint64_t a_type; /* Entry type */
|
||||
|
@ -977,6 +1009,7 @@ typedef struct
|
|||
on 64-bit platforms and vice versa. */
|
||||
} a_un;
|
||||
} Elf64_auxv_t;
|
||||
#endif
|
||||
|
||||
/* Legal values for a_type (entry type). */
|
||||
|
||||
|
@ -1045,12 +1078,14 @@ typedef struct
|
|||
Elf32_Word n_type; /* Type of the note. */
|
||||
} Elf32_Nhdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word n_namesz; /* Length of the note's name. */
|
||||
Elf64_Word n_descsz; /* Length of the note's descriptor. */
|
||||
Elf64_Word n_type; /* Type of the note. */
|
||||
} Elf64_Nhdr;
|
||||
#endif
|
||||
|
||||
/* Known names of notes. */
|
||||
|
||||
|
@ -1104,13 +1139,18 @@ typedef struct
|
|||
/* Move records. */
|
||||
typedef struct
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
Elf32_Xword m_value; /* Symbol value. */
|
||||
#else
|
||||
Elf32_Word m_info; /* Size and index. */
|
||||
Elf32_Word m_info_padding;
|
||||
#endif
|
||||
Elf32_Word m_poffset; /* Symbol offset. */
|
||||
Elf32_Half m_repeat; /* Repeat count. */
|
||||
Elf32_Half m_stride; /* Stride info. */
|
||||
} Elf32_Move;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Xword m_value; /* Symbol value. */
|
||||
|
@ -1119,6 +1159,7 @@ typedef struct
|
|||
Elf64_Half m_repeat; /* Repeat count. */
|
||||
Elf64_Half m_stride; /* Stride info. */
|
||||
} Elf64_Move;
|
||||
#endif
|
||||
|
||||
/* Macro to construct move records. */
|
||||
#define ELF32_M_SYM(info) ((info) >> 8)
|
||||
|
@ -1732,6 +1773,7 @@ typedef struct
|
|||
Elf32_Word l_flags; /* Flags */
|
||||
} Elf32_Lib;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word l_name; /* Name (string table index) */
|
||||
|
@ -1740,7 +1782,7 @@ typedef struct
|
|||
Elf64_Word l_version; /* Interface version */
|
||||
Elf64_Word l_flags; /* Flags */
|
||||
} Elf64_Lib;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for l_flags. */
|
||||
|
||||
|
|
|
@ -223,7 +223,11 @@ static const uint8_t segment_prefixes[] = {
|
|||
static const ASMInstr asm_instrs[] = {
|
||||
#define ALT(x) x
|
||||
/* This removes a 0x0f in the second byte */
|
||||
#if HAVE_LONG_LONG
|
||||
#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
|
||||
#else
|
||||
#define O(o) ((uint32_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
|
||||
#endif
|
||||
/* This constructs instr_type from opcode, type and group. */
|
||||
#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
|
||||
#define DEF_ASM_OP0(name, opcode)
|
||||
|
|
|
@ -13,12 +13,16 @@ typedef __SIZE_TYPE__ uintptr_t;
|
|||
typedef signed char int8_t;
|
||||
typedef signed short int int16_t;
|
||||
typedef signed int int32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef signed long long int int64_t;
|
||||
#endif
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
|
|
2
libtcc.c
2
libtcc.c
|
@ -780,6 +780,8 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
|
||||
tcc_define_symbol(s, "__STDC_HOSTED__", NULL);
|
||||
|
||||
tcc_define_symbol(s, "__SIZEOF_LONG_LONG__", "8");
|
||||
|
||||
/* target defines */
|
||||
#if defined(TCC_TARGET_I386)
|
||||
tcc_define_symbol(s, "__i386__", NULL);
|
||||
|
|
13
tcc.h
13
tcc.h
|
@ -390,7 +390,12 @@ typedef union CValue {
|
|||
long double ld;
|
||||
double d;
|
||||
float f;
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t i;
|
||||
#else
|
||||
uint32_t i;
|
||||
uint32_t i_padding;
|
||||
#endif
|
||||
struct {
|
||||
int size;
|
||||
const void *data;
|
||||
|
@ -606,7 +611,12 @@ typedef struct CachedInclude {
|
|||
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
typedef struct ExprValue {
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t v;
|
||||
#else
|
||||
uint32_t v;
|
||||
uint32_t v_padding;
|
||||
#endif
|
||||
Sym *sym;
|
||||
int pcrel;
|
||||
} ExprValue;
|
||||
|
@ -1516,6 +1526,7 @@ static inline void write32le(unsigned char *p, uint32_t x) {
|
|||
static inline void add32le(unsigned char *p, int32_t x) {
|
||||
write32le(p, read32le(p) + x);
|
||||
}
|
||||
#if HAVE_LONG_LONG
|
||||
static inline uint64_t read64le(unsigned char *p) {
|
||||
return read32le(p) | (uint64_t)read32le(p + 4) << 32;
|
||||
}
|
||||
|
@ -1525,7 +1536,7 @@ static inline void write64le(unsigned char *p, uint64_t x) {
|
|||
static inline void add64le(unsigned char *p, int64_t x) {
|
||||
write64le(p, read64le(p) + x);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* ------------ i386-gen.c ------------ */
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
ST_FUNC void g(int c);
|
||||
|
|
29
tccasm.c
29
tccasm.c
|
@ -90,7 +90,11 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
|
|||
{
|
||||
Sym *sym;
|
||||
int op, label;
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t n;
|
||||
#else
|
||||
uint32_t n;
|
||||
#endif
|
||||
const char *p;
|
||||
|
||||
switch(tok) {
|
||||
|
@ -324,6 +328,7 @@ static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
|
|||
case TOK_NE:
|
||||
pe->v = pe->v != e2.v;
|
||||
break;
|
||||
#if HAVE_LONG_LONG
|
||||
case TOK_LT:
|
||||
pe->v = (int64_t)pe->v < (int64_t)e2.v;
|
||||
break;
|
||||
|
@ -336,11 +341,29 @@ static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
|
|||
case TOK_GT:
|
||||
pe->v = (int64_t)pe->v > (int64_t)e2.v;
|
||||
break;
|
||||
#else
|
||||
case TOK_LT:
|
||||
pe->v = (int32_t)pe->v < (int32_t)e2.v;
|
||||
break;
|
||||
case TOK_GE:
|
||||
pe->v = (int32_t)pe->v >= (int32_t)e2.v;
|
||||
break;
|
||||
case TOK_LE:
|
||||
pe->v = (int32_t)pe->v <= (int32_t)e2.v;
|
||||
break;
|
||||
case TOK_GT:
|
||||
pe->v = (int32_t)pe->v > (int32_t)e2.v;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if HAVE_LONG_LONG
|
||||
/* GAS compare results are -1/0 not 1/0. */
|
||||
pe->v = -(int64_t)pe->v;
|
||||
#else
|
||||
pe->v = -(int32_t)pe->v;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -522,7 +545,11 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
#else
|
||||
next();
|
||||
for(;;) {
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t vl;
|
||||
#else
|
||||
uint32_t vl;
|
||||
#endif
|
||||
const char *p;
|
||||
|
||||
p = tokc.str.data;
|
||||
|
@ -537,7 +564,9 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
if (sec->sh_type != SHT_NOBITS) {
|
||||
/* XXX: endianness */
|
||||
gen_le32(vl);
|
||||
#if HAVE_LONG_LONG
|
||||
gen_le32(vl >> 32);
|
||||
#endif
|
||||
} else {
|
||||
ind += 8;
|
||||
}
|
||||
|
|
75
tccgen.c
75
tccgen.c
|
@ -64,7 +64,11 @@ ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
|||
|
||||
ST_DATA struct switch_t {
|
||||
struct case_t {
|
||||
#if HAVE_LONG_LONG
|
||||
int64_t v1, v2;
|
||||
#else
|
||||
int32_t v1, v1_padding, v2, v2_padding;
|
||||
#endif
|
||||
int sym;
|
||||
} **p; int n; /* list of case ranges */
|
||||
int def_sym; /* default symbol */
|
||||
|
@ -88,8 +92,12 @@ static void vla_runtime_type_size(CType *type, int *a);
|
|||
static void vla_sp_restore(void);
|
||||
static void vla_sp_restore_root(void);
|
||||
static int is_compatible_parameter_types(CType *type1, CType *type2);
|
||||
#if HAVE_LONG_LONG
|
||||
static inline int64_t expr_const64(void);
|
||||
ST_FUNC void vpush64(int ty, unsigned long long v);
|
||||
#else
|
||||
static inline int32_t expr_const32(void);
|
||||
#endif
|
||||
ST_FUNC void vpush(CType *type);
|
||||
ST_FUNC int gvtst(int inv, int t);
|
||||
ST_FUNC int is_btype_size(int bt);
|
||||
|
@ -1302,7 +1310,9 @@ static void lexpand(void)
|
|||
v = vtop->r & (VT_VALMASK | VT_LVAL);
|
||||
if (v == VT_CONST) {
|
||||
vdup();
|
||||
#if HAVE_LONG_LONG
|
||||
vtop[0].c.i >>= 32;
|
||||
#endif
|
||||
} else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
|
||||
vdup();
|
||||
vtop[0].c.i += 4;
|
||||
|
@ -1329,7 +1339,9 @@ ST_FUNC void lexpand_nr(void)
|
|||
v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
|
||||
if (v == VT_CONST) {
|
||||
vtop[-1].c.i = vtop->c.i;
|
||||
#if HAVE_LONG_LONG
|
||||
vtop->c.i = vtop->c.i >> 32;
|
||||
#endif
|
||||
vtop->r = VT_CONST;
|
||||
} else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
|
||||
vtop->c.i += 4;
|
||||
|
@ -1654,6 +1666,7 @@ static void gen_opl(int op)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
|
||||
{
|
||||
uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
|
||||
|
@ -1664,6 +1677,18 @@ static int gen_opic_lt(uint64_t a, uint64_t b)
|
|||
{
|
||||
return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
|
||||
}
|
||||
#else
|
||||
static uint32_t gen_opic_sdiv(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t x = (a >> 31 ? -a : a) / (b >> 31 ? -b : b);
|
||||
return (a ^ b) >> 31 ? -x : x;
|
||||
}
|
||||
|
||||
static int gen_opic_lt(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (a ^ (uint32_t)1 << 31) < (b ^ (uint32_t)1 << 31);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* handle integer constant optimizations and various machine
|
||||
independent opt */
|
||||
|
@ -1675,10 +1700,15 @@ static void gen_opic(int op)
|
|||
int t2 = v2->type.t & VT_BTYPE;
|
||||
int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t l1 = c1 ? v1->c.i : 0;
|
||||
uint64_t l2 = c2 ? v2->c.i : 0;
|
||||
int shm = (t1 == VT_LLONG) ? 63 : 31;
|
||||
|
||||
#else
|
||||
uint32_t l1 = c1 ? v1->c.i : 0;
|
||||
uint32_t l2 = c2 ? v2->c.i : 0;
|
||||
int shm = 31;
|
||||
#endif
|
||||
if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
|
||||
l1 = ((uint32_t)l1 |
|
||||
(v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
|
||||
|
@ -1716,7 +1746,11 @@ static void gen_opic(int op)
|
|||
case TOK_SHL: l1 <<= (l2 & shm); break;
|
||||
case TOK_SHR: l1 >>= (l2 & shm); break;
|
||||
case TOK_SAR:
|
||||
#if HAVE_LONG_LONG
|
||||
l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
|
||||
#else
|
||||
l1 = (l1 >> 31) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
|
||||
#endif
|
||||
break;
|
||||
/* tests */
|
||||
case TOK_ULT: l1 = l1 < l2; break;
|
||||
|
@ -4538,10 +4572,18 @@ ST_FUNC void unary(void)
|
|||
break;
|
||||
case TOK_builtin_choose_expr:
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
int64_t c;
|
||||
#else
|
||||
int32_t c;
|
||||
#endif
|
||||
next();
|
||||
skip('(');
|
||||
#if HAVE_LONG_LONG
|
||||
c = expr_const64();
|
||||
#else
|
||||
c = expr_const32();
|
||||
#endif
|
||||
skip(',');
|
||||
if (!c) {
|
||||
nocode_wanted++;
|
||||
|
@ -5348,6 +5390,7 @@ static void expr_const1(void)
|
|||
const_wanted--;
|
||||
}
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* parse an integer constant and return its value. */
|
||||
static inline int64_t expr_const64(void)
|
||||
{
|
||||
|
@ -5359,13 +5402,30 @@ static inline int64_t expr_const64(void)
|
|||
vpop();
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
/* parse an integer constant and return its value. */
|
||||
static inline int32_t expr_const32(void)
|
||||
{
|
||||
int32_t c;
|
||||
expr_const1();
|
||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
expect("constant expression");
|
||||
c = vtop->c.i;
|
||||
vpop();
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* parse an integer constant and return its value.
|
||||
Complain if it doesn't fit 32bit (signed or unsigned). */
|
||||
ST_FUNC int expr_const(void)
|
||||
{
|
||||
int c;
|
||||
#if HAVE_LONG_LONG
|
||||
int64_t wc = expr_const64();
|
||||
#else
|
||||
int32_t wc = expr_const32();
|
||||
#endif
|
||||
c = wc;
|
||||
if (c != wc && (unsigned)c != wc)
|
||||
tcc_error("constant exceeds 32 bit");
|
||||
|
@ -5460,8 +5520,13 @@ static void gfunc_return(CType *func_type)
|
|||
|
||||
static int case_cmp(const void *pa, const void *pb)
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
int64_t a = (*(struct case_t**) pa)->v1;
|
||||
int64_t b = (*(struct case_t**) pb)->v1;
|
||||
#else
|
||||
int32_t a = (*(struct case_t**) pa)->v1;
|
||||
int32_t b = (*(struct case_t**) pb)->v1;
|
||||
#endif
|
||||
return a < b ? -1 : a > b;
|
||||
}
|
||||
|
||||
|
@ -5786,10 +5851,18 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||
expect("switch");
|
||||
nocode_wanted &= ~0x20000000;
|
||||
next();
|
||||
#if HAVE_LONG_LONG
|
||||
cr->v1 = cr->v2 = expr_const64();
|
||||
#else
|
||||
cr->v1 = cr->v2 = expr_const32();
|
||||
#endif
|
||||
if (gnu_ext && tok == TOK_DOTS) {
|
||||
next();
|
||||
#if HAVE_LONG_LONG
|
||||
cr->v2 = expr_const64();
|
||||
#else
|
||||
cr->v2 = expr_const32();
|
||||
#endif
|
||||
if (cr->v2 < cr->v1)
|
||||
tcc_warning("empty case range");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue