Revert "Fix some errors on arm64-asm.c, rename some variables, fix several code style declarations"

This reverts commit 61537d899a.
This commit is contained in:
mingodad 2021-10-22 07:39:26 +02:00
parent d33f582e25
commit 2ce2dbcb09
18 changed files with 2852 additions and 2851 deletions

238
arm-asm.c
View file

@ -24,9 +24,9 @@
#define CONFIG_TCC_ASM #define CONFIG_TCC_ASM
#define NB_ASM_REGS 16 #define NB_ASM_REGS 16
ST_FUNC void g(TCCState *S, int c); ST_FUNC void g(TCCState* S, int c);
ST_FUNC void gen_le16(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 gen_le32(TCCState* S, int c);
/*************************************************************/ /*************************************************************/
#else #else
@ -100,10 +100,10 @@ static void parse_operand(TCCState *S, Operand *op)
op->type = 0; op->type = 0;
if (S->tok == '{') { // regset literal if (S->tccpp_tok == '{') { // regset literal
next(S); // skip '{' next(S); // skip '{'
while (S->tok != '}' && S->tok != TOK_EOF) { while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {
reg = asm_parse_regvar(S, S->tok); reg = asm_parse_regvar(S, S->tccpp_tok);
if (reg == -1) { if (reg == -1) {
expect(S, "register"); expect(S, "register");
return; return;
@ -113,11 +113,11 @@ static void parse_operand(TCCState *S, Operand *op)
if ((1 << reg) < regset) if ((1 << reg) < regset)
tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here"); tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
regset |= 1 << reg; regset |= 1 << reg;
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); // skip ',' next(S); // skip ','
} }
if (S->tok != '}') if (S->tccpp_tok != '}')
expect(S, "'}'"); expect(S, "'}'");
next(S); // skip '}' next(S); // skip '}'
if (regset == 0) { if (regset == 0) {
@ -128,22 +128,22 @@ static void parse_operand(TCCState *S, Operand *op)
op->regset = regset; op->regset = regset;
} }
return; return;
} else if ((reg = asm_parse_regvar(S, S->tok)) != -1) { } else if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_REG32; op->type = OP_REG32;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if ((reg = asm_parse_vfp_regvar(S->tok, 0)) != -1) { } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_VREG32; op->type = OP_VREG32;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if ((reg = asm_parse_vfp_regvar(S->tok, 1)) != -1) { } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_VREG64; op->type = OP_VREG64;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if (S->tok == '#' || S->tok == '$') { } else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
/* constant value */ /* constant value */
next(S); // skip '#' or '$' next(S); // skip '#' or '$'
} }
@ -160,44 +160,44 @@ static void parse_operand(TCCState *S, Operand *op)
} }
/* XXX: make it faster ? */ /* XXX: make it faster ? */
ST_FUNC void g(TCCState *S, int c) ST_FUNC void g(TCCState* S, int c)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 1; ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c; cur_text_section->data[S->tccgen_ind] = c;
S->ind = ind1; S->tccgen_ind = ind1;
} }
ST_FUNC void gen_le16 (TCCState *S, int i) ST_FUNC void gen_le16 (TCCState* S, int i)
{ {
g(S, i); g(S, i);
g(S, i>>8); g(S, i>>8);
} }
ST_FUNC void gen_le32 (TCCState *S, int i) ST_FUNC void gen_le32 (TCCState* S, int i)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 4; ind1 = S->tccgen_ind + 4;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind++] = i & 0xFF; cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
} }
ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe) ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
{ {
gen_le32(S, pe->v); gen_le32(S, pe->v);
} }
static uint32_t condition_code_of_token(TCCState *S, int token) { static uint32_t condition_code_of_token(TCCState* S, int token) {
if (token < TOK_ASM_nopeq) { if (token < TOK_ASM_nopeq) {
expect(S, "condition-enabled instruction"); expect(S, "condition-enabled instruction");
return 0; return 0;
@ -205,15 +205,15 @@ static uint32_t condition_code_of_token(TCCState *S, int token) {
return (token - TOK_ASM_nopeq) & 15; return (token - TOK_ASM_nopeq) & 15;
} }
static void asm_emit_opcode(TCCState *S, int token, uint32_t opcode) { static void asm_emit_opcode(TCCState* S, int token, uint32_t opcode) {
gen_le32(S, (condition_code_of_token(S, token) << 28) | opcode); gen_le32(S, (condition_code_of_token(S, token) << 28) | opcode);
} }
static void asm_emit_unconditional_opcode(TCCState *S, uint32_t opcode) { static void asm_emit_unconditional_opcode(TCCState* S, uint32_t opcode) {
gen_le32(S, opcode); gen_le32(S, opcode);
} }
static void asm_emit_coprocessor_opcode(TCCState *S, uint32_t high_nibble, uint8_t cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int inter_processor_transfer) static void asm_emit_coprocessor_opcode(TCCState* S, uint32_t high_nibble, uint8_t cp_number, uint8_t cp_opcode, uint8_t cp_destination_register, uint8_t cp_n_operand_register, uint8_t cp_m_operand_register, uint8_t cp_opcode2, int inter_processor_transfer)
{ {
uint32_t opcode = 0xe000000; uint32_t opcode = 0xe000000;
if (inter_processor_transfer) if (inter_processor_transfer)
@ -233,7 +233,7 @@ static void asm_emit_coprocessor_opcode(TCCState *S, uint32_t high_nibble, uint8
asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode); asm_emit_unconditional_opcode(S, (high_nibble << 28) | opcode);
} }
static void asm_nullary_opcode(TCCState *S, int token) static void asm_nullary_opcode(TCCState* S, int token)
{ {
switch (ARM_INSTRUCTION_GROUP(token)) { switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_nopeq: case TOK_ASM_nopeq:
@ -276,7 +276,7 @@ static void asm_binary_opcode(TCCState *S, int token)
uint32_t encoded_rotation = 0; uint32_t encoded_rotation = 0;
uint64_t amount; uint64_t amount;
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -328,9 +328,9 @@ static void asm_binary_opcode(TCCState *S, int token)
if (ops[1].reg == 13) if (ops[1].reg == 13)
tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL)); tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == TOK_ASM_ror) { if (S->tccpp_tok == TOK_ASM_ror) {
next(S); // skip 'ror' next(S); // skip 'ror'
parse_operand(S, &rotation); parse_operand(S, &rotation);
if (rotation.type != OP_IM8) { if (rotation.type != OP_IM8) {
@ -387,15 +387,15 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
uint8_t high_nibble; uint8_t high_nibble;
uint8_t mrc = 0; uint8_t mrc = 0;
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) { if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
coprocessor = S->tok - TOK_ASM_p0; coprocessor = S->tccpp_tok - TOK_ASM_p0;
next(S); next(S);
} else { } else {
expect(S, "'p<number>'"); expect(S, "'p<number>'");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -407,21 +407,21 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
} }
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) { if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {
if (S->tok >= TOK_ASM_r0 && S->tok <= TOK_ASM_r15) { if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {
registers[i] = S->tok - TOK_ASM_r0; registers[i] = S->tccpp_tok - TOK_ASM_r0;
next(S); next(S);
} else { } else {
expect(S, "'r<number>'"); expect(S, "'r<number>'");
return; return;
} }
} else { } else {
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) { if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
registers[i] = S->tok - TOK_ASM_c0; registers[i] = S->tccpp_tok - TOK_ASM_c0;
next(S); next(S);
} else { } else {
expect(S, "'c<number>'"); expect(S, "'c<number>'");
@ -429,7 +429,7 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
} }
} }
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
parse_operand(S, &opcode2); parse_operand(S, &opcode2);
} else { } else {
@ -493,11 +493,11 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
Operand ops[2]; Operand ops[2];
int nb_ops = 1; int nb_ops = 1;
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == '!') { if (S->tccpp_tok == '!') {
op0_exclam = 1; op0_exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip comma next(S); // skip comma
parse_operand(S, &ops[1]); parse_operand(S, &ops[1]);
++nb_ops; ++nb_ops;
@ -600,17 +600,17 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT. NB_SHIFT: will be set to 1 iff SHIFT is filled. Note that for rrx, there's no need to fill SHIFT.
SHIFT: will be filled in with the shift operand to use, if any. */ SHIFT: will be filled in with the shift operand to use, if any. */
static uint32_t asm_parse_optional_shift(TCCState *S, int* nb_shift, Operand* shift) static uint32_t asm_parse_optional_shift(TCCState* S, int* nb_shift, Operand* shift)
{ {
uint32_t opcode = 0; uint32_t opcode = 0;
*nb_shift = 0; *nb_shift = 0;
switch (S->tok) { switch (S->tccpp_tok) {
case TOK_ASM_asl: case TOK_ASM_asl:
case TOK_ASM_lsl: case TOK_ASM_lsl:
case TOK_ASM_asr: case TOK_ASM_asr:
case TOK_ASM_lsr: case TOK_ASM_lsr:
case TOK_ASM_ror: case TOK_ASM_ror:
switch (S->tok) { switch (S->tccpp_tok) {
case TOK_ASM_asl: case TOK_ASM_asl:
/* fallthrough */ /* fallthrough */
case TOK_ASM_lsl: case TOK_ASM_lsl:
@ -677,15 +677,15 @@ static void asm_data_processing_opcode(TCCState *S, int token)
uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
if (S->tok == TOK_ASM_asl || S->tok == TOK_ASM_lsl || S->tok == TOK_ASM_lsr || S->tok == TOK_ASM_asr || S->tok == TOK_ASM_ror || S->tok == TOK_ASM_rrx) if (S->tccpp_tok == TOK_ASM_asl || S->tccpp_tok == TOK_ASM_lsl || S->tccpp_tok == TOK_ASM_lsr || S->tccpp_tok == TOK_ASM_asr || S->tccpp_tok == TOK_ASM_ror || S->tccpp_tok == TOK_ASM_rrx)
break; break;
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
++nb_ops; ++nb_ops;
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); // skip ',' next(S); // skip ','
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
operands |= asm_parse_optional_shift(S, &nb_shift, &shift); operands |= asm_parse_optional_shift(S, &nb_shift, &shift);
if (nb_ops < 2) if (nb_ops < 2)
@ -852,7 +852,7 @@ static void asm_shift_opcode(TCCState *S, int token)
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
++nb_ops; ++nb_ops;
break; break;
} }
@ -961,7 +961,7 @@ static void asm_multiplication_opcode(TCCState *S, int token)
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
++nb_ops; ++nb_ops;
break; break;
} }
@ -1043,7 +1043,7 @@ static void asm_long_multiplication_opcode(TCCState *S, int token)
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
++nb_ops; ++nb_ops;
break; break;
} }
@ -1133,7 +1133,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(destination operand) register"); expect(S, "(destination operand) register");
return; return;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "at least two arguments"); expect(S, "at least two arguments");
else else
next(S); // skip ',' next(S); // skip ','
@ -1146,14 +1146,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "register"); expect(S, "register");
return; return;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "at least three arguments"); expect(S, "at least three arguments");
else else
next(S); // skip ',' next(S); // skip ','
break; break;
} }
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -1165,14 +1165,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ']') { if (S->tccpp_tok == ']') {
next(S); next(S);
closed_bracket = 1; closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software // exclam = 1; // implicit in hardware; don't do it in software
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op2_minus = 1; op2_minus = 1;
next(S); next(S);
} }
@ -1182,7 +1182,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL)); tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
return; return;
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
opcode |= asm_parse_optional_shift(S, &nb_shift, &shift); opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);
if (opcode == 0) if (opcode == 0)
@ -1196,12 +1196,12 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
} }
if (!closed_bracket) { if (!closed_bracket) {
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
if (S->tok == '!') { if (S->tccpp_tok == '!') {
exclam = 1; exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
@ -1389,33 +1389,33 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
// Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 // Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
// Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 // Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) { if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
coprocessor = S->tok - TOK_ASM_p0; coprocessor = S->tccpp_tok - TOK_ASM_p0;
next(S); next(S);
} else { } else {
expect(S, "'c<number>'"); expect(S, "'c<number>'");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) { if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
coprocessor_destination_register = S->tok - TOK_ASM_c0; coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;
next(S); next(S);
} else { } else {
expect(S, "'c<number>'"); expect(S, "'c<number>'");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -1425,14 +1425,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ']') { if (S->tccpp_tok == ']') {
next(S); next(S);
closed_bracket = 1; closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software // exclam = 1; // implicit in hardware; don't do it in software
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op2_minus = 1; op2_minus = 1;
next(S); next(S);
} }
@ -1453,12 +1453,12 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
preincrement = 1; // add offset before transfer preincrement = 1; // add offset before transfer
} }
if (!closed_bracket) { if (!closed_bracket) {
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
preincrement = 1; // add offset before transfer preincrement = 1; // add offset before transfer
if (S->tok == '!') { if (S->tccpp_tok == '!') {
exclam = 1; exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
@ -1528,12 +1528,12 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -1543,7 +1543,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
parse_operand(S, &ops[2]); parse_operand(S, &ops[2]);
if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) { if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
@ -1555,7 +1555,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
ops[2].type = OP_IM8; ops[2].type = OP_IM8;
ops[2].e.v = 0; ops[2].e.v = 0;
} }
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
@ -1593,11 +1593,11 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
break; break;
default: default:
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == '!') { if (S->tccpp_tok == '!') {
op0_exclam = 1; op0_exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); // skip comma next(S); // skip comma
else { else {
expect(S, "','"); expect(S, "','");
@ -1605,16 +1605,16 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
} }
} }
if (S->tok != '{') { if (S->tccpp_tok != '{') {
expect(S, "'{'"); expect(S, "'{'");
return; return;
} }
next(S); // skip '{' next(S); // skip '{'
first_regset_register = asm_parse_vfp_regvar(S->tok, 1); first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);
if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 1)) != -1) { if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
coprocessor = CP_DOUBLE_PRECISION_FLOAT; coprocessor = CP_DOUBLE_PRECISION_FLOAT;
next(S); next(S);
} else if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 0)) != -1) { } else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
coprocessor = CP_SINGLE_PRECISION_FLOAT; coprocessor = CP_SINGLE_PRECISION_FLOAT;
next(S); next(S);
} else { } else {
@ -1622,9 +1622,9 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
return; return;
} }
if (S->tok == '-') { if (S->tccpp_tok == '-') {
next(S); next(S);
if ((last_regset_register = asm_parse_vfp_regvar(S->tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1) if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
next(S); next(S);
else { else {
expect(S, "floating-point register"); expect(S, "floating-point register");
@ -1637,7 +1637,7 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here"); tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
return; return;
} }
if (S->tok != '}') { if (S->tccpp_tok != '}') {
expect(S, "'}'"); expect(S, "'}'");
return; return;
} }
@ -1688,7 +1688,7 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
#define VMOV_FRACTIONAL_DIGITS 7 #define VMOV_FRACTIONAL_DIGITS 7
#define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */ #define VMOV_ONE 10000000 /* pow(10, VMOV_FRACTIONAL_DIGITS) */
static uint32_t vmov_parse_fractional_part(TCCState *S, const char* s) static uint32_t vmov_parse_fractional_part(TCCState* S, const char* s)
{ {
uint32_t result = 0; uint32_t result = 0;
int i; int i;
@ -1720,16 +1720,16 @@ static int vmov_linear_approx_index(uint32_t beginning, uint32_t end, uint32_t v
return -1; return -1;
} }
static uint32_t vmov_parse_immediate_value(TCCState *S) { static uint32_t vmov_parse_immediate_value(TCCState* S) {
uint32_t value; uint32_t value;
unsigned long integral_value; unsigned long integral_value;
const char *p; const char *p;
if (S->tok != TOK_PPNUM) { if (S->tccpp_tok != TOK_PPNUM) {
expect(S, "immediate value"); expect(S, "immediate value");
return 0; return 0;
} }
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
errno = 0; errno = 0;
integral_value = strtoul(p, (char **)&p, 0); integral_value = strtoul(p, (char **)&p, 0);
@ -1747,7 +1747,7 @@ static uint32_t vmov_parse_immediate_value(TCCState *S) {
return value; return value;
} }
static uint8_t vmov_encode_immediate_value(TCCState *S, uint32_t value) static uint8_t vmov_encode_immediate_value(TCCState* S, uint32_t value)
{ {
uint32_t limit; uint32_t limit;
uint32_t end = 0; uint32_t end = 0;
@ -1785,10 +1785,10 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
operands[0] = CRd; operands[0] = CRd;
if (S->tok == '#' || S->tok == '$') { if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
next(S); next(S);
} }
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op_minus = 1; op_minus = 1;
next(S); next(S);
} }
@ -1956,7 +1956,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
break; break;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -2078,7 +2078,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
for (nb_ops = 0; nb_ops < 3; ) { for (nb_ops = 0; nb_ops < 3; ) {
// Note: Necessary because parse_operand can't parse decimal numerals. // Note: Necessary because parse_operand can't parse decimal numerals.
if (nb_ops == 1 && (S->tok == '#' || S->tok == '$' || S->tok == TOK_PPNUM || S->tok == '-')) { if (nb_ops == 1 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) {
asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg); asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg);
return; return;
} }
@ -2100,7 +2100,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
return; return;
} }
++nb_ops; ++nb_ops;
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
break; break;
@ -2239,7 +2239,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0); asm_emit_coprocessor_opcode(S, condition_code_of_token(S, token), coprocessor, opcode1, ops[0].reg, (ops[1].type == OP_IM8) ? ops[1].e.v : ops[1].reg, (ops[2].type == OP_IM8) ? ops[2].e.v : ops[2].reg, opcode2, 0);
} }
static void asm_floating_point_status_register_opcode(TCCState *S, int token) static void asm_floating_point_status_register_opcode(TCCState* S, int token)
{ {
uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT; uint8_t coprocessor = CP_SINGLE_PRECISION_FLOAT;
uint8_t opcode; uint8_t opcode;
@ -2248,7 +2248,7 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
switch (ARM_INSTRUCTION_GROUP(token)) { switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vmrseq: case TOK_ASM_vmrseq:
opcode = 0xf; opcode = 0xf;
if (S->tok == TOK_ASM_apsr_nzcv) { if (S->tccpp_tok == TOK_ASM_apsr_nzcv) {
arm_operand.type = OP_REG32; arm_operand.type = OP_REG32;
arm_operand.reg = 15; // not PC arm_operand.reg = 15; // not PC
next(S); // skip apsr_nzcv next(S); // skip apsr_nzcv
@ -2260,11 +2260,11 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
} }
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "','"); expect(S, "','");
else else
next(S); // skip ',' next(S); // skip ','
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tok); vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
next(S); // skip vfp sys reg next(S); // skip vfp sys reg
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) { if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {
tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL)); tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL));
@ -2273,9 +2273,9 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
break; break;
case TOK_ASM_vmsreq: case TOK_ASM_vmsreq:
opcode = 0xe; opcode = 0xe;
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tok); vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
next(S); // skip vfp sys reg next(S); // skip vfp sys reg
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "','"); expect(S, "','");
else else
next(S); // skip ',' next(S); // skip ','
@ -2329,12 +2329,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(destination operand) register"); expect(S, "(destination operand) register");
return; return;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "at least two arguments"); expect(S, "at least two arguments");
else else
next(S); // skip ',' next(S); // skip ','
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -2346,14 +2346,14 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ']') { if (S->tccpp_tok == ']') {
next(S); next(S);
closed_bracket = 1; closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software // exclam = 1; // implicit in hardware; don't do it in software
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op2_minus = 1; op2_minus = 1;
next(S); next(S);
} }
@ -2365,12 +2365,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
} }
if (!closed_bracket) { if (!closed_bracket) {
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
if (S->tok == '!') { if (S->tccpp_tok == '!') {
exclam = 1; exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
@ -2439,7 +2439,7 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
} }
/* Note: almost dupe of encbranch in arm-gen.c */ /* Note: almost dupe of encbranch in arm-gen.c */
static uint32_t encbranchoffset(TCCState *S, int pos, int addr, int fail) static uint32_t encbranchoffset(TCCState* S, int pos, int addr, int fail)
{ {
addr-=pos+8; addr-=pos+8;
addr/=4; addr/=4;
@ -2467,7 +2467,7 @@ static void asm_branch_opcode(TCCState *S, int token)
tcc_error(S, "invalid branch target"); tcc_error(S, "invalid branch target");
return; return;
} }
jmp_disp = encbranchoffset(S, S->ind, e.v + esym->st_value, 1); jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1);
break; break;
default: default:
parse_operand(S, &op); parse_operand(S, &op);
@ -2501,7 +2501,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
{ {
while (token == TOK_LINEFEED) { while (token == TOK_LINEFEED) {
next(S); next(S);
token = S->tok; token = S->tccpp_tok;
} }
if (token == TOK_EOF) if (token == TOK_EOF)
return; return;
@ -2737,7 +2737,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
} }
} }
ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier) ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier)
{ {
int r, reg, size, val; int r, reg, size, val;
char buf[64]; char buf[64];
@ -2814,7 +2814,7 @@ ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int mo
} }
/* generate prolog and epilog code for asm statement */ /* generate prolog and epilog code for asm statement */
ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands, ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
int nb_outputs, int is_output, int nb_outputs, int is_output,
uint8_t *clobber_regs, uint8_t *clobber_regs,
int out_reg) int out_reg)
@ -2900,7 +2900,7 @@ ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands,
/* return the constraint priority (we allocate first the lowest /* return the constraint priority (we allocate first the lowest
numbered constraints) */ numbered constraints) */
static inline int constraint_priority(TCCState *S, const char *str) static inline int constraint_priority(TCCState* S, const char *str)
{ {
int priority, c, pr; int priority, c, pr;
@ -2956,7 +2956,7 @@ static const char *skip_constraint_modifiers(const char *p)
#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) #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(TCCState* S, ASMOperand *operands,
int nb_operands, int nb_outputs, int nb_operands, int nb_outputs,
const uint8_t *clobber_regs, const uint8_t *clobber_regs,
int *pout_reg) int *pout_reg)
@ -3191,7 +3191,7 @@ ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands,
#endif #endif
} }
ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str) ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)
{ {
int reg; int reg;
TokenSym *ts; TokenSym *ts;

374
arm-gen.c

File diff suppressed because it is too large Load diff

View file

@ -9,9 +9,9 @@
#define CONFIG_TCC_ASM #define CONFIG_TCC_ASM
#define NB_ASM_REGS 16 #define NB_ASM_REGS 16
ST_FUNC void g(TCCState *S, int c); ST_FUNC void g(TCCState* S, int c);
ST_FUNC void gen_le16(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 gen_le32(TCCState* S, int c);
/*************************************************************/ /*************************************************************/
#else #else
@ -19,74 +19,74 @@ ST_FUNC void gen_le32(TCCState *S, int c);
#define USING_GLOBALS #define USING_GLOBALS
#include "tcc.h" #include "tcc.h"
static void asm_error(TCCState *S) static void asm_error(void)
{ {
tcc_error(S, "ARM asm not implemented."); tcc_error("ARM asm not implemented.");
} }
/* XXX: make it faster ? */ /* XXX: make it faster ? */
ST_FUNC void g(TCCState *S, int c) ST_FUNC void g(TCCState* S, int c)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (nocode_wanted)
return; return;
ind1 = S->ind + 1; ind1 = ind + 1;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(cur_text_section, ind1);
cur_text_section->data[S->ind] = c; cur_text_section->data[ind] = c;
S->ind = ind1; ind = ind1;
} }
ST_FUNC void gen_le16 (TCCState *S, int i) ST_FUNC void gen_le16 (TCCState* S, int i)
{ {
g(S, i); g(S, i);
g(S, i>>8); g(S, i>>8);
} }
ST_FUNC void gen_le32 (TCCState *S, int i) ST_FUNC void gen_le32 (TCCState* S, int i)
{ {
gen_le16(S, i); gen_le16(S, i);
gen_le16(S, i>>16); gen_le16(S, i>>16);
} }
ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe) ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
{ {
gen_le32(S, pe->v); gen_le32(S, pe->v);
} }
ST_FUNC void asm_opcode(TCCState *S, int opcode) ST_FUNC void asm_opcode(TCCState *S, int opcode)
{ {
asm_error(S); asm_error();
} }
ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier) ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
{ {
asm_error(S); asm_error();
} }
/* generate prolog and epilog code for asm statement */ /* generate prolog and epilog code for asm statement */
ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands, ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
int nb_outputs, int is_output, int nb_outputs, int is_output,
uint8_t *clobber_regs, uint8_t *clobber_regs,
int out_reg) int out_reg)
{ {
} }
ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands, ST_FUNC void asm_compute_constraints(ASMOperand *operands,
int nb_operands, int nb_outputs, int nb_operands, int nb_outputs,
const uint8_t *clobber_regs, const uint8_t *clobber_regs,
int *pout_reg) int *pout_reg)
{ {
} }
ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str) ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
{ {
asm_error(S); asm_error();
} }
ST_FUNC int asm_parse_regvar (TCCState *S, int t) ST_FUNC int asm_parse_regvar (int t)
{ {
asm_error(S); asm_error();
return -1; return -1;
} }

View file

@ -107,13 +107,13 @@ static uint32_t fltr(int r)
// Add an instruction to text section: // Add an instruction to text section:
ST_FUNC void o(TCCState *S, unsigned int c) ST_FUNC void o(TCCState *S, unsigned int c)
{ {
int ind1 = S->ind + 4; int ind1 = S->tccgen_ind + 4;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
write32le(cur_text_section->data + S->ind, c); write32le(cur_text_section->data + S->tccgen_ind, c);
S->ind = ind1; S->tccgen_ind = ind1;
} }
static int arm64_encode_bimm64(uint64_t x) static int arm64_encode_bimm64(uint64_t x)
@ -452,9 +452,9 @@ static void arm64_strv(TCCState *S, int sz_, int dst, int bas, uint64_t off)
static void arm64_sym(TCCState *S, int r, Sym *sym, unsigned long addend) static void arm64_sym(TCCState *S, int r, Sym *sym, unsigned long addend)
{ {
greloca(S, cur_text_section, sym, S->ind, R_AARCH64_ADR_GOT_PAGE, 0); greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
o(S, 0x90000000 | r); // adrp xr, #sym o(S, 0x90000000 | r); // adrp xr, #sym
greloca(S, cur_text_section, sym, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0); greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
o(S, 0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym] o(S, 0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]
if (addend) { if (addend) {
// add xr, xr, #addend // add xr, xr, #addend
@ -654,14 +654,14 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv)
static void arm64_gen_bl_or_b(TCCState *S, int b) static void arm64_gen_bl_or_b(TCCState *S, int b)
{ {
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->vtop->r & VT_SYM)) { if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
greloca(S, cur_text_section, S->vtop->sym, S->ind, greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0); b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl . o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl .
} }
else { else {
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
S->vtop->r &= ~VT_MUSTBOUND; S->tccgen_vtop->r &= ~VT_MUSTBOUND;
#endif #endif
o(S, 0xd61f0000 | (uint32_t)!b << 21 | intr(S, gv(S, RC_R30)) << 5); // br/blr o(S, 0xd61f0000 | (uint32_t)!b << 21 | intr(S, gv(S, RC_R30)) << 5); // br/blr
} }
@ -673,7 +673,7 @@ static void gen_bounds_call(TCCState *S, int v)
{ {
Sym *sym = external_helper_sym(S, v); Sym *sym = external_helper_sym(S, v);
greloca(S, cur_text_section, sym, S->ind, R_AARCH64_CALL26, 0); greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_CALL26, 0);
o(S, 0x94000000); // bl o(S, 0x94000000); // bl
} }
@ -681,7 +681,7 @@ static void gen_bounds_prolog(TCCState *S)
{ {
/* leave some room for bound checking code */ /* leave some room for bound checking code */
S->func_bound_offset = lbounds_section->data_offset; S->func_bound_offset = lbounds_section->data_offset;
S->func_bound_ind = S->ind; S->func_bound_ind = S->tccgen_ind;
S->func_bound_add_epilog = 0; S->func_bound_add_epilog = 0;
o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */ o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */
o(S, 0xd503201f); o(S, 0xd503201f);
@ -703,27 +703,27 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*bounds_ptr = 0; *bounds_ptr = 0;
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section, sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
S->func_bound_offset, lbounds_section->data_offset); S->func_bound_offset, lbounds_section->data_offset);
/* generate bound local allocation */ /* generate bound local allocation */
if (offset_modified) { if (offset_modified) {
saved_ind = S->ind; saved_ind = S->tccgen_ind;
S->ind = S->func_bound_ind; S->tccgen_ind = S->func_bound_ind;
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_ADR_GOT_PAGE, 0); greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
o(S, 0x90000000 | 0); // adrp x0, #sym_data o(S, 0x90000000 | 0); // adrp x0, #sym_data
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0); greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
gen_bounds_call(S, TOK___bound_local_new); gen_bounds_call(S, TOK___bound_local_new);
S->ind = saved_ind; S->tccgen_ind = saved_ind;
} }
/* generate bound check local freeing */ /* generate bound check local freeing */
o(S, 0xf81f0fe0); /* str x0, [sp, #-16]! */ o(S, 0xf81f0fe0); /* str x0, [sp, #-16]! */
o(S, 0x3c9f0fe0); /* str q0, [sp, #-16]! */ o(S, 0x3c9f0fe0); /* str q0, [sp, #-16]! */
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_ADR_GOT_PAGE, 0); greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
o(S, 0x90000000 | 0); // adrp x0, #sym_data o(S, 0x90000000 | 0); // adrp x0, #sym_data
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0); greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data] o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
gen_bounds_call(S, TOK___bound_local_delete); gen_bounds_call(S, TOK___bound_local_delete);
o(S, 0x3cc107e0); /* ldr q0, [sp], #16 */ o(S, 0x3cc107e0); /* ldr q0, [sp], #16 */
@ -977,7 +977,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
gbound_args(S, nb_args); gbound_args(S, nb_args);
#endif #endif
return_type = &S->vtop[-nb_args].type.ref->type; return_type = &S->tccgen_vtop[-nb_args].type.ref->type;
if ((return_type->t & VT_BTYPE) == VT_STRUCT) if ((return_type->t & VT_BTYPE) == VT_STRUCT)
--nb_args; --nb_args;
@ -987,14 +987,14 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
t[0] = return_type; t[0] = return_type;
for (i = 0; i < nb_args; i++) for (i = 0; i < nb_args; i++)
t[nb_args - i] = &S->vtop[-i].type; t[nb_args - i] = &S->tccgen_vtop[-i].type;
stack = arm64_pcs(nb_args, t, a); stack = arm64_pcs(nb_args, t, a);
// Allocate space for structs replaced by pointer: // Allocate space for structs replaced by pointer:
for (i = nb_args; i; i--) for (i = nb_args; i; i--)
if (a[i] & 1) { if (a[i] & 1) {
SValue *arg = &S->vtop[i - nb_args]; SValue *arg = &S->tccgen_vtop[i - nb_args];
int align, size = type_size(&arg->type, &align); int align, size = type_size(&arg->type, &align);
assert((arg->type.t & VT_BTYPE) == VT_STRUCT); assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
stack = (stack + align - 1) & -align; stack = (stack + align - 1) & -align;
@ -1005,7 +1005,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
stack = (stack + 15) >> 4 << 4; stack = (stack + 15) >> 4 << 4;
/* fetch cpu flag before generating any code */ /* fetch cpu flag before generating any code */
if ((S->vtop->r & VT_VALMASK) == VT_CMP) if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
gv(S, RC_INT); gv(S, RC_INT);
if (stack >= 0x1000000) // 16Mb if (stack >= 0x1000000) // 16Mb
@ -1017,13 +1017,13 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
// First pass: set all values on stack // First pass: set all values on stack
for (i = nb_args; i; i--) { for (i = nb_args; i; i--) {
vpushv(S, S->vtop - nb_args + i); vpushv(S, S->tccgen_vtop - nb_args + i);
if (a[i] & 1) { if (a[i] & 1) {
// struct replaced by pointer // struct replaced by pointer
int r = get_reg(S, RC_INT); int r = get_reg(S, RC_INT);
arm64_spoff(S, intr(S, r), a1[i]); arm64_spoff(S, intr(S, r), a1[i]);
vset(S, &S->vtop->type, r | VT_LVAL, 0); vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
vswap(S); vswap(S);
vstore(S); vstore(S);
if (a[i] >= 32) { if (a[i] >= 32) {
@ -1035,36 +1035,36 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
} }
else if (a[i] >= 32) { else if (a[i] >= 32) {
// value on stack // value on stack
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
int r = get_reg(S, RC_INT); int r = get_reg(S, RC_INT);
arm64_spoff(S, intr(S, r), a[i] - 32); arm64_spoff(S, intr(S, r), a[i] - 32);
vset(S, &S->vtop->type, r | VT_LVAL, 0); vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
vswap(S); vswap(S);
vstore(S); vstore(S);
} }
else if (is_float(S->vtop->type.t)) { else if (is_float(S->tccgen_vtop->type.t)) {
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
arm64_strv(S, arm64_type_size(S->vtop[0].type.t), arm64_strv(S, arm64_type_size(S->tccgen_vtop[0].type.t),
fltr(S->vtop[0].r), 31, a[i] - 32); fltr(S->tccgen_vtop[0].r), 31, a[i] - 32);
} }
else { else {
gv(S, RC_INT); gv(S, RC_INT);
arm64_strx(S, arm64_type_size(S->vtop[0].type.t), arm64_strx(S, arm64_type_size(S->tccgen_vtop[0].type.t),
intr(S, S->vtop[0].r), 31, a[i] - 32); intr(S, S->tccgen_vtop[0].r), 31, a[i] - 32);
} }
} }
--S->vtop; --S->tccgen_vtop;
} }
// Second pass: assign values to registers // Second pass: assign values to registers
for (i = nb_args; i; i--, S->vtop--) { for (i = nb_args; i; i--, S->tccgen_vtop--) {
if (a[i] < 16 && !(a[i] & 1)) { if (a[i] < 16 && !(a[i] & 1)) {
// value in general-purpose registers // value in general-purpose registers
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
int align, size = type_size(&S->vtop->type, &align); int align, size = type_size(&S->tccgen_vtop->type, &align);
if (size) { if (size) {
S->vtop->type.t = VT_PTR; S->tccgen_vtop->type.t = VT_PTR;
gaddrof(S); gaddrof(S);
gv(S, RC_R(a[i] / 2)); gv(S, RC_R(a[i] / 2));
arm64_ldrs(S, a[i] / 2, size); arm64_ldrs(S, a[i] / 2, size);
@ -1078,9 +1078,9 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
arm64_spoff(S, a[i] / 2, a1[i]); arm64_spoff(S, a[i] / 2, a1[i]);
else if (a[i] < 32) { else if (a[i] < 32) {
// value in floating-point registers // value in floating-point registers
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
uint32_t j, sz, n = arm64_hfa(&S->vtop->type, &sz); uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
S->vtop->type.t = VT_PTR; S->tccgen_vtop->type.t = VT_PTR;
gaddrof(S); gaddrof(S);
gv(S, RC_R30); gv(S, RC_R30);
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
@ -1098,7 +1098,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (a[0] == 1) { if (a[0] == 1) {
// indirect return: set x8 and discard the stack value // indirect return: set x8 and discard the stack value
gv(S, RC_R(8)); gv(S, RC_R(8));
--S->vtop; --S->tccgen_vtop;
} }
else else
// return in registers: keep the address for after the call // return in registers: keep the address for after the call
@ -1107,7 +1107,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
save_regs(S, 0); save_regs(S, 0);
arm64_gen_bl_or_b(S, 0); arm64_gen_bl_or_b(S, 0);
--S->vtop; --S->tccgen_vtop;
if (stack & 0xfff) if (stack & 0xfff)
o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n) o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)
if (stack >> 12) if (stack >> 12)
@ -1119,7 +1119,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (bt == VT_STRUCT && !(a[0] & 1)) { if (bt == VT_STRUCT && !(a[0] & 1)) {
// A struct was returned in registers, so write it out: // A struct was returned in registers, so write it out:
gv(S, RC_R(8)); gv(S, RC_R(8));
--S->vtop; --S->tccgen_vtop;
if (a[0] == 0) { if (a[0] == 0) {
int align, size = type_size(return_type, &align); int align, size = type_size(return_type, &align);
assert(size <= 16); assert(size <= 16);
@ -1220,11 +1220,11 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
tcc_free(S, t); tcc_free(S, t);
o(S, 0x910003fd); // mov x29,sp o(S, 0x910003fd); // mov x29,sp
arm64_func_sub_sp_offset = S->ind; arm64_func_sub_sp_offset = S->tccgen_ind;
// In gfunc_epilog these will be replaced with code to decrement SP: // In gfunc_epilog these will be replaced with code to decrement SP:
o(S, 0xd503201f); // nop o(S, 0xd503201f); // nop
o(S, 0xd503201f); // nop o(S, 0xd503201f); // nop
S->loc = 0; S->tccgen_loc = 0;
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
if (S->do_bounds_check) if (S->do_bounds_check)
gen_bounds_prolog(S); gen_bounds_prolog(S);
@ -1234,7 +1234,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
ST_FUNC void gen_va_start(TCCState *S) ST_FUNC void gen_va_start(TCCState *S)
{ {
int r; int r;
--S->vtop; // we don't need the "arg" --S->tccgen_vtop; // we don't need the "arg"
gaddrof(S); gaddrof(S);
r = intr(S, gv(S, RC_INT)); r = intr(S, gv(S, RC_INT));
@ -1264,7 +1264,7 @@ ST_FUNC void gen_va_start(TCCState *S)
arm64_movimm(S, 30, arm64_func_va_list_vr_offs); arm64_movimm(S, 30, arm64_func_va_list_vr_offs);
o(S, 0xb9001c1e | r << 5); // str w30,[x(r),#28] o(S, 0xb9001c1e | r << 5); // str w30,[x(r),#28]
--S->vtop; --S->tccgen_vtop;
} }
ST_FUNC void gen_va_arg(TCCState *S, CType *t) ST_FUNC void gen_va_arg(TCCState *S, CType *t)
@ -1281,7 +1281,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
gaddrof(S); gaddrof(S);
r0 = intr(S, gv(S, RC_INT)); r0 = intr(S, gv(S, RC_INT));
r1 = get_reg(S, RC_INT); r1 = get_reg(S, RC_INT);
S->vtop[0].r = r1 | VT_LVAL; S->tccgen_vtop[0].r = r1 | VT_LVAL;
r1 = intr(S, r1); r1 = intr(S, r1);
if (!hfa) { if (!hfa) {
@ -1310,7 +1310,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
uint32_t b1, b2; uint32_t b1, b2;
o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
o(S, 0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz) o(S, 0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
b1 = S->ind; o(S, 0x5400000d); // b.le lab1 b1 = S->tccgen_ind; o(S, 0x5400000d); // b.le lab1
o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
if (fsize == 16) { if (fsize == 16) {
o(S, 0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15 o(S, 0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
@ -1318,9 +1318,9 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
} }
o(S, 0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz) o(S, 0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
b2 = S->ind; o(S, 0x14000000); // b lab2 b2 = S->tccgen_ind; o(S, 0x14000000); // b lab2
// lab1: // lab1:
write32le(cur_text_section->data + b1, 0x5400000d | (S->ind - b1) << 3); write32le(cur_text_section->data + b1, 0x5400000d | (S->tccgen_ind - b1) << 3);
o(S, 0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs o(S, 0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
o(S, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top o(S, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
if (hfa == 1 || fsize == 16) if (hfa == 1 || fsize == 16)
@ -1328,9 +1328,9 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
else { else {
// We need to change the layout of this HFA. // We need to change the layout of this HFA.
// Get some space on the stack using global variable "loc": // Get some space on the stack using global variable "loc":
S->loc = (S->loc - size) & -(uint32_t)align; S->tccgen_loc = (S->tccgen_loc - size) & -(uint32_t)align;
o(S, 0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw o(S, 0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
arm64_movimm(S, r1, S->loc); arm64_movimm(S, r1, S->tccgen_loc);
o(S, 0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1) o(S, 0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
o(S, 0x4c402bdc | (uint32_t)fsize << 7 | o(S, 0x4c402bdc | (uint32_t)fsize << 7 |
(uint32_t)(hfa == 2) << 15 | (uint32_t)(hfa == 2) << 15 |
@ -1340,7 +1340,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
(uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)] (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
} }
// lab2: // lab2:
write32le(cur_text_section->data + b2, 0x14000000 | (S->ind - b2) >> 2); write32le(cur_text_section->data + b2, 0x14000000 | (S->tccgen_ind - b2) >> 2);
} }
} }
@ -1380,7 +1380,7 @@ ST_FUNC void gfunc_return(TCCState *S, CType *func_type)
} }
case 16: case 16:
if ((func_type->t & VT_BTYPE) == VT_STRUCT) { if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
uint32_t j, sz, n = arm64_hfa(&S->vtop->type, &sz); uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
gaddrof(S); gaddrof(S);
gv(S, RC_R(0)); gv(S, RC_R(0));
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
@ -1394,7 +1394,7 @@ ST_FUNC void gfunc_return(TCCState *S, CType *func_type)
default: default:
assert(0); assert(0);
} }
S->vtop--; S->tccgen_vtop--;
} }
ST_FUNC void gfunc_epilog(TCCState *S) ST_FUNC void gfunc_epilog(TCCState *S)
@ -1404,10 +1404,10 @@ ST_FUNC void gfunc_epilog(TCCState *S)
gen_bounds_epilog(S); gen_bounds_epilog(S);
#endif #endif
if (S->loc) { if (S->tccgen_loc) {
// Insert instructions to subtract size of stack frame from SP. // Insert instructions to subtract size of stack frame from SP.
unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset; unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
uint64_t diff = (-S->loc + 15) & ~15; uint64_t diff = (-S->tccgen_loc + 15) & ~15;
if (!(diff >> 24)) { if (!(diff >> 24)) {
if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff) if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10); write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
@ -1452,8 +1452,8 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
// Generate forward branch to label: // Generate forward branch to label:
ST_FUNC int gjmp(TCCState *S, int t) ST_FUNC int gjmp(TCCState *S, int t)
{ {
int r = S->ind; int r = S->tccgen_ind;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return t; return t;
o(S, t); o(S, t);
return r; return r;
@ -1462,8 +1462,8 @@ ST_FUNC int gjmp(TCCState *S, int t)
// Generate branch to known address: // Generate branch to known address:
ST_FUNC void gjmp_addr(TCCState *S, int a) ST_FUNC void gjmp_addr(TCCState *S, int a)
{ {
assert(a - S->ind + 0x8000000 < 0x10000000); assert(a - S->tccgen_ind + 0x8000000 < 0x10000000);
o(S, 0x14000000 | ((a - S->ind) >> 2 & 0x3ffffff)); o(S, 0x14000000 | ((a - S->tccgen_ind) >> 2 & 0x3ffffff));
} }
ST_FUNC int gjmp_append(TCCState *S, int n, int t) ST_FUNC int gjmp_append(TCCState *S, int n, int t)
@ -1483,7 +1483,7 @@ ST_FUNC int gjmp_append(TCCState *S, int n, int t)
void arm64_vset_VT_CMP(TCCState *S, int op) void arm64_vset_VT_CMP(TCCState *S, int op)
{ {
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
S->vtop->cmp_r = S->vtop->r; S->tccgen_vtop->cmp_r = S->tccgen_vtop->r;
vset_VT_CMP(S, 0x80); vset_VT_CMP(S, 0x80);
} }
} }
@ -1505,16 +1505,16 @@ static void arm64_load_cmp(TCCState *S, int r, SValue *sv)
ST_FUNC int gjmp_cond(TCCState *S, int op, int t) ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
{ {
int bt = S->vtop->type.t & VT_BTYPE; int bt = S->tccgen_vtop->type.t & VT_BTYPE;
int inv = op & 1; int inv = op & 1;
S->vtop->r = S->vtop->cmp_r; S->tccgen_vtop->r = S->tccgen_vtop->cmp_r;
if (bt == VT_LDOUBLE) { if (bt == VT_LDOUBLE) {
uint32_t a, b, f = fltr(gv(S, RC_FLOAT)); uint32_t a, b, f = fltr(gv(S, RC_FLOAT));
a = get_reg(S, RC_INT); a = get_reg(S, RC_INT);
vpushi(S, 0); vpushi(S, 0);
S->vtop[0].r = a; S->tccgen_vtop[0].r = a;
b = get_reg(S, RC_INT); b = get_reg(S, RC_INT);
a = intr(S, a); a = intr(S, a);
b = intr(S, b); b = intr(S, b);
@ -1522,7 +1522,7 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
o(S, 0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1] o(S, 0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
o(S, 0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1 o(S, 0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
o(S, 0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8 o(S, 0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
--S->vtop; --S->tccgen_vtop;
} }
else if (bt == VT_FLOAT || bt == VT_DOUBLE) { else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
uint32_t a = fltr(gv(S, RC_FLOAT)); uint32_t a = fltr(gv(S, RC_FLOAT));
@ -1639,20 +1639,20 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l)
uint64_t val; uint64_t val;
int rev = 1; int rev = 1;
if (arm64_iconst(0, &S->vtop[0])) { if (arm64_iconst(0, &S->tccgen_vtop[0])) {
vswap(S); vswap(S);
rev = 0; rev = 0;
} }
if (arm64_iconst(&val, &S->vtop[-1])) { if (arm64_iconst(&val, &S->tccgen_vtop[-1])) {
gv(S, RC_INT); gv(S, RC_INT);
a = intr(S, S->vtop[0].r); a = intr(S, S->tccgen_vtop[0].r);
--S->vtop; --S->tccgen_vtop;
x = get_reg(S, RC_INT); x = get_reg(S, RC_INT);
++S->vtop; ++S->tccgen_vtop;
if (arm64_gen_opic(S, op, l, rev, val, intr(S, x), a)) { if (arm64_gen_opic(S, op, l, rev, val, intr(S, x), a)) {
S->vtop[0].r = x; S->tccgen_vtop[0].r = x;
vswap(S); vswap(S);
--S->vtop; --S->tccgen_vtop;
return; return;
} }
} }
@ -1661,13 +1661,13 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l)
} }
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
assert(S->vtop[-1].r < VT_CONST && S->vtop[0].r < VT_CONST); assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
a = intr(S, S->vtop[-1].r); a = intr(S, S->tccgen_vtop[-1].r);
b = intr(S, S->vtop[0].r); b = intr(S, S->tccgen_vtop[0].r);
S->vtop -= 2; S->tccgen_vtop -= 2;
x = get_reg(S, RC_INT); x = get_reg(S, RC_INT);
++S->vtop; ++S->tccgen_vtop;
S->vtop[0].r = x; S->tccgen_vtop[0].r = x;
x = intr(S, x); x = intr(S, x);
switch (op) { switch (op) {
@ -1768,7 +1768,7 @@ ST_FUNC void gen_opi(TCCState *S, int op)
arm64_vset_VT_CMP(S, op); arm64_vset_VT_CMP(S, op);
} }
ST_FUNC void gen_opl(TCCState *S, int op) ST_FUNC void gen_opl(TCCState* S, int op)
{ {
arm64_gen_opil(S, op, 1); arm64_gen_opil(S, op, 1);
arm64_vset_VT_CMP(S, op); arm64_vset_VT_CMP(S, op);
@ -1778,8 +1778,8 @@ ST_FUNC void gen_opf(TCCState *S, int op)
{ {
uint32_t x, a, b, dbl; uint32_t x, a, b, dbl;
if (S->vtop[0].type.t == VT_LDOUBLE) { if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
CType type = S->vtop[0].type; CType type = S->tccgen_vtop[0].type;
int func = 0; int func = 0;
int cond = -1; int cond = -1;
switch (op) { switch (op) {
@ -1799,9 +1799,9 @@ ST_FUNC void gen_opf(TCCState *S, int op)
vrott(S, 3); vrott(S, 3);
gfunc_call(S, 2); gfunc_call(S, 2);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = cond < 0 ? REG_FRET : REG_IRET; S->tccgen_vtop->r = cond < 0 ? REG_FRET : REG_IRET;
if (cond < 0) if (cond < 0)
S->vtop->type = type; S->tccgen_vtop->type = type;
else { else {
o(S, 0x7100001f); // cmp w0,#0 o(S, 0x7100001f); // cmp w0,#0
o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond) o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
@ -1809,24 +1809,24 @@ ST_FUNC void gen_opf(TCCState *S, int op)
return; return;
} }
dbl = S->vtop[0].type.t != VT_FLOAT; dbl = S->tccgen_vtop[0].type.t != VT_FLOAT;
gv2(S, RC_FLOAT, RC_FLOAT); gv2(S, RC_FLOAT, RC_FLOAT);
assert(S->vtop[-1].r < VT_CONST && S->vtop[0].r < VT_CONST); assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
a = fltr(S->vtop[-1].r); a = fltr(S->tccgen_vtop[-1].r);
b = fltr(S->vtop[0].r); b = fltr(S->tccgen_vtop[0].r);
S->vtop -= 2; S->tccgen_vtop -= 2;
switch (op) { switch (op) {
case TOK_EQ: case TOK_NE: case TOK_EQ: case TOK_NE:
case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT: case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
x = get_reg(S, RC_INT); x = get_reg(S, RC_INT);
++S->vtop; ++S->tccgen_vtop;
S->vtop[0].r = x; S->tccgen_vtop[0].r = x;
x = intr(S, x); x = intr(S, x);
break; break;
default: default:
x = get_reg(S, RC_FLOAT); x = get_reg(S, RC_FLOAT);
++S->vtop; ++S->tccgen_vtop;
S->vtop[0].r = x; S->tccgen_vtop[0].r = x;
x = fltr(x); x = fltr(x);
break; break;
} }
@ -1894,7 +1894,7 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
ST_FUNC void gen_cvt_itof(TCCState *S, int t) ST_FUNC void gen_cvt_itof(TCCState *S, int t)
{ {
if (t == VT_LDOUBLE) { if (t == VT_LDOUBLE) {
int f = S->vtop->type.t; int f = S->tccgen_vtop->type.t;
int func = (f & VT_BTYPE) == VT_LLONG ? int func = (f & VT_BTYPE) == VT_LLONG ?
(f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) : (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
(f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf); (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
@ -1902,18 +1902,18 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
vrott(S, 2); vrott(S, 2);
gfunc_call(S, 1); gfunc_call(S, 1);
vpushi(S, 0); vpushi(S, 0);
S->vtop->type.t = t; S->tccgen_vtop->type.t = t;
S->vtop->r = REG_FRET; S->tccgen_vtop->r = REG_FRET;
return; return;
} }
else { else {
int d, n = intr(S, gv(S, RC_INT)); int d, n = intr(S, gv(S, RC_INT));
int s = !(S->vtop->type.t & VT_UNSIGNED); int s = !(S->tccgen_vtop->type.t & VT_UNSIGNED);
uint32_t l = ((S->vtop->type.t & VT_BTYPE) == VT_LLONG); uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG);
--S->vtop; --S->tccgen_vtop;
d = get_reg(S, RC_FLOAT); d = get_reg(S, RC_FLOAT);
++S->vtop; ++S->tccgen_vtop;
S->vtop[0].r = d; S->tccgen_vtop[0].r = d;
o(S, 0x1e220000 | (uint32_t)!s << 16 | o(S, 0x1e220000 | (uint32_t)!s << 16 |
(uint32_t)(t != VT_FLOAT) << 22 | fltr(d) | (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n) l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
@ -1922,7 +1922,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
ST_FUNC void gen_cvt_ftoi(TCCState *S, int t) ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
{ {
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
int func = (t & VT_BTYPE) == VT_LLONG ? int func = (t & VT_BTYPE) == VT_LLONG ?
(t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) : (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
(t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi); (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
@ -1930,17 +1930,17 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
vrott(S, 2); vrott(S, 2);
gfunc_call(S, 1); gfunc_call(S, 1);
vpushi(S, 0); vpushi(S, 0);
S->vtop->type.t = t; S->tccgen_vtop->type.t = t;
S->vtop->r = REG_IRET; S->tccgen_vtop->r = REG_IRET;
return; return;
} }
else { else {
int d, n = fltr(gv(S, RC_FLOAT)); int d, n = fltr(gv(S, RC_FLOAT));
uint32_t l = ((S->vtop->type.t & VT_BTYPE) != VT_FLOAT); uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT);
--S->vtop; --S->tccgen_vtop;
d = get_reg(S, RC_INT); d = get_reg(S, RC_INT);
++S->vtop; ++S->tccgen_vtop;
S->vtop[0].r = d; S->tccgen_vtop[0].r = d;
o(S, 0x1e380000 | o(S, 0x1e380000 |
(uint32_t)!!(t & VT_UNSIGNED) << 16 | (uint32_t)!!(t & VT_UNSIGNED) << 16 |
(uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(S, d) | (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(S, d) |
@ -1950,7 +1950,7 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
ST_FUNC void gen_cvt_ftof(TCCState *S, int t) ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
{ {
int f = S->vtop[0].type.t & VT_BTYPE; int f = S->tccgen_vtop[0].type.t & VT_BTYPE;
assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE); assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE); assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
if (t == f) if (t == f)
@ -1964,18 +1964,18 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
vrott(S, 2); vrott(S, 2);
gfunc_call(S, 1); gfunc_call(S, 1);
vpushi(S, 0); vpushi(S, 0);
S->vtop->type.t = t; S->tccgen_vtop->type.t = t;
S->vtop->r = REG_FRET; S->tccgen_vtop->r = REG_FRET;
} }
else { else {
int x, a; int x, a;
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
assert(S->vtop[0].r < VT_CONST); assert(S->tccgen_vtop[0].r < VT_CONST);
a = fltr(S->vtop[0].r); a = fltr(S->tccgen_vtop[0].r);
--S->vtop; --S->tccgen_vtop;
x = get_reg(S, RC_FLOAT); x = get_reg(S, RC_FLOAT);
++S->vtop; ++S->tccgen_vtop;
S->vtop[0].r = x; S->tccgen_vtop[0].r = x;
x = fltr(x); x = fltr(x);
if (f == VT_FLOAT) if (f == VT_FLOAT)
@ -1986,16 +1986,16 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
} }
/* increment tcov counter */ /* increment tcov counter */
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv) ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
{ {
int r1, r2; int r1, r2;
vpushv(S, sv); vpushv(S, sv);
S->vtop->r = r1 = get_reg(S, RC_INT); S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
r2 = get_reg(S, RC_INT); r2 = get_reg(S, RC_INT);
greloca(S, cur_text_section, sv->sym, S->ind, R_AARCH64_ADR_GOT_PAGE, 0); greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
o(S, 0x90000000 | r1); // adrp r1, #sym o(S, 0x90000000 | r1); // adrp r1, #sym
greloca(S, cur_text_section, sv->sym, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0); greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
o(S, 0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym] o(S, 0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym]
o(S, 0xf9400000 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1] o(S, 0xf9400000 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1]
o(S, 0x91000400 | (intr(S, r2)<<5) | intr(S, r2)); // add r2, r2, #1 o(S, 0x91000400 | (intr(S, r2)<<5) | intr(S, r2)); // add r2, r2, #1
@ -2006,7 +2006,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
ST_FUNC void ggoto(TCCState *S) ST_FUNC void ggoto(TCCState *S)
{ {
arm64_gen_bl_or_b(S, 1); arm64_gen_bl_or_b(S, 1);
--S->vtop; --S->tccgen_vtop;
} }
ST_FUNC void gen_clear_cache(TCCState *S) ST_FUNC void gen_clear_cache(TCCState *S)
@ -2014,17 +2014,17 @@ ST_FUNC void gen_clear_cache(TCCState *S)
uint32_t beg, end, dsz, isz, p, lab1, b1; uint32_t beg, end, dsz, isz, p, lab1, b1;
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = get_reg(S, RC_INT); S->tccgen_vtop->r = get_reg(S, RC_INT);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = get_reg(S, RC_INT); S->tccgen_vtop->r = get_reg(S, RC_INT);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = get_reg(S, RC_INT); S->tccgen_vtop->r = get_reg(S, RC_INT);
beg = intr(S, S->vtop[-4].r); // x0 beg = intr(S, S->tccgen_vtop[-4].r); // x0
end = intr(S, S->vtop[-3].r); // x1 end = intr(S, S->tccgen_vtop[-3].r); // x1
dsz = intr(S, S->vtop[-2].r); // x2 dsz = intr(S, S->tccgen_vtop[-2].r); // x2
isz = intr(S, S->vtop[-1].r); // x3 isz = intr(S, S->tccgen_vtop[-1].r); // x3
p = intr(S, S->vtop[0].r); // x4 p = intr(S, S->tccgen_vtop[0].r); // x4
S->vtop -= 5; S->tccgen_vtop -= 5;
o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el0 o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el0
o(S, 0x52800080 | p); // mov w(p),#4 o(S, 0x52800080 | p); // mov w(p),#4
@ -2034,23 +2034,23 @@ ST_FUNC void gen_clear_cache(TCCState *S)
o(S, 0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz) o(S, 0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
o(S, 0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1 o(S, 0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
b1 = S->ind; o(S, 0x14000000); // b b1 = S->tccgen_ind; o(S, 0x14000000); // b
lab1 = S->ind; lab1 = S->tccgen_ind;
o(S, 0xd50b7b20 | p); // dc cvau,x(p) o(S, 0xd50b7b20 | p); // dc cvau,x(p)
o(S, 0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz) o(S, 0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
write32le(cur_text_section->data + b1, 0x14000000 | (S->ind - b1) >> 2); write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);
o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
o(S, 0x54ffffa3 | ((lab1 - S->ind) << 3 & 0xffffe0)); // b.cc lab1 o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1
o(S, 0xd5033b9f); // dsb ish o(S, 0xd5033b9f); // dsb ish
o(S, 0x51000400 | p | isz << 5); // sub w(p),w(isz),#1 o(S, 0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p) o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
b1 = S->ind; o(S, 0x14000000); // b b1 = S->tccgen_ind; o(S, 0x14000000); // b
lab1 = S->ind; lab1 = S->tccgen_ind;
o(S, 0xd50b7520 | p); // ic ivau,x(p) o(S, 0xd50b7520 | p); // ic ivau,x(p)
o(S, 0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz) o(S, 0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
write32le(cur_text_section->data + b1, 0x14000000 | (S->ind - b1) >> 2); write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);
o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end) o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
o(S, 0x54ffffa3 | ((lab1 - S->ind) << 3 & 0xffffe0)); // b.cc lab1 o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1
o(S, 0xd5033b9f); // dsb ish o(S, 0xd5033b9f); // dsb ish
o(S, 0xd5033fdf); // isb o(S, 0xd5033fdf); // isb
} }
@ -2074,7 +2074,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
uint32_t r; uint32_t r;
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check) if (S->do_bounds_check)
vpushv(S, S->vtop); vpushv(S, S->tccgen_vtop);
#endif #endif
r = intr(S, gv(S, RC_INT)); r = intr(S, gv(S, RC_INT));
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
@ -2089,8 +2089,8 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check) { if (S->do_bounds_check) {
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = TREG_R(0); S->tccgen_vtop->r = TREG_R(0);
o(S, 0x910003e0 | S->vtop->r); // mov r0,sp o(S, 0x910003e0 | S->tccgen_vtop->r); // mov r0,sp
vswap(S); vswap(S);
vpush_helper_func(S, TOK___bound_new_region); vpush_helper_func(S, TOK___bound_new_region);
vrott(S, 3); vrott(S, 3);

366
c67-gen.c

File diff suppressed because it is too large Load diff

View file

@ -282,7 +282,7 @@ static inline int get_reg_shift(TCCState *S)
static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type) static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
{ {
int reg = -1; int reg = -1;
if (t >= TOK_IDENT && t < S->tok_ident) { if (t >= TOK_IDENT && t < S->tccpp_tok_ident) {
const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str; const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str;
char c; char c;
*type = OP_REG64; *type = OP_REG64;
@ -318,24 +318,24 @@ static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
} }
#endif #endif
static int asm_parse_reg(TCCState *S, unsigned int *type) static int asm_parse_reg(TCCState* S, unsigned int *type)
{ {
int reg = 0; int reg = 0;
*type = 0; *type = 0;
if (S->tok != '%') if (S->tccpp_tok != '%')
goto error_32; goto error_32;
next(S); next(S);
if (S->tok >= TOK_ASM_eax && S->tok <= TOK_ASM_edi) { if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {
reg = S->tok - TOK_ASM_eax; reg = S->tccpp_tok - TOK_ASM_eax;
*type = OP_REG32; *type = OP_REG32;
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
} else if (S->tok >= TOK_ASM_rax && S->tok <= TOK_ASM_rdi) { } else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {
reg = S->tok - TOK_ASM_rax; reg = S->tccpp_tok - TOK_ASM_rax;
*type = OP_REG64; *type = OP_REG64;
} else if (S->tok == TOK_ASM_rip) { } else if (S->tccpp_tok == TOK_ASM_rip) {
reg = -2; /* Probably should use different escape code. */ reg = -2; /* Probably should use different escape code. */
*type = OP_REG64; *type = OP_REG64;
} else if ((reg = asm_parse_numeric_reg(S, S->tok, type)) >= 0 } else if ((reg = asm_parse_numeric_reg(S, S->tccpp_tok, type)) >= 0
&& (*type == OP_REG32 || *type == OP_REG64)) { && (*type == OP_REG32 || *type == OP_REG64)) {
; ;
#endif #endif
@ -354,15 +354,15 @@ static void parse_operand(TCCState *S, Operand *op)
const char *p; const char *p;
indir = 0; indir = 0;
if (S->tok == '*') { if (S->tccpp_tok == '*') {
next(S); next(S);
indir = OP_INDIR; indir = OP_INDIR;
} }
if (S->tok == '%') { if (S->tccpp_tok == '%') {
next(S); next(S);
if (S->tok >= TOK_ASM_al && S->tok <= TOK_ASM_db7) { if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {
reg = S->tok - TOK_ASM_al; reg = S->tccpp_tok - TOK_ASM_al;
op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
op->reg = reg & 7; op->reg = reg & 7;
if ((op->type & OP_REG) && op->reg == TREG_XAX) if ((op->type & OP_REG) && op->reg == TREG_XAX)
@ -371,21 +371,21 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_CL; op->type |= OP_CL;
else if (op->type == OP_REG16 && op->reg == TREG_XDX) else if (op->type == OP_REG16 && op->reg == TREG_XDX)
op->type |= OP_DX; op->type |= OP_DX;
} else if (S->tok >= TOK_ASM_dr0 && S->tok <= TOK_ASM_dr7) { } else if (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) {
op->type = OP_DB; op->type = OP_DB;
op->reg = S->tok - TOK_ASM_dr0; op->reg = S->tccpp_tok - TOK_ASM_dr0;
} else if (S->tok >= TOK_ASM_es && S->tok <= TOK_ASM_gs) { } else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {
op->type = OP_SEG; op->type = OP_SEG;
op->reg = S->tok - TOK_ASM_es; op->reg = S->tccpp_tok - TOK_ASM_es;
} else if (S->tok == TOK_ASM_st) { } else if (S->tccpp_tok == TOK_ASM_st) {
op->type = OP_ST; op->type = OP_ST;
op->reg = 0; op->reg = 0;
next(S); next(S);
if (S->tok == '(') { if (S->tccpp_tok == '(') {
next(S); next(S);
if (S->tok != TOK_PPNUM) if (S->tccpp_tok != TOK_PPNUM)
goto reg_error; goto reg_error;
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
reg = p[0] - '0'; reg = p[0] - '0';
if ((unsigned)reg >= 8 || p[1] != '\0') if ((unsigned)reg >= 8 || p[1] != '\0')
goto reg_error; goto reg_error;
@ -397,19 +397,19 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_ST0; op->type |= OP_ST0;
goto no_skip; goto no_skip;
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
} else if (S->tok >= TOK_ASM_spl && S->tok <= TOK_ASM_dil) { } else if (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) {
op->type = OP_REG8 | OP_REG8_LOW; op->type = OP_REG8 | OP_REG8_LOW;
op->reg = 4 + S->tok - TOK_ASM_spl; op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;
} else if ((op->reg = asm_parse_numeric_reg(S, S->tok, &op->type)) >= 0) { } else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {
; ;
#endif #endif
} else { } else {
reg_error: reg_error:
tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tok, &S->tokc)); tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
} }
next(S); next(S);
no_skip: ; no_skip: ;
} else if (S->tok == '$') { } else if (S->tccpp_tok == '$') {
/* constant value */ /* constant value */
next(S); next(S);
asm_expr(S, &e); asm_expr(S, &e);
@ -433,19 +433,19 @@ static void parse_operand(TCCState *S, Operand *op)
op->reg = -1; op->reg = -1;
op->reg2 = -1; op->reg2 = -1;
op->shift = 0; op->shift = 0;
if (S->tok != '(') { if (S->tccpp_tok != '(') {
asm_expr(S, &e); asm_expr(S, &e);
op->e = e; op->e = e;
} else { } else {
next(S); next(S);
if (S->tok == '%') { if (S->tccpp_tok == '%') {
unget_tok(S, '('); unget_tok(S, '(');
op->e.v = 0; op->e.v = 0;
op->e.sym = NULL; op->e.sym = NULL;
} else { } else {
/* bracketed offset expression */ /* bracketed offset expression */
asm_expr(S, &e); asm_expr(S, &e);
if (S->tok != ')') if (S->tccpp_tok != ')')
expect(S, ")"); expect(S, ")");
next(S); next(S);
op->e.v = e.v; op->e.v = e.v;
@ -453,18 +453,18 @@ static void parse_operand(TCCState *S, Operand *op)
} }
op->e.pcrel = 0; op->e.pcrel = 0;
} }
if (S->tok == '(') { if (S->tccpp_tok == '(') {
unsigned int type = 0; unsigned int type = 0;
next(S); next(S);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
op->reg = asm_parse_reg(S, &type); op->reg = asm_parse_reg(S, &type);
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
op->reg2 = asm_parse_reg(S, &type); op->reg2 = asm_parse_reg(S, &type);
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
op->shift = get_reg_shift(S); op->shift = get_reg_shift(S);
} }
@ -480,7 +480,7 @@ static void parse_operand(TCCState *S, Operand *op)
} }
/* XXX: unify with C code output ? */ /* XXX: unify with C code output ? */
ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe) ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
{ {
if (pe->pcrel) if (pe->pcrel)
/* If PC-relative, always set VT_SYM, even without symbol, /* If PC-relative, always set VT_SYM, even without symbol,
@ -491,14 +491,14 @@ ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe)
} }
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
ST_FUNC void gen_expr64(TCCState *S, ExprValue *pe) ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe)
{ {
gen_addr64(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v); gen_addr64(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
} }
#endif #endif
/* XXX: unify with C code output ? */ /* XXX: unify with C code output ? */
static void gen_disp32(TCCState *S, ExprValue *pe) static void gen_disp32(TCCState* S, ExprValue *pe)
{ {
Sym *sym = pe->sym; Sym *sym = pe->sym;
ElfSym *esym = elfsym(S, sym); ElfSym *esym = elfsym(S, sym);
@ -507,7 +507,7 @@ static void gen_disp32(TCCState *S, ExprValue *pe)
that the TCC compiler behaves differently here because that the TCC compiler behaves differently here because
it always outputs a relocation to ease (future) code it always outputs a relocation to ease (future) code
elimination in the linker */ elimination in the linker */
gen_le32(S, pe->v + esym->st_value - S->ind - 4); gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4);
} else { } else {
if (sym && sym->type.t == VT_VOID) { if (sym && sym->type.t == VT_VOID) {
sym->type.t = VT_FUNC; sym->type.t = VT_FUNC;
@ -518,7 +518,7 @@ static void gen_disp32(TCCState *S, ExprValue *pe)
} }
/* generate the modrm operand */ /* generate the modrm operand */
static inline int asm_modrm(TCCState *S, int reg, Operand *op) static inline int asm_modrm(TCCState* S, int reg, Operand *op)
{ {
int mod, reg1, reg2, sib_reg1; int mod, reg1, reg2, sib_reg1;
@ -538,7 +538,7 @@ static inline int asm_modrm(TCCState *S, int reg, Operand *op)
ExprValue *pe = &op->e; ExprValue *pe = &op->e;
g(S, 0x05 + (reg << 3)); g(S, 0x05 + (reg << 3));
gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v); gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
return S->ind; return S->tccgen_ind;
#endif #endif
} else { } else {
sib_reg1 = op->reg; sib_reg1 = op->reg;
@ -581,7 +581,7 @@ static inline int asm_modrm(TCCState *S, int reg, Operand *op)
#define REX_X 0x42 #define REX_X 0x42
#define REX_B 0x41 #define REX_B 0x41
static void asm_rex(TCCState *S, int width64, Operand *ops, int nb_ops, int *op_type, static void asm_rex(TCCState* S, int width64, Operand *ops, int nb_ops, int *op_type,
int regi, int rmi) int regi, int rmi)
{ {
unsigned char rex = width64 ? 0x48 : 0; unsigned char rex = width64 ? 0x48 : 0;
@ -705,13 +705,13 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
seg_prefix = 0; seg_prefix = 0;
alltypes = 0; alltypes = 0;
for(;;) { for(;;) {
if (S->tok == ';' || S->tok == TOK_LINEFEED) if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)
break; break;
if (nb_ops >= MAX_OPERANDS) { if (nb_ops >= MAX_OPERANDS) {
tcc_error(S, "incorrect number of operands"); tcc_error(S, "incorrect number of operands");
} }
parse_operand(S, pop); parse_operand(S, pop);
if (S->tok == ':') { if (S->tccpp_tok == ':') {
if (pop->type != OP_SEG || seg_prefix) if (pop->type != OP_SEG || seg_prefix)
tcc_error(S, "incorrect prefix"); tcc_error(S, "incorrect prefix");
seg_prefix = segment_prefixes[pop->reg]; seg_prefix = segment_prefixes[pop->reg];
@ -723,7 +723,7 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
} }
pop++; pop++;
nb_ops++; nb_ops++;
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); next(S);
} }
@ -1038,7 +1038,7 @@ again:
esym = elfsym(S, ops[0].e.sym); esym = elfsym(S, ops[0].e.sym);
if (!esym || esym->st_shndx != cur_text_section->sh_num) if (!esym || esym->st_shndx != cur_text_section->sh_num)
goto no_short_jump; goto no_short_jump;
jmp_disp = ops[0].e.v + esym->st_value - S->ind - 2 - (v >= 0xff); jmp_disp = ops[0].e.v + esym->st_value - S->tccgen_ind - 2 - (v >= 0xff);
if (jmp_disp == (int8_t)jmp_disp) { if (jmp_disp == (int8_t)jmp_disp) {
/* OK to generate jump */ /* OK to generate jump */
ops[0].e.sym = 0; ops[0].e.sym = 0;
@ -1136,12 +1136,12 @@ again:
/* after immediate operands, adjust pc-relative address */ /* after immediate operands, adjust pc-relative address */
if (pc) if (pc)
add32le(cur_text_section->data + pc - 4, pc - S->ind); add32le(cur_text_section->data + pc - 4, pc - S->tccgen_ind);
} }
/* return the constraint priority (we allocate first the lowest /* return the constraint priority (we allocate first the lowest
numbered constraints) */ numbered constraints) */
static inline int constraint_priority(TCCState *S, const char *str) static inline int constraint_priority(TCCState* S, const char *str)
{ {
int priority, c, pr; int priority, c, pr;
@ -1200,7 +1200,7 @@ static const char *skip_constraint_modifiers(const char *p)
/* If T (a token) is of the form "%reg" returns the register /* If T (a token) is of the form "%reg" returns the register
number and type, otherwise return -1. */ number and type, otherwise return -1. */
ST_FUNC int asm_parse_regvar (TCCState *S, int t) ST_FUNC int asm_parse_regvar (TCCState* S, int t)
{ {
const char *s; const char *s;
Operand op; Operand op;
@ -1225,7 +1225,7 @@ ST_FUNC int asm_parse_regvar (TCCState *S, int t)
#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask) #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(TCCState* S, ASMOperand *operands,
int nb_operands, int nb_outputs, int nb_operands, int nb_outputs,
const uint8_t *clobber_regs, const uint8_t *clobber_regs,
int *pout_reg) int *pout_reg)
@ -1471,7 +1471,7 @@ ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands,
#endif #endif
} }
ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str,
SValue *sv, int modifier) SValue *sv, int modifier)
{ {
int r, reg, size, val; int r, reg, size, val;
@ -1593,7 +1593,7 @@ ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str,
} }
/* generate prolog and epilog code for asm statement */ /* generate prolog and epilog code for asm statement */
ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands, ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands,
int nb_outputs, int is_output, int nb_outputs, int is_output,
uint8_t *clobber_regs, uint8_t *clobber_regs,
int out_reg) int out_reg)
@ -1697,7 +1697,7 @@ ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands,
} }
} }
ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str) ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str)
{ {
int reg; int reg;
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64

View file

@ -100,24 +100,24 @@ ST_DATA const int reg_classes[NB_REGS] = {
static unsigned long func_sub_sp_offset; static unsigned long func_sub_sp_offset;
static int func_ret_sub; static int func_ret_sub;
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
static void gen_bounds_prolog(TCCState *S); static void gen_bounds_prolog(TCCState* S);
static void gen_bounds_epilog(TCCState *S); static void gen_bounds_epilog(TCCState* S);
#endif #endif
/* XXX: make it faster ? */ /* XXX: make it faster ? */
ST_FUNC void g(TCCState *S, int c) ST_FUNC void g(TCCState* S, int c)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 1; ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c; cur_text_section->data[S->tccgen_ind] = c;
S->ind = ind1; S->tccgen_ind = ind1;
} }
ST_FUNC void o(TCCState *S, unsigned int c) ST_FUNC void o(TCCState* S, unsigned int c)
{ {
while (c) { while (c) {
g(S, c); g(S, c);
@ -125,13 +125,13 @@ ST_FUNC void o(TCCState *S, unsigned int c)
} }
} }
ST_FUNC void gen_le16(TCCState *S, int v) ST_FUNC void gen_le16(TCCState* S, int v)
{ {
g(S, v); g(S, v);
g(S, v >> 8); g(S, v >> 8);
} }
ST_FUNC void gen_le32(TCCState *S, int c) ST_FUNC void gen_le32(TCCState* S, int c)
{ {
g(S, c); g(S, c);
g(S, c >> 8); g(S, c >> 8);
@ -140,7 +140,7 @@ ST_FUNC void gen_le32(TCCState *S, int c)
} }
/* output a symbol and patch all calls to it */ /* output a symbol and patch all calls to it */
ST_FUNC void gsym_addr(TCCState *S, int t, int a) ST_FUNC void gsym_addr(TCCState* S, int t, int a)
{ {
while (t) { while (t) {
unsigned char *ptr = cur_text_section->data + t; unsigned char *ptr = cur_text_section->data + t;
@ -151,18 +151,18 @@ ST_FUNC void gsym_addr(TCCState *S, int t, int a)
} }
/* instruction + 4 bytes data. Return the address of the data */ /* instruction + 4 bytes data. Return the address of the data */
static int oad(TCCState *S, int c, int s) static int oad(TCCState* S, int c, int s)
{ {
int t; int t;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return s; return s;
o(S, c); o(S, c);
t = S->ind; t = S->tccgen_ind;
gen_le32(S, s); gen_le32(S, s);
return t; return t;
} }
ST_FUNC void gen_fill_nops(TCCState *S, int bytes) ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
{ {
while (bytes--) while (bytes--)
g(S, 0x90); g(S, 0x90);
@ -172,23 +172,23 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
#define gjmp2(s, instr,lbl) oad(s, instr,lbl) #define gjmp2(s, instr,lbl) oad(s, instr,lbl)
/* output constant with relocation if 'r & VT_SYM' is true */ /* output constant with relocation if 'r & VT_SYM' is true */
ST_FUNC void gen_addr32(TCCState *S, int r, Sym *sym, int c) ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c)
{ {
if (r & VT_SYM) if (r & VT_SYM)
greloc(S, cur_text_section, sym, S->ind, R_386_32); greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_32);
gen_le32(S, c); gen_le32(S, c);
} }
ST_FUNC void gen_addrpc32(TCCState *S, int r, Sym *sym, int c) ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c)
{ {
if (r & VT_SYM) if (r & VT_SYM)
greloc(S, cur_text_section, sym, S->ind, R_386_PC32); greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_PC32);
gen_le32(S, c - 4); gen_le32(S, c - 4);
} }
/* generate a modrm reference. 'op_reg' contains the additional 3 /* generate a modrm reference. 'op_reg' contains the additional 3
opcode bits */ opcode bits */
static void gen_modrm(TCCState *S, int op_reg, int r, Sym *sym, int c) static void gen_modrm(TCCState* S, int op_reg, int r, Sym *sym, int c)
{ {
op_reg = op_reg << 3; op_reg = op_reg << 3;
if ((r & VT_VALMASK) == VT_CONST) { if ((r & VT_VALMASK) == VT_CONST) {
@ -210,7 +210,7 @@ static void gen_modrm(TCCState *S, int op_reg, int r, Sym *sym, int c)
} }
/* load 'r' from value 'sv' */ /* load 'r' from value 'sv' */
ST_FUNC void load(TCCState *S, int r, SValue *sv) ST_FUNC void load(TCCState* S, int r, SValue *sv)
{ {
int v, t, ft, fc, fr; int v, t, ft, fc, fr;
SValue v1; SValue v1;
@ -290,7 +290,7 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv)
} }
/* store register 'r' in lvalue 'v' */ /* store register 'r' in lvalue 'v' */
ST_FUNC void store(TCCState *S, int r, SValue *v) ST_FUNC void store(TCCState* S, int r, SValue *v)
{ {
int fr, bt, ft, fc; int fr, bt, ft, fc;
@ -332,7 +332,7 @@ ST_FUNC void store(TCCState *S, int r, SValue *v)
} }
} }
static void gadd_sp(TCCState *S, int val) static void gadd_sp(TCCState* S, int val)
{ {
if (val == (char)val) { if (val == (char)val) {
o(S, 0xc483); o(S, 0xc483);
@ -343,24 +343,24 @@ static void gadd_sp(TCCState *S, int val)
} }
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
static void gen_static_call(TCCState *S, int v) static void gen_static_call(TCCState* S, int v)
{ {
Sym *sym; Sym *sym;
sym = external_helper_sym(S, v); sym = external_helper_sym(S, v);
oad(S, 0xe8, -4); oad(S, 0xe8, -4);
greloc(S, cur_text_section, sym, S->ind-4, R_386_PC32); greloc(S, cur_text_section, sym, S->tccgen_ind-4, R_386_PC32);
} }
#endif #endif
/* 'is_jmp' is '1' if it is a jump */ /* 'is_jmp' is '1' if it is a jump */
static void gcall_or_jmp(TCCState *S, int is_jmp) static void gcall_or_jmp(TCCState* S, int is_jmp)
{ {
int r; int r;
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->vtop->r & VT_SYM)) { if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
/* constant and relocation case */ /* constant and relocation case */
greloc(S, cur_text_section, S->vtop->sym, S->ind + 1, R_386_PC32); greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_386_PC32);
oad(S, 0xe8 + is_jmp, S->vtop->c.i - 4); /* call/jmp im */ oad(S, 0xe8 + is_jmp, S->tccgen_vtop->c.i - 4); /* call/jmp im */
} else { } else {
/* otherwise, indirect call */ /* otherwise, indirect call */
r = gv(S, RC_INT); r = gv(S, RC_INT);
@ -402,7 +402,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int
/* Generate function call. The function address is pushed first, then /* Generate function call. The function address is pushed first, then
all the parameters in call order. This functions pops all the all the parameters in call order. This functions pops all the
parameters and the function address. */ parameters and the function address. */
ST_FUNC void gfunc_call(TCCState *S, int nb_args) ST_FUNC void gfunc_call(TCCState* S, int nb_args)
{ {
int size, align, r, args_size, i, func_call; int size, align, r, args_size, i, func_call;
Sym *func_sym; Sym *func_sym;
@ -414,8 +414,8 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
args_size = 0; args_size = 0;
for(i = 0;i < nb_args; i++) { for(i = 0;i < nb_args; i++) {
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
size = type_size(&S->vtop->type, &align); size = type_size(&S->tccgen_vtop->type, &align);
/* align to stack align size */ /* align to stack align size */
size = (size + 3) & ~3; size = (size + 3) & ~3;
/* allocate the necessary size on stack */ /* allocate the necessary size on stack */
@ -434,15 +434,15 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
r = get_reg(S, RC_INT); r = get_reg(S, RC_INT);
o(S, 0xe089 + (r << 8)); /* mov %esp, r */ o(S, 0xe089 + (r << 8)); /* mov %esp, r */
} }
vset(S, &S->vtop->type, r | VT_LVAL, 0); vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
vswap(S); vswap(S);
vstore(S); vstore(S);
args_size += size; args_size += size;
} else if (is_float(S->vtop->type.t)) { } else if (is_float(S->tccgen_vtop->type.t)) {
gv(S, RC_FLOAT); /* only one float register */ gv(S, RC_FLOAT); /* only one float register */
if ((S->vtop->type.t & VT_BTYPE) == VT_FLOAT) if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT)
size = 4; size = 4;
else if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE) else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
size = 8; size = 8;
else else
size = 12; size = 12;
@ -458,19 +458,19 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
/* simple type (currently always same size) */ /* simple type (currently always same size) */
/* XXX: implicit cast ? */ /* XXX: implicit cast ? */
r = gv(S, RC_INT); r = gv(S, RC_INT);
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
size = 8; size = 8;
o(S, 0x50 + S->vtop->r2); /* push r */ o(S, 0x50 + S->tccgen_vtop->r2); /* push r */
} else { } else {
size = 4; size = 4;
} }
o(S, 0x50 + r); /* push r */ o(S, 0x50 + r); /* push r */
args_size += size; args_size += size;
} }
S->vtop--; S->tccgen_vtop--;
} }
save_regs(S, 0); /* save used temporary registers */ save_regs(S, 0); /* save used temporary registers */
func_sym = S->vtop->type.ref; func_sym = S->tccgen_vtop->type.ref;
func_call = func_sym->f.func_call; func_call = func_sym->f.func_call;
/* fast call case */ /* fast call case */
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
@ -493,7 +493,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
} }
} }
#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD #if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD
else if ((S->vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT) else if ((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
args_size -= 4; args_size -= 4;
#endif #endif
@ -501,7 +501,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW) if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
gadd_sp(S, args_size); gadd_sp(S, args_size);
S->vtop--; S->tccgen_vtop--;
} }
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
@ -511,7 +511,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
#endif #endif
/* generate function prolog of type 't' */ /* generate function prolog of type 't' */
ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym) ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym)
{ {
CType *func_type = &func_sym->type; CType *func_type = &func_sym->type;
int addr, align, size, func_call, fastcall_nb_regs; int addr, align, size, func_call, fastcall_nb_regs;
@ -523,7 +523,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
sym = func_type->ref; sym = func_type->ref;
func_call = sym->f.func_call; func_call = sym->f.func_call;
addr = 8; addr = 8;
S->loc = 0; S->tccgen_loc = 0;
S->tccgen_func_vc = 0; S->tccgen_func_vc = 0;
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) { if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
@ -538,8 +538,8 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
} }
param_index = 0; param_index = 0;
S->ind += FUNC_PROLOG_SIZE; S->tccgen_ind += FUNC_PROLOG_SIZE;
func_sub_sp_offset = S->ind; func_sub_sp_offset = S->tccgen_ind;
/* if the function returns a structure, then add an /* if the function returns a structure, then add an
implicit pointer parameter */ implicit pointer parameter */
#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD #if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD
@ -567,10 +567,10 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
#endif #endif
if (param_index < fastcall_nb_regs) { if (param_index < fastcall_nb_regs) {
/* save FASTCALL register */ /* save FASTCALL register */
S->loc -= 4; S->tccgen_loc -= 4;
o(S, 0x89); /* movl */ o(S, 0x89); /* movl */
gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->loc); gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->tccgen_loc);
param_addr = S->loc; param_addr = S->tccgen_loc;
} else { } else {
param_addr = addr; param_addr = addr;
addr += size; addr += size;
@ -595,7 +595,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
} }
/* generate function epilog */ /* generate function epilog */
ST_FUNC void gfunc_epilog(TCCState *S) ST_FUNC void gfunc_epilog(TCCState* S)
{ {
addr_t v, saved_ind; addr_t v, saved_ind;
@ -605,7 +605,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
#endif #endif
/* align local size to word & save local variables */ /* align local size to word & save local variables */
v = (-S->loc + 3) & -4; v = (-S->tccgen_loc + 3) & -4;
#if USE_EBX #if USE_EBX
o(S, 0x8b); o(S, 0x8b);
@ -620,8 +620,8 @@ ST_FUNC void gfunc_epilog(TCCState *S)
g(S, func_ret_sub); g(S, func_ret_sub);
g(S, func_ret_sub >> 8); g(S, func_ret_sub >> 8);
} }
saved_ind = S->ind; saved_ind = S->tccgen_ind;
S->ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; S->tccgen_ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
if (v >= 4096) { if (v >= 4096) {
oad(S, 0xb8, v); /* mov stacksize, %eax */ oad(S, 0xb8, v); /* mov stacksize, %eax */
@ -637,33 +637,33 @@ ST_FUNC void gfunc_epilog(TCCState *S)
#endif #endif
} }
o(S, 0x53 * USE_EBX); /* push ebx */ o(S, 0x53 * USE_EBX); /* push ebx */
S->ind = saved_ind; S->tccgen_ind = saved_ind;
} }
/* generate a jump to a label */ /* generate a jump to a label */
ST_FUNC int gjmp(TCCState *S, int t) ST_FUNC int gjmp(TCCState* S, int t)
{ {
return gjmp2(S, 0xe9, t); return gjmp2(S, 0xe9, t);
} }
/* generate a jump to a fixed address */ /* generate a jump to a fixed address */
ST_FUNC void gjmp_addr(TCCState *S, int a) ST_FUNC void gjmp_addr(TCCState* S, int a)
{ {
int r; int r;
r = a - S->ind - 2; r = a - S->tccgen_ind - 2;
if (r == (char)r) { if (r == (char)r) {
g(S, 0xeb); g(S, 0xeb);
g(S, r); g(S, r);
} else { } else {
oad(S, 0xe9, a - S->ind - 5); oad(S, 0xe9, a - S->tccgen_ind - 5);
} }
} }
#if 0 #if 0
/* generate a jump to a fixed address */ /* generate a jump to a fixed address */
ST_FUNC void gjmp_cond_addr(TCCState *S, int a, int op) ST_FUNC void gjmp_cond_addr(TCCState* S, int a, int op)
{ {
int r = a - S->ind - 2; int r = a - S->tccgen_ind - 2;
if (r == (char)r) if (r == (char)r)
g(S, op - 32), g(r); g(S, op - 32), g(r);
else else
@ -671,7 +671,7 @@ ST_FUNC void gjmp_cond_addr(TCCState *S, int a, int op)
} }
#endif #endif
ST_FUNC int gjmp_append(TCCState *S, int n, int t) ST_FUNC int gjmp_append(TCCState* S, int n, int t)
{ {
void *p; void *p;
/* insert vtop->c jump list in t */ /* insert vtop->c jump list in t */
@ -685,14 +685,14 @@ ST_FUNC int gjmp_append(TCCState *S, int n, int t)
return t; return t;
} }
ST_FUNC int gjmp_cond(TCCState *S, int op, int t) ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
{ {
g(S, 0x0f); g(S, 0x0f);
t = gjmp2(S, op - 16, t); t = gjmp2(S, op - 16, t);
return t; return t;
} }
ST_FUNC void gen_opi(TCCState *S, int op) ST_FUNC void gen_opi(TCCState* S, int op)
{ {
int r, fr, opc, c; int r, fr, opc, c;
@ -701,12 +701,12 @@ ST_FUNC void gen_opi(TCCState *S, int op)
case TOK_ADDC1: /* add with carry generation */ case TOK_ADDC1: /* add with carry generation */
opc = 0; opc = 0;
gen_op8: gen_op8:
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
/* constant case */ /* constant case */
vswap(S); vswap(S);
r = gv(S, RC_INT); r = gv(S, RC_INT);
vswap(S); vswap(S);
c = S->vtop->c.i; c = S->tccgen_vtop->c.i;
if (c == (char)c) { if (c == (char)c) {
/* generate inc and dec for smaller code */ /* generate inc and dec for smaller code */
if ((c == 1 || c == -1) && (op == '+' || op == '-')) { if ((c == 1 || c == -1) && (op == '+' || op == '-')) {
@ -723,12 +723,12 @@ ST_FUNC void gen_opi(TCCState *S, int op)
} }
} else { } else {
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
o(S, (opc << 3) | 0x01); o(S, (opc << 3) | 0x01);
o(S, 0xc0 + r + fr * 8); o(S, 0xc0 + r + fr * 8);
} }
S->vtop--; S->tccgen_vtop--;
if (op >= TOK_ULT && op <= TOK_GT) if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(S, op); vset_VT_CMP(S, op);
break; break;
@ -753,9 +753,9 @@ ST_FUNC void gen_opi(TCCState *S, int op)
goto gen_op8; goto gen_op8;
case '*': case '*':
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
S->vtop--; S->tccgen_vtop--;
o(S, 0xaf0f); /* imul fr, r */ o(S, 0xaf0f); /* imul fr, r */
o(S, 0xc0 + fr + r * 8); o(S, 0xc0 + fr + r * 8);
break; break;
@ -769,23 +769,23 @@ ST_FUNC void gen_opi(TCCState *S, int op)
opc = 7; opc = 7;
gen_shift: gen_shift:
opc = 0xc0 | (opc << 3); opc = 0xc0 | (opc << 3);
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
/* constant case */ /* constant case */
vswap(S); vswap(S);
r = gv(S, RC_INT); r = gv(S, RC_INT);
vswap(S); vswap(S);
c = S->vtop->c.i & 0x1f; c = S->tccgen_vtop->c.i & 0x1f;
o(S, 0xc1); /* shl/shr/sar $xxx, r */ o(S, 0xc1); /* shl/shr/sar $xxx, r */
o(S, opc | r); o(S, opc | r);
g(S, c); g(S, c);
} else { } else {
/* we generate the shift in ecx */ /* we generate the shift in ecx */
gv2(S, RC_INT, RC_ECX); gv2(S, RC_INT, RC_ECX);
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
o(S, 0xd3); /* shl/shr/sar %cl, r */ o(S, 0xd3); /* shl/shr/sar %cl, r */
o(S, opc | r); o(S, opc | r);
} }
S->vtop--; S->tccgen_vtop--;
break; break;
case '/': case '/':
case TOK_UDIV: case TOK_UDIV:
@ -796,16 +796,16 @@ ST_FUNC void gen_opi(TCCState *S, int op)
/* first operand must be in eax */ /* first operand must be in eax */
/* XXX: need better constraint for second operand */ /* XXX: need better constraint for second operand */
gv2(S, RC_EAX, RC_ECX); gv2(S, RC_EAX, RC_ECX);
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
S->vtop--; S->tccgen_vtop--;
save_reg(S, TREG_EDX); save_reg(S, TREG_EDX);
/* save EAX too if used otherwise */ /* save EAX too if used otherwise */
save_reg_upstack(S, TREG_EAX, 1); save_reg_upstack(S, TREG_EAX, 1);
if (op == TOK_UMULL) { if (op == TOK_UMULL) {
o(S, 0xf7); /* mul fr */ o(S, 0xf7); /* mul fr */
o(S, 0xe0 + fr); o(S, 0xe0 + fr);
S->vtop->r2 = TREG_EDX; S->tccgen_vtop->r2 = TREG_EDX;
r = TREG_EAX; r = TREG_EAX;
} else { } else {
if (op == TOK_UDIV || op == TOK_UMOD) { if (op == TOK_UDIV || op == TOK_UMOD) {
@ -820,7 +820,7 @@ ST_FUNC void gen_opi(TCCState *S, int op)
else else
r = TREG_EAX; r = TREG_EAX;
} }
S->vtop->r = r; S->tccgen_vtop->r = r;
break; break;
default: default:
opc = 7; opc = 7;
@ -831,7 +831,7 @@ ST_FUNC void gen_opi(TCCState *S, int op)
/* generate a floating point operation 'v = t1 op t2' instruction. The /* generate a floating point operation 'v = t1 op t2' instruction. The
two operands are guaranteed to have the same floating point type */ two operands are guaranteed to have the same floating point type */
/* XXX: need to use ST1 too */ /* XXX: need to use ST1 too */
ST_FUNC void gen_opf(TCCState *S, int op) ST_FUNC void gen_opf(TCCState* S, int op)
{ {
int a, ft, fc, swapped, r; int a, ft, fc, swapped, r;
@ -842,17 +842,17 @@ ST_FUNC void gen_opf(TCCState *S, int op)
} }
/* convert constants to memory references */ /* convert constants to memory references */
if ((S->vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { if ((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
vswap(S); vswap(S);
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
vswap(S); vswap(S);
} }
if ((S->vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) if ((S->tccgen_vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
/* must put at least one value in the floating point register */ /* must put at least one value in the floating point register */
if ((S->vtop[-1].r & VT_LVAL) && if ((S->tccgen_vtop[-1].r & VT_LVAL) &&
(S->vtop[0].r & VT_LVAL)) { (S->tccgen_vtop[0].r & VT_LVAL)) {
vswap(S); vswap(S);
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
vswap(S); vswap(S);
@ -860,13 +860,13 @@ ST_FUNC void gen_opf(TCCState *S, int op)
swapped = 0; swapped = 0;
/* swap the stack if needed so that t1 is the register and t2 is /* swap the stack if needed so that t1 is the register and t2 is
the memory reference */ the memory reference */
if (S->vtop[-1].r & VT_LVAL) { if (S->tccgen_vtop[-1].r & VT_LVAL) {
vswap(S); vswap(S);
swapped = 1; swapped = 1;
} }
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
/* load on stack second operand */ /* load on stack second operand */
load(S, TREG_ST0, S->vtop); load(S, TREG_ST0, S->tccgen_vtop);
save_reg(S, TREG_EAX); /* eax is used by FP comparison code */ save_reg(S, TREG_EAX); /* eax is used by FP comparison code */
if (op == TOK_GE || op == TOK_GT) if (op == TOK_GE || op == TOK_GT)
swapped = !swapped; swapped = !swapped;
@ -893,12 +893,12 @@ ST_FUNC void gen_opf(TCCState *S, int op)
o(S, 0x45c4f6); /* test $0x45, %ah */ o(S, 0x45c4f6); /* test $0x45, %ah */
op = TOK_EQ; op = TOK_EQ;
} }
S->vtop--; S->tccgen_vtop--;
vset_VT_CMP(S, op); vset_VT_CMP(S, op);
} else { } else {
/* no memory reference possible for long double operations */ /* no memory reference possible for long double operations */
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
load(S, TREG_ST0, S->vtop); load(S, TREG_ST0, S->tccgen_vtop);
swapped = !swapped; swapped = !swapped;
} }
@ -921,14 +921,14 @@ ST_FUNC void gen_opf(TCCState *S, int op)
a++; a++;
break; break;
} }
ft = S->vtop->type.t; ft = S->tccgen_vtop->type.t;
fc = S->vtop->c.i; fc = S->tccgen_vtop->c.i;
if ((ft & VT_BTYPE) == VT_LDOUBLE) { if ((ft & VT_BTYPE) == VT_LDOUBLE) {
o(S, 0xde); /* fxxxp %st, %st(1) */ o(S, 0xde); /* fxxxp %st, %st(1) */
o(S, 0xc1 + (a << 3)); o(S, 0xc1 + (a << 3));
} else { } else {
/* if saved lvalue, then we must reload it */ /* if saved lvalue, then we must reload it */
r = S->vtop->r; r = S->tccgen_vtop->r;
if ((r & VT_VALMASK) == VT_LLOCAL) { if ((r & VT_VALMASK) == VT_LLOCAL) {
SValue v1; SValue v1;
r = get_reg(S, RC_INT); r = get_reg(S, RC_INT);
@ -944,48 +944,48 @@ ST_FUNC void gen_opf(TCCState *S, int op)
o(S, 0xdc); o(S, 0xdc);
else else
o(S, 0xd8); o(S, 0xd8);
gen_modrm(S, a, r, S->vtop->sym, fc); gen_modrm(S, a, r, S->tccgen_vtop->sym, fc);
} }
S->vtop--; S->tccgen_vtop--;
} }
} }
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int' /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
and 'long long' cases. */ and 'long long' cases. */
ST_FUNC void gen_cvt_itof(TCCState *S, int t) ST_FUNC void gen_cvt_itof(TCCState* S, int t)
{ {
save_reg(S, TREG_ST0); save_reg(S, TREG_ST0);
gv(S, RC_INT); gv(S, RC_INT);
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) { if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
/* signed long long to float/double/long double (unsigned case /* signed long long to float/double/long double (unsigned case
is handled generically) */ is handled generically) */
o(S, 0x50 + S->vtop->r2); /* push r2 */ o(S, 0x50 + S->tccgen_vtop->r2); /* push r2 */
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */ o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
o(S, 0x242cdf); /* fildll (%esp) */ o(S, 0x242cdf); /* fildll (%esp) */
o(S, 0x08c483); /* add $8, %esp */ o(S, 0x08c483); /* add $8, %esp */
S->vtop->r2 = VT_CONST; S->tccgen_vtop->r2 = VT_CONST;
} else if ((S->vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == } else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED)) { (VT_INT | VT_UNSIGNED)) {
/* unsigned int to float/double/long double */ /* unsigned int to float/double/long double */
o(S, 0x6a); /* push $0 */ o(S, 0x6a); /* push $0 */
g(S, 0x00); g(S, 0x00);
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */ o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
o(S, 0x242cdf); /* fildll (%esp) */ o(S, 0x242cdf); /* fildll (%esp) */
o(S, 0x08c483); /* add $8, %esp */ o(S, 0x08c483); /* add $8, %esp */
} else { } else {
/* int to float/double/long double */ /* int to float/double/long double */
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */ o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
o(S, 0x2404db); /* fildl (%esp) */ o(S, 0x2404db); /* fildl (%esp) */
o(S, 0x04c483); /* add $4, %esp */ o(S, 0x04c483); /* add $4, %esp */
} }
S->vtop->r2 = VT_CONST; S->tccgen_vtop->r2 = VT_CONST;
S->vtop->r = TREG_ST0; S->tccgen_vtop->r = TREG_ST0;
} }
/* convert fp to int 't' type */ /* convert fp to int 't' type */
ST_FUNC void gen_cvt_ftoi(TCCState *S, int t) ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)
{ {
int bt = S->vtop->type.t & VT_BTYPE; int bt = S->tccgen_vtop->type.t & VT_BTYPE;
if (bt == VT_FLOAT) if (bt == VT_FLOAT)
vpush_helper_func(S, TOK___fixsfdi); vpush_helper_func(S, TOK___fixsfdi);
else if (bt == VT_LDOUBLE) else if (bt == VT_LDOUBLE)
@ -995,20 +995,20 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
vswap(S); vswap(S);
gfunc_call(S, 1); gfunc_call(S, 1);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = REG_IRET; S->tccgen_vtop->r = REG_IRET;
if ((t & VT_BTYPE) == VT_LLONG) if ((t & VT_BTYPE) == VT_LLONG)
S->vtop->r2 = REG_IRE2; S->tccgen_vtop->r2 = REG_IRE2;
} }
/* convert from one floating point type to another */ /* convert from one floating point type to another */
ST_FUNC void gen_cvt_ftof(TCCState *S, int t) ST_FUNC void gen_cvt_ftof(TCCState* S, int t)
{ {
/* all we have to do on i386 is to put the float in a register */ /* all we have to do on i386 is to put the float in a register */
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
} }
/* char/short to int conversion */ /* char/short to int conversion */
ST_FUNC void gen_cvt_csti(TCCState *S, int t) ST_FUNC void gen_cvt_csti(TCCState* S, int t)
{ {
int r, sz, xl; int r, sz, xl;
r = gv(S, RC_INT); r = gv(S, RC_INT);
@ -1021,39 +1021,39 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
} }
/* increment tcov counter */ /* increment tcov counter */
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv) ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
{ {
o(S, 0x0583); /* addl $1, xxx */ o(S, 0x0583); /* addl $1, xxx */
greloc(S, cur_text_section, sv->sym, S->ind, R_386_32); greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);
gen_le32(S, 0); gen_le32(S, 0);
o(S, 1); o(S, 1);
o(S, 0x1583); /* addcl $0, xxx */ o(S, 0x1583); /* addcl $0, xxx */
greloc(S, cur_text_section, sv->sym, S->ind, R_386_32); greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);
gen_le32(S, 4); gen_le32(S, 4);
g(S, 0); g(S, 0);
} }
/* computed goto support */ /* computed goto support */
ST_FUNC void ggoto(TCCState *S) ST_FUNC void ggoto(TCCState* S)
{ {
gcall_or_jmp(S, 1); gcall_or_jmp(S, 1);
S->vtop--; S->tccgen_vtop--;
} }
/* bound check support functions */ /* bound check support functions */
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
static void gen_bounds_prolog(TCCState *S) static void gen_bounds_prolog(TCCState* S)
{ {
/* leave some room for bound checking code */ /* leave some room for bound checking code */
S->func_bound_offset = lbounds_section->data_offset; S->func_bound_offset = lbounds_section->data_offset;
S->func_bound_ind = S->ind; S->func_bound_ind = S->tccgen_ind;
S->func_bound_add_epilog = 0; S->func_bound_add_epilog = 0;
oad(S, 0xb8, 0); /* lbound section pointer */ oad(S, 0xb8, 0); /* lbound section pointer */
oad(S, 0xb8, 0); /* call to function */ oad(S, 0xb8, 0); /* call to function */
} }
static void gen_bounds_epilog(TCCState *S) static void gen_bounds_epilog(TCCState* S)
{ {
addr_t saved_ind; addr_t saved_ind;
addr_t *bounds_ptr; addr_t *bounds_ptr;
@ -1067,22 +1067,22 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*bounds_ptr = 0; *bounds_ptr = 0;
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section, sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
S->func_bound_offset, lbounds_section->data_offset); S->func_bound_offset, lbounds_section->data_offset);
/* generate bound local allocation */ /* generate bound local allocation */
if (offset_modified) { if (offset_modified) {
saved_ind = S->ind; saved_ind = S->tccgen_ind;
S->ind = S->func_bound_ind; S->tccgen_ind = S->func_bound_ind;
greloc(S, cur_text_section, sym_data, S->ind + 1, R_386_32); greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
S->ind = S->ind + 5; S->tccgen_ind = S->tccgen_ind + 5;
gen_static_call(S, TOK___bound_local_new); gen_static_call(S, TOK___bound_local_new);
S->ind = saved_ind; S->tccgen_ind = saved_ind;
} }
/* generate bound check local freeing */ /* generate bound check local freeing */
o(S, 0x5250); /* save returned value, if any */ o(S, 0x5250); /* save returned value, if any */
greloc(S, cur_text_section, sym_data, S->ind + 1, R_386_32); greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
oad(S, 0xb8, 0); /* mov %eax, xxx */ oad(S, 0xb8, 0); /* mov %eax, xxx */
gen_static_call(S, TOK___bound_local_delete); gen_static_call(S, TOK___bound_local_delete);
o(S, 0x585a); /* restore returned value, if any */ o(S, 0x585a); /* restore returned value, if any */
@ -1090,20 +1090,20 @@ static void gen_bounds_epilog(TCCState *S)
#endif #endif
/* Save the stack pointer onto the stack */ /* Save the stack pointer onto the stack */
ST_FUNC void gen_vla_sp_save(TCCState *S, int addr) { ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {
/* mov %esp,addr(%ebp)*/ /* mov %esp,addr(%ebp)*/
o(S, 0x89); o(S, 0x89);
gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr); gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr);
} }
/* Restore the SP from a location on the stack */ /* Restore the SP from a location on the stack */
ST_FUNC void gen_vla_sp_restore(TCCState *S, int addr) { ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {
o(S, 0x8b); o(S, 0x8b);
gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr); gen_modrm(S, TREG_ESP, VT_LOCAL, NULL, addr);
} }
/* Subtract from the stack pointer, and push the resulting value onto the stack */ /* Subtract from the stack pointer, and push the resulting value onto the stack */
ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) { ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {
int use_call = 0; int use_call = 0;
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)

View file

@ -233,7 +233,7 @@ PUB_FUNC char *tcc_fileextension (const char *name)
return e ? e : strchr(b, 0); return e ? e : strchr(b, 0);
} }
ST_FUNC char *tcc_load_text(TCCState *S, int fd) ST_FUNC char *tcc_load_text(TCCState* S, int fd)
{ {
int len = lseek(fd, 0, SEEK_END); int len = lseek(fd, 0, SEEK_END);
char *buf = load_data(S, fd, 0, len + 1); char *buf = load_data(S, fd, 0, len + 1);
@ -275,12 +275,12 @@ PUB_FUNC void *tcc_mallocz_base(unsigned long size)
#ifndef MEM_DEBUG #ifndef MEM_DEBUG
PUB_FUNC void tcc_free(TCCState *S, void *ptr) PUB_FUNC void tcc_free(TCCState* S, void *ptr)
{ {
free(ptr); free(ptr);
} }
PUB_FUNC void *tcc_malloc(TCCState *S, unsigned long size) PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size)
{ {
void *ptr; void *ptr;
ptr = malloc(size); ptr = malloc(size);
@ -289,7 +289,7 @@ PUB_FUNC void *tcc_malloc(TCCState *S, unsigned long size)
return ptr; return ptr;
} }
PUB_FUNC void *tcc_mallocz(TCCState *S, unsigned long size) PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size)
{ {
void *ptr; void *ptr;
ptr = tcc_malloc(S, size); ptr = tcc_malloc(S, size);
@ -298,7 +298,7 @@ PUB_FUNC void *tcc_mallocz(TCCState *S, unsigned long size)
return ptr; return ptr;
} }
PUB_FUNC void *tcc_realloc(TCCState *S, void *ptr, unsigned long size) PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size)
{ {
void *ptr1; void *ptr1;
ptr1 = realloc(ptr, size); ptr1 = realloc(ptr, size);
@ -307,7 +307,7 @@ PUB_FUNC void *tcc_realloc(TCCState *S, void *ptr, unsigned long size)
return ptr1; return ptr1;
} }
PUB_FUNC char *tcc_strdup(TCCState *S, const char *str) PUB_FUNC char *tcc_strdup(TCCState* S, const char *str)
{ {
char *ptr; char *ptr;
ptr = tcc_malloc(S, strlen(str) + 1); ptr = tcc_malloc(S, strlen(str) + 1);
@ -361,7 +361,7 @@ static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
return header; return header;
} }
PUB_FUNC void *tcc_malloc_debug(TCCState *S, unsigned long size, const char *file, int line) PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line)
{ {
int ofs; int ofs;
mem_debug_header_t *header; mem_debug_header_t *header;
@ -392,7 +392,7 @@ PUB_FUNC void *tcc_malloc_debug(TCCState *S, unsigned long size, const char *fil
return MEM_USER_PTR(header); return MEM_USER_PTR(header);
} }
PUB_FUNC void tcc_free_debug(TCCState *S, void *ptr) PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr)
{ {
mem_debug_header_t *header; mem_debug_header_t *header;
if (!ptr) if (!ptr)
@ -409,7 +409,7 @@ PUB_FUNC void tcc_free_debug(TCCState *S, void *ptr)
free(header); free(header);
} }
PUB_FUNC void *tcc_mallocz_debug(TCCState *S, unsigned long size, const char *file, int line) PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line)
{ {
void *ptr; void *ptr;
ptr = tcc_malloc_debug(S, size,file,line); ptr = tcc_malloc_debug(S, size,file,line);
@ -417,7 +417,7 @@ PUB_FUNC void *tcc_mallocz_debug(TCCState *S, unsigned long size, const char *fi
return ptr; return ptr;
} }
PUB_FUNC void *tcc_realloc_debug(TCCState *S, void *ptr, unsigned long size, const char *file, int line) PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line)
{ {
mem_debug_header_t *header; mem_debug_header_t *header;
int mem_debug_chain_update = 0; int mem_debug_chain_update = 0;
@ -443,7 +443,7 @@ PUB_FUNC void *tcc_realloc_debug(TCCState *S, void *ptr, unsigned long size, con
return MEM_USER_PTR(header); return MEM_USER_PTR(header);
} }
PUB_FUNC char *tcc_strdup_debug(TCCState *S, const char *str, const char *file, int line) PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line)
{ {
char *ptr; char *ptr;
ptr = tcc_malloc_debug(S, strlen(str) + 1, file, line); ptr = tcc_malloc_debug(S, strlen(str) + 1, file, line);
@ -532,7 +532,7 @@ int vio_close(vio_fd *fd) {
/********************************************************/ /********************************************************/
/* dynarrays */ /* dynarrays */
ST_FUNC void dynarray_add(TCCState *S, void *ptab, int *nb_ptr, void *data) ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data)
{ {
int nb, nb_alloc; int nb, nb_alloc;
void **pp; void **pp;
@ -552,7 +552,7 @@ ST_FUNC void dynarray_add(TCCState *S, void *ptab, int *nb_ptr, void *data)
*nb_ptr = nb; *nb_ptr = nb;
} }
ST_FUNC void dynarray_reset(TCCState *S, void *pp, int *n) ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n)
{ {
void **p; void **p;
for (p = *(void***)pp; *n; ++p, --*n) for (p = *(void***)pp; *n; ++p, --*n)
@ -608,7 +608,7 @@ static void tcc_split_path(TCCState *S, void *p_ary, int *p_nb_ary, const char *
/* error1() modes */ /* error1() modes */
enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR }; enum { ERROR_WARN, ERROR_NOABORT, ERROR_ERROR };
static void error1(TCCState *S, int mode, const char *fmt, va_list ap) static void error1(TCCState* S, int mode, const char *fmt, va_list ap)
{ {
BufferedFile **pf, *f; BufferedFile **pf, *f;
CString cs; CString cs;
@ -650,7 +650,7 @@ static void error1(TCCState *S, int mode, const char *fmt, va_list ap)
cstr_printf(S, &cs, "In file included from %s:%d:\n", cstr_printf(S, &cs, "In file included from %s:%d:\n",
(*pf)->filename, (*pf)->line_num); (*pf)->filename, (*pf)->line_num);
cstr_printf(S, &cs, "%s:%d: ", cstr_printf(S, &cs, "%s:%d: ",
f->filename, (*pf)->line_num - !!(S->tok_flags & TOK_FLAG_BOL)); f->filename, (*pf)->line_num - !!(S->tccpp_tok_flags & TOK_FLAG_BOL));
} else if (S->current_filename) { } else if (S->current_filename) {
cstr_printf(S, &cs, "%s: ", S->current_filename); cstr_printf(S, &cs, "%s: ", S->current_filename);
} }
@ -699,7 +699,7 @@ LIBTCCAPI void *tcc_get_error_opaque(TCCState *S)
} }
/* error without aborting current compilation */ /* error without aborting current compilation */
PUB_FUNC void _tcc_error_noabort(TCCState *S, const char *fmt, ...) PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@ -707,14 +707,14 @@ PUB_FUNC void _tcc_error_noabort(TCCState *S, const char *fmt, ...)
va_end(ap); va_end(ap);
} }
PUB_FUNC void _tcc_error(TCCState *S, const char *fmt, ...) PUB_FUNC void _tcc_error(TCCState* S, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
for (;;) error1(S, ERROR_ERROR, fmt, ap); for (;;) error1(S, ERROR_ERROR, fmt, ap);
} }
PUB_FUNC void _tcc_warning(TCCState *S, const char *fmt, ...) PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@ -744,10 +744,10 @@ ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen)
bf->fd = -1; bf->fd = -1;
bf->prev = S->tccpp_file; bf->prev = S->tccpp_file;
S->tccpp_file = bf; S->tccpp_file = bf;
S->tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; S->tccpp_tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
} }
ST_FUNC void tcc_close(TCCState *S) ST_FUNC void tcc_close(TCCState* S)
{ {
BufferedFile *bf = S->tccpp_file; BufferedFile *bf = S->tccpp_file;
if (bf->fd > 0) { if (bf->fd > 0) {
@ -1388,7 +1388,7 @@ static const char *skip_linker_arg(const char **str)
return s2; return s2;
} }
static void copy_linker_arg(TCCState *S, char **pp, const char *s, int sep) static void copy_linker_arg(TCCState* S, char **pp, const char *s, int sep)
{ {
const char *q = s; const char *q = s;
char *p = *pp; char *p = *pp;
@ -1723,7 +1723,7 @@ static void args_parser_add_file(TCCState *S, const char* filename, int filetype
dynarray_add(S, &S->files, &S->nb_files, f); dynarray_add(S, &S->files, &S->nb_files, f);
} }
static int args_parser_make_argv(TCCState *S, const char *r, int *argc, char ***argv) static int args_parser_make_argv(TCCState* S, const char *r, int *argc, char ***argv)
{ {
int ret = 0, q, c; int ret = 0, q, c;
CString str; CString str;

View file

@ -9,9 +9,9 @@
#define CONFIG_TCC_ASM #define CONFIG_TCC_ASM
#define NB_ASM_REGS 32 #define NB_ASM_REGS 32
ST_FUNC void g(TCCState *S, int c); ST_FUNC void g(TCCState* S, int c);
ST_FUNC void gen_le16(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 gen_le32(TCCState* S, int c);
/*************************************************************/ /*************************************************************/
#else #else
@ -20,44 +20,44 @@ ST_FUNC void gen_le32(TCCState *S, int c);
#include "tcc.h" #include "tcc.h"
/* XXX: make it faster ? */ /* XXX: make it faster ? */
ST_FUNC void g(TCCState *S, int c) ST_FUNC void g(TCCState* S, int c)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 1; ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c; cur_text_section->data[S->tccgen_ind] = c;
S->ind = ind1; S->tccgen_ind = ind1;
} }
ST_FUNC void gen_le16 (TCCState *S, int i) ST_FUNC void gen_le16 (TCCState* S, int i)
{ {
g(S, i); g(S, i);
g(S, i>>8); g(S, i>>8);
} }
ST_FUNC void gen_le32 (TCCState *S, int i) ST_FUNC void gen_le32 (TCCState* S, int i)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 4; ind1 = S->tccgen_ind + 4;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind++] = i & 0xFF; cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
} }
ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe) ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
{ {
gen_le32(S, pe->v); gen_le32(S, pe->v);
} }
static void asm_emit_opcode(TCCState *S, uint32_t opcode) { static void asm_emit_opcode(TCCState* S, uint32_t opcode) {
gen_le32(S, opcode); gen_le32(S, opcode);
} }
@ -128,12 +128,12 @@ static void parse_operand(TCCState *S, Operand *op)
op->type = 0; op->type = 0;
if ((reg = asm_parse_regvar(S, S->tok)) != -1) { if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_REG; op->type = OP_REG;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if (S->tok == '$') { } else if (S->tccpp_tok == '$') {
/* constant value */ /* constant value */
next(S); // skip '#' or '$' next(S); // skip '#' or '$'
} }
@ -207,11 +207,11 @@ static void asm_emit_u(TCCState *S, int token, uint32_t opcode, const Operand* r
gen_le32(S, opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12)); gen_le32(S, opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));
} }
static void asm_binary_opcode(TCCState *S, int token) static void asm_binary_opcode(TCCState* S, int token)
{ {
Operand ops[2]; Operand ops[2];
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -230,7 +230,7 @@ static void asm_binary_opcode(TCCState *S, int token)
} }
/* caller: Add funct3, funct7 into opcode */ /* caller: Add funct3, funct7 into opcode */
static void asm_emit_r(TCCState *S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2) static void asm_emit_r(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
{ {
if (rd->type != OP_REG) { if (rd->type != OP_REG) {
tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL)); tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));
@ -255,7 +255,7 @@ static void asm_emit_r(TCCState *S, int token, uint32_t opcode, const Operand* r
} }
/* caller: Add funct3 into opcode */ /* caller: Add funct3 into opcode */
static void asm_emit_i(TCCState *S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2) static void asm_emit_i(TCCState* S, int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
{ {
if (rd->type != OP_REG) { if (rd->type != OP_REG) {
tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL)); tcc_error(S, "'%s': Expected destination operand that is a register", get_tok_str(S, token, NULL));
@ -283,12 +283,12 @@ static void asm_shift_opcode(TCCState *S, int token)
{ {
Operand ops[3]; Operand ops[3];
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
parse_operand(S, &ops[1]); parse_operand(S, &ops[1]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -336,16 +336,16 @@ static void asm_shift_opcode(TCCState *S, int token)
} }
} }
static void asm_data_processing_opcode(TCCState *S, int token) static void asm_data_processing_opcode(TCCState* S, int token)
{ {
Operand ops[3]; Operand ops[3];
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
parse_operand(S, &ops[1]); parse_operand(S, &ops[1]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -414,7 +414,7 @@ static void asm_data_processing_opcode(TCCState *S, int token)
} }
/* caller: Add funct3 to opcode */ /* caller: Add funct3 to opcode */
static void asm_emit_s(TCCState *S, int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm) static void asm_emit_s(TCCState* S, int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm)
{ {
if (rs1->type != OP_REG) { if (rs1->type != OP_REG) {
tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL)); tcc_error(S, "'%s': Expected first source operand that is a register", get_tok_str(S, token, NULL));
@ -442,7 +442,7 @@ static void asm_emit_s(TCCState *S, int token, uint32_t opcode, const Operand* r
} }
} }
static void asm_data_transfer_opcode(TCCState *S, int token) static void asm_data_transfer_opcode(TCCState* S, int token)
{ {
Operand ops[3]; Operand ops[3];
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
@ -450,7 +450,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
expect(S, "register"); expect(S, "register");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -459,7 +459,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
expect(S, "register"); expect(S, "register");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -511,7 +511,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
} }
} }
static void asm_branch_opcode(TCCState *S, int token) static void asm_branch_opcode(TCCState* S, int token)
{ {
// Branch (RS1,RS2,IMM); SB-format // Branch (RS1,RS2,IMM); SB-format
uint32_t opcode = (0x18 << 2) | 3; uint32_t opcode = (0x18 << 2) | 3;
@ -522,7 +522,7 @@ static void asm_branch_opcode(TCCState *S, int token)
expect(S, "register"); expect(S, "register");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -531,7 +531,7 @@ static void asm_branch_opcode(TCCState *S, int token)
expect(S, "register"); expect(S, "register");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -709,7 +709,7 @@ ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str)
clobber_regs[reg] = 1; clobber_regs[reg] = 1;
} }
ST_FUNC int asm_parse_regvar (TCCState *S, int t) ST_FUNC int asm_parse_regvar (TCCState* S, int t)
{ {
if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */ if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */
switch (t) { switch (t) {

View file

@ -100,37 +100,37 @@ static int is_freg(int r)
return r >= 8 && r < 16; return r >= 8 && r < 16;
} }
ST_FUNC void o(TCCState *S, unsigned int c) ST_FUNC void o(TCCState* S, unsigned int c)
{ {
int ind1 = S->ind + 4; int ind1 = S->tccgen_ind + 4;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
write32le(cur_text_section->data + S->ind, c); write32le(cur_text_section->data + S->tccgen_ind, c);
S->ind = ind1; S->tccgen_ind = ind1;
} }
static void EIu(TCCState *S, uint32_t opcode, uint32_t func3, static void EIu(TCCState* S, uint32_t opcode, uint32_t func3,
uint32_t rd, uint32_t rs1, uint32_t imm) uint32_t rd, uint32_t rs1, uint32_t imm)
{ {
o(S, opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20)); o(S, opcode | (func3 << 12) | (rd << 7) | (rs1 << 15) | (imm << 20));
} }
static void ER(TCCState *S, uint32_t opcode, uint32_t func3, static void ER(TCCState* S, uint32_t opcode, uint32_t func3,
uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7) uint32_t rd, uint32_t rs1, uint32_t rs2, uint32_t func7)
{ {
o(S, opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25); o(S, opcode | func3 << 12 | rd << 7 | rs1 << 15 | rs2 << 20 | func7 << 25);
} }
static void EI(TCCState *S, uint32_t opcode, uint32_t func3, static void EI(TCCState* S, uint32_t opcode, uint32_t func3,
uint32_t rd, uint32_t rs1, uint32_t imm) uint32_t rd, uint32_t rs1, uint32_t imm)
{ {
assert(! ((imm + (1 << 11)) >> 12)); assert(! ((imm + (1 << 11)) >> 12));
EIu(S, opcode, func3, rd, rs1, imm); EIu(S, opcode, func3, rd, rs1, imm);
} }
static void ES(TCCState *S, uint32_t opcode, uint32_t func3, static void ES(TCCState* S, uint32_t opcode, uint32_t func3,
uint32_t rs1, uint32_t rs2, uint32_t imm) uint32_t rs1, uint32_t rs2, uint32_t imm)
{ {
assert(! ((imm + (1 << 11)) >> 12)); assert(! ((imm + (1 << 11)) >> 12));
@ -139,7 +139,7 @@ static void ES(TCCState *S, uint32_t opcode, uint32_t func3,
} }
// Patch all branches in list pointed to by t to branch to a: // Patch all branches in list pointed to by t to branch to a:
ST_FUNC void gsym_addr(TCCState *S, int t_, int a_) ST_FUNC void gsym_addr(TCCState* S, int t_, int a_)
{ {
uint32_t t = t_; uint32_t t = t_;
uint32_t a = a_; uint32_t a = a_;
@ -158,7 +158,7 @@ ST_FUNC void gsym_addr(TCCState *S, int t_, int a_)
} }
} }
static int load_symofs(TCCState *S, int r, SValue *sv, int forstore) static int load_symofs(TCCState* S, int r, SValue *sv, int forstore)
{ {
int rr, doload = 0; int rr, doload = 0;
int fc = sv->c.i, v = sv->r & VT_VALMASK; int fc = sv->c.i, v = sv->r & VT_VALMASK;
@ -166,21 +166,21 @@ static int load_symofs(TCCState *S, int r, SValue *sv, int forstore)
Sym label = {0}; Sym label = {0};
assert(v == VT_CONST); assert(v == VT_CONST);
if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
greloca(S, cur_text_section, sv->sym, S->ind, greloca(S, cur_text_section, sv->sym, S->tccgen_ind,
R_RISCV_PCREL_HI20, sv->c.i); R_RISCV_PCREL_HI20, sv->c.i);
sv->c.i = 0; sv->c.i = 0;
} else { } else {
if (((unsigned)fc + (1 << 11)) >> 12) if (((unsigned)fc + (1 << 11)) >> 12)
tcc_error(S, "unimp: large addend for global address (0x%lx)", (long)sv->c.i); tcc_error(S, "unimp: large addend for global address (0x%lx)", (long)sv->c.i);
greloca(S, cur_text_section, sv->sym, S->ind, greloca(S, cur_text_section, sv->sym, S->tccgen_ind,
R_RISCV_GOT_HI20, 0); R_RISCV_GOT_HI20, 0);
doload = 1; doload = 1;
} }
label.type.t = VT_VOID | VT_STATIC; label.type.t = VT_VOID | VT_STATIC;
put_extern_sym(S, &label, cur_text_section, S->ind, 0); put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
rr = is_ireg(r) ? ireg(r) : 5; rr = is_ireg(r) ? ireg(r) : 5;
o(S, 0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend o(S, 0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend
greloca(S, cur_text_section, &label, S->ind, greloca(S, cur_text_section, &label, S->tccgen_ind,
doload || !forstore doload || !forstore
? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0); ? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
if (doload) { if (doload) {
@ -201,7 +201,7 @@ static int load_symofs(TCCState *S, int r, SValue *sv, int forstore)
return rr; return rr;
} }
static void load_large_constant(TCCState *S, int rr, int fc, uint32_t pi) static void load_large_constant(TCCState* S, int rr, int fc, uint32_t pi)
{ {
if (fc < 0) if (fc < 0)
pi++; pi++;
@ -215,7 +215,7 @@ static void load_large_constant(TCCState *S, int rr, int fc, uint32_t pi)
EI(S, 0x13, 1, rr, rr, 8); // slli RR, RR, 8 EI(S, 0x13, 1, rr, rr, 8); // slli RR, RR, 8
} }
ST_FUNC void load(TCCState *S, int r, SValue *sv) ST_FUNC void load(TCCState* S, int r, SValue *sv)
{ {
int fr = sv->r; int fr = sv->r;
int v = fr & VT_VALMASK; int v = fr & VT_VALMASK;
@ -314,9 +314,9 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv)
| (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR | (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR
} }
} else if (v == VT_CMP) { } else if (v == VT_CMP) {
int op = S->vtop->cmp_op; int op = S->tccgen_vtop->cmp_op;
int a = S->vtop->cmp_r & 0xff; int a = S->tccgen_vtop->cmp_r & 0xff;
int b = (S->vtop->cmp_r >> 8) & 0xff; int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
int inv = 0; int inv = 0;
switch (op) { switch (op) {
case TOK_ULT: case TOK_ULT:
@ -353,14 +353,14 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv)
int t = v & 1; int t = v & 1;
assert(is_ireg(r)); assert(is_ireg(r));
EI(S, 0x13, 0, rr, 0, t); // addi RR, x0, t EI(S, 0x13, 0, rr, 0, t); // addi RR, x0, t
gjmp_addr(S, S->ind + 8); gjmp_addr(S, S->tccgen_ind + 8);
gsym(S, fc); gsym(S, fc);
EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
} else } else
tcc_error(S, "unimp: load(non-const)"); tcc_error(S, "unimp: load(non-const)");
} }
ST_FUNC void store(TCCState *S, int r, SValue *sv) ST_FUNC void store(TCCState* S, int r, SValue *sv)
{ {
int fr = sv->r & VT_VALMASK; int fr = sv->r & VT_VALMASK;
int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg; int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;
@ -403,22 +403,22 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv)
ptrreg, rr, fc); // RR, fc(base) ptrreg, rr, fc); // RR, fc(base)
} }
static void gcall_or_jmp(TCCState *S, int docall) static void gcall_or_jmp(TCCState* S, int docall)
{ {
int tr = docall ? 1 : 5; // ra or t0 int tr = docall ? 1 : 5; // ra or t0
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((S->vtop->r & VT_SYM) && S->vtop->c.i == (int)S->vtop->c.i)) { ((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->c.i == (int)S->tccgen_vtop->c.i)) {
/* constant symbolic case -> simple relocation */ /* constant symbolic case -> simple relocation */
greloca(S, cur_text_section, S->vtop->sym, S->ind, greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
R_RISCV_CALL_PLT, (int)S->vtop->c.i); R_RISCV_CALL_PLT, (int)S->tccgen_vtop->c.i);
o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func) o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func)
EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR) EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR)
} else if (S->vtop->r < VT_CONST) { } else if (S->tccgen_vtop->r < VT_CONST) {
int r = ireg(S->vtop->r); int r = ireg(S->tccgen_vtop->r);
EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R) EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
} else { } else {
int r = TREG_RA; int r = TREG_RA;
load(S, r, S->vtop); load(S, r, S->tccgen_vtop);
r = ireg(r); r = ireg(r);
EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R) EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
} }
@ -426,20 +426,20 @@ static void gcall_or_jmp(TCCState *S, int docall)
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
static void gen_bounds_call(TCCState *S, int v) static void gen_bounds_call(TCCState* S, int v)
{ {
Sym *sym = external_helper_sym(S, v); Sym *sym = external_helper_sym(S, v);
greloca(S, cur_text_section, sym, S->ind, R_RISCV_CALL_PLT, 0); greloca(S, cur_text_section, sym, S->tccgen_ind, R_RISCV_CALL_PLT, 0);
o(S, 0x17 | (1 << 7)); // auipc TR, 0 %call(func) o(S, 0x17 | (1 << 7)); // auipc TR, 0 %call(func)
EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR) EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR)
} }
static void gen_bounds_prolog(TCCState *S) static void gen_bounds_prolog(TCCState* S)
{ {
/* leave some room for bound checking code */ /* leave some room for bound checking code */
S->func_bound_offset = lbounds_section->data_offset; S->func_bound_offset = lbounds_section->data_offset;
S->func_bound_ind = S->ind; S->func_bound_ind = S->tccgen_ind;
S->func_bound_add_epilog = 0; S->func_bound_add_epilog = 0;
o(S, 0x00000013); /* ld a0,#lbound section pointer */ o(S, 0x00000013); /* ld a0,#lbound section pointer */
o(S, 0x00000013); o(S, 0x00000013);
@ -447,7 +447,7 @@ static void gen_bounds_prolog(TCCState *S)
o(S, 0x00000013); o(S, 0x00000013);
} }
static void gen_bounds_epilog(TCCState *S) static void gen_bounds_epilog(TCCState* S)
{ {
addr_t saved_ind; addr_t saved_ind;
addr_t *bounds_ptr; addr_t *bounds_ptr;
@ -463,31 +463,31 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t)); bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*bounds_ptr = 0; *bounds_ptr = 0;
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section, sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
S->func_bound_offset, lbounds_section->data_offset); S->func_bound_offset, lbounds_section->data_offset);
label.type.t = VT_VOID | VT_STATIC; label.type.t = VT_VOID | VT_STATIC;
/* generate bound local allocation */ /* generate bound local allocation */
if (offset_modified) { if (offset_modified) {
saved_ind = S->ind; saved_ind = S->tccgen_ind;
S->ind = S->func_bound_ind; S->tccgen_ind = S->func_bound_ind;
put_extern_sym(S, &label, cur_text_section, S->ind, 0); put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
greloca(S, cur_text_section, sym_data, S->ind, R_RISCV_GOT_HI20, 0); greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);
o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_I, 0); greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0) EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)
gen_bounds_call(S, TOK___bound_local_new); gen_bounds_call(S, TOK___bound_local_new);
S->ind = saved_ind; S->tccgen_ind = saved_ind;
label.c = 0; /* force new local ELF symbol */ label.c = 0; /* force new local ELF symbol */
} }
/* generate bound check local freeing */ /* generate bound check local freeing */
o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */ o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */
o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */ o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */
put_extern_sym(S, &label, cur_text_section, S->ind, 0); put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
greloca(S, cur_text_section, sym_data, S->ind, R_RISCV_GOT_HI20, 0); greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);
o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_I, 0); greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0) EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)
gen_bounds_call(S, TOK___bound_local_delete); gen_bounds_call(S, TOK___bound_local_delete);
o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */ o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */
@ -540,7 +540,7 @@ static void reg_pass(CType *type, int *prc, int *fieldofs, int named)
} }
} }
ST_FUNC void gfunc_call(TCCState *S, int nb_args) ST_FUNC void gfunc_call(TCCState* S, int nb_args)
{ {
int i, align, size, areg[2]; int i, align, size, areg[2];
int *info = tcc_malloc(S, (nb_args + 1) * sizeof (int)); int *info = tcc_malloc(S, (nb_args + 1) * sizeof (int));
@ -556,11 +556,11 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
areg[0] = 0; /* int arg regs */ areg[0] = 0; /* int arg regs */
areg[1] = 8; /* float arg regs */ areg[1] = 8; /* float arg regs */
sa = S->vtop[-nb_args].type.ref->next; sa = S->tccgen_vtop[-nb_args].type.ref->next;
for (i = 0; i < nb_args; i++) { for (i = 0; i < nb_args; i++) {
int nregs, byref = 0, tempofs; int nregs, byref = 0, tempofs;
int prc[3], fieldofs[3]; int prc[3], fieldofs[3];
sv = &S->vtop[1 + i - nb_args]; sv = &S->tccgen_vtop[1 + i - nb_args];
sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c
size = type_size(&sv->type, &align); size = type_size(&sv->type, &align);
if (size > 16) { if (size > 16) {
@ -617,7 +617,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
stack_add = stack_adj + tempspace; stack_add = stack_adj + tempspace;
/* fetch cpu flag before generating any code */ /* fetch cpu flag before generating any code */
if ((S->vtop->r & VT_VALMASK) == VT_CMP) if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
gv(S, RC_INT); gv(S, RC_INT);
if (stack_add) { if (stack_add) {
@ -631,15 +631,15 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
for (i = ofs = 0; i < nb_args; i++) { for (i = ofs = 0; i < nb_args; i++) {
if (info[i] & (64 | 32)) { if (info[i] & (64 | 32)) {
vrotb(S, nb_args - i); vrotb(S, nb_args - i);
size = type_size(&S->vtop->type, &align); size = type_size(&S->tccgen_vtop->type, &align);
if (info[i] & 64) { if (info[i] & 64) {
vset(S, &S->char_pointer_type, TREG_SP, 0); vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);
vpushi(S, stack_adj + (info[i] >> 7)); vpushi(S, stack_adj + (info[i] >> 7));
gen_op(S, '+'); gen_op(S, '+');
vpushv(S, S->vtop); // this replaces the old argument vpushv(S, S->tccgen_vtop); // this replaces the old argument
vrott(S, 3); vrott(S, 3);
indir(S); indir(S);
S->vtop->type = S->vtop[-1].type; S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
vswap(S); vswap(S);
vstore(S); vstore(S);
vpop(S); vpop(S);
@ -649,18 +649,18 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (align < XLEN) if (align < XLEN)
align = XLEN; align = XLEN;
/* Once we support offseted regs we can do this: /* Once we support offseted regs we can do this:
vset(S, &S->vtop->type, TREG_SP | VT_LVAL, ofs); vset(S, &S->tccgen_vtop->type, TREG_SP | VT_LVAL, ofs);
to construct the lvalue for the outgoing stack slot, to construct the lvalue for the outgoing stack slot,
until then we have to jump through hoops. */ until then we have to jump through hoops. */
vset(S, &S->char_pointer_type, TREG_SP, 0); vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);
ofs = (ofs + align - 1) & -align; ofs = (ofs + align - 1) & -align;
vpushi(S, ofs); vpushi(S, ofs);
gen_op(S, '+'); gen_op(S, '+');
indir(S); indir(S);
S->vtop->type = S->vtop[-1].type; S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
vswap(S); vswap(S);
vstore(S); vstore(S);
S->vtop->r = S->vtop->r2 = VT_CONST; // this arg is done S->tccgen_vtop->r = S->tccgen_vtop->r2 = VT_CONST; // this arg is done
ofs += size; ofs += size;
} }
vrott(S, nb_args - i); vrott(S, nb_args - i);
@ -680,11 +680,11 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
r2 = r2 & 64 ? 0 : (r2 >> 7) & 31; r2 = r2 & 64 ? 0 : (r2 >> 7) & 31;
assert(r2 <= 16); assert(r2 <= 16);
vrotb(S, i+1); vrotb(S, i+1);
origtype = S->vtop->type; origtype = S->tccgen_vtop->type;
size = type_size(&S->vtop->type, &align); size = type_size(&S->tccgen_vtop->type, &align);
if (size == 0) if (size == 0)
goto done; goto done;
loadt = S->vtop->type.t & VT_BTYPE; loadt = S->tccgen_vtop->type.t & VT_BTYPE;
if (loadt == VT_STRUCT) { if (loadt == VT_STRUCT) {
loadt = (ii >> 12) & VT_BTYPE; loadt = (ii >> 12) & VT_BTYPE;
} }
@ -697,18 +697,18 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
r2--; r2--;
} else if (r2) { } else if (r2) {
test_lvalue(S); test_lvalue(S);
vpushv(S, S->vtop); vpushv(S, S->tccgen_vtop);
} }
S->vtop->type.t = loadt | (S->vtop->type.t & VT_UNSIGNED); S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
gv(S, r < 8 ? RC_R(r) : RC_F(r - 8)); gv(S, r < 8 ? RC_R(r) : RC_F(r - 8));
S->vtop->type = origtype; S->tccgen_vtop->type = origtype;
if (r2 && loadt != VT_LDOUBLE) { if (r2 && loadt != VT_LDOUBLE) {
r2--; r2--;
assert(r2 < 16 || r2 == TREG_RA); assert(r2 < 16 || r2 == TREG_RA);
vswap(S); vswap(S);
gaddrof(S); gaddrof(S);
S->vtop->type = S->char_pointer_type; S->tccgen_vtop->type = S->tccgen_char_pointer_type;
vpushi(S, ii >> 20); vpushi(S, ii >> 20);
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
if ((origtype.t & VT_BTYPE) == VT_STRUCT) if ((origtype.t & VT_BTYPE) == VT_STRUCT)
@ -719,27 +719,27 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
S->do_bounds_check = bc_save; S->do_bounds_check = bc_save;
#endif #endif
indir(S); indir(S);
S->vtop->type = origtype; S->tccgen_vtop->type = origtype;
loadt = S->vtop->type.t & VT_BTYPE; loadt = S->tccgen_vtop->type.t & VT_BTYPE;
if (loadt == VT_STRUCT) { if (loadt == VT_STRUCT) {
loadt = (ii >> 16) & VT_BTYPE; loadt = (ii >> 16) & VT_BTYPE;
} }
save_reg_upstack(S, r2, 1); save_reg_upstack(S, r2, 1);
S->vtop->type.t = loadt | (S->vtop->type.t & VT_UNSIGNED); S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
load(S, r2, S->vtop); load(S, r2, S->tccgen_vtop);
assert(r2 < VT_CONST); assert(r2 < VT_CONST);
S->vtop--; S->tccgen_vtop--;
S->vtop->r2 = r2; S->tccgen_vtop->r2 = r2;
} }
if (info[nb_args - 1 - i] & 16) { if (info[nb_args - 1 - i] & 16) {
ES(S, 0x23, 3, 2, ireg(S->vtop->r2), splitofs); // sd t0, ofs(sp) ES(S, 0x23, 3, 2, ireg(S->tccgen_vtop->r2), splitofs); // sd t0, ofs(sp)
S->vtop->r2 = VT_CONST; S->tccgen_vtop->r2 = VT_CONST;
} else if (loadt == VT_LDOUBLE && S->vtop->r2 != r2) { } else if (loadt == VT_LDOUBLE && S->tccgen_vtop->r2 != r2) {
assert(S->vtop->r2 <= 7 && r2 <= 7); assert(S->tccgen_vtop->r2 <= 7 && r2 <= 7);
/* XXX we'd like to have 'gv' move directly into /* XXX we'd like to have 'gv' move directly into
the right class instead of us fixing it up. */ the right class instead of us fixing it up. */
EI(S, 0x13, 0, ireg(r2), ireg(S->vtop->r2), 0); // mv Ra+1, RR2 EI(S, 0x13, 0, ireg(r2), ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
S->vtop->r2 = r2; S->tccgen_vtop->r2 = r2;
} }
done: done:
vrott(S, i+1); vrott(S, i+1);
@ -748,7 +748,7 @@ done:
vrotb(S, nb_args + 1); vrotb(S, nb_args + 1);
save_regs(S, nb_args + 1); save_regs(S, nb_args + 1);
gcall_or_jmp(S, 1); gcall_or_jmp(S, 1);
S->vtop -= nb_args + 1; S->tccgen_vtop -= nb_args + 1;
if (stack_add) { if (stack_add) {
if (stack_add >= 0x1000) { if (stack_add >= 0x1000) {
o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v) o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)
@ -763,7 +763,7 @@ done:
static int func_sub_sp_offset, num_va_regs, func_va_list_ofs; static int func_sub_sp_offset, num_va_regs, func_va_list_ofs;
ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym) ST_FUNC void gfunc_prolog(TCCState* S, Sym *func_sym)
{ {
CType *func_type = &func_sym->type; CType *func_type = &func_sym->type;
int i, addr, align, size; int i, addr, align, size;
@ -773,9 +773,9 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
CType *type; CType *type;
sym = func_type->ref; sym = func_type->ref;
S->loc = -16; // for ra and s0 S->tccgen_loc = -16; // for ra and s0
func_sub_sp_offset = S->ind; func_sub_sp_offset = S->tccgen_ind;
S->ind += 5 * 4; S->tccgen_ind += 5 * 4;
areg[0] = 0, areg[1] = 0; areg[0] = 0, areg[1] = 0;
addr = 0; addr = 0;
@ -783,9 +783,9 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
implicit pointer parameter */ implicit pointer parameter */
size = type_size(&S->tccgen_func_vt, &align); size = type_size(&S->tccgen_func_vt, &align);
if (size > 2 * XLEN) { if (size > 2 * XLEN) {
S->loc -= 8; S->tccgen_loc -= 8;
S->tccgen_func_vc = S->loc; S->tccgen_func_vc = S->tccgen_loc;
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->loc); // sd a0, loc(s0) ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc); // sd a0, loc(s0)
} }
/* define parameters */ /* define parameters */
while ((sym = sym->next) != NULL) { while ((sym = sym->next) != NULL) {
@ -795,7 +795,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
type = &sym->type; type = &sym->type;
size = type_size(type, &align); size = type_size(type, &align);
if (size > 2 * XLEN) { if (size > 2 * XLEN) {
type = &S->char_pointer_type; type = &S->tccgen_char_pointer_type;
size = align = byref = 8; size = align = byref = 8;
} }
reg_pass(type, prc, fieldofs, 1); reg_pass(type, prc, fieldofs, 1);
@ -810,18 +810,18 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
param_addr = addr; param_addr = addr;
addr += size; addr += size;
} else { } else {
S->loc -= regcount * 8; // XXX could reserve only 'size' bytes S->tccgen_loc -= regcount * 8; // XXX could reserve only 'size' bytes
param_addr = S->loc; param_addr = S->tccgen_loc;
for (i = 0; i < regcount; i++) { for (i = 0; i < regcount; i++) {
if (areg[prc[1+i] - 1] >= 8) { if (areg[prc[1+i] - 1] >= 8) {
assert(i == 1 && regcount == 2 && !(addr & 7)); assert(i == 1 && regcount == 2 && !(addr & 7));
EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0) EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0)
addr += 8; addr += 8;
ES(S, 0x23, 3, 8, 5, S->loc + i*8); // sd t0, loc(s0) ES(S, 0x23, 3, 8, 5, S->tccgen_loc + i*8); // sd t0, loc(s0)
} else if (prc[1+i] == RC_FLOAT) { } else if (prc[1+i] == RC_FLOAT) {
ES(S, 0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, S->loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0) ES(S, 0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, S->tccgen_loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0)
} else { } else {
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->loc + i*8); // sd aX, loc(s0) // XXX ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc + i*8); // sd aX, loc(s0) // XXX
} }
} }
} }
@ -864,22 +864,22 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
return nregs; return nregs;
} }
ST_FUNC void arch_transfer_ret_regs(TCCState *S, int aftercall) ST_FUNC void arch_transfer_ret_regs(TCCState* S, int aftercall)
{ {
int prc[3], fieldofs[3]; int prc[3], fieldofs[3];
reg_pass(&S->vtop->type, prc, fieldofs, 1); reg_pass(&S->tccgen_vtop->type, prc, fieldofs, 1);
assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4)); assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4));
assert(S->vtop->r == (VT_LOCAL | VT_LVAL)); assert(S->tccgen_vtop->r == (VT_LOCAL | VT_LVAL));
vpushv(S, S->vtop); vpushv(S, S->tccgen_vtop);
S->vtop->type.t = fieldofs[1] & VT_BTYPE; S->tccgen_vtop->type.t = fieldofs[1] & VT_BTYPE;
(aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->vtop); (aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
S->vtop->c.i += fieldofs[2] >> 4; S->tccgen_vtop->c.i += fieldofs[2] >> 4;
S->vtop->type.t = fieldofs[2] & VT_BTYPE; S->tccgen_vtop->type.t = fieldofs[2] & VT_BTYPE;
(aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->vtop); (aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
S->vtop--; S->tccgen_vtop--;
} }
ST_FUNC void gfunc_epilog(TCCState *S) ST_FUNC void gfunc_epilog(TCCState* S)
{ {
int v, saved_ind, d, large_ofs_ind; int v, saved_ind, d, large_ofs_ind;
@ -888,8 +888,8 @@ ST_FUNC void gfunc_epilog(TCCState *S)
gen_bounds_epilog(S); gen_bounds_epilog(S);
#endif #endif
S->loc = (S->loc - num_va_regs * 8); S->tccgen_loc = (S->tccgen_loc - num_va_regs * 8);
d = v = (-S->loc + 15) & -16; d = v = (-S->tccgen_loc + 15) & -16;
if (v >= (1 << 11)) { if (v >= (1 << 11)) {
d = 16; d = 16;
@ -901,7 +901,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
EI(S, 0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp) EI(S, 0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)
EI(S, 0x13, 0, 2, 2, d); // addi sp, sp, v EI(S, 0x13, 0, 2, 2, d); // addi sp, sp, v
EI(S, 0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret EI(S, 0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
large_ofs_ind = S->ind; large_ofs_ind = S->tccgen_ind;
if (v >= (1 << 11)) { if (v >= (1 << 11)) {
EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v) o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
@ -909,9 +909,9 @@ ST_FUNC void gfunc_epilog(TCCState *S)
ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0 ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0
gjmp_addr(S, func_sub_sp_offset + 5*4); gjmp_addr(S, func_sub_sp_offset + 5*4);
} }
saved_ind = S->ind; saved_ind = S->tccgen_ind;
S->ind = func_sub_sp_offset; S->tccgen_ind = func_sub_sp_offset;
EI(S, 0x13, 0, 2, 2, -d); // addi sp, sp, -d EI(S, 0x13, 0, 2, 2, -d); // addi sp, sp, -d
ES(S, 0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp) ES(S, 0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp)
ES(S, 0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp) ES(S, 0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp)
@ -919,18 +919,18 @@ ST_FUNC void gfunc_epilog(TCCState *S)
EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
else else
gjmp_addr(S, large_ofs_ind); gjmp_addr(S, large_ofs_ind);
if ((S->ind - func_sub_sp_offset) != 5*4) if ((S->tccgen_ind - func_sub_sp_offset) != 5*4)
EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop
S->ind = saved_ind; S->tccgen_ind = saved_ind;
} }
ST_FUNC void gen_va_start(TCCState *S) ST_FUNC void gen_va_start(TCCState *S)
{ {
S->vtop--; S->tccgen_vtop--;
vset(S, &S->char_pointer_type, VT_LOCAL, func_va_list_ofs); vset(S, &S->tccgen_char_pointer_type, VT_LOCAL, func_va_list_ofs);
} }
ST_FUNC void gen_fill_nops(TCCState *S, int bytes) ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
{ {
if ((bytes & 3)) if ((bytes & 3))
tcc_error(S, "alignment of code section not multiple of 4"); tcc_error(S, "alignment of code section not multiple of 4");
@ -941,18 +941,18 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
} }
// Generate forward branch to label: // Generate forward branch to label:
ST_FUNC int gjmp(TCCState *S, int t) ST_FUNC int gjmp(TCCState* S, int t)
{ {
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return t; return t;
o(S, t); o(S, t);
return S->ind - 4; return S->tccgen_ind - 4;
} }
// Generate branch to known address: // Generate branch to known address:
ST_FUNC void gjmp_addr(TCCState *S, int a) ST_FUNC void gjmp_addr(TCCState* S, int a)
{ {
uint32_t r = a - S->ind, imm; uint32_t r = a - S->tccgen_ind, imm;
if ((r + (1 << 21)) & ~((1U << 22) - 2)) { if ((r + (1 << 21)) & ~((1U << 22) - 2)) {
o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r) o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)
r = (int)r << 20 >> 20; r = (int)r << 20 >> 20;
@ -966,11 +966,11 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
} }
} }
ST_FUNC int gjmp_cond(TCCState *S, int op, int t) ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
{ {
int tmp; int tmp;
int a = S->vtop->cmp_r & 0xff; int a = S->tccgen_vtop->cmp_r & 0xff;
int b = (S->vtop->cmp_r >> 8) & 0xff; int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
switch (op) { switch (op) {
case TOK_ULT: op = 6; break; case TOK_ULT: op = 6; break;
case TOK_UGE: op = 7; break; case TOK_UGE: op = 7; break;
@ -987,7 +987,7 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
return gjmp(S, t); return gjmp(S, t);
} }
ST_FUNC int gjmp_append(TCCState *S, int n, int t) ST_FUNC int gjmp_append(TCCState* S, int n, int t)
{ {
void *p; void *p;
/* insert jump list n into t */ /* insert jump list n into t */
@ -1001,22 +1001,22 @@ ST_FUNC int gjmp_append(TCCState *S, int n, int t)
return t; return t;
} }
static void gen_opil(TCCState *S, int op, int ll) static void gen_opil(TCCState* S, int op, int ll)
{ {
int a, b, d; int a, b, d;
int func3 = 0; int func3 = 0;
ll = ll ? 0 : 8; ll = ll ? 0 : 8;
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
int fc = S->vtop->c.i; int fc = S->tccgen_vtop->c.i;
if (fc == S->vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) { if (fc == S->tccgen_vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
int cll = 0; int cll = 0;
int m = ll ? 31 : 63; int m = ll ? 31 : 63;
vswap(S); vswap(S);
gv(S, RC_INT); gv(S, RC_INT);
a = ireg(S->vtop[0].r); a = ireg(S->tccgen_vtop[0].r);
--S->vtop; --S->tccgen_vtop;
d = get_reg(S, RC_INT); d = get_reg(S, RC_INT);
++S->vtop; ++S->tccgen_vtop;
vswap(S); vswap(S);
switch (op) { switch (op) {
case '-': case '-':
@ -1028,12 +1028,12 @@ static void gen_opil(TCCState *S, int op, int ll)
cll = ll; cll = ll;
do_cop: do_cop:
EI(S, 0x13 | cll, func3, ireg(d), a, fc); EI(S, 0x13 | cll, func3, ireg(d), a, fc);
--S->vtop; --S->tccgen_vtop;
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
vset_VT_CMP(S, TOK_NE); vset_VT_CMP(S, TOK_NE);
S->vtop->cmp_r = ireg(d) | 0 << 8; S->tccgen_vtop->cmp_r = ireg(d) | 0 << 8;
} else } else
S->vtop[0].r = d; S->tccgen_vtop[0].r = d;
return; return;
case TOK_LE: case TOK_LE:
if (fc >= (1 << 11) - 1) if (fc >= (1 << 11) - 1)
@ -1057,33 +1057,33 @@ static void gen_opil(TCCState *S, int op, int ll)
case TOK_GE: /* -> TOK_LT */ case TOK_GE: /* -> TOK_LT */
case TOK_GT: /* -> TOK_LE */ case TOK_GT: /* -> TOK_LE */
gen_opil(S, op - 1, !ll); gen_opil(S, op - 1, !ll);
S->vtop->cmp_op ^= 1; S->tccgen_vtop->cmp_op ^= 1;
return; return;
case TOK_NE: case TOK_NE:
case TOK_EQ: case TOK_EQ:
if (fc) if (fc)
gen_opil(S, '-', !ll), a = ireg(S->vtop++->r); gen_opil(S, '-', !ll), a = ireg(S->tccgen_vtop++->r);
--S->vtop; --S->tccgen_vtop;
vset_VT_CMP(S, op); vset_VT_CMP(S, op);
S->vtop->cmp_r = a | 0 << 8; S->tccgen_vtop->cmp_r = a | 0 << 8;
return; return;
} }
} }
} }
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
a = ireg(S->vtop[-1].r); a = ireg(S->tccgen_vtop[-1].r);
b = ireg(S->vtop[0].r); b = ireg(S->tccgen_vtop[0].r);
S->vtop -= 2; S->tccgen_vtop -= 2;
d = get_reg(S, RC_INT); d = get_reg(S, RC_INT);
S->vtop++; S->tccgen_vtop++;
S->vtop[0].r = d; S->tccgen_vtop[0].r = d;
d = ireg(d); d = ireg(d);
switch (op) { switch (op) {
default: default:
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
vset_VT_CMP(S, op); vset_VT_CMP(S, op);
S->vtop->cmp_r = a | b << 8; S->tccgen_vtop->cmp_r = a | b << 8;
break; break;
} }
tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL)); tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL));
@ -1132,21 +1132,21 @@ static void gen_opil(TCCState *S, int op, int ll)
} }
} }
ST_FUNC void gen_opi(TCCState *S, int op) ST_FUNC void gen_opi(TCCState* S, int op)
{ {
gen_opil(S, op, 0); gen_opil(S, op, 0);
} }
ST_FUNC void gen_opl(TCCState *S, int op) ST_FUNC void gen_opl(TCCState* S, int op)
{ {
gen_opil(S, op, 1); gen_opil(S, op, 1);
} }
ST_FUNC void gen_opf(TCCState *S, int op) ST_FUNC void gen_opf(TCCState* S, int op)
{ {
int rs1, rs2, rd, dbl, invert; int rs1, rs2, rd, dbl, invert;
if (S->vtop[0].type.t == VT_LDOUBLE) { if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
CType type = S->vtop[0].type; CType type = S->tccgen_vtop[0].type;
int func = 0; int func = 0;
int cond = -1; int cond = -1;
switch (op) { switch (op) {
@ -1166,10 +1166,10 @@ ST_FUNC void gen_opf(TCCState *S, int op)
vrott(S, 3); vrott(S, 3);
gfunc_call(S, 2); gfunc_call(S, 2);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = REG_IRET; S->tccgen_vtop->r = REG_IRET;
S->vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST; S->tccgen_vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
if (cond < 0) if (cond < 0)
S->vtop->type = type; S->tccgen_vtop->type = type;
else { else {
vpushi(S, 0); vpushi(S, 0);
gen_opil(S, op, 1); gen_opil(S, op, 1);
@ -1178,11 +1178,11 @@ ST_FUNC void gen_opf(TCCState *S, int op)
} }
gv2(S, RC_FLOAT, RC_FLOAT); gv2(S, RC_FLOAT, RC_FLOAT);
assert(S->vtop->type.t == VT_DOUBLE || S->vtop->type.t == VT_FLOAT); assert(S->tccgen_vtop->type.t == VT_DOUBLE || S->tccgen_vtop->type.t == VT_FLOAT);
dbl = S->vtop->type.t == VT_DOUBLE; dbl = S->tccgen_vtop->type.t == VT_DOUBLE;
rs1 = freg(S->vtop[-1].r); rs1 = freg(S->tccgen_vtop[-1].r);
rs2 = freg(S->vtop->r); rs2 = freg(S->tccgen_vtop->r);
S->vtop--; S->tccgen_vtop--;
invert = 0; invert = 0;
switch(op) { switch(op) {
default: default:
@ -1191,7 +1191,7 @@ ST_FUNC void gen_opf(TCCState *S, int op)
op = 0; // fadd op = 0; // fadd
arithop: arithop:
rd = get_reg(S, RC_FLOAT); rd = get_reg(S, RC_FLOAT);
S->vtop->r = rd; S->tccgen_vtop->r = rd;
rd = freg(rd); rd = freg(rd);
ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm) ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)
break; break;
@ -1208,7 +1208,7 @@ ST_FUNC void gen_opf(TCCState *S, int op)
op = 2; // EQ op = 2; // EQ
cmpop: cmpop:
rd = get_reg(S, RC_INT); rd = get_reg(S, RC_INT);
S->vtop->r = rd; S->tccgen_vtop->r = rd;
rd = ireg(rd); rd = ireg(rd);
ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le) ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
if (invert) if (invert)
@ -1241,11 +1241,11 @@ ST_FUNC void gen_cvt_sxtw(TCCState *S)
Let's try to not do anything here. */ Let's try to not do anything here. */
} }
ST_FUNC void gen_cvt_itof(TCCState *S, int t) ST_FUNC void gen_cvt_itof(TCCState* S, int t)
{ {
int rr = ireg(gv(S, RC_INT)), dr; int rr = ireg(gv(S, RC_INT)), dr;
int u = S->vtop->type.t & VT_UNSIGNED; int u = S->tccgen_vtop->type.t & VT_UNSIGNED;
int l = (S->vtop->type.t & VT_BTYPE) == VT_LLONG; int l = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;
if (t == VT_LDOUBLE) { if (t == VT_LDOUBLE) {
int func = l ? int func = l ?
(u ? TOK___floatunditf : TOK___floatditf) : (u ? TOK___floatunditf : TOK___floatditf) :
@ -1254,22 +1254,22 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
vrott(S, 2); vrott(S, 2);
gfunc_call(S, 1); gfunc_call(S, 1);
vpushi(S, 0); vpushi(S, 0);
S->vtop->type.t = t; S->tccgen_vtop->type.t = t;
S->vtop->r = REG_IRET; S->tccgen_vtop->r = REG_IRET;
S->vtop->r2 = TREG_R(1); S->tccgen_vtop->r2 = TREG_R(1);
} else { } else {
S->vtop--; S->tccgen_vtop--;
dr = get_reg(S, RC_FLOAT); dr = get_reg(S, RC_FLOAT);
S->vtop++; S->tccgen_vtop++;
S->vtop->r = dr; S->tccgen_vtop->r = dr;
dr = freg(dr); dr = freg(dr);
EIu(S, 0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u] EIu(S, 0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u]
} }
} }
ST_FUNC void gen_cvt_ftoi(TCCState *S, int t) ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)
{ {
int ft = S->vtop->type.t & VT_BTYPE; int ft = S->tccgen_vtop->type.t & VT_BTYPE;
int l = (t & VT_BTYPE) == VT_LLONG; int l = (t & VT_BTYPE) == VT_LLONG;
int u = t & VT_UNSIGNED; int u = t & VT_UNSIGNED;
if (ft == VT_LDOUBLE) { if (ft == VT_LDOUBLE) {
@ -1280,22 +1280,22 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
vrott(S, 2); vrott(S, 2);
gfunc_call(S, 1); gfunc_call(S, 1);
vpushi(S, 0); vpushi(S, 0);
S->vtop->type.t = t; S->tccgen_vtop->type.t = t;
S->vtop->r = REG_IRET; S->tccgen_vtop->r = REG_IRET;
} else { } else {
int rr = freg(gv(S, RC_FLOAT)), dr; int rr = freg(gv(S, RC_FLOAT)), dr;
S->vtop--; S->tccgen_vtop--;
dr = get_reg(S, RC_INT); dr = get_reg(S, RC_INT);
S->vtop++; S->tccgen_vtop++;
S->vtop->r = dr; S->tccgen_vtop->r = dr;
dr = ireg(dr); dr = ireg(dr);
EIu(S, 0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz EIu(S, 0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz
} }
} }
ST_FUNC void gen_cvt_ftof(TCCState *S, int dt) ST_FUNC void gen_cvt_ftof(TCCState* S, int dt)
{ {
int st = S->vtop->type.t & VT_BTYPE, rs, rd; int st = S->tccgen_vtop->type.t & VT_BTYPE, rs, rd;
dt &= VT_BTYPE; dt &= VT_BTYPE;
if (st == dt) if (st == dt)
return; return;
@ -1312,21 +1312,21 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int dt)
gv(S, RC_F(0)); gv(S, RC_F(0));
else { else {
gv(S, RC_R(0)); gv(S, RC_R(0));
assert(S->vtop->r2 < 7); assert(S->tccgen_vtop->r2 < 7);
if (S->vtop->r2 != 1 + S->vtop->r) { if (S->tccgen_vtop->r2 != 1 + S->tccgen_vtop->r) {
EI(S, 0x13, 0, ireg(S->vtop->r) + 1, ireg(S->vtop->r2), 0); // mv Ra+1, RR2 EI(S, 0x13, 0, ireg(S->tccgen_vtop->r) + 1, ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
S->vtop->r2 = 1 + S->vtop->r; S->tccgen_vtop->r2 = 1 + S->tccgen_vtop->r;
} }
} }
vpush_helper_func(S, func); vpush_helper_func(S, func);
gcall_or_jmp(S, 1); gcall_or_jmp(S, 1);
S->vtop -= 2; S->tccgen_vtop -= 2;
vpushi(S, 0); vpushi(S, 0);
S->vtop->type.t = dt; S->tccgen_vtop->type.t = dt;
if (dt == VT_LDOUBLE) if (dt == VT_LDOUBLE)
S->vtop->r = REG_IRET, S->vtop->r2 = REG_IRET+1; S->tccgen_vtop->r = REG_IRET, S->tccgen_vtop->r2 = REG_IRET+1;
else else
S->vtop->r = REG_FRET; S->tccgen_vtop->r = REG_FRET;
} else { } else {
assert (dt == VT_FLOAT || dt == VT_DOUBLE); assert (dt == VT_FLOAT || dt == VT_DOUBLE);
assert (st == VT_FLOAT || st == VT_DOUBLE); assert (st == VT_FLOAT || st == VT_DOUBLE);
@ -1336,59 +1336,59 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int dt)
EI(S, 0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm) EI(S, 0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm)
else else
EI(S, 0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm) EI(S, 0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm)
S->vtop->r = rd; S->tccgen_vtop->r = rd;
} }
} }
/* increment tcov counter */ /* increment tcov counter */
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv) ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
{ {
int r1, r2; int r1, r2;
Sym label = {0}; Sym label = {0};
label.type.t = VT_VOID | VT_STATIC; label.type.t = VT_VOID | VT_STATIC;
vpushv(S, sv); vpushv(S, sv);
S->vtop->r = r1 = get_reg(S, RC_INT); S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
r2 = get_reg(S, RC_INT); r2 = get_reg(S, RC_INT);
r1 = ireg(r1); r1 = ireg(r1);
r2 = ireg(r2); r2 = ireg(r2);
greloca(S, cur_text_section, sv->sym, S->ind, R_RISCV_PCREL_HI20, 0); greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);
put_extern_sym(S, &label, cur_text_section, S->ind, 0); put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym) o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_I, 0); greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
EI(S, 0x03, 3, r2, r1, 0); // ld r2, x[r1] EI(S, 0x03, 3, r2, r1, 0); // ld r2, x[r1]
EI(S, 0x13, 0, r2, r2, 1); // addi r2, r2, #1 EI(S, 0x13, 0, r2, r2, 1); // addi r2, r2, #1
greloca(S, cur_text_section, sv->sym, S->ind, R_RISCV_PCREL_HI20, 0); greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);
label.c = 0; /* force new local ELF symbol */ label.c = 0; /* force new local ELF symbol */
put_extern_sym(S, &label, cur_text_section, S->ind, 0); put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym) o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_S, 0); greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_S, 0);
ES(S, 0x23, 3, r1, r2, 0); // sd r2, [r1] ES(S, 0x23, 3, r1, r2, 0); // sd r2, [r1]
vpop(S); vpop(S);
} }
ST_FUNC void ggoto(TCCState *S) ST_FUNC void ggoto(TCCState* S)
{ {
gcall_or_jmp(S, 0); gcall_or_jmp(S, 0);
S->vtop--; S->tccgen_vtop--;
} }
ST_FUNC void gen_vla_sp_save(TCCState *S, int addr) ST_FUNC void gen_vla_sp_save(TCCState* S, int addr)
{ {
ES(S, 0x23, 3, 8, 2, addr); // sd sp, fc(s0) ES(S, 0x23, 3, 8, 2, addr); // sd sp, fc(s0)
} }
ST_FUNC void gen_vla_sp_restore(TCCState *S, int addr) ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr)
{ {
EI(S, 0x03, 3, 2, 8, addr); // ld sp, fc(s0) EI(S, 0x03, 3, 2, 8, addr); // ld sp, fc(s0)
} }
ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align)
{ {
int rr; int rr;
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check) if (S->do_bounds_check)
vpushv(S, S->vtop); vpushv(S, S->tccgen_vtop);
#endif #endif
rr = ireg(gv(S, RC_INT)); rr = ireg(gv(S, RC_INT));
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
@ -1403,7 +1403,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align)
#if defined(CONFIG_TCC_BCHECK) #if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check) { if (S->do_bounds_check) {
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = TREG_R(0); S->tccgen_vtop->r = TREG_R(0);
o(S, 0x00010513); /* mv a0,sp */ o(S, 0x00010513); /* mv a0,sp */
vswap(S); vswap(S);
vpush_helper_func(S, TOK___bound_new_region); vpush_helper_func(S, TOK___bound_new_region);

323
tcc.h
View file

@ -1074,21 +1074,21 @@ struct TCCState {
/* ------------ tccpp.c ------------ */ /* ------------ tccpp.c ------------ */
struct BufferedFile *tccpp_file; struct BufferedFile *tccpp_file;
int tccpp_ch, tok; int tccpp_ch, tccpp_tok;
CValue tokc; CValue tccpp_tokc;
const int *tccpp_macro_ptr; const int *tccpp_macro_ptr;
int tccpp_parse_flags; int tccpp_parse_flags;
int tok_flags; int tccpp_tok_flags;
CString tokcstr; /* current parsed string, if any */ CString tccpp_tokcstr; /* current parsed string, if any */
CString tccpp_cstr_buf; CString tccpp_cstr_buf;
CString tccpp_macro_equal_buf; CString tccpp_macro_equal_buf;
TokenString tokstr_buf; TokenString tccpp_tokstr_buf;
TokenString *tccpp_macro_stack; TokenString *tccpp_macro_stack;
/* display benchmark infos */ /* display benchmark infos */
int tccpp_total_lines; int tccpp_total_lines;
int tccpp_total_bytes; int tccpp_total_bytes;
int tok_ident; int tccpp_tok_ident;
TokenSym **tccpp_table_ident; TokenSym **tccpp_table_ident;
int *tccpp_macro_ptr_allocated; int *tccpp_macro_ptr_allocated;
@ -1096,7 +1096,7 @@ struct TCCState {
int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1]; int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1];
int tccpp_unget_buffer_enabled; int tccpp_unget_buffer_enabled;
TokenSym *tccpp_hash_ident[TOK_HASH_SIZE]; TokenSym *tccpp_hash_ident[TOK_HASH_SIZE];
char token_buf[STRING_MAX_SIZE + 1]; char tccpp_token_buf[STRING_MAX_SIZE + 1];
/* true if isid(c) || isnum(c) */ /* true if isid(c) || isnum(c) */
unsigned char tccpp_isidnum_table[256-CH_EOF]; unsigned char tccpp_isidnum_table[256-CH_EOF];
@ -1105,8 +1105,8 @@ struct TCCState {
int tccpp_pp_expr; int tccpp_pp_expr;
int tccpp_pp_counter; int tccpp_pp_counter;
TinyAlloc *toksym_alloc; TinyAlloc *tccpp_toksym_alloc;
TinyAlloc *tokstr_alloc; TinyAlloc *tccpp_tokstr_alloc;
/*----------- tccasm.c --------*/ /*----------- tccasm.c --------*/
Section *tccasm_last_text_section; /* to handle .previous asm directive */ Section *tccasm_last_text_section; /* to handle .previous asm directive */
@ -1114,18 +1114,18 @@ struct TCCState {
/* ------------ tccgen.c ------------ */ /* ------------ tccgen.c ------------ */
Sym *tccgen_global_stack; Sym *tccgen_global_stack;
Sym *local_stack; Sym *tccgen_local_stack;
Sym *local_label_stack; Sym *tccgen_local_label_stack;
Sym *tccgen_global_label_stack; Sym *tccgen_global_label_stack;
Sym *tccgen_define_stack; Sym *tccgen_define_stack;
CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, char_pointer_type; CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, tccgen_char_pointer_type;
SValue *vtop; SValue *tccgen_vtop;
SValue tccgen__vstack[1 + VSTACK_SIZE]; SValue tccgen__vstack[1 + VSTACK_SIZE];
int tccgen_rsym, tccgen_anon_sym, ind, loc; int tccgen_rsym, tccgen_anon_sym, tccgen_ind, tccgen_loc;
char tccgen_debug_modes; char tccgen_debug_modes;
int tccgen_const_wanted; /* true if constant wanted */ int tccgen_const_wanted; /* true if constant wanted */
int nocode_wanted; /* true if no code generation wanted for an expression */ int tccgen_nocode_wanted; /* true if no code generation wanted for an expression */
int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
CType tccgen_func_vt; /* current function return type (used by return instruction) */ CType tccgen_func_vt; /* current function return type (used by return instruction) */
int tccgen_func_var; /* true if current function is variadic */ int tccgen_func_var; /* true if current function is variadic */
@ -1136,7 +1136,7 @@ struct TCCState {
void **tccgen_sym_pools; void **tccgen_sym_pools;
int tccgen_nb_sym_pools; int tccgen_nb_sym_pools;
Sym *tccgen_all_cleanups, *tccgen_pending_gotos; Sym *tccgen_all_cleanups, *tccgen_pending_gotos;
int local_scope; int tccgen_local_scope;
int tccgen_in_sizeof; int tccgen_in_sizeof;
int tccgen_in_generic; int tccgen_in_generic;
int tccgen_section_sym; int tccgen_section_sym;
@ -1155,7 +1155,7 @@ struct TCCState {
int tccgen_debug_next_type; int tccgen_debug_next_type;
debug_hash_t *tccgen_debug_hash; debug_hash_t *tccgen_debug_hash;
int tccgen_n_debug_hash; int tccgen_n_debug_hash;
debug_info_t *debug_info, *debug_info_root; debug_info_t *tccgen_debug_info, *tccgen_debug_info_root;
unsigned char tccgen_prec[256]; unsigned char tccgen_prec[256];
@ -1374,22 +1374,22 @@ PUB_FUNC void tcc_free_base(void *ptr);
PUB_FUNC void *tcc_malloc_base(unsigned long size); PUB_FUNC void *tcc_malloc_base(unsigned long size);
PUB_FUNC void *tcc_mallocz_base(unsigned long size); PUB_FUNC void *tcc_mallocz_base(unsigned long size);
#ifndef MEM_DEBUG #ifndef MEM_DEBUG
PUB_FUNC void tcc_free(TCCState *S, void *ptr); PUB_FUNC void tcc_free(TCCState* S, void *ptr);
PUB_FUNC void *tcc_malloc(TCCState *S, unsigned long size); PUB_FUNC void *tcc_malloc(TCCState* S, unsigned long size);
PUB_FUNC void *tcc_mallocz(TCCState *S, unsigned long size); PUB_FUNC void *tcc_mallocz(TCCState* S, unsigned long size);
PUB_FUNC void *tcc_realloc(TCCState *S, void *ptr, unsigned long size); PUB_FUNC void *tcc_realloc(TCCState* S, void *ptr, unsigned long size);
PUB_FUNC char *tcc_strdup(TCCState *S, const char *str); PUB_FUNC char *tcc_strdup(TCCState* S, const char *str);
#else #else
#define tcc_free(s, ptr) tcc_free_debug(s, ptr) #define tcc_free(s, ptr) tcc_free_debug(s, ptr)
#define tcc_malloc(s, size) tcc_malloc_debug(s, size, __FILE__, __LINE__) #define tcc_malloc(s, size) tcc_malloc_debug(s, size, __FILE__, __LINE__)
#define tcc_mallocz(s, size) tcc_mallocz_debug(s, size, __FILE__, __LINE__) #define tcc_mallocz(s, size) tcc_mallocz_debug(s, size, __FILE__, __LINE__)
#define tcc_realloc(s, ptr, size) tcc_realloc_debug(s, ptr, size, __FILE__, __LINE__) #define tcc_realloc(s, ptr, size) tcc_realloc_debug(s, ptr, size, __FILE__, __LINE__)
#define tcc_strdup(s, str) tcc_strdup_debug(s, str, __FILE__, __LINE__) #define tcc_strdup(s, str) tcc_strdup_debug(s, str, __FILE__, __LINE__)
PUB_FUNC void tcc_free_debug(TCCState *S, void *ptr); PUB_FUNC void tcc_free_debug(TCCState* S, void *ptr);
PUB_FUNC void *tcc_malloc_debug(TCCState *S, unsigned long size, const char *file, int line); PUB_FUNC void *tcc_malloc_debug(TCCState* S, unsigned long size, const char *file, int line);
PUB_FUNC void *tcc_mallocz_debug(TCCState *S, unsigned long size, const char *file, int line); PUB_FUNC void *tcc_mallocz_debug(TCCState* S, unsigned long size, const char *file, int line);
PUB_FUNC void *tcc_realloc_debug(TCCState *S, void *ptr, unsigned long size, const char *file, int line); PUB_FUNC void *tcc_realloc_debug(TCCState* S, void *ptr, unsigned long size, const char *file, int line);
PUB_FUNC char *tcc_strdup_debug(TCCState *S, const char *str, const char *file, int line); PUB_FUNC char *tcc_strdup_debug(TCCState* S, const char *str, const char *file, int line);
#endif #endif
#define free(p) use_tcc_free(S, p) #define free(p) use_tcc_free(S, p)
@ -1397,22 +1397,22 @@ PUB_FUNC char *tcc_strdup_debug(TCCState *S, const char *str, const char *file,
#define realloc(p, s) use_tcc_realloc(S, p, s) #define realloc(p, s) use_tcc_realloc(S, p, s)
#undef strdup #undef strdup
#define strdup(s) use_tcc_strdup(S, s) #define strdup(s) use_tcc_strdup(S, s)
PUB_FUNC void _tcc_error_noabort(TCCState *S, const char *fmt, ...) PRINTF_LIKE(2,3); PUB_FUNC void _tcc_error_noabort(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);
PUB_FUNC NORETURN void _tcc_error(TCCState *S, const char *fmt, ...) PRINTF_LIKE(2,3); PUB_FUNC NORETURN void _tcc_error(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);
PUB_FUNC void _tcc_warning(TCCState *S, const char *fmt, ...) PRINTF_LIKE(2,3); PUB_FUNC void _tcc_warning(TCCState* S, const char *fmt, ...) PRINTF_LIKE(2,3);
#define tcc_internal_error(S, msg) tcc_error(S, "internal compiler error\n"\ #define tcc_internal_error(S, msg) tcc_error(S, "internal compiler error\n"\
"%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__) "%s:%d: in %s(): " msg, __FILE__,__LINE__,__FUNCTION__)
/* other utilities */ /* other utilities */
ST_FUNC void dynarray_add(TCCState *S, void *ptab, int *nb_ptr, void *data); ST_FUNC void dynarray_add(TCCState* S, void *ptab, int *nb_ptr, void *data);
ST_FUNC void dynarray_reset(TCCState *S, void *pp, int *n); ST_FUNC void dynarray_reset(TCCState* S, void *pp, int *n);
ST_INLN void cstr_ccat(TCCState *S, CString *cstr, int ch); ST_INLN void cstr_ccat(TCCState* S, CString *cstr, int ch);
ST_FUNC void cstr_cat(TCCState *S, CString *cstr, const char *str, int len); ST_FUNC void cstr_cat(TCCState* S, CString *cstr, const char *str, int len);
ST_FUNC void cstr_wccat(TCCState *S, CString *cstr, int ch); ST_FUNC void cstr_wccat(TCCState* S, CString *cstr, int ch);
ST_FUNC void cstr_new(TCCState *S, CString *cstr); ST_FUNC void cstr_new(TCCState* S, CString *cstr);
ST_FUNC void cstr_free(TCCState *S, CString *cstr); ST_FUNC void cstr_free(TCCState* S, CString *cstr);
ST_FUNC int cstr_printf(TCCState *S, CString *cs, const char *fmt, ...) PRINTF_LIKE(3,4); ST_FUNC int cstr_printf(TCCState* S, CString *cs, const char *fmt, ...) PRINTF_LIKE(3,4);
ST_FUNC int cstr_vprintf(TCCState *S, CString *cstr, const char *fmt, va_list ap); ST_FUNC int cstr_vprintf(TCCState* S, CString *cstr, const char *fmt, va_list ap);
ST_FUNC void cstr_reset(CString *cstr); ST_FUNC void cstr_reset(CString *cstr);
ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen); ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen);
@ -1499,36 +1499,36 @@ enum line_macro_output_format {
LINE_MACRO_OUTPUT_FORMAT_P10 = 11 LINE_MACRO_OUTPUT_FORMAT_P10 = 11
}; };
ST_FUNC TokenSym *tok_alloc(TCCState *S, const char *str, int len); ST_FUNC TokenSym *tok_alloc(TCCState* S, const char *str, int len);
ST_FUNC int tok_alloc_const(TCCState *S, const char *str); ST_FUNC int tok_alloc_const(TCCState* S, const char *str);
ST_FUNC const char *get_tok_str(TCCState *S, int v, CValue *cv); ST_FUNC const char *get_tok_str(TCCState* S, int v, CValue *cv);
ST_FUNC void begin_macro(TCCState *S, TokenString *str, int alloc); ST_FUNC void begin_macro(TCCState* S, TokenString *str, int alloc);
ST_FUNC void end_macro(TCCState *S); ST_FUNC void end_macro(TCCState* S);
ST_FUNC int set_idnum(TCCState *S, int c, int val); ST_FUNC int set_idnum(TCCState* S, int c, int val);
ST_INLN void tok_str_new(TokenString *s); ST_INLN void tok_str_new(TokenString *s);
ST_FUNC TokenString *tok_str_alloc(TCCState *S); ST_FUNC TokenString *tok_str_alloc(TCCState* S);
ST_FUNC void tok_str_free(TCCState *S, TokenString *s); ST_FUNC void tok_str_free(TCCState* S, TokenString *s);
ST_FUNC void tok_str_free_str(TCCState *S, int *str); ST_FUNC void tok_str_free_str(TCCState* S, int *str);
ST_FUNC void tok_str_add(TCCState *S, TokenString *s, int t); ST_FUNC void tok_str_add(TCCState* S, TokenString *s, int t);
ST_FUNC void tok_str_add_tok(TCCState *S, TokenString *s); ST_FUNC void tok_str_add_tok(TCCState* S, TokenString *s);
ST_INLN void define_push(TCCState *S, int v, int macro_type, int *str, Sym *first_arg); ST_INLN void define_push(TCCState* S, int v, int macro_type, int *str, Sym *first_arg);
ST_FUNC void define_undef(TCCState *S, Sym *s); ST_FUNC void define_undef(TCCState* S, Sym *s);
ST_INLN Sym *define_find(TCCState *S, int v); ST_INLN Sym *define_find(TCCState* S, int v);
ST_FUNC void free_defines(TCCState *S, Sym *b); ST_FUNC void free_defines(TCCState* S, Sym *b);
ST_FUNC Sym *label_find(TCCState *S, int v); ST_FUNC Sym *label_find(TCCState* S, int v);
ST_FUNC Sym *label_push(TCCState *S, Sym **ptop, int v, int flags); ST_FUNC Sym *label_push(TCCState* S, Sym **ptop, int v, int flags);
ST_FUNC void label_pop(TCCState *S, Sym **ptop, Sym *slast, int keep); ST_FUNC void label_pop(TCCState* S, Sym **ptop, Sym *slast, int keep);
ST_FUNC void parse_define(TCCState *S); ST_FUNC void parse_define(TCCState* S);
ST_FUNC void preprocess(TCCState *S, int is_bof); ST_FUNC void preprocess(TCCState* S, int is_bof);
ST_FUNC void next(TCCState *S); ST_FUNC void next(TCCState* S);
ST_INLN void unget_tok(TCCState *S, int last_tok); ST_INLN void unget_tok(TCCState* S, int last_tok);
ST_FUNC void preprocess_start(TCCState *S, int filetype); ST_FUNC void preprocess_start(TCCState *S, int filetype);
ST_FUNC void preprocess_end(TCCState *S); ST_FUNC void preprocess_end(TCCState *S);
ST_FUNC void tccpp_new(TCCState *S); ST_FUNC void tccpp_new(TCCState *S);
ST_FUNC void tccpp_delete(TCCState *S); ST_FUNC void tccpp_delete(TCCState *S);
ST_FUNC int tcc_preprocess(TCCState *S); ST_FUNC int tcc_preprocess(TCCState *S);
ST_FUNC void skip(TCCState *S, int c); ST_FUNC void skip(TCCState* S, int c);
ST_FUNC NORETURN void expect(TCCState *S, const char *msg); ST_FUNC NORETURN void expect(TCCState* S, const char *msg);
/* space excluding newline */ /* space excluding newline */
static inline int is_space(int ch) { static inline int is_space(int ch) {
@ -1559,76 +1559,77 @@ ST_FUNC void tcc_debug_putfile(TCCState *S, const char *filename);
ST_FUNC void tccgen_init(TCCState *S); ST_FUNC void tccgen_init(TCCState *S);
ST_FUNC int tccgen_compile(TCCState *S); ST_FUNC int tccgen_compile(TCCState *S);
ST_FUNC void tccgen_finish(TCCState *S); ST_FUNC void tccgen_finish(TCCState *S);
ST_FUNC void check_vstack(TCCState *S); ST_FUNC void check_vstack(TCCState* S);
ST_INLN int is_float(int t); ST_INLN int is_float(int t);
ST_FUNC int ieee_finite(double d); ST_FUNC int ieee_finite(double d);
ST_FUNC int exact_log2p1(int i); ST_FUNC int exact_log2p1(int i);
ST_FUNC void test_lvalue(TCCState *S); ST_FUNC void test_lvalue(TCCState* S);
ST_FUNC ElfSym *elfsym(TCCState *S, Sym *); ST_FUNC ElfSym *elfsym(TCCState* S, Sym *);
ST_FUNC void update_storage(TCCState *S, Sym *sym); ST_FUNC void update_storage(TCCState* S, Sym *sym);
ST_FUNC void put_extern_sym2(TCCState *S, Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore); ST_FUNC void put_extern_sym2(TCCState* S, Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
ST_FUNC void put_extern_sym(TCCState *S, Sym *sym, Section *section, addr_t value, unsigned long size); ST_FUNC void put_extern_sym(TCCState* S, Sym *sym, Section *section, addr_t value, unsigned long size);
#if PTR_SIZE == 4 #if PTR_SIZE == 4
ST_FUNC void greloc(TCCState *S, Section *s, Sym *sym, unsigned long offset, int type); ST_FUNC void greloc(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type);
#endif #endif
ST_FUNC void greloca(TCCState *S, Section *s, Sym *sym, unsigned long offset, int type, addr_t addend); ST_FUNC void greloca(TCCState* S, Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
ST_INLN void sym_free(TCCState *S, Sym *sym); ST_INLN void sym_free(TCCState* S, Sym *sym);
ST_FUNC Sym *sym_push(TCCState *S, int v, CType *type, int r, int c); ST_FUNC Sym *sym_push(TCCState* S, int v, CType *type, int r, int c);
ST_FUNC void sym_pop(TCCState *S, Sym **ptop, Sym *b, int keep); ST_FUNC void sym_pop(TCCState* S, Sym **ptop, Sym *b, int keep);
ST_FUNC Sym *sym_push2(TCCState *S, Sym **ps, int v, int t, int c); ST_FUNC Sym *sym_push2(TCCState* S, Sym **ps, int v, int t, int c);
ST_FUNC Sym *sym_find2(Sym *s, int v); ST_FUNC Sym *sym_find2(Sym *s, int v);
ST_INLN Sym *sym_find(TCCState *S, int v); ST_INLN Sym *sym_find(TCCState* S, int v);
ST_INLN Sym *struct_find(TCCState *S, int v); ST_INLN Sym *struct_find(TCCState* S, int v);
ST_FUNC Sym *global_identifier_push(TCCState *S, int v, int t, int c); ST_FUNC Sym *global_identifier_push(TCCState* S, int v, int t, int c);
ST_FUNC Sym *external_global_sym(TCCState *S, int v, CType *type); ST_FUNC Sym *external_global_sym(TCCState* S, int v, CType *type);
ST_FUNC Sym *external_helper_sym(TCCState *S, int v); ST_FUNC Sym *external_helper_sym(TCCState* S, int v);
ST_FUNC void vpush_helper_func(TCCState *S, int v); ST_FUNC void vpush_helper_func(TCCState* S, int v);
ST_FUNC void vset(TCCState *S, CType *type, int r, int v); ST_FUNC void vset(TCCState* S, CType *type, int r, int v);
ST_FUNC void vset_VT_CMP(TCCState *S, int op); ST_FUNC void vset_VT_CMP(TCCState* S, int op);
ST_FUNC void vpushi(TCCState *S, int v); ST_FUNC void vpushi(TCCState* S, int v);
ST_FUNC void vpushv(TCCState *S, SValue *v); ST_FUNC void vpushv(TCCState* S, SValue *v);
ST_FUNC void vpushsym(TCCState *S, CType *type, Sym *sym); ST_FUNC void vpushsym(TCCState* S, CType *type, Sym *sym);
ST_FUNC void vswap(TCCState *S); ST_FUNC void vswap(TCCState* S);
ST_FUNC void vrote(TCCState *S, SValue *e, int n); ST_FUNC void vrote(TCCState* S, SValue *e, int n);
ST_FUNC void vrott(TCCState *S, int n); ST_FUNC void vrott(TCCState* S, int n);
ST_FUNC void vrotb(TCCState *S, int n); ST_FUNC void vrotb(TCCState* S, int n);
ST_FUNC void vpop(TCCState *S); ST_FUNC void vpop(TCCState* S);
#if PTR_SIZE == 4 #if PTR_SIZE == 4
ST_FUNC void lexpand(TCCState *S); ST_FUNC void lexpand(TCCState* S);
#endif #endif
#ifdef TCC_TARGET_ARM #ifdef TCC_TARGET_ARM
ST_FUNC int get_reg_ex(TCCState *S, int rc, int rc2); ST_FUNC int get_reg_ex(TCCState* S, int rc, int rc2);
#endif #endif
ST_FUNC void save_reg(TCCState *S, int r); ST_FUNC void save_reg(TCCState* S, int r);
ST_FUNC void save_reg_upstack(TCCState *S, int r, int n); ST_FUNC void save_reg_upstack(TCCState* S, int r, int n);
ST_FUNC int get_reg(TCCState *S, int rc); ST_FUNC int get_reg(TCCState* S, int rc);
ST_FUNC void save_regs(TCCState *S, int n); ST_FUNC void save_regs(TCCState* S, int n);
ST_FUNC void gaddrof(TCCState *S); ST_FUNC void gaddrof(TCCState* S);
ST_FUNC int gv(TCCState *S, int rc); ST_FUNC int gv(TCCState* S, int rc);
ST_FUNC void gv2(TCCState *S, int rc1, int rc2); ST_FUNC void gv2(TCCState* S, int rc1, int rc2);
ST_FUNC void gen_op(TCCState *S, int op); ST_FUNC void gen_op(TCCState* S, int op);
ST_FUNC int type_size(CType *type, int *a); ST_FUNC int type_size(CType *type, int *a);
ST_FUNC void mk_pointer(TCCState *S, CType *type); ST_FUNC void mk_pointer(TCCState* S, CType *type);
ST_FUNC void vstore(TCCState *S); ST_FUNC void vstore(TCCState* S);
ST_FUNC void inc(TCCState *S, int post, int c); ST_FUNC void inc(TCCState* S, int post, int c);
ST_FUNC void parse_mult_str (TCCState *S, CString *astr, const char *msg); ST_FUNC void parse_mult_str (TCCState* S, CString *astr, const char *msg);
ST_FUNC void parse_asm_str(TCCState *S, CString *astr); ST_FUNC void parse_asm_str(TCCState* S, CString *astr);
ST_FUNC void indir(TCCState *S); ST_FUNC void indir(TCCState* S);
ST_FUNC void unary(TCCState *S); ST_FUNC void unary(TCCState* S);
ST_FUNC void gexpr(TCCState *S); ST_FUNC void gexpr(TCCState* S);
ST_FUNC int expr_const(TCCState *S); ST_FUNC int expr_const(TCCState* S);
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67 #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
ST_FUNC Sym *get_sym_ref(TCCState *S, CType *type, Section *sec, unsigned long offset, unsigned long size); ST_FUNC Sym *get_sym_ref(TCCState* S, CType *type, Section *sec, unsigned long offset, unsigned long size);
#endif #endif
#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE #if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
ST_FUNC int classify_x86_64_va_arg(CType *ty); ST_FUNC int classify_x86_64_va_arg(CType *ty);
#endif #endif
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
ST_FUNC void gbound_args(TCCState *S, int nb_args); ST_FUNC void gbound_args(TCCState* S, int nb_args);
ST_DATA int func_bound_add_epilog;
#endif #endif
/* ------------ tccelf.c ------------ */ /* ------------ tccelf.c ------------ */
@ -1656,14 +1657,14 @@ ST_FUNC void tccelf_end_file(TCCState *S);
ST_FUNC void tccelf_bounds_new(TCCState *S); ST_FUNC void tccelf_bounds_new(TCCState *S);
#endif #endif
ST_FUNC Section *new_section(TCCState *S, const char *name, int sh_type, int sh_flags); ST_FUNC Section *new_section(TCCState *S, const char *name, int sh_type, int sh_flags);
ST_FUNC void section_realloc(TCCState *S, Section *sec, unsigned long new_size); ST_FUNC void section_realloc(TCCState* S, Section *sec, unsigned long new_size);
ST_FUNC size_t section_add(TCCState *S, Section *sec, addr_t size, int align); ST_FUNC size_t section_add(TCCState* S, Section *sec, addr_t size, int align);
ST_FUNC void *section_ptr_add(TCCState *S, Section *sec, addr_t size); ST_FUNC void *section_ptr_add(TCCState* S, Section *sec, addr_t size);
ST_FUNC Section *find_section(TCCState *S, const char *name); ST_FUNC Section *find_section(TCCState *S, const char *name);
ST_FUNC Section *new_symtab(TCCState *S, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); ST_FUNC Section *new_symtab(TCCState *S, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
ST_FUNC int put_elf_str(TCCState *S, Section *s, const char *sym); ST_FUNC int put_elf_str(TCCState* S, Section *s, const char *sym);
ST_FUNC int put_elf_sym(TCCState *S, Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); ST_FUNC int put_elf_sym(TCCState* S, Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
ST_FUNC int set_elf_sym(Section *S, addr_t value, unsigned long size, int info, int other, int shndx, const char *name); ST_FUNC int set_elf_sym(Section *S, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
ST_FUNC int find_elf_sym(Section *S, const char *name); ST_FUNC int find_elf_sym(Section *S, const char *name);
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
@ -1678,7 +1679,7 @@ ST_FUNC void relocate_syms(TCCState *S, Section *symtab, int do_resolve);
ST_FUNC void relocate_sections(TCCState *S); ST_FUNC void relocate_sections(TCCState *S);
ST_FUNC ssize_t full_read(int fd, void *buf, size_t count); ST_FUNC ssize_t full_read(int fd, void *buf, size_t count);
ST_FUNC void *load_data(TCCState *S, int fd, unsigned long file_offset, unsigned long size); ST_FUNC void *load_data(TCCState* S, int fd, unsigned long file_offset, unsigned long size);
ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h); ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
ST_FUNC int tcc_load_object_file(TCCState *S, int fd, unsigned long file_offset); ST_FUNC int tcc_load_object_file(TCCState *S, int fd, unsigned long file_offset);
ST_FUNC int tcc_load_archive(TCCState *S, int fd, int alacarte); ST_FUNC int tcc_load_archive(TCCState *S, int fd, int alacarte);
@ -1732,31 +1733,31 @@ ST_FUNC void relocate(TCCState *S, ElfW_Rel *rel, int type, unsigned char *ptr,
ST_DATA const char * const target_machine_defs; ST_DATA const char * const target_machine_defs;
ST_DATA const int reg_classes[NB_REGS]; ST_DATA const int reg_classes[NB_REGS];
ST_FUNC void gsym_addr(TCCState *S, int t, int a); ST_FUNC void gsym_addr(TCCState* S, int t, int a);
ST_FUNC void gsym(TCCState *S, int t); ST_FUNC void gsym(TCCState* S, int t);
ST_FUNC void load(TCCState *S, int r, SValue *sv); ST_FUNC void load(TCCState *S, int r, SValue *sv);
ST_FUNC void store(TCCState *S, int r, SValue *v); ST_FUNC void store(TCCState *S, int r, SValue *v);
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize); ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
ST_FUNC void gfunc_call(TCCState *S, int nb_args); ST_FUNC void gfunc_call(TCCState *S, int nb_args);
ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym); ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym);
ST_FUNC void gfunc_epilog(TCCState *S); ST_FUNC void gfunc_epilog(TCCState *S);
ST_FUNC void gen_fill_nops(TCCState *S, int); ST_FUNC void gen_fill_nops(TCCState* S, int);
ST_FUNC int gjmp(TCCState *S, int t); ST_FUNC int gjmp(TCCState* S, int t);
ST_FUNC void gjmp_addr(TCCState *S, int a); ST_FUNC void gjmp_addr(TCCState* S, int a);
ST_FUNC int gjmp_cond(TCCState *S, int op, int t); ST_FUNC int gjmp_cond(TCCState* S, int op, int t);
ST_FUNC int gjmp_append(TCCState *S, int n, int t); ST_FUNC int gjmp_append(TCCState *S, int n, int t);
ST_FUNC void gen_opi(TCCState *S, int op); ST_FUNC void gen_opi(TCCState* S, int op);
ST_FUNC void gen_opf(TCCState *S, int op); ST_FUNC void gen_opf(TCCState* S, int op);
ST_FUNC void gen_cvt_ftoi(TCCState *S, int t); ST_FUNC void gen_cvt_ftoi(TCCState *S, int t);
ST_FUNC void gen_cvt_itof(TCCState *S, int t); ST_FUNC void gen_cvt_itof(TCCState *S, int t);
ST_FUNC void gen_cvt_ftof(TCCState *S, int t); ST_FUNC void gen_cvt_ftof(TCCState *S, int t);
ST_FUNC void ggoto(TCCState *S); ST_FUNC void ggoto(TCCState *S);
#ifndef TCC_TARGET_C67 #ifndef TCC_TARGET_C67
ST_FUNC void o(TCCState *S, unsigned int c); ST_FUNC void o(TCCState* S, unsigned int c);
#endif #endif
ST_FUNC void gen_vla_sp_save(TCCState *S, int addr); ST_FUNC void gen_vla_sp_save(TCCState* S, int addr);
ST_FUNC void gen_vla_sp_restore(TCCState *S, int addr); ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr);
ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align); ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align);
static inline uint16_t read16le(unsigned char *p) { static inline uint16_t read16le(unsigned char *p) {
return p[0] | (uint16_t)p[1] << 8; return p[0] | (uint16_t)p[1] << 8;
@ -1785,26 +1786,26 @@ static inline void add64le(unsigned char *p, int64_t x) {
/* ------------ i386-gen.c ------------ */ /* ------------ i386-gen.c ------------ */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM
ST_FUNC void g(TCCState *S, int c); ST_FUNC void g(TCCState* S, int c);
ST_FUNC void gen_le16(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 gen_le32(TCCState* S, int c);
#endif #endif
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC void gen_addr32(TCCState *S, int r, Sym *sym, int c); ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c);
ST_FUNC void gen_addrpc32(TCCState *S, int r, Sym *sym, int c); ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c);
ST_FUNC void gen_cvt_csti(TCCState *S, int t); ST_FUNC void gen_cvt_csti(TCCState* S, int t);
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv); ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
#endif #endif
/* ------------ x86_64-gen.c ------------ */ /* ------------ x86_64-gen.c ------------ */
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
ST_FUNC void gen_addr64(TCCState *S, int r, Sym *sym, int64_t c); ST_FUNC void gen_addr64(TCCState* S, int r, Sym *sym, int64_t c);
ST_FUNC void gen_opl(TCCState *S, int op); ST_FUNC void gen_opl(TCCState* S, int op);
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
ST_FUNC void gen_vla_result(TCCState *S, int addr); ST_FUNC void gen_vla_result(TCCState* S, int addr);
#endif #endif
ST_FUNC void gen_cvt_sxtw(TCCState *S); ST_FUNC void gen_cvt_sxtw(TCCState *S);
ST_FUNC void gen_cvt_csti(TCCState *S, int t); ST_FUNC void gen_cvt_csti(TCCState* S, int t);
#endif #endif
/* ------------ arm-gen.c ------------ */ /* ------------ arm-gen.c ------------ */
@ -1813,29 +1814,29 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t);
PUB_FUNC const char *default_elfinterp(TCCState *S); PUB_FUNC const char *default_elfinterp(TCCState *S);
#endif #endif
ST_FUNC void arm_init(TCCState *S); ST_FUNC void arm_init(TCCState *S);
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv); ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
#endif #endif
/* ------------ arm64-gen.c ------------ */ /* ------------ arm64-gen.c ------------ */
#ifdef TCC_TARGET_ARM64 #ifdef TCC_TARGET_ARM64
ST_FUNC void gen_opl(TCCState *S, int op); ST_FUNC void gen_opl(TCCState* S, int op);
ST_FUNC void gfunc_return(TCCState *S, CType *func_type); ST_FUNC void gfunc_return(TCCState *S, CType *func_type);
ST_FUNC void gen_va_start(TCCState *S); ST_FUNC void gen_va_start(TCCState *S);
ST_FUNC void gen_va_arg(TCCState *S, CType *t); ST_FUNC void gen_va_arg(TCCState *S, CType *t);
ST_FUNC void gen_clear_cache(TCCState *S); ST_FUNC void gen_clear_cache(TCCState *S);
ST_FUNC void gen_cvt_sxtw(TCCState *S); ST_FUNC void gen_cvt_sxtw(TCCState *S);
ST_FUNC void gen_cvt_csti(TCCState *S, int t); ST_FUNC void gen_cvt_csti(TCCState *S, int t);
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv); ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
#endif #endif
/* ------------ riscv64-gen.c ------------ */ /* ------------ riscv64-gen.c ------------ */
#ifdef TCC_TARGET_RISCV64 #ifdef TCC_TARGET_RISCV64
ST_FUNC void gen_opl(TCCState *S, int op); ST_FUNC void gen_opl(TCCState* S, int op);
//ST_FUNC void gfunc_return(TCCState *S, CType *func_type); //ST_FUNC void gfunc_return(TCCState *S, CType *func_type);
ST_FUNC void gen_va_start(TCCState *S); ST_FUNC void gen_va_start(TCCState *S);
ST_FUNC void arch_transfer_ret_regs(TCCState *S, int); ST_FUNC void arch_transfer_ret_regs(TCCState* S, int);
ST_FUNC void gen_cvt_sxtw(TCCState *S); ST_FUNC void gen_cvt_sxtw(TCCState *S);
ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv); ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv);
#endif #endif
/* ------------ c67-gen.c ------------ */ /* ------------ c67-gen.c ------------ */
@ -1850,25 +1851,25 @@ ST_FUNC int tcc_load_coff(TCCState *S, int fd);
#endif #endif
/* ------------ tccasm.c ------------ */ /* ------------ tccasm.c ------------ */
ST_FUNC void asm_instr(TCCState *S); ST_FUNC void asm_instr(TCCState* S);
ST_FUNC void asm_global_instr(TCCState *S); ST_FUNC void asm_global_instr(TCCState* S);
ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess); ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess);
#ifdef CONFIG_TCC_ASM #ifdef CONFIG_TCC_ASM
ST_FUNC int find_constraint(TCCState *S, ASMOperand *operands, int nb_operands, const char *name, const char **pp); ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands, const char *name, const char **pp);
ST_FUNC Sym* get_asm_sym(TCCState *S, int name, Sym *csym); ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym);
ST_FUNC void asm_expr(TCCState *S, ExprValue *pe); ST_FUNC void asm_expr(TCCState *S, ExprValue *pe);
ST_FUNC int asm_int_expr(TCCState *S); ST_FUNC int asm_int_expr(TCCState *S);
/* ------------ i386-asm.c ------------ */ /* ------------ i386-asm.c ------------ */
ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe); ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe);
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
ST_FUNC void gen_expr64(TCCState *S, ExprValue *pe); ST_FUNC void gen_expr64(TCCState* S, ExprValue *pe);
#endif #endif
ST_FUNC void asm_opcode(TCCState *S, int opcode); ST_FUNC void asm_opcode(TCCState *S, int opcode);
ST_FUNC int asm_parse_regvar(TCCState *S, int t); ST_FUNC int asm_parse_regvar(TCCState* S, int t);
ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg); ST_FUNC void asm_compute_constraints(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier); ST_FUNC void subst_asm_operand(TCCState* S, CString *add_str, SValue *sv, int modifier);
ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg); ST_FUNC void asm_gen_code(TCCState* S, ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str); ST_FUNC void asm_clobber(TCCState* S, uint8_t *clobber_regs, const char *str);
#endif #endif
/* ------------ tccpe.c -------------- */ /* ------------ tccpe.c -------------- */
@ -1880,9 +1881,9 @@ ST_FUNC int pe_putimport(TCCState *S, int dllindex, const char *name, addr_t val
ST_FUNC SValue *pe_getimport(TCCState * S, SValue *sv, SValue *v2); ST_FUNC SValue *pe_getimport(TCCState * S, SValue *sv, SValue *v2);
#endif #endif
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
ST_FUNC void pe_add_unwind_data(TCCState *S, unsigned start, unsigned end, unsigned stack); ST_FUNC void pe_add_unwind_data(TCCState* S, unsigned start, unsigned end, unsigned stack);
#endif #endif
PUB_FUNC int tcc_get_dllexports(TCCState *S, const char *filename, char **pp); PUB_FUNC int tcc_get_dllexports(TCCState* S, const char *filename, char **pp);
/* symbol properties stored in Elf32_Sym->st_other */ /* symbol properties stored in Elf32_Sym->st_other */
# define ST_PE_EXPORT 0x10 # define ST_PE_EXPORT 0x10
# define ST_PE_IMPORT 0x20 # define ST_PE_IMPORT 0x20
@ -1896,7 +1897,7 @@ ST_FUNC int macho_output_file(TCCState * S, const char *filename);
ST_FUNC int macho_load_dll(TCCState *S, int fd, const char *filename, int lev); ST_FUNC int macho_load_dll(TCCState *S, int fd, const char *filename, int lev);
ST_FUNC int macho_load_tbd(TCCState *S, int fd, const char *filename, int lev); ST_FUNC int macho_load_tbd(TCCState *S, int fd, const char *filename, int lev);
#ifdef TCC_IS_NATIVE #ifdef TCC_IS_NATIVE
ST_FUNC void tcc_add_macos_sdkpath(TCCState *S); ST_FUNC void tcc_add_macos_sdkpath(TCCState* S);
ST_FUNC const char* macho_tbd_soname(const char* filename); ST_FUNC const char* macho_tbd_soname(const char* filename);
#endif #endif
#endif #endif

246
tccasm.c
View file

@ -39,7 +39,7 @@ static Sym* asm_new_label1(TCCState *S, int label, int is_local, int sh_num, int
the global C symbol table to track ASM names as well, so we need to the global C symbol table to track ASM names as well, so we need to
transform those into ones that don't conflict with a C name, transform those into ones that don't conflict with a C name,
so prepend a '.' for them, but force the ELF asm name to be set. */ so prepend a '.' for them, but force the ELF asm name to be set. */
static int asm2cname(TCCState *S, int v, int *addeddot) static int asm2cname(TCCState* S, int v, int *addeddot)
{ {
const char *name; const char *name;
*addeddot = 0; *addeddot = 0;
@ -59,7 +59,7 @@ static int asm2cname(TCCState *S, int v, int *addeddot)
return v; return v;
} }
static Sym *asm_label_find(TCCState *S, int v) static Sym *asm_label_find(TCCState* S, int v)
{ {
Sym *sym; Sym *sym;
int addeddot; int addeddot;
@ -70,7 +70,7 @@ static Sym *asm_label_find(TCCState *S, int v)
return sym; return sym;
} }
static Sym *asm_label_push(TCCState *S, int v) static Sym *asm_label_push(TCCState* S, int v)
{ {
int addeddot, v2 = asm2cname(S, v, &addeddot); int addeddot, v2 = asm2cname(S, v, &addeddot);
/* We always add VT_EXTERN, for sym definition that's tentative /* We always add VT_EXTERN, for sym definition that's tentative
@ -92,7 +92,7 @@ static Sym *asm_label_push(TCCState *S, int v)
are anonymous in C, in this case CSYM can be used to transfer are anonymous in C, in this case CSYM can be used to transfer
all information from that symbol to the (possibly newly created) all information from that symbol to the (possibly newly created)
asm symbol. */ asm symbol. */
ST_FUNC Sym* get_asm_sym(TCCState *S, int name, Sym *csym) ST_FUNC Sym* get_asm_sym(TCCState* S, int name, Sym *csym)
{ {
Sym *sym = asm_label_find(S, name); Sym *sym = asm_label_find(S, name);
if (!sym) { if (!sym) {
@ -122,9 +122,9 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
uint64_t n; uint64_t n;
const char *p; const char *p;
switch(S->tok) { switch(S->tccpp_tok) {
case TOK_PPNUM: case TOK_PPNUM:
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
n = strtoull(p, (char **)&p, 0); n = strtoull(p, (char **)&p, 0);
if (*p == 'b' || *p == 'f') { if (*p == 'b' || *p == 'f') {
/* backward or forward label */ /* backward or forward label */
@ -161,7 +161,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
break; break;
case '-': case '-':
case '~': case '~':
op = S->tok; op = S->tccpp_tok;
next(S); next(S);
asm_expr_unary(S, pe); asm_expr_unary(S, pe);
if (pe->sym) if (pe->sym)
@ -173,7 +173,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
break; break;
case TOK_CCHAR: case TOK_CCHAR:
case TOK_LCHAR: case TOK_LCHAR:
pe->v = S->tokc.i; pe->v = S->tccpp_tokc.i;
pe->sym = NULL; pe->sym = NULL;
pe->pcrel = 0; pe->pcrel = 0;
next(S); next(S);
@ -184,16 +184,16 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
skip(S, ')'); skip(S, ')');
break; break;
case '.': case '.':
pe->v = S->ind; pe->v = S->tccgen_ind;
pe->sym = asm_section_sym(S, cur_text_section); pe->sym = asm_section_sym(S, cur_text_section);
pe->pcrel = 0; pe->pcrel = 0;
next(S); next(S);
break; break;
default: default:
if (S->tok >= TOK_IDENT) { if (S->tccpp_tok >= TOK_IDENT) {
ElfSym *esym; ElfSym *esym;
/* label case : if the label was not found, add one */ /* label case : if the label was not found, add one */
sym = get_asm_sym(S, S->tok, NULL); sym = get_asm_sym(S, S->tccpp_tok, NULL);
esym = elfsym(S, sym); esym = elfsym(S, sym);
if (esym && esym->st_shndx == SHN_ABS) { if (esym && esym->st_shndx == SHN_ABS) {
/* if absolute symbol, no need to put a symbol value */ /* if absolute symbol, no need to put a symbol value */
@ -207,7 +207,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
} }
next(S); next(S);
} else { } else {
tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tok, &S->tokc)); tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
} }
break; break;
} }
@ -220,7 +220,7 @@ static void asm_expr_prod(TCCState *S, ExprValue *pe)
asm_expr_unary(S, pe); asm_expr_unary(S, pe);
for(;;) { for(;;) {
op = S->tok; op = S->tccpp_tok;
if (op != '*' && op != '/' && op != '%' && if (op != '*' && op != '/' && op != '%' &&
op != TOK_SHL && op != TOK_SAR) op != TOK_SHL && op != TOK_SAR)
break; break;
@ -262,7 +262,7 @@ static void asm_expr_logic(TCCState *S, ExprValue *pe)
asm_expr_prod(S, pe); asm_expr_prod(S, pe);
for(;;) { for(;;) {
op = S->tok; op = S->tccpp_tok;
if (op != '&' && op != '|' && op != '^') if (op != '&' && op != '|' && op != '^')
break; break;
next(S); next(S);
@ -291,7 +291,7 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe)
asm_expr_logic(S, pe); asm_expr_logic(S, pe);
for(;;) { for(;;) {
op = S->tok; op = S->tccpp_tok;
if (op != '+' && op != '-') if (op != '+' && op != '-')
break; break;
next(S); next(S);
@ -323,7 +323,7 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe)
} else if (esym2->st_shndx == cur_text_section->sh_num) { } else if (esym2->st_shndx == cur_text_section->sh_num) {
/* When subtracting a defined symbol in current section /* When subtracting a defined symbol in current section
this actually makes the value PC-relative. */ this actually makes the value PC-relative. */
pe->v -= esym2->st_value - S->ind - 4; pe->v -= esym2->st_value - S->tccgen_ind - 4;
pe->pcrel = 1; pe->pcrel = 1;
e2.sym = NULL; e2.sym = NULL;
} else { } else {
@ -342,7 +342,7 @@ static inline void asm_expr_cmp(TCCState *S, ExprValue *pe)
asm_expr_sum(S, pe); asm_expr_sum(S, pe);
for(;;) { for(;;) {
op = S->tok; op = S->tccpp_tok;
if (op != TOK_EQ && op != TOK_NE if (op != TOK_EQ && op != TOK_NE
&& (op > TOK_GT || op < TOK_ULE)) && (op > TOK_GT || op < TOK_ULE))
break; break;
@ -428,7 +428,7 @@ static Sym* asm_new_label1(TCCState *S, int label, int is_local,
static Sym* asm_new_label(TCCState *S, int label, int is_local) static Sym* asm_new_label(TCCState *S, int label, int is_local)
{ {
return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->ind); return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->tccgen_ind);
} }
/* Set the value of LABEL to that of some expression (possibly /* Set the value of LABEL to that of some expression (possibly
@ -452,9 +452,9 @@ static Sym* set_symbol(TCCState *S, int label)
static void use_section1(TCCState *S, Section *sec) static void use_section1(TCCState *S, Section *sec)
{ {
cur_text_section->data_offset = S->ind; cur_text_section->data_offset = S->tccgen_ind;
cur_text_section = sec; cur_text_section = sec;
S->ind = cur_text_section->data_offset; S->tccgen_ind = cur_text_section->data_offset;
} }
static void use_section(TCCState *S, const char *name) static void use_section(TCCState *S, const char *name)
@ -488,13 +488,13 @@ static void asm_parse_directive(TCCState *S, int global)
/* assembler directive */ /* assembler directive */
sec = cur_text_section; sec = cur_text_section;
switch(S->tok) { switch(S->tccpp_tok) {
case TOK_ASMDIR_align: case TOK_ASMDIR_align:
case TOK_ASMDIR_balign: case TOK_ASMDIR_balign:
case TOK_ASMDIR_p2align: case TOK_ASMDIR_p2align:
case TOK_ASMDIR_skip: case TOK_ASMDIR_skip:
case TOK_ASMDIR_space: case TOK_ASMDIR_space:
tok1 = S->tok; tok1 = S->tccpp_tok;
next(S); next(S);
n = asm_int_expr(S); n = asm_int_expr(S);
if (tok1 == TOK_ASMDIR_p2align) if (tok1 == TOK_ASMDIR_p2align)
@ -507,8 +507,8 @@ static void asm_parse_directive(TCCState *S, int global)
if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) { if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
if (n < 0 || (n & (n-1)) != 0) if (n < 0 || (n & (n-1)) != 0)
tcc_error(S, "alignment must be a positive power of two"); tcc_error(S, "alignment must be a positive power of two");
offset = (S->ind + n - 1) & -n; offset = (S->tccgen_ind + n - 1) & -n;
size = offset - S->ind; size = offset - S->tccgen_ind;
/* the section must have a compatible alignment */ /* the section must have a compatible alignment */
if (sec->sh_addralign < n) if (sec->sh_addralign < n)
sec->sh_addralign = n; sec->sh_addralign = n;
@ -518,17 +518,17 @@ static void asm_parse_directive(TCCState *S, int global)
size = n; size = n;
} }
v = 0; v = 0;
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
v = asm_int_expr(S); v = asm_int_expr(S);
} }
zero_pad: zero_pad:
if (sec->sh_type != SHT_NOBITS) { if (sec->sh_type != SHT_NOBITS) {
sec->data_offset = S->ind; sec->data_offset = S->tccgen_ind;
ptr = section_ptr_add(S, sec, size); ptr = section_ptr_add(S, sec, size);
memset(ptr, v, size); memset(ptr, v, size);
} }
S->ind += size; S->tccgen_ind += size;
break; break;
case TOK_ASMDIR_quad: case TOK_ASMDIR_quad:
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
@ -540,8 +540,8 @@ static void asm_parse_directive(TCCState *S, int global)
uint64_t vl; uint64_t vl;
const char *p; const char *p;
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
if (S->tok != TOK_PPNUM) { if (S->tccpp_tok != TOK_PPNUM) {
error_constant: error_constant:
tcc_error(S, "64 bit constant"); tcc_error(S, "64 bit constant");
} }
@ -554,9 +554,9 @@ static void asm_parse_directive(TCCState *S, int global)
gen_le32(S, vl); gen_le32(S, vl);
gen_le32(S, vl >> 32); gen_le32(S, vl >> 32);
} else { } else {
S->ind += 8; S->tccgen_ind += 8;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); next(S);
} }
@ -593,9 +593,9 @@ static void asm_parse_directive(TCCState *S, int global)
gen_le16(S, e.v); gen_le16(S, e.v);
} }
} else { } else {
S->ind += size; S->tccgen_ind += size;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); next(S);
} }
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *S, int global)
} }
size = 1; size = 1;
val = 0; val = 0;
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
size = asm_int_expr(S); size = asm_int_expr(S);
if (size < 0) { if (size < 0) {
@ -621,7 +621,7 @@ static void asm_parse_directive(TCCState *S, int global)
} }
if (size > 8) if (size > 8)
size = 8; size = 8;
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
val = asm_int_expr(S); val = asm_int_expr(S);
} }
@ -649,8 +649,8 @@ static void asm_parse_directive(TCCState *S, int global)
next(S); next(S);
repeat = asm_int_expr(S); repeat = asm_int_expr(S);
init_str = tok_str_alloc(S); init_str = tok_str_alloc(S);
while (next(S), S->tok != TOK_ASMDIR_endr) { while (next(S), S->tccpp_tok != TOK_ASMDIR_endr) {
if (S->tok == CH_EOF) if (S->tccpp_tok == CH_EOF)
tcc_error(S, "we at end of file, .endr not found"); tcc_error(S, "we at end of file, .endr not found");
tok_str_add_tok(S, init_str); tok_str_add_tok(S, init_str);
} }
@ -680,31 +680,31 @@ static void asm_parse_directive(TCCState *S, int global)
expect(S, "constant or same-section symbol"); expect(S, "constant or same-section symbol");
n += esym->st_value; n += esym->st_value;
} }
if (n < S->ind) if (n < S->tccgen_ind)
tcc_error(S, "attempt to .org backwards"); tcc_error(S, "attempt to .org backwards");
v = 0; v = 0;
size = n - S->ind; size = n - S->tccgen_ind;
goto zero_pad; goto zero_pad;
} }
break; break;
case TOK_ASMDIR_set: case TOK_ASMDIR_set:
next(S); next(S);
tok1 = S->tok; tok1 = S->tccpp_tok;
next(S); next(S);
/* Also accept '.set stuff', but don't do anything with this. /* Also accept '.set stuff', but don't do anything with this.
It's used in GAS to set various features like '.set mips16'. */ It's used in GAS to set various features like '.set mips16'. */
if (S->tok == ',') if (S->tccpp_tok == ',')
set_symbol(S, tok1); set_symbol(S, tok1);
break; break;
case TOK_ASMDIR_globl: case TOK_ASMDIR_globl:
case TOK_ASMDIR_global: case TOK_ASMDIR_global:
case TOK_ASMDIR_weak: case TOK_ASMDIR_weak:
case TOK_ASMDIR_hidden: case TOK_ASMDIR_hidden:
tok1 = S->tok; tok1 = S->tccpp_tok;
do { do {
Sym *sym; Sym *sym;
next(S); next(S);
sym = get_asm_sym(S, S->tok, NULL); sym = get_asm_sym(S, S->tccpp_tok, NULL);
if (tok1 != TOK_ASMDIR_hidden) if (tok1 != TOK_ASMDIR_hidden)
sym->type.t &= ~VT_STATIC; sym->type.t &= ~VT_STATIC;
if (tok1 == TOK_ASMDIR_weak) if (tok1 == TOK_ASMDIR_weak)
@ -713,7 +713,7 @@ static void asm_parse_directive(TCCState *S, int global)
sym->a.visibility = STV_HIDDEN; sym->a.visibility = STV_HIDDEN;
update_storage(S, sym); update_storage(S, sym);
next(S); next(S);
} while (S->tok == ','); } while (S->tccpp_tok == ',');
break; break;
case TOK_ASMDIR_string: case TOK_ASMDIR_string:
case TOK_ASMDIR_ascii: case TOK_ASMDIR_ascii:
@ -722,21 +722,21 @@ static void asm_parse_directive(TCCState *S, int global)
const uint8_t *p; const uint8_t *p;
int i, size, t; int i, size, t;
t = S->tok; t = S->tccpp_tok;
next(S); next(S);
for(;;) { for(;;) {
if (S->tok != TOK_STR) if (S->tccpp_tok != TOK_STR)
expect(S, "string constant"); expect(S, "string constant");
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
size = S->tokc.str.size; size = S->tccpp_tokc.str.size;
if (t == TOK_ASMDIR_ascii && size > 0) if (t == TOK_ASMDIR_ascii && size > 0)
size--; size--;
for(i = 0; i < size; i++) for(i = 0; i < size; i++)
g(S, p[i]); g(S, p[i]);
next(S); next(S);
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
} else if (S->tok != TOK_STR) { } else if (S->tccpp_tok != TOK_STR) {
break; break;
} }
} }
@ -747,10 +747,10 @@ static void asm_parse_directive(TCCState *S, int global)
case TOK_ASMDIR_bss: case TOK_ASMDIR_bss:
{ {
char sname[64]; char sname[64];
tok1 = S->tok; tok1 = S->tccpp_tok;
n = 0; n = 0;
next(S); next(S);
if (S->tok != ';' && S->tok != TOK_LINEFEED) { if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) {
n = asm_int_expr(S); n = asm_int_expr(S);
next(S); next(S);
} }
@ -767,10 +767,10 @@ static void asm_parse_directive(TCCState *S, int global)
filename[0] = '\0'; filename[0] = '\0';
next(S); next(S);
if (S->tok == TOK_STR) if (S->tccpp_tok == TOK_STR)
pstrcat(filename, sizeof(filename), S->tokc.str.data); pstrcat(filename, sizeof(filename), S->tccpp_tokc.str.data);
else else
pstrcat(filename, sizeof(filename), get_tok_str(S, S->tok, NULL)); pstrcat(filename, sizeof(filename), get_tok_str(S, S->tccpp_tok, NULL));
tcc_warning_c(warn_unsupported)(S, "ignoring .file %s", filename); tcc_warning_c(warn_unsupported)(S, "ignoring .file %s", filename);
next(S); next(S);
} }
@ -781,10 +781,10 @@ static void asm_parse_directive(TCCState *S, int global)
ident[0] = '\0'; ident[0] = '\0';
next(S); next(S);
if (S->tok == TOK_STR) if (S->tccpp_tok == TOK_STR)
pstrcat(ident, sizeof(ident), S->tokc.str.data); pstrcat(ident, sizeof(ident), S->tccpp_tokc.str.data);
else else
pstrcat(ident, sizeof(ident), get_tok_str(S, S->tok, NULL)); pstrcat(ident, sizeof(ident), get_tok_str(S, S->tccpp_tok, NULL));
tcc_warning_c(warn_unsupported)(S, "ignoring .ident %s", ident); tcc_warning_c(warn_unsupported)(S, "ignoring .ident %s", ident);
next(S); next(S);
} }
@ -794,15 +794,15 @@ static void asm_parse_directive(TCCState *S, int global)
Sym *sym; Sym *sym;
next(S); next(S);
sym = asm_label_find(S, S->tok); sym = asm_label_find(S, S->tccpp_tok);
if (!sym) { if (!sym) {
tcc_error(S, "label not found: %s", get_tok_str(S, S->tok, NULL)); tcc_error(S, "label not found: %s", get_tok_str(S, S->tccpp_tok, NULL));
} }
/* XXX .size name,label2-label1 */ /* XXX .size name,label2-label1 */
tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tok, NULL)); tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tccpp_tok, NULL));
next(S); next(S);
skip(S, ','); skip(S, ',');
while (S->tok != TOK_LINEFEED && S->tok != ';' && S->tok != CH_EOF) { while (S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ';' && S->tccpp_tok != CH_EOF) {
next(S); next(S);
} }
} }
@ -813,15 +813,15 @@ static void asm_parse_directive(TCCState *S, int global)
const char *newtype; const char *newtype;
next(S); next(S);
sym = get_asm_sym(S, S->tok, NULL); sym = get_asm_sym(S, S->tccpp_tok, NULL);
next(S); next(S);
skip(S, ','); skip(S, ',');
if (S->tok == TOK_STR) { if (S->tccpp_tok == TOK_STR) {
newtype = S->tokc.str.data; newtype = S->tccpp_tokc.str.data;
} else { } else {
if (S->tok == '@' || S->tok == '%') if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
next(S); next(S);
newtype = get_tok_str(S, S->tok, NULL); newtype = get_tok_str(S, S->tccpp_tok, NULL);
} }
if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
@ -839,26 +839,26 @@ static void asm_parse_directive(TCCState *S, int global)
char sname[256]; char sname[256];
int old_nb_section = S->nb_sections; int old_nb_section = S->nb_sections;
tok1 = S->tok; tok1 = S->tccpp_tok;
/* XXX: support more options */ /* XXX: support more options */
next(S); next(S);
sname[0] = '\0'; sname[0] = '\0';
while (S->tok != ';' && S->tok != TOK_LINEFEED && S->tok != ',') { while (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ',') {
if (S->tok == TOK_STR) if (S->tccpp_tok == TOK_STR)
pstrcat(sname, sizeof(sname), S->tokc.str.data); pstrcat(sname, sizeof(sname), S->tccpp_tokc.str.data);
else else
pstrcat(sname, sizeof(sname), get_tok_str(S, S->tok, NULL)); pstrcat(sname, sizeof(sname), get_tok_str(S, S->tccpp_tok, NULL));
next(S); next(S);
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
/* skip section options */ /* skip section options */
next(S); next(S);
if (S->tok != TOK_STR) if (S->tccpp_tok != TOK_STR)
expect(S, "string constant"); expect(S, "string constant");
next(S); next(S);
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
if (S->tok == '@' || S->tok == '%') if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
next(S); next(S);
next(S); next(S);
} }
@ -911,7 +911,7 @@ static void asm_parse_directive(TCCState *S, int global)
break; break;
#endif #endif
default: default:
tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tok, NULL)); tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tccpp_tok, NULL));
break; break;
} }
} }
@ -928,20 +928,20 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS; S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS;
for(;;) { for(;;) {
next(S); next(S);
if (S->tok == TOK_EOF) if (S->tccpp_tok == TOK_EOF)
break; break;
S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
redo: redo:
if (S->tok == '#') { if (S->tccpp_tok == '#') {
/* horrible gas comment */ /* horrible gas comment */
while (S->tok != TOK_LINEFEED) while (S->tccpp_tok != TOK_LINEFEED)
next(S); next(S);
} else if (S->tok >= TOK_ASMDIR_FIRST && S->tok <= TOK_ASMDIR_LAST) { } else if (S->tccpp_tok >= TOK_ASMDIR_FIRST && S->tccpp_tok <= TOK_ASMDIR_LAST) {
asm_parse_directive(S, global); asm_parse_directive(S, global);
} else if (S->tok == TOK_PPNUM) { } else if (S->tccpp_tok == TOK_PPNUM) {
const char *p; const char *p;
int n; int n;
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
n = strtoul(p, (char **)&p, 10); n = strtoul(p, (char **)&p, 10);
if (*p != '\0') if (*p != '\0')
expect(S, "':'"); expect(S, "':'");
@ -950,16 +950,16 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
next(S); next(S);
skip(S, ':'); skip(S, ':');
goto redo; goto redo;
} else if (S->tok >= TOK_IDENT) { } else if (S->tccpp_tok >= TOK_IDENT) {
/* instruction or label */ /* instruction or label */
opcode = S->tok; opcode = S->tccpp_tok;
next(S); next(S);
if (S->tok == ':') { if (S->tccpp_tok == ':') {
/* new label */ /* new label */
asm_new_label(S, opcode, 0); asm_new_label(S, opcode, 0);
next(S); next(S);
goto redo; goto redo;
} else if (S->tok == '=') { } else if (S->tccpp_tok == '=') {
set_symbol(S, opcode); set_symbol(S, opcode);
goto redo; goto redo;
} else { } else {
@ -967,7 +967,7 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
} }
} }
/* end of line */ /* end of line */
if (S->tok != ';' && S->tok != TOK_LINEFEED) if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED)
expect(S, "end of line"); expect(S, "end of line");
S->tccpp_parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */ S->tccpp_parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
} }
@ -983,10 +983,10 @@ ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess)
tcc_debug_start(S); tcc_debug_start(S);
/* default section is text */ /* default section is text */
cur_text_section = text_section; cur_text_section = text_section;
S->ind = cur_text_section->data_offset; S->tccgen_ind = cur_text_section->data_offset;
S->nocode_wanted = 0; S->tccgen_nocode_wanted = 0;
ret = tcc_assemble_internal(S, do_preprocess, 1); ret = tcc_assemble_internal(S, do_preprocess, 1);
cur_text_section->data_offset = S->ind; cur_text_section->data_offset = S->tccgen_ind;
tcc_debug_end(S); tcc_debug_end(S);
return ret; return ret;
} }
@ -1017,7 +1017,7 @@ static void tcc_assemble_inline(TCCState *S, char *str, int len, int global)
/* find a constraint by its number or id (gcc 3 extended /* find a constraint by its number or id (gcc 3 extended
syntax). return -1 if not found. Return in *pp in char after the syntax). return -1 if not found. Return in *pp in char after the
constraint */ constraint */
ST_FUNC int find_constraint(TCCState *S, ASMOperand *operands, int nb_operands, ST_FUNC int find_constraint(TCCState* S, ASMOperand *operands, int nb_operands,
const char *name, const char **pp) const char *name, const char **pp)
{ {
int index; int index;
@ -1055,7 +1055,7 @@ ST_FUNC int find_constraint(TCCState *S, ASMOperand *operands, int nb_operands,
return index; return index;
} }
static void subst_asm_operands(TCCState *S, ASMOperand *operands, int nb_operands, static void subst_asm_operands(TCCState* S, ASMOperand *operands, int nb_operands,
CString *out_str, CString *in_str) CString *out_str, CString *in_str)
{ {
int c, index, modifier; int c, index, modifier;
@ -1101,13 +1101,13 @@ static void subst_asm_operands(TCCState *S, ASMOperand *operands, int nb_operand
} }
static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operands_ptr, static void parse_asm_operands(TCCState* S, ASMOperand *operands, int *nb_operands_ptr,
int is_output) int is_output)
{ {
ASMOperand *op; ASMOperand *op;
int nb_operands; int nb_operands;
if (S->tok != ':') { if (S->tccpp_tok != ':') {
nb_operands = *nb_operands_ptr; nb_operands = *nb_operands_ptr;
for(;;) { for(;;) {
CString astr; CString astr;
@ -1115,11 +1115,11 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
tcc_error(S, "too many asm operands"); tcc_error(S, "too many asm operands");
op = &operands[nb_operands++]; op = &operands[nb_operands++];
op->id = 0; op->id = 0;
if (S->tok == '[') { if (S->tccpp_tok == '[') {
next(S); next(S);
if (S->tok < TOK_IDENT) if (S->tccpp_tok < TOK_IDENT)
expect(S, "identifier"); expect(S, "identifier");
op->id = S->tok; op->id = S->tccpp_tok;
next(S); next(S);
skip(S, ']'); skip(S, ']');
} }
@ -1130,23 +1130,23 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
skip(S, '('); skip(S, '(');
gexpr(S); gexpr(S);
if (is_output) { if (is_output) {
if (!(S->vtop->type.t & VT_ARRAY)) if (!(S->tccgen_vtop->type.t & VT_ARRAY))
test_lvalue(S); test_lvalue(S);
} else { } else {
/* we want to avoid LLOCAL case, except when the 'm' /* we want to avoid LLOCAL case, except when the 'm'
constraint is used. Note that it may come from constraint is used. Note that it may come from
register storage, so we need to convert (reg) register storage, so we need to convert (reg)
case */ case */
if ((S->vtop->r & VT_LVAL) && if ((S->tccgen_vtop->r & VT_LVAL) &&
((S->vtop->r & VT_VALMASK) == VT_LLOCAL || ((S->tccgen_vtop->r & VT_VALMASK) == VT_LLOCAL ||
(S->vtop->r & VT_VALMASK) < VT_CONST) && (S->tccgen_vtop->r & VT_VALMASK) < VT_CONST) &&
!strchr(op->constraint, 'm')) { !strchr(op->constraint, 'm')) {
gv(S, RC_INT); gv(S, RC_INT);
} }
} }
op->vt = S->vtop; op->vt = S->tccgen_vtop;
skip(S, ')'); skip(S, ')');
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
} else { } else {
break; break;
@ -1157,7 +1157,7 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
} }
/* parse the GCC asm() instruction */ /* parse the GCC asm() instruction */
ST_FUNC void asm_instr(TCCState *S) ST_FUNC void asm_instr(TCCState* S)
{ {
CString astr, astr1; CString astr, astr1;
ASMOperand operands[MAX_ASM_OPERANDS]; ASMOperand operands[MAX_ASM_OPERANDS];
@ -1167,7 +1167,7 @@ ST_FUNC void asm_instr(TCCState *S)
/* since we always generate the asm() instruction, we can ignore /* since we always generate the asm() instruction, we can ignore
volatile */ volatile */
if (S->tok == TOK_VOLATILE1 || S->tok == TOK_VOLATILE2 || S->tok == TOK_VOLATILE3) { if (S->tccpp_tok == TOK_VOLATILE1 || S->tccpp_tok == TOK_VOLATILE2 || S->tccpp_tok == TOK_VOLATILE3) {
next(S); next(S);
} }
parse_asm_str(S, &astr); parse_asm_str(S, &astr);
@ -1175,27 +1175,27 @@ ST_FUNC void asm_instr(TCCState *S)
nb_outputs = 0; nb_outputs = 0;
must_subst = 0; must_subst = 0;
memset(clobber_regs, 0, sizeof(clobber_regs)); memset(clobber_regs, 0, sizeof(clobber_regs));
if (S->tok == ':') { if (S->tccpp_tok == ':') {
next(S); next(S);
must_subst = 1; must_subst = 1;
/* output args */ /* output args */
parse_asm_operands(S, operands, &nb_operands, 1); parse_asm_operands(S, operands, &nb_operands, 1);
nb_outputs = nb_operands; nb_outputs = nb_operands;
if (S->tok == ':') { if (S->tccpp_tok == ':') {
next(S); next(S);
if (S->tok != ')') { if (S->tccpp_tok != ')') {
/* input args */ /* input args */
parse_asm_operands(S, operands, &nb_operands, 0); parse_asm_operands(S, operands, &nb_operands, 0);
if (S->tok == ':') { if (S->tccpp_tok == ':') {
/* clobber list */ /* clobber list */
/* XXX: handle registers */ /* XXX: handle registers */
next(S); next(S);
for(;;) { for(;;) {
if (S->tok != TOK_STR) if (S->tccpp_tok != TOK_STR)
expect(S, "string constant"); expect(S, "string constant");
asm_clobber(S, clobber_regs, S->tokc.str.data); asm_clobber(S, clobber_regs, S->tccpp_tokc.str.data);
next(S); next(S);
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
} else { } else {
break; break;
@ -1208,7 +1208,7 @@ ST_FUNC void asm_instr(TCCState *S)
skip(S, ')'); skip(S, ')');
/* NOTE: we do not eat the ';' so that we can restore the current /* NOTE: we do not eat the ';' so that we can restore the current
token after the assembler parsing */ token after the assembler parsing */
if (S->tok != ';') if (S->tccpp_tok != ';')
expect(S, "';'"); expect(S, "';'");
/* save all values in the memory */ /* save all values in the memory */
@ -1264,37 +1264,37 @@ ST_FUNC void asm_instr(TCCState *S)
cstr_free(S, &astr1); cstr_free(S, &astr1);
} }
ST_FUNC void asm_global_instr(TCCState *S) ST_FUNC void asm_global_instr(TCCState* S)
{ {
CString astr; CString astr;
int saved_nocode_wanted = S->nocode_wanted; int saved_nocode_wanted = S->tccgen_nocode_wanted;
/* Global asm blocks are always emitted. */ /* Global asm blocks are always emitted. */
S->nocode_wanted = 0; S->tccgen_nocode_wanted = 0;
next(S); next(S);
parse_asm_str(S, &astr); parse_asm_str(S, &astr);
skip(S, ')'); skip(S, ')');
/* NOTE: we do not eat the ';' so that we can restore the current /* NOTE: we do not eat the ';' so that we can restore the current
token after the assembler parsing */ token after the assembler parsing */
if (S->tok != ';') if (S->tccpp_tok != ';')
expect(S, "';'"); expect(S, "';'");
#ifdef ASM_DEBUG #ifdef ASM_DEBUG
printf("asm_global: \"%s\"\n", (char *)astr.data); printf("asm_global: \"%s\"\n", (char *)astr.data);
#endif #endif
cur_text_section = text_section; cur_text_section = text_section;
S->ind = cur_text_section->data_offset; S->tccgen_ind = cur_text_section->data_offset;
/* assemble the string with tcc internal assembler */ /* assemble the string with tcc internal assembler */
tcc_assemble_inline(S, astr.data, astr.size - 1, 1); tcc_assemble_inline(S, astr.data, astr.size - 1, 1);
cur_text_section->data_offset = S->ind; cur_text_section->data_offset = S->tccgen_ind;
/* restore the current C token */ /* restore the current C token */
next(S); next(S);
cstr_free(S, &astr); cstr_free(S, &astr);
S->nocode_wanted = saved_nocode_wanted; S->tccgen_nocode_wanted = saved_nocode_wanted;
} }
/********************************************************/ /********************************************************/
@ -1304,12 +1304,12 @@ ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess)
tcc_error(S, "asm not supported"); tcc_error(S, "asm not supported");
} }
ST_FUNC void asm_instr(TCCState *S) ST_FUNC void asm_instr(S)
{ {
tcc_error(S, "inline asm() not supported"); tcc_error(S, "inline asm() not supported");
} }
ST_FUNC void asm_global_instr(TCCState *S) ST_FUNC void asm_global_instr(S)
{ {
tcc_error(S, "inline asm() not supported"); tcc_error(S, "inline asm() not supported");
} }

View file

@ -107,7 +107,7 @@ ST_FUNC void tccelf_stab_new(TCCState *S)
put_stabs(S, "", 0, 0, 0, 0); put_stabs(S, "", 0, 0, 0, 0);
} }
static void free_section(TCCState *S, Section *s) static void free_section(TCCState* S, Section *s)
{ {
tcc_free(S, s->data); tcc_free(S, s->data);
} }
@ -284,7 +284,7 @@ ST_FUNC Section *new_symtab(TCCState *S,
} }
/* realloc section and set its content to zero */ /* realloc section and set its content to zero */
ST_FUNC void section_realloc(TCCState *S, Section *sec, unsigned long new_size) ST_FUNC void section_realloc(TCCState* S, Section *sec, unsigned long new_size)
{ {
unsigned long size; unsigned long size;
unsigned char *data; unsigned char *data;
@ -302,7 +302,7 @@ ST_FUNC void section_realloc(TCCState *S, Section *sec, unsigned long new_size)
/* reserve at least 'size' bytes aligned per 'align' in section /* reserve at least 'size' bytes aligned per 'align' in section
'sec' from current offset, and return the aligned offset */ 'sec' from current offset, and return the aligned offset */
ST_FUNC size_t section_add(TCCState *S, Section *sec, addr_t size, int align) ST_FUNC size_t section_add(TCCState* S, Section *sec, addr_t size, int align)
{ {
size_t offset, offset1; size_t offset, offset1;
@ -318,7 +318,7 @@ ST_FUNC size_t section_add(TCCState *S, Section *sec, addr_t size, int align)
/* reserve at least 'size' bytes in section 'sec' from /* reserve at least 'size' bytes in section 'sec' from
sec->data_offset. */ sec->data_offset. */
ST_FUNC void *section_ptr_add(TCCState *S, Section *sec, addr_t size) ST_FUNC void *section_ptr_add(TCCState* S, Section *sec, addr_t size)
{ {
size_t offset = section_add(S, sec, size, 1); size_t offset = section_add(S, sec, size, 1);
return sec->data + offset; return sec->data + offset;
@ -326,7 +326,7 @@ ST_FUNC void *section_ptr_add(TCCState *S, Section *sec, addr_t size)
#ifndef ELF_OBJ_ONLY #ifndef ELF_OBJ_ONLY
/* reserve at least 'size' bytes from section start */ /* reserve at least 'size' bytes from section start */
static void section_reserve(TCCState *S, Section *sec, unsigned long size) static void section_reserve(TCCState* S, Section *sec, unsigned long size)
{ {
if (size > sec->data_allocated) if (size > sec->data_allocated)
section_realloc(S, sec, size); section_realloc(S, sec, size);
@ -357,7 +357,7 @@ ST_FUNC Section *find_section(TCCState *S, const char *name)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
ST_FUNC int put_elf_str(TCCState *S, Section *s, const char *sym) ST_FUNC int put_elf_str(TCCState* S, Section *s, const char *sym)
{ {
int offset, len; int offset, len;
char *ptr; char *ptr;
@ -386,7 +386,7 @@ static unsigned long elf_hash(const unsigned char *name)
/* rebuild hash table of section s */ /* rebuild hash table of section s */
/* NOTE: we do factorize the hash table code to go faster */ /* NOTE: we do factorize the hash table code to go faster */
static void rebuild_hash(TCCState *S, Section *s, unsigned int nb_buckets) static void rebuild_hash(TCCState* S, Section *s, unsigned int nb_buckets)
{ {
ElfW(Sym) *sym; ElfW(Sym) *sym;
int *ptr, *hash, nb_syms, sym_index, h; int *ptr, *hash, nb_syms, sym_index, h;
@ -422,7 +422,7 @@ static void rebuild_hash(TCCState *S, Section *s, unsigned int nb_buckets)
} }
/* return the symbol number */ /* return the symbol number */
ST_FUNC int put_elf_sym(TCCState *S, Section *s, addr_t value, unsigned long size, ST_FUNC int put_elf_sym(TCCState* S, Section *s, addr_t value, unsigned long size,
int info, int other, int shndx, const char *name) int info, int other, int shndx, const char *name)
{ {
int name_offset, sym_index; int name_offset, sym_index;
@ -2082,7 +2082,7 @@ static int layout_sections(TCCState *S, ElfW(Phdr) *phdr,
} }
/* put dynamic tag */ /* put dynamic tag */
static void put_dt(TCCState *S, Section *dynamic, int dt, addr_t val) static void put_dt(TCCState* S, Section *dynamic, int dt, addr_t val)
{ {
ElfW(Dyn) *dyn; ElfW(Dyn) *dyn;
dyn = section_ptr_add(S, dynamic, sizeof(ElfW(Dyn))); dyn = section_ptr_add(S, dynamic, sizeof(ElfW(Dyn)));
@ -2827,7 +2827,7 @@ ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
} }
} }
ST_FUNC void *load_data(TCCState *S, int fd, unsigned long file_offset, unsigned long size) ST_FUNC void *load_data(TCCState* S, int fd, unsigned long file_offset, unsigned long size)
{ {
void *data; void *data;

1802
tccgen.c

File diff suppressed because it is too large Load diff

View file

@ -249,7 +249,7 @@ struct macho {
#define SHT_LINKEDIT (SHT_LOOS + 42) #define SHT_LINKEDIT (SHT_LOOS + 42)
#define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */ #define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */
static void * add_lc(TCCState *S, struct macho *mo, uint32_t cmd, uint32_t cmdsize) static void * add_lc(TCCState* S, struct macho *mo, uint32_t cmd, uint32_t cmdsize)
{ {
struct load_command *lc = tcc_mallocz(S, cmdsize); struct load_command *lc = tcc_mallocz(S, cmdsize);
lc->cmd = cmd; lc->cmd = cmd;
@ -259,7 +259,7 @@ static void * add_lc(TCCState *S, struct macho *mo, uint32_t cmd, uint32_t cmdsi
return lc; return lc;
} }
static struct segment_command_64 * add_segment(TCCState *S, struct macho *mo, const char *name) static struct segment_command_64 * add_segment(TCCState* S, struct macho *mo, const char *name)
{ {
struct segment_command_64 *sc = add_lc(S, mo, LC_SEGMENT_64, sizeof(*sc)); struct segment_command_64 *sc = add_lc(S, mo, LC_SEGMENT_64, sizeof(*sc));
strncpy(sc->segname, name, 16); strncpy(sc->segname, name, 16);
@ -272,7 +272,7 @@ static struct segment_command_64 * get_segment(struct macho *mo, int i)
return (struct segment_command_64 *) (mo->lc[mo->seg2lc[i]]); return (struct segment_command_64 *) (mo->lc[mo->seg2lc[i]]);
} }
static int add_section(TCCState *S, struct macho *mo, struct segment_command_64 **_seg, const char *name) static int add_section(TCCState* S, struct macho *mo, struct segment_command_64 **_seg, const char *name)
{ {
struct segment_command_64 *seg = *_seg; struct segment_command_64 *seg = *_seg;
int ret = seg->nsects; int ret = seg->nsects;
@ -293,7 +293,7 @@ static struct section_64 *get_section(struct segment_command_64 *seg, int i)
return (struct section_64*)((char*)seg + sizeof(*seg)) + i; return (struct section_64*)((char*)seg + sizeof(*seg)) + i;
} }
static void * add_dylib(TCCState *S, struct macho *mo, char *name) static void * add_dylib(TCCState* S, struct macho *mo, char *name)
{ {
struct dylib_command *lc; struct dylib_command *lc;
int sz = (sizeof(*lc) + strlen(name) + 1 + 7) & -8; int sz = (sizeof(*lc) + strlen(name) + 1 + 7) & -8;
@ -836,7 +836,7 @@ static uint32_t macho_swap32(uint32_t x)
} }
#define SWAP(x) (swap ? macho_swap32(x) : (x)) #define SWAP(x) (swap ? macho_swap32(x) : (x))
ST_FUNC int macho_add_dllref(TCCState *S, int lev, const char* soname) ST_FUNC int macho_add_dllref(TCCState* S, int lev, const char* soname)
{ {
/* if the dll is already loaded, do not load it */ /* if the dll is already loaded, do not load it */
DLLReference *dllref; DLLReference *dllref;
@ -865,7 +865,7 @@ ST_FUNC int macho_add_dllref(TCCState *S, int lev, const char* soname)
#ifdef TCC_IS_NATIVE #ifdef TCC_IS_NATIVE
/* Looks for the active developer SDK set by xcode-select (or the default /* Looks for the active developer SDK set by xcode-select (or the default
one set during installation.) */ one set during installation.) */
ST_FUNC void tcc_add_macos_sdkpath(TCCState *S) ST_FUNC void tcc_add_macos_sdkpath(TCCState* s)
{ {
char *sdkroot = NULL, *pos = NULL; char *sdkroot = NULL, *pos = NULL;
void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY); void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY);
@ -912,7 +912,7 @@ the_end:
} }
#endif /* TCC_IS_NATIVE */ #endif /* TCC_IS_NATIVE */
ST_FUNC int macho_load_tbd(TCCState *S, int fd, const char* filename, int lev) ST_FUNC int macho_load_tbd(TCCState* S, int fd, const char* filename, int lev)
{ {
char *soname, *data, *pos; char *soname, *data, *pos;
int ret = -1; int ret = -1;

View file

@ -1492,7 +1492,7 @@ static void pe_print_sections(TCCState *S, const char *fname)
/* helper function for load/store to insert one more indirection */ /* helper function for load/store to insert one more indirection */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC SValue *pe_getimport(TCCState *S, SValue *sv, SValue *v2) ST_FUNC SValue *pe_getimport(TCCState* S, SValue *sv, SValue *v2)
{ {
int r2; int r2;
if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST)) if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
@ -1512,7 +1512,7 @@ ST_FUNC SValue *pe_getimport(TCCState *S, SValue *sv, SValue *v2)
vpushv(S, v2); vpushv(S, v2);
vpushi(S, sv->c.i); vpushi(S, sv->c.i);
gen_opi(S, '+'); gen_opi(S, '+');
*v2 = *S->vtop--; *v2 = *S->tccgen_vtop--;
} }
v2->type.t = sv->type.t; v2->type.t = sv->type.t;
v2->r |= sv->r & VT_LVAL; v2->r |= sv->r & VT_LVAL;
@ -1551,7 +1551,7 @@ static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static int get_dllexports(TCCState *S, int fd, char **pp) static int get_dllexports(TCCState* S, int fd, char **pp)
{ {
int l, i, n, n0, ret; int l, i, n, n0, ret;
char *p; char *p;

710
tccpp.c

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff