Browse Source

Revert "Move almost all global variables to TCCState, actually all tests pass on Ubuntu 18.04 x86_64"

This reverts commit af686a796b.
mob/mob.devnexen
mingodad 2 years ago
parent
commit
1645616843
  1. 1112
      arm-asm.c
  2. 1133
      arm-gen.c
  3. 64
      arm-link.c
  4. 26
      arm64-asm.c
  5. 1288
      arm64-gen.c
  6. 64
      arm64-link.c
  7. 1516
      c67-gen.c
  8. 14
      c67-link.c
  9. 374
      i386-asm.c
  10. 733
      i386-gen.c
  11. 68
      i386-link.c
  12. 863
      libtcc.c
  13. 93
      libtcc.h
  14. 374
      riscv64-asm.c
  15. 908
      riscv64-gen.c
  16. 60
      riscv64-link.c
  17. 238
      tcc.c
  18. 757
      tcc.h
  19. 838
      tccasm.c
  20. 116
      tcccoff.c
  21. 1347
      tccelf.c
  22. 5364
      tccgen.c
  23. 225
      tccmacho.c
  24. 355
      tccpe.c
  25. 2171
      tccpp.c
  26. 261
      tccqsort.c
  27. 128
      tccrun.c
  28. 54
      tcctools.c
  29. 1347
      x86_64-gen.c
  30. 76
      x86_64-link.c

1112
arm-asm.c

File diff suppressed because it is too large

1133
arm-gen.c

File diff suppressed because it is too large

64
arm-link.c

@ -107,9 +107,9 @@ int gotplt_entry_type (int reloc_type)
}
#ifndef TCC_TARGET_PE
ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
Section *plt = S->plt;
Section *plt = s1->plt;
uint8_t *p;
unsigned plt_offset;
@ -119,7 +119,7 @@ ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_a
/* empty PLT: create PLT0 entry that push address of call site and
jump to ld.so resolution routine (GOT + 8) */
if (plt->data_offset == 0) {
p = section_ptr_add(S, plt, 20);
p = section_ptr_add(plt, 20);
write32le(p, 0xe52de004); /* push {lr} */
write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
@ -129,11 +129,11 @@ ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_a
plt_offset = plt->data_offset;
if (attr->plt_thumb_stub) {
p = section_ptr_add(S, plt, 4);
p = section_ptr_add(plt, 4);
write32le(p, 0x4778); /* bx pc */
write32le(p+2, 0x46c0); /* nop */
}
p = section_ptr_add(S, plt, 16);
p = section_ptr_add(plt, 16);
/* save GOT offset for relocate_plt */
write32le(p + 4, got_offset);
return plt_offset;
@ -141,22 +141,22 @@ ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_a
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *S)
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!S->plt)
if (!s1->plt)
return;
p = S->plt->data;
p_end = p + S->plt->data_offset;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
int x = S->got->sh_addr - S->plt->sh_addr - 12;
write32le(S->plt->data + 16, x - 4);
int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
write32le(s1->plt->data + 16, x - 4);
p += 20;
while (p < p_end) {
unsigned off = x + read32le(p + 4) + (S->plt->data - p) + 4;
unsigned off = x + read32le(p + 4) + (s1->plt->data - p) + 4;
if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
p += 4;
write32le(p, 0xe28fc200 | ((off >> 28) & 0xf)); // add ip, pc, #0xN0000000
@ -167,17 +167,17 @@ ST_FUNC void relocate_plt(TCCState *S)
}
}
if (S->plt->reloc) {
if (s1->plt->reloc) {
ElfW_Rel *rel;
p = S->got->data;
for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {
write32le(p + rel->r_offset, S->plt->sh_addr);
p = s1->got->data;
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
write32le(p + rel->r_offset, s1->plt->sh_addr);
}
}
}
#endif
void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
ElfW(Sym) *sym;
int sym_index, esym_index;
@ -212,7 +212,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
h = x & 2;
th_ko = (x & 3) && (!blx_avail || !is_call);
if (th_ko || x >= 0x2000000 || x < -0x2000000)
tcc_error(S, "can't relocate value at %x,%d",addr, type);
tcc_error("can't relocate value at %x,%d",addr, type);
x >>= 2;
x &= 0xffffff;
/* Only reached if blx is avail and it is a call */
@ -255,7 +255,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
/* Relocation infos */
to_thumb = val & 1;
plt = S->plt;
plt = s1->plt;
to_plt = (val >= plt->sh_addr) &&
(val < plt->sh_addr + plt->data_offset);
is_call = (type == R_ARM_THM_PC22);
@ -267,10 +267,10 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
Section *text;
name = (char *) symtab_section->link->data + sym->st_name;
text = S->sections[sym->st_shndx];
text = s1->sections[sym->st_shndx];
/* Modify reloc to target a thumb stub to switch to ARM */
snprintf(buf, sizeof(buf), "%s_from_thumb", name);
index = put_elf_sym(S, symtab_section,
index = put_elf_sym(symtab_section,
text->data_offset + 1,
sym->st_size, sym->st_info, 0,
sym->st_shndx, buf);
@ -281,7 +281,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
put_elf_reloc(symtab_section, text,
text->data_offset + 4, R_ARM_JUMP24,
sym_index);
p = section_ptr_add(S, text, 8);
p = section_ptr_add(text, 8);
write32le(p, 0x4778); /* bx pc */
write32le(p+2, 0x46c0); /* nop */
write32le(p+4, 0xeafffffe); /* b $sym */
@ -301,7 +301,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
- instruction must be a call (bl) or a jump to PLT */
if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
if (to_thumb || (val & 2) || (!is_call && !to_plt))
tcc_error(S, "can't relocate value at %x,%d",addr, type);
tcc_error("can't relocate value at %x,%d",addr, type);
/* Compute and store final offset */
s = (x >> 24) & 1;
@ -372,14 +372,14 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
x = (x * 2) / 2;
x += val - addr;
if((x^(x>>1))&0x40000000)
tcc_error(S, "can't relocate value at %x,%d",addr, type);
tcc_error("can't relocate value at %x,%d",addr, type);
(*(int *)ptr) |= x & 0x7fffffff;
}
return;
case R_ARM_ABS32:
case R_ARM_TARGET1:
if (S->output_type == TCC_OUTPUT_DLL) {
esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
if (s1->output_type == TCC_OUTPUT_DLL) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_ARM_ABS32);
@ -396,19 +396,19 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
*(int *)ptr += val - addr;
return;
case R_ARM_GOTPC:
*(int *)ptr += S->got->sh_addr - addr;
*(int *)ptr += s1->got->sh_addr - addr;
return;
case R_ARM_GOTOFF:
*(int *)ptr += val - S->got->sh_addr;
*(int *)ptr += val - s1->got->sh_addr;
return;
case R_ARM_GOT32:
/* we load the got offset */
*(int *)ptr += get_sym_attr(S, sym_index, 0)->got_offset;
*(int *)ptr += get_sym_attr(s1, sym_index, 0)->got_offset;
return;
case R_ARM_GOT_PREL:
/* we load the pc relative got offset */
*(int *)ptr += S->got->sh_addr +
get_sym_attr(S, sym_index, 0)->got_offset -
*(int *)ptr += s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset -
addr;
return;
case R_ARM_COPY:
@ -428,7 +428,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
return;
case R_ARM_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - S->pe_imagebase);
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;

26
arm64-asm.c

@ -9,9 +9,9 @@
#define CONFIG_TCC_ASM
#define NB_ASM_REGS 16
ST_FUNC void g(TCCState* S, int c);
ST_FUNC void gen_le16(TCCState* S, int c);
ST_FUNC void gen_le32(TCCState* S, int c);
ST_FUNC void g(int c);
ST_FUNC void gen_le16(int c);
ST_FUNC void gen_le32(int c);
/*************************************************************/
#else
@ -25,7 +25,7 @@ static void asm_error(void)
}
/* XXX: make it faster ? */
ST_FUNC void g(TCCState* S, int c)
ST_FUNC void g(int c)
{
int ind1;
if (nocode_wanted)
@ -37,24 +37,24 @@ ST_FUNC void g(TCCState* S, int c)
ind = ind1;
}
ST_FUNC void gen_le16 (TCCState* S, int i)
ST_FUNC void gen_le16 (int i)
{
g(S, i);
g(S, i>>8);
g(i);
g(i>>8);
}
ST_FUNC void gen_le32 (TCCState* S, int i)
ST_FUNC void gen_le32 (int i)
{
gen_le16(S, i);
gen_le16(S, i>>16);
gen_le16(i);
gen_le16(i>>16);
}
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
ST_FUNC void gen_expr32(ExprValue *pe)
{
gen_le32(S, pe->v);
gen_le32(pe->v);
}
ST_FUNC void asm_opcode(TCCState *S, int opcode)
ST_FUNC void asm_opcode(TCCState *s1, int opcode)
{
asm_error();
}

1288
arm64-gen.c

File diff suppressed because it is too large

64
arm64-link.c

@ -90,18 +90,18 @@ int gotplt_entry_type (int reloc_type)
return -1;
}
ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
Section *plt = S->plt;
Section *plt = s1->plt;
uint8_t *p;
unsigned plt_offset;
if (plt->data_offset == 0) {
section_ptr_add(S, plt, 32);
section_ptr_add(plt, 32);
}
plt_offset = plt->data_offset;
p = section_ptr_add(S, plt, 16);
p = section_ptr_add(plt, 16);
write32le(p, got_offset);
write32le(p + 4, (uint64_t) got_offset >> 32);
return plt_offset;
@ -109,22 +109,22 @@ ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_a
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *S)
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!S->plt)
if (!s1->plt)
return;
p = S->plt->data;
p_end = p + S->plt->data_offset;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
uint64_t plt = S->plt->sh_addr;
uint64_t got = S->got->sh_addr + 16;
uint64_t plt = s1->plt->sh_addr;
uint64_t got = s1->got->sh_addr + 16;
uint64_t off = (got >> 12) - (plt >> 12);
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error(S, "Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
write32le(p + 4, (0x90000010 | // adrp x16,...
(off & 0x1ffffc) << 3 | (off & 3) << 29));
@ -137,13 +137,13 @@ ST_FUNC void relocate_plt(TCCState *S)
write32le(p + 24, 0xd503201f); // nop
write32le(p + 28, 0xd503201f); // nop
p += 32;
got = S->got->sh_addr;
got = s1->got->sh_addr;
while (p < p_end) {
uint64_t pc = plt + (p - S->plt->data);
uint64_t pc = plt + (p - s1->plt->data);
uint64_t addr = got + read64le(p);
uint64_t off = (addr >> 12) - (pc >> 12);
if ((off + ((uint32_t)1 << 20)) >> 21)
tcc_error(S, "Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
write32le(p, (0x90000010 | // adrp x16,...
(off & 0x1ffffc) << 3 | (off & 3) << 29));
write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
@ -155,16 +155,16 @@ ST_FUNC void relocate_plt(TCCState *S)
}
}
if (S->plt->reloc) {
if (s1->plt->reloc) {
ElfW_Rel *rel;
p = S->got->data;
for_each_elem(S->plt->reloc, 0, rel, ElfW_Rel) {
write64le(p + rel->r_offset, S->plt->sh_addr);
p = s1->got->data;
for_each_elem(s1->plt->reloc, 0, rel, ElfW_Rel) {
write64le(p + rel->r_offset, s1->plt->sh_addr);
}
}
}
void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
#ifdef DEBUG_RELOC
@ -173,8 +173,8 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
switch(type) {
case R_AARCH64_ABS64:
if (S->output_type == TCC_OUTPUT_DLL) {
esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
if (s1->output_type == TCC_OUTPUT_DLL) {
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
qrel->r_offset = rel->r_offset;
if (esym_index) {
qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_ABS64);
@ -190,7 +190,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
add64le(ptr, val);
return;
case R_AARCH64_ABS32:
if (S->output_type == TCC_OUTPUT_DLL) {
if (s1->output_type == TCC_OUTPUT_DLL) {
/* XXX: this logic may depend on TCC's codegen
now TCC uses R_AARCH64_RELATIVE even for a 64bit pointer */
qrel->r_offset = rel->r_offset;
@ -202,9 +202,9 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
add32le(ptr, val);
return;
case R_AARCH64_PREL32:
if (S->output_type == TCC_OUTPUT_DLL) {
if (s1->output_type == TCC_OUTPUT_DLL) {
/* DLL relocation */
esym_index = get_sym_attr(S, sym_index, 0)->dyn_index;
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
if (esym_index) {
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_AARCH64_PREL32);
@ -235,7 +235,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
case R_AARCH64_ADR_PREL_PG_HI21: {
uint64_t off = (val >> 12) - (addr >> 12);
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error(S, "R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
(off & 0x1ffffc) << 3 | (off & 3) << 29));
return;
@ -268,7 +268,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
(char *) symtab_section->link->data + sym->st_name);
#endif
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
tcc_error(S, "R_AARCH64_(JUMP|CALL)26 relocation failed"
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
" (val=%lx, addr=%lx)", (long)val, (long)addr);
write32le(ptr, (0x14000000 |
(uint32_t)(type == R_AARCH64_CALL26) << 31 |
@ -276,10 +276,10 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
return;
case R_AARCH64_ADR_GOT_PAGE: {
uint64_t off =
(((S->got->sh_addr +
get_sym_attr(S, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
(((s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset) >> 12) - (addr >> 12));
if ((off + ((uint64_t)1 << 20)) >> 21)
tcc_error(S, "R_AARCH64_ADR_GOT_PAGE relocation failed");
tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
(off & 0x1ffffc) << 3 | (off & 3) << 29));
return;
@ -287,8 +287,8 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
case R_AARCH64_LD64_GOT_LO12_NC:
write32le(ptr,
((read32le(ptr) & 0xfff803ff) |
((S->got->sh_addr +
get_sym_attr(S, sym_index, 0)->got_offset) & 0xff8) << 7));
((s1->got->sh_addr +
get_sym_attr(s1, sym_index, 0)->got_offset) & 0xff8) << 7));
return;
case R_AARCH64_COPY:
return;
@ -304,7 +304,7 @@ void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t a
return;
case R_AARCH64_RELATIVE:
#ifdef TCC_TARGET_PE
add32le(ptr, val - S->pe_imagebase);
add32le(ptr, val - s1->pe_imagebase);
#endif
/* do nothing */
return;

1516
c67-gen.c

File diff suppressed because it is too large

14
c67-link.c

@ -65,23 +65,23 @@ int gotplt_entry_type (int reloc_type)
return -1;
}
ST_FUNC unsigned create_plt_entry(TCCState *S, unsigned got_offset, struct sym_attr *attr)
ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{
tcc_error(S, "C67 got not implemented");
tcc_error("C67 got not implemented");
return 0;
}
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
ST_FUNC void relocate_plt(TCCState *S)
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!S->plt)
if (!s1->plt)
return;
p = S->plt->data;
p_end = p + S->plt->data_offset;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
/* XXX: TODO */
@ -91,7 +91,7 @@ ST_FUNC void relocate_plt(TCCState *S)
}
}
void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{
switch(type) {
case R_C60_32:

374
i386-asm.c

@ -253,10 +253,10 @@ static const uint16_t op0_codes[] = {
#endif
};
static inline int get_reg_shift(TCCState *S)
static inline int get_reg_shift(TCCState *s1)
{
int shift, v;
v = asm_int_expr(S);
v = asm_int_expr(s1);
switch(v) {
case 1:
shift = 0;
@ -271,7 +271,7 @@ static inline int get_reg_shift(TCCState *S)
shift = 3;
break;
default:
expect(S, "1, 2, 4 or 8 constant");
expect("1, 2, 4 or 8 constant");
shift = 0;
break;
}
@ -279,11 +279,11 @@ static inline int get_reg_shift(TCCState *S)
}
#ifdef TCC_TARGET_X86_64
static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
static int asm_parse_numeric_reg(int t, unsigned int *type)
{
int reg = -1;
if (t >= TOK_IDENT && t < S->tccpp_tok_ident) {
const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str;
if (t >= TOK_IDENT && t < tok_ident) {
const char *s = table_ident[t - TOK_IDENT]->str;
char c;
*type = OP_REG64;
if (*s == 'c') {
@ -318,51 +318,51 @@ static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
}
#endif
static int asm_parse_reg(TCCState* S, unsigned int *type)
static int asm_parse_reg(unsigned int *type)
{
int reg = 0;
*type = 0;
if (S->tccpp_tok != '%')
if (tok != '%')
goto error_32;
next(S);
if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {
reg = S->tccpp_tok - TOK_ASM_eax;
next();
if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
reg = tok - TOK_ASM_eax;
*type = OP_REG32;
#ifdef TCC_TARGET_X86_64
} else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {
reg = S->tccpp_tok - TOK_ASM_rax;
} else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
reg = tok - TOK_ASM_rax;
*type = OP_REG64;
} else if (S->tccpp_tok == TOK_ASM_rip) {
} else if (tok == TOK_ASM_rip) {
reg = -2; /* Probably should use different escape code. */
*type = OP_REG64;
} else if ((reg = asm_parse_numeric_reg(S, S->tccpp_tok, type)) >= 0
} else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0
&& (*type == OP_REG32 || *type == OP_REG64)) {
;
#endif
} else {
error_32:
expect(S, "register");
expect("register");
}
next(S);
next();
return reg;
}
static void parse_operand(TCCState *S, Operand *op)
static void parse_operand(TCCState *s1, Operand *op)
{
ExprValue e;
int reg, indir;
const char *p;
indir = 0;
if (S->tccpp_tok == '*') {
next(S);
if (tok == '*') {
next();
indir = OP_INDIR;
}
if (S->tccpp_tok == '%') {
next(S);
if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {
reg = S->tccpp_tok - TOK_ASM_al;
if (tok == '%') {
next();
if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
reg = tok - TOK_ASM_al;
op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
op->reg = reg & 7;
if ((op->type & OP_REG) && op->reg == TREG_XAX)
@ -371,48 +371,48 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_CL;
else if (op->type == OP_REG16 && op->reg == TREG_XDX)
op->type |= OP_DX;
} else if (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) {
} else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
op->type = OP_DB;
op->reg = S->tccpp_tok - TOK_ASM_dr0;
} else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {
op->reg = tok - TOK_ASM_dr0;
} else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
op->type = OP_SEG;
op->reg = S->tccpp_tok - TOK_ASM_es;
} else if (S->tccpp_tok == TOK_ASM_st) {
op->reg = tok - TOK_ASM_es;
} else if (tok == TOK_ASM_st) {
op->type = OP_ST;
op->reg = 0;
next(S);
if (S->tccpp_tok == '(') {
next(S);
if (S->tccpp_tok != TOK_PPNUM)
next();
if (tok == '(') {
next();
if (tok != TOK_PPNUM)
goto reg_error;
p = S->tccpp_tokc.str.data;
p = tokc.str.data;
reg = p[0] - '0';
if ((unsigned)reg >= 8 || p[1] != '\0')
goto reg_error;
op->reg = reg;
next(S);
skip(S, ')');
next();
skip(')');
}
if (op->reg == 0)
op->type |= OP_ST0;
goto no_skip;
#ifdef TCC_TARGET_X86_64
} else if (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) {
} else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
op->type = OP_REG8 | OP_REG8_LOW;
op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;
} else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {
op->reg = 4 + tok - TOK_ASM_spl;
} else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
;
#endif
} else {
reg_error:
tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
}
next(S);
next();
no_skip: ;
} else if (S->tccpp_tok == '$') {
} else if (tok == '$') {
/* constant value */
next(S);
asm_expr(S, &e);
next();
asm_expr(s1, &e);
op->type = OP_IM32;
op->e = e;
if (!op->e.sym) {
@ -433,45 +433,45 @@ static void parse_operand(TCCState *S, Operand *op)
op->reg = -1;
op->reg2 = -1;
op->shift = 0;
if (S->tccpp_tok != '(') {
asm_expr(S, &e);
if (tok != '(') {
asm_expr(s1, &e);
op->e = e;
} else {
next(S);
if (S->tccpp_tok == '%') {
unget_tok(S, '(');
next();
if (tok == '%') {
unget_tok('(');
op->e.v = 0;
op->e.sym = NULL;
} else {
/* bracketed offset expression */
asm_expr(S, &e);
if (S->tccpp_tok != ')')
expect(S, ")");
next(S);
asm_expr(s1, &e);
if (tok != ')')
expect(")");
next();
op->e.v = e.v;
op->e.sym = e.sym;
}
op->e.pcrel = 0;
}
if (S->tccpp_tok == '(') {
if (tok == '(') {
unsigned int type = 0;
next(S);
if (S->tccpp_tok != ',') {
op->reg = asm_parse_reg(S, &type);
next();
if (tok != ',') {
op->reg = asm_parse_reg(&type);
}
if (S->tccpp_tok == ',') {
next(S);
if (S->tccpp_tok != ',') {
op->reg2 = asm_parse_reg(S, &type);
if (tok == ',') {
next();
if (tok != ',') {
op->reg2 = asm_parse_reg(&type);
}
if (S->tccpp_tok == ',') {
next(S);
op->shift = get_reg_shift(S);
if (tok == ',') {
next();
op->shift = get_reg_shift(s1);
}
}
if (type & OP_REG32)
op->type |= OP_EA32;
skip(S, ')');
skip(')');
}
if (op->reg == -1 && op->reg2 == -1)
op->type |= OP_ADDR;
@ -480,65 +480,65 @@ static void parse_operand(TCCState *S, Operand *op)
}
/* XXX: unify with C code output ? */
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
ST_FUNC void gen_expr32(ExprValue *pe)
{
if (pe->pcrel)
/* If PC-relative, always set VT_SYM, even without symbol,
so as to force a relocation to be emitted. */
gen_addrpc32(S, VT_SYM, pe->sym, pe->v);
gen_addrpc32(VT_SYM, pe->sym, pe->v);
else
gen_addr32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
}
#ifdef TCC_TARGET_X86_64
ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe)
ST_FUNC void gen_expr64(ExprValue *pe)
{
gen_addr64(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
}
#endif
/* XXX: unify with C code output ? */
static void gen_disp32(TCCState* S, ExprValue *pe)
static void gen_disp32(ExprValue *pe)
{
Sym *sym = pe->sym;
ElfSym *esym = elfsym(S, sym);
ElfSym *esym = elfsym(sym);
if (esym && esym->st_shndx == cur_text_section->sh_num) {
/* same section: we can output an absolute value. Note
that the TCC compiler behaves differently here because
it always outputs a relocation to ease (future) code
elimination in the linker */
gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4);
gen_le32(pe->v + esym->st_value - ind - 4);
} else {
if (sym && sym->type.t == VT_VOID) {
sym->type.t = VT_FUNC;
sym->type.ref = NULL;
}
gen_addrpc32(S, VT_SYM, sym, pe->v);
gen_addrpc32(VT_SYM, sym, pe->v);
}
}
/* generate the modrm operand */
static inline int asm_modrm(TCCState* S, int reg, Operand *op)
static inline int asm_modrm(int reg, Operand *op)
{
int mod, reg1, reg2, sib_reg1;
if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
g(S, 0xc0 + (reg << 3) + op->reg);
g(0xc0 + (reg << 3) + op->reg);
} else if (op->reg == -1 && op->reg2 == -1) {
/* displacement only */
#ifdef TCC_TARGET_X86_64
g(S, 0x04 + (reg << 3));
g(S, 0x25);
g(0x04 + (reg << 3));
g(0x25);
#else
g(S, 0x05 + (reg << 3));
g(0x05 + (reg << 3));
#endif
gen_expr32(S, &op->e);
gen_expr32(&op->e);
#ifdef TCC_TARGET_X86_64
} else if (op->reg == -2) {
ExprValue *pe = &op->e;
g(S, 0x05 + (reg << 3));
gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
return S->tccgen_ind;
g(0x05 + (reg << 3));
gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
return ind;
#endif
} else {
sib_reg1 = op->reg;
@ -557,19 +557,19 @@ static inline int asm_modrm(TCCState* S, int reg, Operand *op)
reg1 = op->reg;
if (op->reg2 != -1)
reg1 = 4;
g(S, mod + (reg << 3) + reg1);
g(mod + (reg << 3) + reg1);
if (reg1 == 4) {
/* add sib byte */
reg2 = op->reg2;
if (reg2 == -1)
reg2 = 4; /* indicate no index */
g(S, (op->shift << 6) + (reg2 << 3) + sib_reg1);
g((op->shift << 6) + (reg2 << 3) + sib_reg1);
}
/* add offset */
if (mod == 0x40) {
g(S, op->e.v);
g(op->e.v);
} else if (mod == 0x80 || op->reg == -1) {
gen_expr32(S, &op->e);
gen_expr32(&op->e);
}
}
return 0;
@ -581,7 +581,7 @@ static inline int asm_modrm(TCCState* S, int reg, Operand *op)
#define REX_X 0x42
#define REX_B 0x41
static void asm_rex(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_type,
static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,
int regi, int rmi)
{
unsigned char rex = width64 ? 0x48 : 0;
@ -631,9 +631,9 @@ static void asm_rex(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_
}
if (rex) {
if (saw_high_8bit)
tcc_error(S, "can't encode register %%%ch when REX prefix is required",
tcc_error("can't encode register %%%ch when REX prefix is required",
"acdb"[saw_high_8bit-4]);
g(S, rex);
g(rex);
}
}
#endif
@ -679,7 +679,7 @@ static void maybe_print_stats (void)
}
}
ST_FUNC void asm_opcode(TCCState *S, int opcode)
ST_FUNC void asm_opcode(TCCState *s1, int opcode)
{
const ASMInstr *pa;
int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
@ -697,7 +697,7 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
/* force synthetic ';' after prefix instruction, so we can handle */
/* one-line things like "rep stosb" instead of only "rep\nstosb" */
if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)
unget_tok(S, ';');
unget_tok(';');
/* get operands */
pop = ops;
@ -705,27 +705,27 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
seg_prefix = 0;
alltypes = 0;
for(;;) {
if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)
if (tok == ';' || tok == TOK_LINEFEED)
break;
if (nb_ops >= MAX_OPERANDS) {
tcc_error(S, "incorrect number of operands");
tcc_error("incorrect number of operands");
}
parse_operand(S, pop);
if (S->tccpp_tok == ':') {
parse_operand(s1, pop);
if (tok == ':') {
if (pop->type != OP_SEG || seg_prefix)
tcc_error(S, "incorrect prefix");
tcc_error("incorrect prefix");
seg_prefix = segment_prefixes[pop->reg];
next(S);
parse_operand(S, pop);
next();
parse_operand(s1, pop);
if (!(pop->type & OP_EA)) {
tcc_error(S, "segment prefix must be followed by memory reference");
tcc_error("segment prefix must be followed by memory reference");
}
}
pop++;
nb_ops++;
if (S->tccpp_tok != ',')
if (tok != ',')
break;
next(S);
next();
}
s = 0; /* avoid warning */
@ -842,23 +842,23 @@ again:
int b;
b = op0_codes[opcode - TOK_ASM_first];
if (b & 0xff00)
g(S, b >> 8);
g(S, b);
g(b >> 8);
g(b);
return;
} else if (opcode <= TOK_ASM_alllast) {
tcc_error(S, "bad operand with opcode '%s'",
get_tok_str(S, opcode, NULL));
tcc_error("bad operand with opcode '%s'",
get_tok_str(opcode, NULL));
} else {
/* Special case for cmovcc, we accept size suffixes but ignore
them, but we don't want them to blow up our tables. */
TokenSym *ts = S->tccpp_table_ident[opcode - TOK_IDENT];
TokenSym *ts = table_ident[opcode - TOK_IDENT];
if (ts->len >= 6
&& strchr("wlq", ts->str[ts->len-1])
&& !memcmp(ts->str, "cmov", 4)) {
opcode = tok_alloc(S, ts->str, ts->len-1)->tok;
opcode = tok_alloc(ts->str, ts->len-1)->tok;
goto again;
}
tcc_error(S, "unknown opcode '%s'", ts->str);
tcc_error("unknown opcode '%s'", ts->str);
}
}
/* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
@ -886,7 +886,7 @@ again:
(ops[0].type & OP_EA))
s = NBWLX - 2;
else
tcc_error(S, "cannot infer opcode suffix");
tcc_error("cannot infer opcode suffix");
}
}
@ -894,7 +894,7 @@ again:
/* Generate addr32 prefix if needed */
for(i = 0; i < nb_ops; i++) {
if (ops[i].type & OP_EA32) {
g(S, 0x67);
g(0x67);
break;
}
}
@ -913,7 +913,7 @@ again:
p66 = 1;
}
if (p66)
g(S, 0x66);
g(0x66);
#ifdef TCC_TARGET_X86_64
rex64 = 0;
if (pa->instr_type & OPC_48)
@ -943,9 +943,9 @@ again:
/* now generates the operation */
if (OPCT_IS(pa->instr_type, OPC_FWAIT))
g(S, 0x9b);
g(0x9b);
if (seg_prefix)
g(S, seg_prefix);
g(seg_prefix);
v = pa->opcode;
if (pa->instr_type & OPC_0F)
@ -998,7 +998,7 @@ again:
goto modrm_found;
}
#ifdef ASM_DEBUG
tcc_error(S, "bad op table");
tcc_error("bad op table");
#endif
modrm_found:
modrm_index = i;
@ -1014,7 +1014,7 @@ again:
}
}
#ifdef TCC_TARGET_X86_64
asm_rex (S, rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
#endif
if (pa->instr_type & OPC_REG) {
@ -1035,10 +1035,10 @@ again:
int jmp_disp;
/* see if we can really generate the jump with a byte offset */
esym = elfsym(S, ops[0].e.sym);
esym = elfsym(ops[0].e.sym);
if (!esym || esym->st_shndx != cur_text_section->sh_num)
goto no_short_jump;
jmp_disp = ops[0].e.v + esym->st_value - S->tccgen_ind - 2 - (v >= 0xff);
jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
if (jmp_disp == (int8_t)jmp_disp) {
/* OK to generate jump */
ops[0].e.sym = 0;
@ -1053,18 +1053,18 @@ again:
else if (v == 0x70) /* jcc */
v += 0x0f10;
else
tcc_error(S, "invalid displacement");
tcc_error("invalid displacement");
}
}
if (OPCT_IS(pa->instr_type, OPC_TEST))
v += test_bits[opcode - pa->sym];
op1 = v >> 16;
if (op1)
g(S, op1);
g(op1);
op1 = (v >> 8) & 0xff;
if (op1)
g(S, op1);
g(S, v);
g(op1);
g(v);
if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
reg = (opcode - pa->sym) / NBWLX;
@ -1084,7 +1084,7 @@ again:
used instead of group */
if (modreg_index >= 0)
reg = ops[modreg_index].reg;
pc = asm_modrm(S, reg, &ops[modrm_index]);
pc = asm_modrm(reg, &ops[modrm_index]);
}
/* emit constants */
@ -1092,10 +1092,10 @@ again:
if (!(pa->instr_type & OPC_0F)
&& (pa->opcode == 0x9a || pa->opcode == 0xea)) {
/* ljmp or lcall kludge */
gen_expr32(S, &ops[1].e);
gen_expr32(&ops[1].e);
if (ops[0].e.sym)
tcc_error(S, "cannot relocate");
gen_le16(S, ops[0].e.v);
tcc_error("cannot relocate");
gen_le16(ops[0].e.v);
return;
}
#endif
@ -1116,32 +1116,32 @@ again:
}
if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
tcc_error(S, "cannot relocate");
tcc_error("cannot relocate");
if (v & (OP_IM8 | OP_IM8S)) {
g(S, ops[i].e.v);
g(ops[i].e.v);
} else if (v & OP_IM16) {
gen_le16(S, ops[i].e.v);
gen_le16(ops[i].e.v);
#ifdef TCC_TARGET_X86_64
} else if (v & OP_IM64) {
gen_expr64(S, &ops[i].e);
gen_expr64(&ops[i].e);
#endif
} else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
gen_disp32(S, &ops[i].e);
gen_disp32(&ops[i].e);
} else {
gen_expr32(S, &ops[i].e);
gen_expr32(&ops[i].e);
}
}
}
/* after immediate operands, adjust pc-relative address */
if (pc)
add32le(cur_text_section->data + pc - 4, pc - S->tccgen_ind);
add32le(cur_text_section->data + pc - 4, pc - ind);
}
/* return the constraint priority (we allocate first the lowest
numbered constraints) */
static inline int constraint_priority(TCCState* S, const char *str)
static inline int constraint_priority(const char *str)
{
int priority, c, pr;
@ -1182,7 +1182,7 @@ static inline int constraint_priority(TCCState* S, const char *str)
pr = 4;
break;
default:
tcc_error(S, "unknown constraint '%c'", c);
tcc_error("unknown constraint '%c'", c);
pr = 0;
}
if (pr > priority)
@ -1200,19 +1200,19 @@ static const char *skip_constraint_modifiers(const char *p)
/* If T (a token) is of the form "%reg" returns the register
number and type, otherwise return -1. */
ST_FUNC int asm_parse_regvar (TCCState* S, int t)
ST_FUNC int asm_parse_regvar (int t)
{
const char *s;
Operand op;
if (t < TOK_IDENT || (t & SYM_FIELD))
return -1;
s = S->tccpp_table_ident[t - TOK_IDENT]->str;
s = table_ident[t - TOK_IDENT]->str;
if (s[0] != '%')
return -1;
t = tok_alloc_const(S, s + 1);
unget_tok(S, t);
unget_tok(S, '%');
parse_operand(S, &op);
t = tok_alloc_const(s + 1);
unget_tok(t);
unget_tok('%');
parse_operand(tcc_state, &op);
/* Accept only integer regs for now. */
if (op.type & OP_REG)
return op.reg;
@ -1225,7 +1225,7 @@ ST_FUNC int asm_parse_regvar (TCCState* S, int t)
#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
ST_FUNC void asm_compute_constraints(ASMOperand *operands,
int nb_operands, int nb_outputs,
const uint8_t *clobber_regs,
int *pout_reg)
@ -1253,13 +1253,13 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
str = skip_constraint_modifiers(str);
if (isnum(*str) || *str == '[') {
/* this is a reference to another constraint */
k = find_constraint(S, operands, nb_operands, str, NULL);
k = find_constraint(operands, nb_operands, str, NULL);
if ((unsigned)k >= i || i < nb_outputs)
tcc_error(S, "invalid reference in constraint %d ('%s')",
tcc_error("invalid reference in constraint %d ('%s')",
i, str);
op->ref_index = k;
if (operands[k].input_index >= 0)
tcc_error(S, "cannot reference twice the same operand");
tcc_error("cannot reference twice the same operand");
operands[k].input_index = i;
op->priority = 5;
} else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
@ -1268,7 +1268,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
op->priority = 1;
op->reg = reg;
} else {
op->priority = constraint_priority(S, str);
op->priority = constraint_priority(str);
}
}
@ -1316,7 +1316,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
}
if (op->reg >= 0) {
if (is_reg_allocated(op->reg))
tcc_error(S, "asm regvar requests register that's taken already");
tcc_error("asm regvar requests register that's taken already");
reg = op->reg;
goto reg_found;
}
@ -1330,7 +1330,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
/* FALL THRU */
case '&':
if (j >= nb_outputs)
tcc_error(S, "'%c' modifier can only be applied to outputs", c);
tcc_error("'%c' modifier can only be applied to outputs", c);
reg_mask = REG_IN_MASK | REG_OUT_MASK;
goto try_next;
case 'A':
@ -1424,7 +1424,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
}
break;
default:
tcc_error(S, "asm constraint %d ('%s') could not be satisfied",
tcc_error("asm constraint %d ('%s') could not be satisfied",
j, op->constraint);
break;
}
@ -1447,7 +1447,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
if (!(regs_allocated[reg] & REG_OUT_MASK))
goto reg_found2;
}
tcc_error(S, "could not find free output register for reloading");
tcc_error("could not find free output register for reloading");
reg_found2:
*pout_reg = reg;
break;
@ -1461,7 +1461,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
op = &operands[j];
printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
j,
op->id ? get_tok_str(S, op->id, NULL) : "",
op->id ? get_tok_str(op->id, NULL) : "",
op->constraint,
op->vt->r,
op->reg);
@ -1471,7 +1471,7 @@ ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands,
#endif
}
ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str,
ST_FUNC void subst_asm_operand(CString *add_str,
SValue *sv, int modifier)
{
int r, reg, size, val;
@ -1481,33 +1481,33 @@ ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str,
if ((r & VT_VALMASK) == VT_CONST) {
if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
modifier != 'P')
cstr_ccat(S, add_str, '$');
cstr_ccat(add_str, '$');
if (r & VT_SYM) {
const char *name = get_tok_str(S, sv->sym->v, NULL);
const char *name = get_tok_str(sv->sym->v, NULL);
if (sv->sym->v >= SYM_FIRST_ANOM) {
/* In case of anonymous symbols ("L.42", used
for static data labels) we can't find them
in the C symbol table when later looking up
this name. So enter them now into the asm label
list when we still know the symbol. */
get_asm_sym(S, tok_alloc_const(S, name), sv->sym);
get_asm_sym(tok_alloc_const(name), sv->sym);
}
if (S->leading_underscore)
cstr_ccat(S, add_str, '_');
cstr_cat(S, add_str, name, -1);
if (tcc_state->leading_underscore)
cstr_ccat(add_str, '_');
cstr_cat(add_str, name, -1);
if ((uint32_t)sv->c.i == 0)
goto no_offset;
cstr_ccat(S, add_str, '+');
cstr_ccat(add_str, '+');
}
val = sv->c.i;
if (modifier == 'n')
val = -val;
snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
cstr_cat(S, add_str, buf, -1);
cstr_cat(add_str, buf, -1);
no_offset:;
#ifdef TCC_TARGET_X86_64
if (r & VT_LVAL)
cstr_cat(S, add_str, "(%rip)", -1);
cstr_cat(add_str, "(%rip)", -1);
#endif
} else if ((r & VT_VALMASK) == VT_LOCAL) {
#ifdef TCC_TARGET_X86_64
@ -1515,24 +1515,24 @@ ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str,
#else
snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
#endif
cstr_cat(S, add_str, buf, -1);
cstr_cat(add_str, buf, -1);
} else if (r & VT_LVAL) {
reg = r & VT_VALMASK;
if (reg >= VT_CONST)
tcc_internal_error(S, "");
tcc_internal_error("");