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

192
arm-asm.c
View file

@ -100,10 +100,10 @@ static void parse_operand(TCCState *S, Operand *op)
op->type = 0;
if (S->tok == '{') { // regset literal
if (S->tccpp_tok == '{') { // regset literal
next(S); // skip '{'
while (S->tok != '}' && S->tok != TOK_EOF) {
reg = asm_parse_regvar(S, S->tok);
while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {
reg = asm_parse_regvar(S, S->tccpp_tok);
if (reg == -1) {
expect(S, "register");
return;
@ -113,11 +113,11 @@ static void parse_operand(TCCState *S, Operand *op)
if ((1 << reg) < regset)
tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
regset |= 1 << reg;
if (S->tok != ',')
if (S->tccpp_tok != ',')
break;
next(S); // skip ','
}
if (S->tok != '}')
if (S->tccpp_tok != '}')
expect(S, "'}'");
next(S); // skip '}'
if (regset == 0) {
@ -128,22 +128,22 @@ static void parse_operand(TCCState *S, Operand *op)
op->regset = regset;
}
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
op->type = OP_REG32;
op->reg = (uint8_t) reg;
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
op->type = OP_VREG32;
op->reg = (uint8_t) reg;
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
op->type = OP_VREG64;
op->reg = (uint8_t) reg;
return;
} else if (S->tok == '#' || S->tok == '$') {
} else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
/* constant value */
next(S); // skip '#' or '$'
}
@ -163,13 +163,13 @@ static void parse_operand(TCCState *S, Operand *op)
ST_FUNC void g(TCCState* S, int c)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 1;
ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c;
S->ind = ind1;
cur_text_section->data[S->tccgen_ind] = c;
S->tccgen_ind = ind1;
}
ST_FUNC void gen_le16 (TCCState* S, int i)
@ -181,15 +181,15 @@ ST_FUNC void gen_le16 (TCCState *S, int i)
ST_FUNC void gen_le32 (TCCState* S, int i)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 4;
ind1 = S->tccgen_ind + 4;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind++] = i & 0xFF;
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF;
cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
}
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
@ -276,7 +276,7 @@ static void asm_binary_opcode(TCCState *S, int token)
uint32_t encoded_rotation = 0;
uint64_t amount;
parse_operand(S, &ops[0]);
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -328,9 +328,9 @@ static void asm_binary_opcode(TCCState *S, int token)
if (ops[1].reg == 13)
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 ','
if (S->tok == TOK_ASM_ror) {
if (S->tccpp_tok == TOK_ASM_ror) {
next(S); // skip 'ror'
parse_operand(S, &rotation);
if (rotation.type != OP_IM8) {
@ -387,15 +387,15 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
uint8_t high_nibble;
uint8_t mrc = 0;
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) {
coprocessor = S->tok - TOK_ASM_p0;
if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
coprocessor = S->tccpp_tok - TOK_ASM_p0;
next(S);
} else {
expect(S, "'p<number>'");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -407,21 +407,21 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
}
for (i = 0; i < 3; ++i) {
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
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) {
registers[i] = S->tok - TOK_ASM_r0;
if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {
registers[i] = S->tccpp_tok - TOK_ASM_r0;
next(S);
} else {
expect(S, "'r<number>'");
return;
}
} else {
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) {
registers[i] = S->tok - TOK_ASM_c0;
if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
registers[i] = S->tccpp_tok - TOK_ASM_c0;
next(S);
} else {
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);
parse_operand(S, &opcode2);
} else {
@ -493,11 +493,11 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
Operand ops[2];
int nb_ops = 1;
parse_operand(S, &ops[0]);
if (S->tok == '!') {
if (S->tccpp_tok == '!') {
op0_exclam = 1;
next(S); // skip '!'
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S); // skip comma
parse_operand(S, &ops[1]);
++nb_ops;
@ -604,13 +604,13 @@ static uint32_t asm_parse_optional_shift(TCCState *S, int* nb_shift, Operand* sh
{
uint32_t opcode = 0;
*nb_shift = 0;
switch (S->tok) {
switch (S->tccpp_tok) {
case TOK_ASM_asl:
case TOK_ASM_lsl:
case TOK_ASM_asr:
case TOK_ASM_lsr:
case TOK_ASM_ror:
switch (S->tok) {
switch (S->tccpp_tok) {
case TOK_ASM_asl:
/* fallthrough */
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
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;
parse_operand(S, &ops[nb_ops]);
++nb_ops;
if (S->tok != ',')
if (S->tccpp_tok != ',')
break;
next(S); // skip ','
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
operands |= asm_parse_optional_shift(S, &nb_shift, &shift);
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) {
parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') {
if (S->tccpp_tok != ',') {
++nb_ops;
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) {
parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') {
if (S->tccpp_tok != ',') {
++nb_ops;
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) {
parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') {
if (S->tccpp_tok != ',') {
++nb_ops;
break;
}
@ -1133,7 +1133,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(destination operand) register");
return;
}
if (S->tok != ',')
if (S->tccpp_tok != ',')
expect(S, "at least two arguments");
else
next(S); // skip ','
@ -1146,14 +1146,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "register");
return;
}
if (S->tok != ',')
if (S->tccpp_tok != ',')
expect(S, "at least three arguments");
else
next(S); // skip ','
break;
}
if (S->tok != '[')
if (S->tccpp_tok != '[')
expect(S, "'['");
else
next(S); // skip '['
@ -1165,14 +1165,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register");
return;
}
if (S->tok == ']') {
if (S->tccpp_tok == ']') {
next(S);
closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S); // skip ','
if (S->tok == '-') {
if (S->tccpp_tok == '-') {
op2_minus = 1;
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));
return;
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);
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
}
if (!closed_bracket) {
if (S->tok != ']')
if (S->tccpp_tok != ']')
expect(S, "']'");
else
next(S); // skip ']'
opcode |= 1 << 24; // add offset before transfer
if (S->tok == '!') {
if (S->tccpp_tok == '!') {
exclam = 1;
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 p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) {
coprocessor = S->tok - TOK_ASM_p0;
if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
coprocessor = S->tccpp_tok - TOK_ASM_p0;
next(S);
} else {
expect(S, "'c<number>'");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) {
coprocessor_destination_register = S->tok - TOK_ASM_c0;
if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;
next(S);
} else {
expect(S, "'c<number>'");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
if (S->tok != '[')
if (S->tccpp_tok != '[')
expect(S, "'['");
else
next(S); // skip '['
@ -1425,14 +1425,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register");
return;
}
if (S->tok == ']') {
if (S->tccpp_tok == ']') {
next(S);
closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S); // skip ','
if (S->tok == '-') {
if (S->tccpp_tok == '-') {
op2_minus = 1;
next(S);
}
@ -1453,12 +1453,12 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
preincrement = 1; // add offset before transfer
}
if (!closed_bracket) {
if (S->tok != ']')
if (S->tccpp_tok != ']')
expect(S, "']'");
else
next(S); // skip ']'
preincrement = 1; // add offset before transfer
if (S->tok == '!') {
if (S->tccpp_tok == '!') {
exclam = 1;
next(S); // skip '!'
}
@ -1528,12 +1528,12 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
if (S->tok != '[')
if (S->tccpp_tok != '[')
expect(S, "'['");
else
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");
return;
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S); // skip ','
parse_operand(S, &ops[2]);
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].e.v = 0;
}
if (S->tok != ']')
if (S->tccpp_tok != ']')
expect(S, "']'");
else
next(S); // skip ']'
@ -1593,11 +1593,11 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
break;
default:
parse_operand(S, &ops[0]);
if (S->tok == '!') {
if (S->tccpp_tok == '!') {
op0_exclam = 1;
next(S); // skip '!'
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S); // skip comma
else {
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, "'{'");
return;
}
next(S); // skip '{'
first_regset_register = asm_parse_vfp_regvar(S->tok, 1);
if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 1)) != -1) {
first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);
if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
coprocessor = CP_DOUBLE_PRECISION_FLOAT;
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;
next(S);
} else {
@ -1622,9 +1622,9 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
return;
}
if (S->tok == '-') {
if (S->tccpp_tok == '-') {
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);
else {
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");
return;
}
if (S->tok != '}') {
if (S->tccpp_tok != '}') {
expect(S, "'}'");
return;
}
@ -1725,11 +1725,11 @@ static uint32_t vmov_parse_immediate_value(TCCState *S) {
unsigned long integral_value;
const char *p;
if (S->tok != TOK_PPNUM) {
if (S->tccpp_tok != TOK_PPNUM) {
expect(S, "immediate value");
return 0;
}
p = S->tokc.str.data;
p = S->tccpp_tokc.str.data;
errno = 0;
integral_value = strtoul(p, (char **)&p, 0);
@ -1785,10 +1785,10 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
operands[0] = CRd;
if (S->tok == '#' || S->tok == '$') {
if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
next(S);
}
if (S->tok == '-') {
if (S->tccpp_tok == '-') {
op_minus = 1;
next(S);
}
@ -1956,7 +1956,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
break;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
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; ) {
// 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);
return;
}
@ -2100,7 +2100,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
return;
}
++nb_ops;
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
break;
@ -2248,7 +2248,7 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vmrseq:
opcode = 0xf;
if (S->tok == TOK_ASM_apsr_nzcv) {
if (S->tccpp_tok == TOK_ASM_apsr_nzcv) {
arm_operand.type = OP_REG32;
arm_operand.reg = 15; // not PC
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, "','");
else
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
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));
@ -2273,9 +2273,9 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
break;
case TOK_ASM_vmsreq:
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
if (S->tok != ',')
if (S->tccpp_tok != ',')
expect(S, "','");
else
next(S); // skip ','
@ -2329,12 +2329,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(destination operand) register");
return;
}
if (S->tok != ',')
if (S->tccpp_tok != ',')
expect(S, "at least two arguments");
else
next(S); // skip ','
if (S->tok != '[')
if (S->tccpp_tok != '[')
expect(S, "'['");
else
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");
return;
}
if (S->tok == ']') {
if (S->tccpp_tok == ']') {
next(S);
closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S); // skip ','
if (S->tok == '-') {
if (S->tccpp_tok == '-') {
op2_minus = 1;
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
}
if (!closed_bracket) {
if (S->tok != ']')
if (S->tccpp_tok != ']')
expect(S, "']'");
else
next(S); // skip ']'
opcode |= 1 << 24; // add offset before transfer
if (S->tok == '!') {
if (S->tccpp_tok == '!') {
exclam = 1;
next(S); // skip '!'
}
@ -2467,7 +2467,7 @@ static void asm_branch_opcode(TCCState *S, int token)
tcc_error(S, "invalid branch target");
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;
default:
parse_operand(S, &op);
@ -2501,7 +2501,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
{
while (token == TOK_LINEFEED) {
next(S);
token = S->tok;
token = S->tccpp_tok;
}
if (token == TOK_EOF)
return;

288
arm-gen.c
View file

@ -244,21 +244,21 @@ void o(TCCState *S, uint32_t i)
{
/* this is a good place to start adding big-endian support*/
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 4;
ind1 = S->tccgen_ind + 4;
if (!cur_text_section)
tcc_error(S, "compiler error! This happens f.ex. if the compiler\n"
"can't evaluate constant expressions outside of a function.");
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind++] = i&255;
cur_text_section->data[S->tccgen_ind++] = i&255;
i>>=8;
cur_text_section->data[S->ind++] = i&255;
cur_text_section->data[S->tccgen_ind++] = i&255;
i>>=8;
cur_text_section->data[S->ind++] = i&255;
cur_text_section->data[S->tccgen_ind++] = i&255;
i>>=8;
cur_text_section->data[S->ind++] = i;
cur_text_section->data[S->tccgen_ind++] = i;
}
static uint32_t stuff_const(uint32_t op, uint32_t c)
@ -538,7 +538,7 @@ static void load_value(TCCState *S, SValue *sv, int r)
o(S, 0xEA000000); /* b $+4 */
#ifndef CONFIG_TCC_PIE
if(sv->r & VT_SYM)
greloc(S, cur_text_section, sv->sym, S->ind, R_ARM_ABS32);
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_ABS32);
o(S, sv->c.i);
#else
if(sv->r & VT_SYM) {
@ -787,17 +787,17 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
{
int r;
uint32_t x;
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
/* constant case */
if(S->vtop->r & VT_SYM){
x=encbranch(S, S->ind, S->ind+S->vtop->c.i,0);
if(S->tccgen_vtop->r & VT_SYM){
x=encbranch(S, S->tccgen_ind, S->tccgen_ind+S->tccgen_vtop->c.i,0);
if(x) {
/* relocation case */
greloc(S, cur_text_section, S->vtop->sym, S->ind, R_ARM_PC24);
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_ARM_PC24);
o(S, x|(is_jmp?0xE0000000:0xE1000000));
} else {
r = TREG_LR;
load_value(S, S->vtop, r);
load_value(S, S->tccgen_vtop, r);
if(is_jmp)
o(S, 0xE1A0F000 | intr(S, r)); // mov pc, r
else
@ -807,12 +807,12 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
if(!is_jmp)
o(S, 0xE28FE004); // add lr,pc,#4
o(S, 0xE51FF004); // ldr pc,[pc,#-4]
o(S, S->vtop->c.i);
o(S, S->tccgen_vtop->c.i);
}
} else {
/* otherwise, indirect call */
#ifdef CONFIG_TCC_BCHECK
S->vtop->r &= ~VT_MUSTBOUND;
S->tccgen_vtop->r &= ~VT_MUSTBOUND;
#endif
r = gv(S, RC_INT);
if(!is_jmp)
@ -827,7 +827,7 @@ static void gen_bounds_call(TCCState *S, int v)
{
Sym *sym = external_helper_sym(S, v);
greloc(S, cur_text_section, sym, S->ind, R_ARM_PC24);
greloc(S, cur_text_section, sym, S->tccgen_ind, R_ARM_PC24);
o(S, 0xebfffffe);
}
@ -835,7 +835,7 @@ static void gen_bounds_prolog(TCCState *S)
{
/* leave some room for bound checking code */
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;
o(S, 0xe1a00000); /* ld r0,lbounds_section->data_offset */
o(S, 0xe1a00000);
@ -858,20 +858,20 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*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);
/* generate bound local allocation */
if (offset_modified) {
saved_ind = S->ind;
S->ind = S->func_bound_ind;
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->func_bound_ind;
o(S, 0xe59f0000); /* ldr r0, [pc] */
o(S, 0xea000000); /* b $+4 */
greloc(S, cur_text_section, sym_data, S->ind, R_ARM_REL32);
greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
o(S, -12); /* lbounds_section->data_offset */
o(S, 0xe080000f); /* add r0,r0,pc */
gen_bounds_call(S, TOK___bound_local_new);
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
/* generate bound check local freeing */
@ -879,7 +879,7 @@ static void gen_bounds_epilog(TCCState *S)
o(S, 0xed2d0b02); /* vpush {d0} */
o(S, 0xe59f0000); /* ldr r0, [pc] */
o(S, 0xea000000); /* b $+4 */
greloc(S, cur_text_section, sym_data, S->ind, R_ARM_REL32);
greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
o(S, -12); /* lbounds_section->data_offset */
o(S, 0xe080000f); /* add r0,r0,pc */
gen_bounds_call(S, TOK___bound_local_delete);
@ -1081,12 +1081,12 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
for(i = nb_args; i-- ;) {
int j, start_vfpreg = 0;
CType type = S->vtop[-i].type;
CType type = S->tccgen_vtop[-i].type;
type.t &= ~VT_ARRAY;
size = type_size(&type, &align);
size = (size + 3) & ~3;
align = (align + 3) & ~3;
switch(S->vtop[-i].type.t & VT_BTYPE) {
switch(S->tccgen_vtop[-i].type.t & VT_BTYPE) {
case VT_STRUCT:
case VT_FLOAT:
case VT_DOUBLE:
@ -1094,15 +1094,15 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
if (float_abi == ARM_HARD_FLOAT) {
int is_hfa = 0; /* Homogeneous float aggregate */
if (is_float(S->vtop[-i].type.t)
|| (is_hfa = is_hgen_float_aggr(&S->vtop[-i].type))) {
if (is_float(S->tccgen_vtop[-i].type.t)
|| (is_hfa = is_hgen_float_aggr(&S->tccgen_vtop[-i].type))) {
int end_vfpreg;
start_vfpreg = assign_vfpreg(&avregs, align, size);
end_vfpreg = start_vfpreg + ((size - 1) >> 2);
if (start_vfpreg >= 0) {
add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,
start_vfpreg, end_vfpreg, &S->vtop[-i]);
start_vfpreg, end_vfpreg, &S->tccgen_vtop[-i]);
continue;
} else
break;
@ -1115,7 +1115,7 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
* CORE_STRUCT_CLASS or the first of STACK_CLASS. */
for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
*todo|=(1<<j);
add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->vtop[-i]);
add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->tccgen_vtop[-i]);
ncrn += size/4;
if (ncrn > 4)
nsaa = (ncrn - 4) * 4;
@ -1126,20 +1126,20 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
continue;
default:
if (ncrn < 4) {
int is_long = (S->vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
int is_long = (S->tccgen_vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
if (is_long) {
ncrn = (ncrn + 1) & -2;
if (ncrn == 4)
break;
}
add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->vtop[-i]);
add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->tccgen_vtop[-i]);
ncrn += 1 + is_long;
continue;
}
}
nsaa = (nsaa + (align - 1)) & ~(align - 1);
add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->vtop[-i]);
add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->tccgen_vtop[-i]);
nsaa += size; /* size already rounded up before */
}
return nsaa;
@ -1201,7 +1201,7 @@ again:
/* generate structure store */
r = get_reg(S, RC_INT);
o(S, 0xE28D0000|(intr(S, r)<<12)|padding); /* add r, sp, padding */
vset(S, &S->vtop->type, r | VT_LVAL, 0);
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
vswap(S);
/* XXX: optimize. Save all register because memcpy can use them */
o(S, 0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */
@ -1255,7 +1255,7 @@ again:
size = 8;
r = gv(S, RC_INT);
o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
S->vtop--;
S->tccgen_vtop--;
}
r = gv(S, RC_INT);
o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
@ -1269,7 +1269,7 @@ again:
gv(S, regmask(S, TREG_F0 + (pplan->start >> 1)));
if (pplan->start & 1) { /* Must be in upper part of double register */
o(S, 0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
S->vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
S->tccgen_vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
}
break;
@ -1277,16 +1277,16 @@ again:
if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
lexpand(S);
gv(S, regmask(S, pplan->end));
pplan->sval->r2 = S->vtop->r;
S->vtop--;
pplan->sval->r2 = S->tccgen_vtop->r;
S->tccgen_vtop--;
}
gv(S, regmask(S, pplan->start));
/* Mark register as used so that gcall_or_jmp use another one
(regs >=4 are free as never used to pass parameters) */
pplan->sval->r = S->vtop->r;
pplan->sval->r = S->tccgen_vtop->r;
break;
}
S->vtop--;
S->tccgen_vtop--;
}
}
@ -1312,7 +1312,7 @@ again:
if (todo & (1 << r)) {
nb_extra_sval++;
vpushi(S, 0);
S->vtop->r = r;
S->tccgen_vtop->r = r;
}
}
}
@ -1340,15 +1340,15 @@ void gfunc_call(TCCState *S, int nb_args)
#ifdef TCC_ARM_EABI
if (float_abi == ARM_HARD_FLOAT) {
variadic = (S->vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
if (variadic || floats_in_core_regs(&S->vtop[-nb_args]))
variadic = (S->tccgen_vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
if (variadic || floats_in_core_regs(&S->tccgen_vtop[-nb_args]))
float_abi = ARM_SOFTFP_FLOAT;
}
#endif
/* cannot let cpu flags if other instruction are generated. Also avoid leaving
VT_JMP anywhere except on the top of the stack because it would complicate
the code generator. */
r = S->vtop->r & VT_VALMASK;
r = S->tccgen_vtop->r & VT_VALMASK;
if (r == VT_CMP || (r & ~1) == VT_JMP)
gv(S, RC_INT);
@ -1374,8 +1374,8 @@ void gfunc_call(TCCState *S, int nb_args)
if (args_size)
gadd_sp(S, args_size); /* pop all parameters passed on the stack */
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->vtop->type.ref->type.t)) {
if((S->vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->tccgen_vtop->type.ref->type.t)) {
if((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
o(S, 0xEE000A10); /*vmov s0, r0 */
} else {
o(S, 0xEE000B10); /* vmov.32 d0[0], r0 */
@ -1383,7 +1383,7 @@ void gfunc_call(TCCState *S, int nb_args)
}
}
#endif
S->vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
S->tccgen_vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
float_abi = def_float_abi;
}
@ -1443,7 +1443,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
}
o(S, 0xE92D5800); /* save fp, ip, lr */
o(S, 0xE1A0B00D); /* mov fp, sp */
func_sub_sp_offset = S->ind;
func_sub_sp_offset = S->tccgen_ind;
o(S, 0xE1A00000); /* nop, leave space for stack adjustment in epilog */
#ifdef TCC_ARM_EABI
@ -1490,7 +1490,7 @@ from_stack:
}
last_itod_magic=0;
leaffunc = 1;
S->loc = 0;
S->tccgen_loc = 0;
#ifdef CONFIG_TCC_BCHECK
if (S->do_bounds_check)
gen_bounds_prolog(S);
@ -1520,7 +1520,7 @@ void gfunc_epilog(TCCState *S)
}
#endif
o(S, 0xE89BA800); /* restore fp, sp, pc */
diff = (-S->loc + 3) & -4;
diff = (-S->tccgen_loc + 3) & -4;
#ifdef TCC_ARM_EABI
if(!leaffunc)
diff = ((diff + 11) & -8) - 4;
@ -1531,7 +1531,7 @@ void gfunc_epilog(TCCState *S)
*(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
else {
int addr;
addr=S->ind;
addr=S->tccgen_ind;
o(S, 0xE59FC004); /* ldr ip,[pc+4] */
o(S, 0xE04BD00C); /* sub sp,fp,ip */
o(S, 0xE1A0F00E); /* mov pc,lr */
@ -1555,9 +1555,9 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
ST_FUNC int gjmp(TCCState* S, int t)
{
int r;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return t;
r=S->ind;
r=S->tccgen_ind;
o(S, 0xE0000000|encbranch(S, r,t,1));
return r;
}
@ -1571,9 +1571,9 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
{
int r;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return t;
r=S->ind;
r=S->tccgen_ind;
op=mapcc(S, op);
op|=encbranch(S, r,t,1);
o(S, op);
@ -1644,9 +1644,9 @@ void gen_opi(TCCState *S, int op)
break;
case '*':
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
o(S, 0xE0000090|(intr(S, r)<<16)|(intr(S, r)<<8)|intr(S, fr));
return;
case TOK_SHL:
@ -1690,11 +1690,11 @@ void gen_opi(TCCState *S, int op)
break;
case TOK_UMULL:
gv2(S, RC_INT, RC_INT);
r=intr(S, S->vtop[-1].r2=get_reg(S, RC_INT));
c=S->vtop[-1].r;
S->vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));
S->vtop--;
o(S, 0xE0800090|(r<<16)|(intr(S, S->vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->vtop[1].r));
r=intr(S, S->tccgen_vtop[-1].r2=get_reg(S, RC_INT));
c=S->tccgen_vtop[-1].r;
S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));
S->tccgen_vtop--;
o(S, 0xE0800090|(r<<16)|(intr(S, S->tccgen_vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->tccgen_vtop[1].r));
return;
default:
opc = 0x15;
@ -1703,27 +1703,27 @@ void gen_opi(TCCState *S, int op)
}
switch(c) {
case 1:
if((S->vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
if((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
if(opc == 4 || opc == 5 || opc == 0xc) {
vswap(S);
opc|=2; // sub -> rsb
}
}
if ((S->vtop->r & VT_VALMASK) == VT_CMP ||
(S->vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
(S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
gv(S, RC_INT);
vswap(S);
c=intr(S, gv(S, RC_INT));
vswap(S);
opc=0xE0000000|(opc<<20);
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) {
uint32_t x;
x=stuff_const(opc|0x2000000|(c<<16),S->vtop->c.i);
x=stuff_const(opc|0x2000000|(c<<16),S->tccgen_vtop->c.i);
if(x) {
if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c
o(S, x);
else {
r=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->vtop[-1].r)));
r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
o(S, x|(r<<12));
}
goto done;
@ -1731,7 +1731,7 @@ void gen_opi(TCCState *S, int op)
}
fr=intr(S, gv(S, RC_INT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
c=intr(S, gv(S, RC_INT));
vswap(S);
@ -1740,46 +1740,46 @@ void gen_opi(TCCState *S, int op)
if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
o(S, opc|(c<<16)|fr);
else {
r=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->vtop->r,S->vtop[-1].r)));
r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
o(S, opc|(c<<16)|(r<<12)|fr);
}
done:
S->vtop--;
S->tccgen_vtop--;
if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(S, op);
break;
case 2:
opc=0xE1A00000|(opc<<5);
if ((S->vtop->r & VT_VALMASK) == VT_CMP ||
(S->vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
(S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
gv(S, RC_INT);
vswap(S);
r=intr(S, gv(S, RC_INT));
vswap(S);
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
fr=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->vtop[-1].r)));
c = S->vtop->c.i & 0x1f;
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
fr=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
c = S->tccgen_vtop->c.i & 0x1f;
o(S, opc|r|(c<<7)|(fr<<12));
} else {
fr=intr(S, gv(S, RC_INT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=intr(S, gv(S, RC_INT));
vswap(S);
}
#endif
c=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->vtop->r,S->vtop[-1].r)));
c=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
o(S, opc|r|(c<<12)|(fr<<8)|0x10);
}
S->vtop--;
S->tccgen_vtop--;
break;
case 3:
vpush_helper_func(S, func);
vrott(S, 3);
gfunc_call(S, 2);
vpushi(S, 0);
S->vtop->r = retreg;
S->tccgen_vtop->r = retreg;
break;
default:
tcc_error(S, "gen_opi %i unimplemented!",op);
@ -1789,13 +1789,13 @@ done:
#ifdef TCC_ARM_VFP
static int is_zero(TCCState* S, int i)
{
if((S->vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
if((S->tccgen_vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
return 0;
if (S->vtop[i].type.t == VT_FLOAT)
return (S->vtop[i].c.f == 0.f);
else if (S->vtop[i].type.t == VT_DOUBLE)
return (S->vtop[i].c.d == 0.0);
return (S->vtop[i].c.ld == 0.l);
if (S->tccgen_vtop[i].type.t == VT_FLOAT)
return (S->tccgen_vtop[i].c.f == 0.f);
else if (S->tccgen_vtop[i].type.t == VT_DOUBLE)
return (S->tccgen_vtop[i].c.d == 0.0);
return (S->tccgen_vtop[i].c.ld == 0.l);
}
/* generate a floating point operation 'v = t1 op t2' instruction. The
@ -1804,13 +1804,13 @@ void gen_opf(TCCState *S, int op)
{
uint32_t x;
int fneg=0,r;
x=0xEE000A00|T2CPR(S->vtop->type.t);
x=0xEE000A00|T2CPR(S->tccgen_vtop->type.t);
switch(op) {
case '+':
if(is_zero(S, -1))
vswap(S);
if(is_zero(S, 0)) {
S->vtop--;
S->tccgen_vtop--;
return;
}
x|=0x300000;
@ -1818,13 +1818,13 @@ void gen_opf(TCCState *S, int op)
case '-':
x|=0x300040;
if(is_zero(S, 0)) {
S->vtop--;
S->tccgen_vtop--;
return;
}
if(is_zero(S, -1)) {
x|=0x810000; /* fsubX -> fnegX */
vswap(S);
S->vtop--;
S->tccgen_vtop--;
fneg=1;
}
break;
@ -1852,13 +1852,13 @@ void gen_opf(TCCState *S, int op)
if(op!=TOK_EQ && op!=TOK_NE)
x|=0x80; /* fcmpX -> fcmpeX */
if(is_zero(S, 0)) {
S->vtop--;
S->tccgen_vtop--;
o(S, x|0x10000|(vfpr(S, gv(S, RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
} else {
gv2(S, RC_FLOAT,RC_FLOAT);
x|=vfpr(S, S->vtop[0].r);
o(S, x|(vfpr(S, S->vtop[-1].r) << 12));
S->vtop--;
x|=vfpr(S, S->tccgen_vtop[0].r);
o(S, x|(vfpr(S, S->tccgen_vtop[-1].r) << 12));
S->tccgen_vtop--;
}
o(S, 0xEEF1FA10); /* fmstat */
@ -1881,7 +1881,7 @@ void gen_opf(TCCState *S, int op)
x|=vfpr(S, r2)<<16;
r|=regmask(S, r2);
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=gv(S, RC_FLOAT);
vswap(S);
@ -1889,10 +1889,10 @@ void gen_opf(TCCState *S, int op)
}
#endif
}
S->vtop->r=get_reg_ex(S, RC_FLOAT,r);
S->tccgen_vtop->r=get_reg_ex(S, RC_FLOAT,r);
if(!fneg)
S->vtop--;
o(S, x|(vfpr(S, S->vtop->r)<<12));
S->tccgen_vtop--;
o(S, x|(vfpr(S, S->tccgen_vtop->r)<<12));
}
#else
@ -1900,14 +1900,14 @@ static uint32_t is_fconst(TCCState *S)
{
long double f;
uint32_t r;
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)
return 0;
if (S->vtop->type.t == VT_FLOAT)
f = S->vtop->c.f;
else if (S->vtop->type.t == VT_DOUBLE)
f = S->vtop->c.d;
if (S->tccgen_vtop->type.t == VT_FLOAT)
f = S->tccgen_vtop->c.f;
else if (S->tccgen_vtop->type.t == VT_DOUBLE)
f = S->tccgen_vtop->c.d;
else
f = S->vtop->c.ld;
f = S->tccgen_vtop->c.ld;
if(!ieee_finite(f))
return 0;
r=0x8;
@ -1946,12 +1946,12 @@ void gen_opf(TCCState *S, int op)
c2 = is_fconst(S);
x=0xEE000100;
#if LDOUBLE_SIZE == 8
if ((S->vtop->type.t & VT_BTYPE) != VT_FLOAT)
if ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT)
x|=0x80;
#else
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE)
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
x|=0x80;
else if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
x|=0x80000;
#endif
switch(op)
@ -1971,7 +1971,7 @@ void gen_opf(TCCState *S, int op)
} else {
r2=fpr(S, gv(S, RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=fpr(S, gv(S, RC_FLOAT));
vswap(S);
@ -1999,7 +1999,7 @@ void gen_opf(TCCState *S, int op)
vswap(S);
r2=fpr(S, gv(S, RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=fpr(S, gv(S, RC_FLOAT));
vswap(S);
@ -2020,7 +2020,7 @@ void gen_opf(TCCState *S, int op)
else {
r2=fpr(S, gv(S, RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=fpr(S, gv(S, RC_FLOAT));
vswap(S);
@ -2048,7 +2048,7 @@ void gen_opf(TCCState *S, int op)
vswap(S);
r2=fpr(S, gv(S, RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=fpr(S, gv(S, RC_FLOAT));
vswap(S);
@ -2107,31 +2107,31 @@ void gen_opf(TCCState *S, int op)
} else {
r2=fpr(S, gv(S, RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
vswap(S);
r=fpr(S, gv(S, RC_FLOAT));
vswap(S);
}
#endif
}
--S->vtop;
--S->tccgen_vtop;
vset_VT_CMP(S, op);
++S->vtop;
++S->tccgen_vtop;
} else {
tcc_error(S, "unknown fp op %x!",op);
return;
}
}
if(S->vtop[-1].r == VT_CMP)
if(S->tccgen_vtop[-1].r == VT_CMP)
c1=15;
else {
c1=S->vtop->r;
c1=S->tccgen_vtop->r;
if(r2&0x8)
c1=S->vtop[-1].r;
S->vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->vtop[-1].r,c1));
c1=fpr(S, S->vtop[-1].r);
c1=S->tccgen_vtop[-1].r;
S->tccgen_vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->tccgen_vtop[-1].r,c1));
c1=fpr(S, S->tccgen_vtop[-1].r);
}
S->vtop--;
S->tccgen_vtop--;
o(S, x|(r<<16)|(c1<<12)|r2);
}
#endif
@ -2142,30 +2142,30 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
{
uint32_t r, r2;
int bt;
bt=S->vtop->type.t & VT_BTYPE;
bt=S->tccgen_vtop->type.t & VT_BTYPE;
if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
#ifndef TCC_ARM_VFP
uint32_t dsize = 0;
#endif
r=intr(S, gv(S, RC_INT));
#ifdef TCC_ARM_VFP
r2=vfpr(S, S->vtop->r=get_reg(S, RC_FLOAT));
r2=vfpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
o(S, 0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
r2|=r2<<12;
if(!(S->vtop->type.t & VT_UNSIGNED))
if(!(S->tccgen_vtop->type.t & VT_UNSIGNED))
r2|=0x80; /* fuitoX -> fsituX */
o(S, 0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
#else
r2=fpr(S, S->vtop->r=get_reg(S, RC_FLOAT));
r2=fpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
if((t & VT_BTYPE) != VT_FLOAT)
dsize=0x80; /* flts -> fltd */
o(S, 0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
if((S->vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
if((S->tccgen_vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
uint32_t off = 0;
o(S, 0xE3500000|(r<<12)); /* cmp */
r=fpr(S, get_reg(S, RC_FLOAT));
if(last_itod_magic) {
off=S->ind+8-last_itod_magic;
off=S->tccgen_ind+8-last_itod_magic;
off/=4;
if(off>255)
off=0;
@ -2173,7 +2173,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
o(S, 0xBD1F0100|(r<<12)|off); /* ldflts */
if(!off) {
o(S, 0xEA000000); /* b */
last_itod_magic=S->ind;
last_itod_magic=S->tccgen_ind;
o(S, 0x4F800000); /* 4294967296.0f */
}
o(S, 0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
@ -2185,14 +2185,14 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
CType *func_type = 0;
if((t & VT_BTYPE) == VT_FLOAT) {
func_type = &S->armgen_func_float_type;
if(S->vtop->type.t & VT_UNSIGNED)
if(S->tccgen_vtop->type.t & VT_UNSIGNED)
func=TOK___floatundisf;
else
func=TOK___floatdisf;
#if LDOUBLE_SIZE != 8
} else if((t & VT_BTYPE) == VT_LDOUBLE) {
func_type = &S->armgen_func_ldouble_type;
if(S->vtop->type.t & VT_UNSIGNED)
if(S->tccgen_vtop->type.t & VT_UNSIGNED)
func=TOK___floatundixf;
else
func=TOK___floatdixf;
@ -2201,7 +2201,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
} else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
#endif
func_type = &S->armgen_func_double_type;
if(S->vtop->type.t & VT_UNSIGNED)
if(S->tccgen_vtop->type.t & VT_UNSIGNED)
func=TOK___floatundidf;
else
func=TOK___floatdidf;
@ -2211,11 +2211,11 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
vswap(S);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->r=TREG_F0;
S->tccgen_vtop->r=TREG_F0;
return;
}
}
tcc_error(S, "unimplemented gen_cvt_itof %x!",S->vtop->type.t);
tcc_error(S, "unimplemented gen_cvt_itof %x!",S->tccgen_vtop->type.t);
}
/* convert fp to int 't' type */
@ -2225,13 +2225,13 @@ void gen_cvt_ftoi(TCCState *S, int t)
int u, func = 0;
u=t&VT_UNSIGNED;
t&=VT_BTYPE;
r2=S->vtop->type.t & VT_BTYPE;
r2=S->tccgen_vtop->type.t & VT_BTYPE;
if(t==VT_INT) {
#ifdef TCC_ARM_VFP
r=vfpr(S, gv(S, RC_FLOAT));
u=u?0:0x10000;
o(S, 0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
r2=intr(S, S->vtop->r=get_reg(S, RC_INT));
r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
o(S, 0xEE100A10|(r<<16)|(r2<<12));
return;
#else
@ -2248,7 +2248,7 @@ void gen_cvt_ftoi(TCCState *S, int t)
func=TOK___fixunsdfsi;
} else {
r=fpr(S, gv(S, RC_FLOAT));
r2=intr(S, S->vtop->r=get_reg(S, RC_INT));
r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
o(S, 0xEE100170|(r2<<12)|r);
return;
}
@ -2271,8 +2271,8 @@ void gen_cvt_ftoi(TCCState *S, int t)
gfunc_call(S, 1);
vpushi(S, 0);
if(t == VT_LLONG)
S->vtop->r2 = REG_IRE2;
S->vtop->r = REG_IRET;
S->tccgen_vtop->r2 = REG_IRE2;
S->tccgen_vtop->r = REG_IRET;
return;
}
tcc_error(S, "unimplemented gen_cvt_ftoi!");
@ -2282,9 +2282,9 @@ void gen_cvt_ftoi(TCCState *S, int t)
void gen_cvt_ftof(TCCState* S, int t)
{
#ifdef TCC_ARM_VFP
if(((S->vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
if(((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
uint32_t r = vfpr(S, gv(S, RC_FLOAT));
o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->vtop->type.t));
o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->tccgen_vtop->type.t));
}
#else
/* all we have to do on i386 and FPA ARM is to put the float in a register */
@ -2298,11 +2298,11 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
int r1, r2;
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);
o(S, 0xE59F0000 | (intr(S, r1)<<12)); // ldr r1,[pc]
o(S, 0xEA000000); // b $+4
greloc(S, cur_text_section, sv->sym, S->ind, R_ARM_REL32);
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_REL32);
o(S, -12);
o(S, 0xe080000f | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1,r1,pc
o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]
@ -2319,7 +2319,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
void ggoto(TCCState* S)
{
gcall_or_jmp(S, 1);
S->vtop--;
S->tccgen_vtop--;
}
/* Save the stack pointer onto the stack and return the location of its address */
@ -2345,7 +2345,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
int r;
#if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check)
vpushv(S, S->vtop);
vpushv(S, S->tccgen_vtop);
#endif
r = intr(S, gv(S, RC_INT));
#if defined(CONFIG_TCC_BCHECK)
@ -2367,8 +2367,8 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
#if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check) {
vpushi(S, 0);
S->vtop->r = TREG_R0;
o(S, 0xe1a0000d | (S->vtop->r << 12)); // mov r0,sp
S->tccgen_vtop->r = TREG_R0;
o(S, 0xe1a0000d | (S->tccgen_vtop->r << 12)); // mov r0,sp
vswap(S);
vpush_helper_func(S, TOK___bound_new_region);
vrott(S, 3);

View file

@ -19,22 +19,22 @@ ST_FUNC void gen_le32(TCCState *S, int c);
#define USING_GLOBALS
#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 ? */
ST_FUNC void g(TCCState* S, int c)
{
int ind1;
if (S->nocode_wanted)
if (nocode_wanted)
return;
ind1 = S->ind + 1;
ind1 = ind + 1;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c;
S->ind = ind1;
section_realloc(cur_text_section, ind1);
cur_text_section->data[ind] = c;
ind = ind1;
}
ST_FUNC void gen_le16 (TCCState* S, int i)
@ -56,37 +56,37 @@ ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe)
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 */
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,
uint8_t *clobber_regs,
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,
const uint8_t *clobber_regs,
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;
}

View file

@ -107,13 +107,13 @@ static uint32_t fltr(int r)
// Add an instruction to text section:
ST_FUNC void o(TCCState *S, unsigned int c)
{
int ind1 = S->ind + 4;
if (S->nocode_wanted)
int ind1 = S->tccgen_ind + 4;
if (S->tccgen_nocode_wanted)
return;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
write32le(cur_text_section->data + S->ind, c);
S->ind = ind1;
write32le(cur_text_section->data + S->tccgen_ind, c);
S->tccgen_ind = ind1;
}
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)
{
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
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]
if (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)
{
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->vtop->r & VT_SYM)) {
greloca(S, cur_text_section, S->vtop->sym, S->ind,
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl .
}
else {
#ifdef CONFIG_TCC_BCHECK
S->vtop->r &= ~VT_MUSTBOUND;
S->tccgen_vtop->r &= ~VT_MUSTBOUND;
#endif
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);
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
}
@ -681,7 +681,7 @@ static void gen_bounds_prolog(TCCState *S)
{
/* leave some room for bound checking code */
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;
o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */
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 = 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);
/* generate bound local allocation */
if (offset_modified) {
saved_ind = S->ind;
S->ind = S->func_bound_ind;
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_ADR_GOT_PAGE, 0);
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->func_bound_ind;
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
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]
gen_bounds_call(S, TOK___bound_local_new);
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
/* generate bound check local freeing */
o(S, 0xf81f0fe0); /* str x0, [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
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]
gen_bounds_call(S, TOK___bound_local_delete);
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);
#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)
--nb_args;
@ -987,14 +987,14 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
t[0] = return_type;
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);
// Allocate space for structs replaced by pointer:
for (i = nb_args; i; i--)
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);
assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
stack = (stack + align - 1) & -align;
@ -1005,7 +1005,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
stack = (stack + 15) >> 4 << 4;
/* 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);
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
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) {
// struct replaced by pointer
int r = get_reg(S, RC_INT);
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);
vstore(S);
if (a[i] >= 32) {
@ -1035,36 +1035,36 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
}
else if (a[i] >= 32) {
// 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);
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);
vstore(S);
}
else if (is_float(S->vtop->type.t)) {
else if (is_float(S->tccgen_vtop->type.t)) {
gv(S, RC_FLOAT);
arm64_strv(S, arm64_type_size(S->vtop[0].type.t),
fltr(S->vtop[0].r), 31, a[i] - 32);
arm64_strv(S, arm64_type_size(S->tccgen_vtop[0].type.t),
fltr(S->tccgen_vtop[0].r), 31, a[i] - 32);
}
else {
gv(S, RC_INT);
arm64_strx(S, arm64_type_size(S->vtop[0].type.t),
intr(S, S->vtop[0].r), 31, a[i] - 32);
arm64_strx(S, arm64_type_size(S->tccgen_vtop[0].type.t),
intr(S, S->tccgen_vtop[0].r), 31, a[i] - 32);
}
}
--S->vtop;
--S->tccgen_vtop;
}
// 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)) {
// value in general-purpose registers
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
int align, size = type_size(&S->vtop->type, &align);
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
int align, size = type_size(&S->tccgen_vtop->type, &align);
if (size) {
S->vtop->type.t = VT_PTR;
S->tccgen_vtop->type.t = VT_PTR;
gaddrof(S);
gv(S, RC_R(a[i] / 2));
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]);
else if (a[i] < 32) {
// value in floating-point registers
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
uint32_t j, sz, n = arm64_hfa(&S->vtop->type, &sz);
S->vtop->type.t = VT_PTR;
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
S->tccgen_vtop->type.t = VT_PTR;
gaddrof(S);
gv(S, RC_R30);
for (j = 0; j < n; j++)
@ -1098,7 +1098,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (a[0] == 1) {
// indirect return: set x8 and discard the stack value
gv(S, RC_R(8));
--S->vtop;
--S->tccgen_vtop;
}
else
// 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);
arm64_gen_bl_or_b(S, 0);
--S->vtop;
--S->tccgen_vtop;
if (stack & 0xfff)
o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)
if (stack >> 12)
@ -1119,7 +1119,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (bt == VT_STRUCT && !(a[0] & 1)) {
// A struct was returned in registers, so write it out:
gv(S, RC_R(8));
--S->vtop;
--S->tccgen_vtop;
if (a[0] == 0) {
int align, size = type_size(return_type, &align);
assert(size <= 16);
@ -1220,11 +1220,11 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
tcc_free(S, t);
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:
o(S, 0xd503201f); // nop
o(S, 0xd503201f); // nop
S->loc = 0;
S->tccgen_loc = 0;
#ifdef CONFIG_TCC_BCHECK
if (S->do_bounds_check)
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)
{
int r;
--S->vtop; // we don't need the "arg"
--S->tccgen_vtop; // we don't need the "arg"
gaddrof(S);
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);
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)
@ -1281,7 +1281,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
gaddrof(S);
r0 = intr(S, gv(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);
if (!hfa) {
@ -1310,7 +1310,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
uint32_t b1, b2;
o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
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
if (fsize == 16) {
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, 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:
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, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
if (hfa == 1 || fsize == 16)
@ -1328,9 +1328,9 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
else {
// We need to change the layout of this HFA.
// 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
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, 0x4c402bdc | (uint32_t)fsize << 7 |
(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)]
}
// 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:
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);
gv(S, RC_R(0));
for (j = 0; j < n; j++)
@ -1394,7 +1394,7 @@ ST_FUNC void gfunc_return(TCCState *S, CType *func_type)
default:
assert(0);
}
S->vtop--;
S->tccgen_vtop--;
}
ST_FUNC void gfunc_epilog(TCCState *S)
@ -1404,10 +1404,10 @@ ST_FUNC void gfunc_epilog(TCCState *S)
gen_bounds_epilog(S);
#endif
if (S->loc) {
if (S->tccgen_loc) {
// Insert instructions to subtract size of stack frame from SP.
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 & 0xfff) // sub sp,sp,#(diff & 0xfff)
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:
ST_FUNC int gjmp(TCCState *S, int t)
{
int r = S->ind;
if (S->nocode_wanted)
int r = S->tccgen_ind;
if (S->tccgen_nocode_wanted)
return t;
o(S, t);
return r;
@ -1462,8 +1462,8 @@ ST_FUNC int gjmp(TCCState *S, int t)
// Generate branch to known address:
ST_FUNC void gjmp_addr(TCCState *S, int a)
{
assert(a - S->ind + 0x8000000 < 0x10000000);
o(S, 0x14000000 | ((a - S->ind) >> 2 & 0x3ffffff));
assert(a - S->tccgen_ind + 0x8000000 < 0x10000000);
o(S, 0x14000000 | ((a - S->tccgen_ind) >> 2 & 0x3ffffff));
}
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)
{
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);
}
}
@ -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)
{
int bt = S->vtop->type.t & VT_BTYPE;
int bt = S->tccgen_vtop->type.t & VT_BTYPE;
int inv = op & 1;
S->vtop->r = S->vtop->cmp_r;
S->tccgen_vtop->r = S->tccgen_vtop->cmp_r;
if (bt == VT_LDOUBLE) {
uint32_t a, b, f = fltr(gv(S, RC_FLOAT));
a = get_reg(S, RC_INT);
vpushi(S, 0);
S->vtop[0].r = a;
S->tccgen_vtop[0].r = a;
b = get_reg(S, RC_INT);
a = intr(S, a);
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, 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
--S->vtop;
--S->tccgen_vtop;
}
else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
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;
int rev = 1;
if (arm64_iconst(0, &S->vtop[0])) {
if (arm64_iconst(0, &S->tccgen_vtop[0])) {
vswap(S);
rev = 0;
}
if (arm64_iconst(&val, &S->vtop[-1])) {
if (arm64_iconst(&val, &S->tccgen_vtop[-1])) {
gv(S, RC_INT);
a = intr(S, S->vtop[0].r);
--S->vtop;
a = intr(S, S->tccgen_vtop[0].r);
--S->tccgen_vtop;
x = get_reg(S, RC_INT);
++S->vtop;
++S->tccgen_vtop;
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);
--S->vtop;
--S->tccgen_vtop;
return;
}
}
@ -1661,13 +1661,13 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l)
}
gv2(S, RC_INT, RC_INT);
assert(S->vtop[-1].r < VT_CONST && S->vtop[0].r < VT_CONST);
a = intr(S, S->vtop[-1].r);
b = intr(S, S->vtop[0].r);
S->vtop -= 2;
assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
a = intr(S, S->tccgen_vtop[-1].r);
b = intr(S, S->tccgen_vtop[0].r);
S->tccgen_vtop -= 2;
x = get_reg(S, RC_INT);
++S->vtop;
S->vtop[0].r = x;
++S->tccgen_vtop;
S->tccgen_vtop[0].r = x;
x = intr(S, x);
switch (op) {
@ -1778,8 +1778,8 @@ ST_FUNC void gen_opf(TCCState *S, int op)
{
uint32_t x, a, b, dbl;
if (S->vtop[0].type.t == VT_LDOUBLE) {
CType type = S->vtop[0].type;
if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
CType type = S->tccgen_vtop[0].type;
int func = 0;
int cond = -1;
switch (op) {
@ -1799,9 +1799,9 @@ ST_FUNC void gen_opf(TCCState *S, int op)
vrott(S, 3);
gfunc_call(S, 2);
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)
S->vtop->type = type;
S->tccgen_vtop->type = type;
else {
o(S, 0x7100001f); // cmp w0,#0
o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
@ -1809,24 +1809,24 @@ ST_FUNC void gen_opf(TCCState *S, int op)
return;
}
dbl = S->vtop[0].type.t != VT_FLOAT;
dbl = S->tccgen_vtop[0].type.t != VT_FLOAT;
gv2(S, RC_FLOAT, RC_FLOAT);
assert(S->vtop[-1].r < VT_CONST && S->vtop[0].r < VT_CONST);
a = fltr(S->vtop[-1].r);
b = fltr(S->vtop[0].r);
S->vtop -= 2;
assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
a = fltr(S->tccgen_vtop[-1].r);
b = fltr(S->tccgen_vtop[0].r);
S->tccgen_vtop -= 2;
switch (op) {
case TOK_EQ: case TOK_NE:
case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
x = get_reg(S, RC_INT);
++S->vtop;
S->vtop[0].r = x;
++S->tccgen_vtop;
S->tccgen_vtop[0].r = x;
x = intr(S, x);
break;
default:
x = get_reg(S, RC_FLOAT);
++S->vtop;
S->vtop[0].r = x;
++S->tccgen_vtop;
S->tccgen_vtop[0].r = x;
x = fltr(x);
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)
{
if (t == VT_LDOUBLE) {
int f = S->vtop->type.t;
int f = S->tccgen_vtop->type.t;
int func = (f & VT_BTYPE) == VT_LLONG ?
(f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
(f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
@ -1902,18 +1902,18 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
vrott(S, 2);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->type.t = t;
S->vtop->r = REG_FRET;
S->tccgen_vtop->type.t = t;
S->tccgen_vtop->r = REG_FRET;
return;
}
else {
int d, n = intr(S, gv(S, RC_INT));
int s = !(S->vtop->type.t & VT_UNSIGNED);
uint32_t l = ((S->vtop->type.t & VT_BTYPE) == VT_LLONG);
--S->vtop;
int s = !(S->tccgen_vtop->type.t & VT_UNSIGNED);
uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG);
--S->tccgen_vtop;
d = get_reg(S, RC_FLOAT);
++S->vtop;
S->vtop[0].r = d;
++S->tccgen_vtop;
S->tccgen_vtop[0].r = d;
o(S, 0x1e220000 | (uint32_t)!s << 16 |
(uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
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)
{
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 ?
(t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
(t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
@ -1930,17 +1930,17 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
vrott(S, 2);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->type.t = t;
S->vtop->r = REG_IRET;
S->tccgen_vtop->type.t = t;
S->tccgen_vtop->r = REG_IRET;
return;
}
else {
int d, n = fltr(gv(S, RC_FLOAT));
uint32_t l = ((S->vtop->type.t & VT_BTYPE) != VT_FLOAT);
--S->vtop;
uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT);
--S->tccgen_vtop;
d = get_reg(S, RC_INT);
++S->vtop;
S->vtop[0].r = d;
++S->tccgen_vtop;
S->tccgen_vtop[0].r = d;
o(S, 0x1e380000 |
(uint32_t)!!(t & VT_UNSIGNED) << 16 |
(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)
{
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(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
if (t == f)
@ -1964,18 +1964,18 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
vrott(S, 2);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->type.t = t;
S->vtop->r = REG_FRET;
S->tccgen_vtop->type.t = t;
S->tccgen_vtop->r = REG_FRET;
}
else {
int x, a;
gv(S, RC_FLOAT);
assert(S->vtop[0].r < VT_CONST);
a = fltr(S->vtop[0].r);
--S->vtop;
assert(S->tccgen_vtop[0].r < VT_CONST);
a = fltr(S->tccgen_vtop[0].r);
--S->tccgen_vtop;
x = get_reg(S, RC_FLOAT);
++S->vtop;
S->vtop[0].r = x;
++S->tccgen_vtop;
S->tccgen_vtop[0].r = x;
x = fltr(x);
if (f == VT_FLOAT)
@ -1991,11 +1991,11 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
int r1, r2;
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);
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
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 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1]
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)
{
arm64_gen_bl_or_b(S, 1);
--S->vtop;
--S->tccgen_vtop;
}
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;
gv2(S, RC_INT, RC_INT);
vpushi(S, 0);
S->vtop->r = get_reg(S, RC_INT);
S->tccgen_vtop->r = get_reg(S, RC_INT);
vpushi(S, 0);
S->vtop->r = get_reg(S, RC_INT);
S->tccgen_vtop->r = get_reg(S, RC_INT);
vpushi(S, 0);
S->vtop->r = get_reg(S, RC_INT);
beg = intr(S, S->vtop[-4].r); // x0
end = intr(S, S->vtop[-3].r); // x1
dsz = intr(S, S->vtop[-2].r); // x2
isz = intr(S, S->vtop[-1].r); // x3
p = intr(S, S->vtop[0].r); // x4
S->vtop -= 5;
S->tccgen_vtop->r = get_reg(S, RC_INT);
beg = intr(S, S->tccgen_vtop[-4].r); // x0
end = intr(S, S->tccgen_vtop[-3].r); // x1
dsz = intr(S, S->tccgen_vtop[-2].r); // x2
isz = intr(S, S->tccgen_vtop[-1].r); // x3
p = intr(S, S->tccgen_vtop[0].r); // x4
S->tccgen_vtop -= 5;
o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el0
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, 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)
b1 = S->ind; o(S, 0x14000000); // b
lab1 = S->ind;
b1 = S->tccgen_ind; o(S, 0x14000000); // b
lab1 = S->tccgen_ind;
o(S, 0xd50b7b20 | p); // dc cvau,x(p)
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, 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, 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)
b1 = S->ind; o(S, 0x14000000); // b
lab1 = S->ind;
b1 = S->tccgen_ind; o(S, 0x14000000); // b
lab1 = S->tccgen_ind;
o(S, 0xd50b7520 | p); // ic ivau,x(p)
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, 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, 0xd5033fdf); // isb
}
@ -2074,7 +2074,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
uint32_t r;
#if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check)
vpushv(S, S->vtop);
vpushv(S, S->tccgen_vtop);
#endif
r = intr(S, gv(S, RC_INT));
#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 (S->do_bounds_check) {
vpushi(S, 0);
S->vtop->r = TREG_R(0);
o(S, 0x910003e0 | S->vtop->r); // mov r0,sp
S->tccgen_vtop->r = TREG_R(0);
o(S, 0x910003e0 | S->tccgen_vtop->r); // mov r0,sp
vswap(S);
vpush_helper_func(S, TOK___bound_new_region);
vrott(S, 3);

178
c67-gen.c
View file

@ -189,19 +189,19 @@ FILE *f = NULL;
void C67_g(TCCState* S, int c)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
#ifdef ASSEMBLY_LISTING_C67
fprintf(f, " %08X", c);
#endif
ind1 = S->ind + 4;
ind1 = S->tccgen_ind + 4;
if (ind1 > (int) cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c & 0xff;
cur_text_section->data[S->ind + 1] = (c >> 8) & 0xff;
cur_text_section->data[S->ind + 2] = (c >> 16) & 0xff;
cur_text_section->data[S->ind + 3] = (c >> 24) & 0xff;
S->ind = ind1;
cur_text_section->data[S->tccgen_ind] = c & 0xff;
cur_text_section->data[S->tccgen_ind + 1] = (c >> 8) & 0xff;
cur_text_section->data[S->tccgen_ind + 2] = (c >> 16) & 0xff;
cur_text_section->data[S->tccgen_ind + 3] = (c >> 24) & 0xff;
S->tccgen_ind = ind1;
}
@ -220,7 +220,7 @@ void gsym_addr(TCCState *S, int t, int a)
// define a label that will be relocated
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, a, 0);
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);
greloc(S, cur_text_section, sym, t, R_C60LO16);
greloc(S, cur_text_section, sym, t + 4, R_C60HI16);
@ -1395,7 +1395,7 @@ void C67_B_DISP(TCCState *S, int disp) // B +2 Branch with constant displacem
// so add in how many words into the fetch packet the branch is
C67_asm(S, "B DISP", disp + ((S->ind & 31) >> 2), 0, 0);
C67_asm(S, "B DISP", disp + ((S->tccgen_ind & 31) >> 2), 0, 0);
}
void C67_NOP(TCCState* S, int n)
@ -1625,8 +1625,8 @@ void load(TCCState *S, int r, SValue * sv)
C67_NOP(S, 4); // NOP 4
return;
} else if (fr & VT_SYM) {
greloc(S, cur_text_section, sv->sym, S->ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sv->sym, S->ind + 4, R_C60HI16);
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);
C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
@ -1681,8 +1681,8 @@ void load(TCCState *S, int r, SValue * sv)
} else {
if (v == VT_CONST) {
if (fr & VT_SYM) {
greloc(S, cur_text_section, sv->sym, S->ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sv->sym, S->ind + 4, R_C60HI16);
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);
}
C67_MVKL(S, r, fc); //r=reg to load, constant
C67_MVKH(S, r, fc); //r=reg to load, constant
@ -1736,8 +1736,8 @@ void store(TCCState *S, int r, SValue * v)
/* constant memory reference */
if (v->r & VT_SYM) {
greloc(S, cur_text_section, v->sym, S->ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, v->sym, S->ind + 4, R_C60HI16);
greloc(S, cur_text_section, v->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, v->sym, S->tccgen_ind + 4, R_C60HI16);
}
C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
C67_MVKH(S, C67_A0, fc); //r=reg to load, constant
@ -1818,15 +1818,15 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
int r;
Sym *sym;
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
/* constant case */
if (S->vtop->r & VT_SYM) {
if (S->tccgen_vtop->r & VT_SYM) {
/* relocation case */
// get add into A0, then start the jump B3
greloc(S, cur_text_section, S->vtop->sym, S->ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, S->vtop->sym, S->ind + 4, R_C60HI16);
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 4, R_C60HI16);
C67_MVKL(S, C67_A0, 0); //r=reg to load, constant
C67_MVKH(S, C67_A0, 0); //r=reg to load, constant
@ -1837,9 +1837,9 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
} else {
// Call, must load return address into B3 during delay slots
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, S->ind + 12, 0); // symbol for return address
greloc(S, cur_text_section, sym, S->ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16);
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address
greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
C67_MVKH(S, C67_B3, 0); //r=reg to load, constant
C67_NOP(S, 3); // put remaining NOPs
@ -1858,9 +1858,9 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
} else {
// Call, must load return address into B3 during delay slots
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, S->ind + 12, 0); // symbol for return address
greloc(S, cur_text_section, sym, S->ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16);
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address
greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
C67_MVKH(S, C67_B3, 0); //r=reg to load, constant
C67_NOP(S, 3); // put remaining NOPs
@ -1888,18 +1888,18 @@ void gfunc_call(TCCState *S, int nb_args)
}
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) {
ALWAYS_ASSERT(FALSE);
} else {
/* simple type (currently always same size) */
/* XXX: implicit cast ? */
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
tcc_error(S, "long long not supported");
} else if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
} else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
tcc_error(S, "long double not supported");
} else if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
} else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
size = 8;
} else {
size = 4;
@ -1919,7 +1919,7 @@ void gfunc_call(TCCState *S, int nb_args)
}
args_sizes[i] = size;
}
S->vtop--;
S->tccgen_vtop--;
}
// POP all the params on the stack into registers for the
// immediate call (in reverse order)
@ -1932,7 +1932,7 @@ void gfunc_call(TCCState *S, int nb_args)
C67_POP(S, TREG_C67_A4 + i * 2);
}
gcall_or_jmp(S, 0);
S->vtop--;
S->tccgen_vtop--;
}
@ -1997,11 +1997,11 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
// place all the args passed in regs onto the stack
S->loc = 0;
S->tccgen_loc = 0;
for (i = 0; i < NoOfCurFuncArgs; i++) {
ParamLocOnStack[i] = S->loc; // remember where the param is
S->loc += -8;
ParamLocOnStack[i] = S->tccgen_loc; // remember where the param is
S->tccgen_loc += -8;
C67_PUSH(S, TREG_C67_A4 + i * 2);
@ -2010,9 +2010,9 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
}
}
TotalBytesPushedOnStack = -S->loc;
TotalBytesPushedOnStack = -S->tccgen_loc;
func_sub_sp_offset = S->ind; // remember where we put the stack instruction
func_sub_sp_offset = S->tccgen_ind; // remember where we put the stack instruction
C67_ADDK(S, 0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
C67_PUSH(S, C67_A0);
@ -2023,7 +2023,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
void gfunc_epilog(TCCState* S)
{
{
int local = (-S->loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
int local = (-S->tccgen_loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
C67_POP(S, C67_B3);
C67_NOP(S, 4); // NOP wait for load
C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_B3); // B.S2 B3
@ -2049,8 +2049,8 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
/* generate a jump to a label */
int gjmp(TCCState* S, int t)
{
int ind1 = S->ind;
if (S->nocode_wanted)
int ind1 = S->tccgen_ind;
if (S->tccgen_nocode_wanted)
return t;
C67_MVKL(S, C67_A0, t); //r=reg to load, constant
@ -2070,9 +2070,9 @@ void gjmp_addr(TCCState *S, int a)
// define a label that will be relocated
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, a, 0);
greloc(S, cur_text_section, sym, S->ind, R_C60LO16);
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16);
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);
greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16);
greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
gjmp(S, 0); // place a zero there later the symbol will be added to it
}
@ -2082,12 +2082,12 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
{
int ind1;
int inv = op & 1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return t;
/* fast case : can jump directly since flags are set */
// C67 uses B2 sort of as flags register
ind1 = S->ind;
ind1 = S->tccgen_ind;
C67_MVKL(S, C67_A0, t); //r=reg to load, constant
C67_MVKH(S, C67_A0, t); //r=reg to load, constant
@ -2150,8 +2150,8 @@ void gen_opi(TCCState *S, int op)
else
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
C67_compare_reg = C67_B2;
@ -2199,7 +2199,7 @@ void gen_opi(TCCState *S, int op)
else
ALWAYS_ASSERT(FALSE);
S->vtop--;
S->tccgen_vtop--;
if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(S, 0x80);
break;
@ -2225,33 +2225,33 @@ void gen_opi(TCCState *S, int op)
case '*':
case TOK_UMULL:
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr
C67_NOP(S, 8); // NOP 8 for worst case
break;
case TOK_SHL:
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
C67_SHL(S, fr, r); // arithmetic/logical shift
break;
case TOK_SHR:
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
C67_SHRU(S, fr, r); // logical shift
break;
case TOK_SAR:
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
C67_SHR(S, fr, r); // arithmetic shift
break;
@ -2264,8 +2264,8 @@ void gen_opi(TCCState *S, int op)
vrott(S, 3);
gfunc_call(S, 2);
vpushi(S, 0);
S->vtop->r = REG_IRET;
S->vtop->r2 = VT_CONST;
S->tccgen_vtop->r = REG_IRET;
S->tccgen_vtop->r2 = VT_CONST;
break;
case TOK_UDIV:
case TOK_PDIV:
@ -2296,10 +2296,10 @@ void gen_opf(TCCState *S, int op)
else
gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
ft = S->vtop->type.t;
fc = S->vtop->c.i;
r = S->vtop->r;
fr = S->vtop[-1].r;
ft = S->tccgen_vtop->type.t;
fc = S->tccgen_vtop->c.i;
r = S->tccgen_vtop->r;
fr = S->tccgen_vtop[-1].r;
if ((ft & VT_BTYPE) == VT_LDOUBLE)
@ -2307,8 +2307,8 @@ void gen_opf(TCCState *S, int op)
if (op >= TOK_ULT && op <= TOK_GT) {
r = S->vtop[-1].r;
fr = S->vtop[0].r;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
C67_compare_reg = C67_B2;
@ -2367,7 +2367,7 @@ void gen_opf(TCCState *S, int op)
C67_ADDSP(S, r, fr); // ADD fr,r,fr
C67_NOP(S, 3);
}
S->vtop--;
S->tccgen_vtop--;
} else if (op == '-') {
if ((ft & VT_BTYPE) == VT_DOUBLE) {
C67_SUBDP(S, r, fr); // SUB fr,r,fr
@ -2376,7 +2376,7 @@ void gen_opf(TCCState *S, int op)
C67_SUBSP(S, r, fr); // SUB fr,r,fr
C67_NOP(S, 3);
}
S->vtop--;
S->tccgen_vtop--;
} else if (op == '*') {
if ((ft & VT_BTYPE) == VT_DOUBLE) {
C67_MPYDP(S, r, fr); // MPY fr,r,fr
@ -2385,7 +2385,7 @@ void gen_opf(TCCState *S, int op)
C67_MPYSP(S, r, fr); // MPY fr,r,fr
C67_NOP(S, 3);
}
S->vtop--;
S->tccgen_vtop--;
} else if (op == '/') {
if ((ft & VT_BTYPE) == VT_DOUBLE) {
// must call intrinsic DP floating point divide
@ -2395,8 +2395,8 @@ void gen_opf(TCCState *S, int op)
vrott(S, 3);
gfunc_call(S, 2);
vpushi(S, 0);
S->vtop->r = REG_FRET;
S->vtop->r2 = REG_IRE2;
S->tccgen_vtop->r = REG_FRET;
S->tccgen_vtop->r2 = REG_IRE2;
} else {
// must call intrinsic SP floating point divide
@ -2406,8 +2406,8 @@ void gen_opf(TCCState *S, int op)
vrott(S, 3);
gfunc_call(S, 2);
vpushi(S, 0);
S->vtop->r = REG_FRET;
S->vtop->r2 = VT_CONST;
S->tccgen_vtop->r = REG_FRET;
S->tccgen_vtop->r2 = VT_CONST;
}
} else
ALWAYS_ASSERT(FALSE);
@ -2424,7 +2424,7 @@ void gen_cvt_itof(TCCState *S, int t)
int r;
gv(S, RC_INT);
r = S->vtop->r;
r = S->tccgen_vtop->r;
if ((t & VT_BTYPE) == VT_DOUBLE) {
if (t & VT_UNSIGNED)
@ -2433,14 +2433,14 @@ void gen_cvt_itof(TCCState *S, int t)
C67_INTDP(S, r, r);
C67_NOP(S, 4);
S->vtop->type.t = VT_DOUBLE;
S->tccgen_vtop->type.t = VT_DOUBLE;
} else {
if (t & VT_UNSIGNED)
C67_INTSPU(S, r, r);
else
C67_INTSP(S, r, r);
C67_NOP(S, 3);
S->vtop->type.t = VT_FLOAT;
S->tccgen_vtop->type.t = VT_FLOAT;
}
}
@ -2452,12 +2452,12 @@ void gen_cvt_ftoi(TCCState *S, int t)
int r;
gv(S, RC_FLOAT);
r = S->vtop->r;
r = S->tccgen_vtop->r;
if (t != VT_INT)
tcc_error(S, "long long not supported");
else {
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
C67_DPTRUNC(S, r, r);
C67_NOP(S, 3);
} else {
@ -2465,7 +2465,7 @@ void gen_cvt_ftoi(TCCState *S, int t)
C67_NOP(S, 3);
}
S->vtop->type.t = VT_INT;
S->tccgen_vtop->type.t = VT_INT;
}
}
@ -2475,26 +2475,26 @@ void gen_cvt_ftof(TCCState *S, int t)
{
int r, r2;
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
(t & VT_BTYPE) == VT_FLOAT) {
// convert double to float
gv(S, RC_FLOAT); // get it in a register pair
r = S->vtop->r;
r = S->tccgen_vtop->r;
C67_DPSP(S, r, r); // convert it to SP same register
C67_NOP(S, 3);
S->vtop->type.t = VT_FLOAT;
S->vtop->r2 = VT_CONST; // set this as unused
} else if ((S->vtop->type.t & VT_BTYPE) == VT_FLOAT &&
S->tccgen_vtop->type.t = VT_FLOAT;
S->tccgen_vtop->r2 = VT_CONST; // set this as unused
} else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT &&
(t & VT_BTYPE) == VT_DOUBLE) {
// convert float to double
gv(S, RC_FLOAT); // get it in a register
r = S->vtop->r;
r = S->tccgen_vtop->r;
if (r == TREG_EAX) { // make sure the paired reg is avail
r2 = get_reg(S, RC_ECX);
@ -2508,8 +2508,8 @@ void gen_cvt_ftof(TCCState *S, int t)
C67_SPDP(S, r, r); // convert it to DP same register
C67_NOP(S, 1);
S->vtop->type.t = VT_DOUBLE;
S->vtop->r2 = r2; // set this as unused
S->tccgen_vtop->type.t = VT_DOUBLE;
S->tccgen_vtop->r2 = r2; // set this as unused
} else {
ALWAYS_ASSERT(FALSE);
}
@ -2519,7 +2519,7 @@ void gen_cvt_ftof(TCCState *S, int t)
void ggoto(TCCState* S)
{
gcall_or_jmp(S, 1);
S->vtop--;
S->tccgen_vtop--;
}
/* Save the stack pointer onto the stack and return the location of its address */

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)
{
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;
char c;
*type = OP_REG64;
@ -322,20 +322,20 @@ static int asm_parse_reg(TCCState *S, unsigned int *type)
{
int reg = 0;
*type = 0;
if (S->tok != '%')
if (S->tccpp_tok != '%')
goto error_32;
next(S);
if (S->tok >= TOK_ASM_eax && S->tok <= TOK_ASM_edi) {
reg = S->tok - TOK_ASM_eax;
if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {
reg = S->tccpp_tok - TOK_ASM_eax;
*type = OP_REG32;
#ifdef TCC_TARGET_X86_64
} else if (S->tok >= TOK_ASM_rax && S->tok <= TOK_ASM_rdi) {
reg = S->tok - TOK_ASM_rax;
} else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {
reg = S->tccpp_tok - TOK_ASM_rax;
*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. */
*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)) {
;
#endif
@ -354,15 +354,15 @@ static void parse_operand(TCCState *S, Operand *op)
const char *p;
indir = 0;
if (S->tok == '*') {
if (S->tccpp_tok == '*') {
next(S);
indir = OP_INDIR;
}
if (S->tok == '%') {
if (S->tccpp_tok == '%') {
next(S);
if (S->tok >= TOK_ASM_al && S->tok <= TOK_ASM_db7) {
reg = S->tok - TOK_ASM_al;
if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {
reg = S->tccpp_tok - TOK_ASM_al;
op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
op->reg = reg & 7;
if ((op->type & OP_REG) && op->reg == TREG_XAX)
@ -371,21 +371,21 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_CL;
else if (op->type == OP_REG16 && op->reg == TREG_XDX)
op->type |= OP_DX;
} else if (S->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->reg = S->tok - TOK_ASM_dr0;
} else if (S->tok >= TOK_ASM_es && S->tok <= TOK_ASM_gs) {
op->reg = S->tccpp_tok - TOK_ASM_dr0;
} else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {
op->type = OP_SEG;
op->reg = S->tok - TOK_ASM_es;
} else if (S->tok == TOK_ASM_st) {
op->reg = S->tccpp_tok - TOK_ASM_es;
} else if (S->tccpp_tok == TOK_ASM_st) {
op->type = OP_ST;
op->reg = 0;
next(S);
if (S->tok == '(') {
if (S->tccpp_tok == '(') {
next(S);
if (S->tok != TOK_PPNUM)
if (S->tccpp_tok != TOK_PPNUM)
goto reg_error;
p = S->tokc.str.data;
p = S->tccpp_tokc.str.data;
reg = p[0] - '0';
if ((unsigned)reg >= 8 || p[1] != '\0')
goto reg_error;
@ -397,19 +397,19 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_ST0;
goto no_skip;
#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->reg = 4 + S->tok - TOK_ASM_spl;
} else if ((op->reg = asm_parse_numeric_reg(S, S->tok, &op->type)) >= 0) {
op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;
} else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {
;
#endif
} else {
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);
no_skip: ;
} else if (S->tok == '$') {
} else if (S->tccpp_tok == '$') {
/* constant value */
next(S);
asm_expr(S, &e);
@ -433,19 +433,19 @@ static void parse_operand(TCCState *S, Operand *op)
op->reg = -1;
op->reg2 = -1;
op->shift = 0;
if (S->tok != '(') {
if (S->tccpp_tok != '(') {
asm_expr(S, &e);
op->e = e;
} else {
next(S);
if (S->tok == '%') {
if (S->tccpp_tok == '%') {
unget_tok(S, '(');
op->e.v = 0;
op->e.sym = NULL;
} else {
/* bracketed offset expression */
asm_expr(S, &e);
if (S->tok != ')')
if (S->tccpp_tok != ')')
expect(S, ")");
next(S);
op->e.v = e.v;
@ -453,18 +453,18 @@ static void parse_operand(TCCState *S, Operand *op)
}
op->e.pcrel = 0;
}
if (S->tok == '(') {
if (S->tccpp_tok == '(') {
unsigned int type = 0;
next(S);
if (S->tok != ',') {
if (S->tccpp_tok != ',') {
op->reg = asm_parse_reg(S, &type);
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
if (S->tok != ',') {
if (S->tccpp_tok != ',') {
op->reg2 = asm_parse_reg(S, &type);
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
op->shift = get_reg_shift(S);
}
@ -507,7 +507,7 @@ static void gen_disp32(TCCState *S, ExprValue *pe)
that the TCC compiler behaves differently here because
it always outputs a relocation to ease (future) code
elimination in the linker */
gen_le32(S, pe->v + esym->st_value - S->ind - 4);
gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4);
} else {
if (sym && sym->type.t == VT_VOID) {
sym->type.t = VT_FUNC;
@ -538,7 +538,7 @@ static inline int asm_modrm(TCCState *S, int reg, Operand *op)
ExprValue *pe = &op->e;
g(S, 0x05 + (reg << 3));
gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
return S->ind;
return S->tccgen_ind;
#endif
} else {
sib_reg1 = op->reg;
@ -705,13 +705,13 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
seg_prefix = 0;
alltypes = 0;
for(;;) {
if (S->tok == ';' || S->tok == TOK_LINEFEED)
if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)
break;
if (nb_ops >= MAX_OPERANDS) {
tcc_error(S, "incorrect number of operands");
}
parse_operand(S, pop);
if (S->tok == ':') {
if (S->tccpp_tok == ':') {
if (pop->type != OP_SEG || seg_prefix)
tcc_error(S, "incorrect prefix");
seg_prefix = segment_prefixes[pop->reg];
@ -723,7 +723,7 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
}
pop++;
nb_ops++;
if (S->tok != ',')
if (S->tccpp_tok != ',')
break;
next(S);
}
@ -1038,7 +1038,7 @@ again:
esym = elfsym(S, ops[0].e.sym);
if (!esym || esym->st_shndx != cur_text_section->sh_num)
goto no_short_jump;
jmp_disp = ops[0].e.v + esym->st_value - S->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) {
/* OK to generate jump */
ops[0].e.sym = 0;
@ -1136,7 +1136,7 @@ again:
/* after immediate operands, adjust pc-relative address */
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

View file

@ -108,13 +108,13 @@ static void gen_bounds_epilog(TCCState *S);
ST_FUNC void g(TCCState* S, int c)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 1;
ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c;
S->ind = ind1;
cur_text_section->data[S->tccgen_ind] = c;
S->tccgen_ind = ind1;
}
ST_FUNC void o(TCCState* S, unsigned int c)
@ -154,10 +154,10 @@ ST_FUNC void gsym_addr(TCCState *S, int t, int a)
static int oad(TCCState* S, int c, int s)
{
int t;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return s;
o(S, c);
t = S->ind;
t = S->tccgen_ind;
gen_le32(S, s);
return t;
}
@ -175,14 +175,14 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c)
{
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);
}
ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c)
{
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);
}
@ -349,7 +349,7 @@ static void gen_static_call(TCCState *S, int v)
sym = external_helper_sym(S, v);
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
@ -357,10 +357,10 @@ static void gen_static_call(TCCState *S, int v)
static void gcall_or_jmp(TCCState* S, int is_jmp)
{
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 */
greloc(S, cur_text_section, S->vtop->sym, S->ind + 1, R_386_PC32);
oad(S, 0xe8 + is_jmp, S->vtop->c.i - 4); /* call/jmp im */
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_386_PC32);
oad(S, 0xe8 + is_jmp, S->tccgen_vtop->c.i - 4); /* call/jmp im */
} else {
/* otherwise, indirect call */
r = gv(S, RC_INT);
@ -414,8 +414,8 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
args_size = 0;
for(i = 0;i < nb_args; i++) {
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
size = type_size(&S->vtop->type, &align);
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
size = type_size(&S->tccgen_vtop->type, &align);
/* align to stack align size */
size = (size + 3) & ~3;
/* 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);
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);
vstore(S);
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 */
if ((S->vtop->type.t & VT_BTYPE) == VT_FLOAT)
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT)
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;
else
size = 12;
@ -458,19 +458,19 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
/* simple type (currently always same size) */
/* XXX: implicit cast ? */
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;
o(S, 0x50 + S->vtop->r2); /* push r */
o(S, 0x50 + S->tccgen_vtop->r2); /* push r */
} else {
size = 4;
}
o(S, 0x50 + r); /* push r */
args_size += size;
}
S->vtop--;
S->tccgen_vtop--;
}
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;
/* fast call case */
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
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;
#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)
gadd_sp(S, args_size);
S->vtop--;
S->tccgen_vtop--;
}
#ifdef TCC_TARGET_PE
@ -523,7 +523,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
sym = func_type->ref;
func_call = sym->f.func_call;
addr = 8;
S->loc = 0;
S->tccgen_loc = 0;
S->tccgen_func_vc = 0;
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;
S->ind += FUNC_PROLOG_SIZE;
func_sub_sp_offset = S->ind;
S->tccgen_ind += FUNC_PROLOG_SIZE;
func_sub_sp_offset = S->tccgen_ind;
/* if the function returns a structure, then add an
implicit pointer parameter */
#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD
@ -567,10 +567,10 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
#endif
if (param_index < fastcall_nb_regs) {
/* save FASTCALL register */
S->loc -= 4;
S->tccgen_loc -= 4;
o(S, 0x89); /* movl */
gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->loc);
param_addr = S->loc;
gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->tccgen_loc);
param_addr = S->tccgen_loc;
} else {
param_addr = addr;
addr += size;
@ -605,7 +605,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
#endif
/* align local size to word & save local variables */
v = (-S->loc + 3) & -4;
v = (-S->tccgen_loc + 3) & -4;
#if USE_EBX
o(S, 0x8b);
@ -620,8 +620,8 @@ ST_FUNC void gfunc_epilog(TCCState *S)
g(S, func_ret_sub);
g(S, func_ret_sub >> 8);
}
saved_ind = S->ind;
S->ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
saved_ind = S->tccgen_ind;
S->tccgen_ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE
if (v >= 4096) {
oad(S, 0xb8, v); /* mov stacksize, %eax */
@ -637,7 +637,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
#endif
}
o(S, 0x53 * USE_EBX); /* push ebx */
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
/* generate a jump to a label */
@ -650,12 +650,12 @@ ST_FUNC int gjmp(TCCState *S, int t)
ST_FUNC void gjmp_addr(TCCState* S, int a)
{
int r;
r = a - S->ind - 2;
r = a - S->tccgen_ind - 2;
if (r == (char)r) {
g(S, 0xeb);
g(S, r);
} else {
oad(S, 0xe9, a - S->ind - 5);
oad(S, 0xe9, a - S->tccgen_ind - 5);
}
}
@ -663,7 +663,7 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
/* generate a jump to a fixed address */
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)
g(S, op - 32), g(r);
else
@ -701,12 +701,12 @@ ST_FUNC void gen_opi(TCCState *S, int op)
case TOK_ADDC1: /* add with carry generation */
opc = 0;
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 */
vswap(S);
r = gv(S, RC_INT);
vswap(S);
c = S->vtop->c.i;
c = S->tccgen_vtop->c.i;
if (c == (char)c) {
/* generate inc and dec for smaller code */
if ((c == 1 || c == -1) && (op == '+' || op == '-')) {
@ -723,12 +723,12 @@ ST_FUNC void gen_opi(TCCState *S, int op)
}
} else {
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
o(S, (opc << 3) | 0x01);
o(S, 0xc0 + r + fr * 8);
}
S->vtop--;
S->tccgen_vtop--;
if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(S, op);
break;
@ -753,9 +753,9 @@ ST_FUNC void gen_opi(TCCState *S, int op)
goto gen_op8;
case '*':
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
o(S, 0xaf0f); /* imul fr, r */
o(S, 0xc0 + fr + r * 8);
break;
@ -769,23 +769,23 @@ ST_FUNC void gen_opi(TCCState *S, int op)
opc = 7;
gen_shift:
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 */
vswap(S);
r = gv(S, RC_INT);
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, opc | r);
g(S, c);
} else {
/* we generate the shift in 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, opc | r);
}
S->vtop--;
S->tccgen_vtop--;
break;
case '/':
case TOK_UDIV:
@ -796,16 +796,16 @@ ST_FUNC void gen_opi(TCCState *S, int op)
/* first operand must be in eax */
/* XXX: need better constraint for second operand */
gv2(S, RC_EAX, RC_ECX);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
save_reg(S, TREG_EDX);
/* save EAX too if used otherwise */
save_reg_upstack(S, TREG_EAX, 1);
if (op == TOK_UMULL) {
o(S, 0xf7); /* mul fr */
o(S, 0xe0 + fr);
S->vtop->r2 = TREG_EDX;
S->tccgen_vtop->r2 = TREG_EDX;
r = TREG_EAX;
} else {
if (op == TOK_UDIV || op == TOK_UMOD) {
@ -820,7 +820,7 @@ ST_FUNC void gen_opi(TCCState *S, int op)
else
r = TREG_EAX;
}
S->vtop->r = r;
S->tccgen_vtop->r = r;
break;
default:
opc = 7;
@ -842,17 +842,17 @@ ST_FUNC void gen_opf(TCCState *S, int op)
}
/* 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);
gv(S, RC_FLOAT);
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);
/* must put at least one value in the floating point register */
if ((S->vtop[-1].r & VT_LVAL) &&
(S->vtop[0].r & VT_LVAL)) {
if ((S->tccgen_vtop[-1].r & VT_LVAL) &&
(S->tccgen_vtop[0].r & VT_LVAL)) {
vswap(S);
gv(S, RC_FLOAT);
vswap(S);
@ -860,13 +860,13 @@ ST_FUNC void gen_opf(TCCState *S, int op)
swapped = 0;
/* swap the stack if needed so that t1 is the register and t2 is
the memory reference */
if (S->vtop[-1].r & VT_LVAL) {
if (S->tccgen_vtop[-1].r & VT_LVAL) {
vswap(S);
swapped = 1;
}
if (op >= TOK_ULT && op <= TOK_GT) {
/* 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 */
if (op == TOK_GE || op == TOK_GT)
swapped = !swapped;
@ -893,12 +893,12 @@ ST_FUNC void gen_opf(TCCState *S, int op)
o(S, 0x45c4f6); /* test $0x45, %ah */
op = TOK_EQ;
}
S->vtop--;
S->tccgen_vtop--;
vset_VT_CMP(S, op);
} else {
/* no memory reference possible for long double operations */
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
load(S, TREG_ST0, S->vtop);
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
load(S, TREG_ST0, S->tccgen_vtop);
swapped = !swapped;
}
@ -921,14 +921,14 @@ ST_FUNC void gen_opf(TCCState *S, int op)
a++;
break;
}
ft = S->vtop->type.t;
fc = S->vtop->c.i;
ft = S->tccgen_vtop->type.t;
fc = S->tccgen_vtop->c.i;
if ((ft & VT_BTYPE) == VT_LDOUBLE) {
o(S, 0xde); /* fxxxp %st, %st(1) */
o(S, 0xc1 + (a << 3));
} else {
/* if saved lvalue, then we must reload it */
r = S->vtop->r;
r = S->tccgen_vtop->r;
if ((r & VT_VALMASK) == VT_LLOCAL) {
SValue v1;
r = get_reg(S, RC_INT);
@ -944,9 +944,9 @@ ST_FUNC void gen_opf(TCCState *S, int op)
o(S, 0xdc);
else
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--;
}
}
@ -956,36 +956,36 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
{
save_reg(S, TREG_ST0);
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
is handled generically) */
o(S, 0x50 + S->vtop->r2); /* push r2 */
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
o(S, 0x50 + S->tccgen_vtop->r2); /* push r2 */
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
o(S, 0x242cdf); /* fildll (%esp) */
o(S, 0x08c483); /* add $8, %esp */
S->vtop->r2 = VT_CONST;
} else if ((S->vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
S->tccgen_vtop->r2 = VT_CONST;
} else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED)) {
/* unsigned int to float/double/long double */
o(S, 0x6a); /* push $0 */
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, 0x08c483); /* add $8, %esp */
} else {
/* 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, 0x04c483); /* add $4, %esp */
}
S->vtop->r2 = VT_CONST;
S->vtop->r = TREG_ST0;
S->tccgen_vtop->r2 = VT_CONST;
S->tccgen_vtop->r = TREG_ST0;
}
/* convert fp to int 't' type */
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)
vpush_helper_func(S, TOK___fixsfdi);
else if (bt == VT_LDOUBLE)
@ -995,9 +995,9 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
vswap(S);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->r = REG_IRET;
S->tccgen_vtop->r = REG_IRET;
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 */
@ -1024,11 +1024,11 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
{
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);
o(S, 1);
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);
g(S, 0);
}
@ -1037,7 +1037,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
ST_FUNC void ggoto(TCCState* S)
{
gcall_or_jmp(S, 1);
S->vtop--;
S->tccgen_vtop--;
}
/* bound check support functions */
@ -1047,7 +1047,7 @@ static void gen_bounds_prolog(TCCState *S)
{
/* leave some room for bound checking code */
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;
oad(S, 0xb8, 0); /* lbound section pointer */
oad(S, 0xb8, 0); /* call to function */
@ -1067,22 +1067,22 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*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);
/* generate bound local allocation */
if (offset_modified) {
saved_ind = S->ind;
S->ind = S->func_bound_ind;
greloc(S, cur_text_section, sym_data, S->ind + 1, R_386_32);
S->ind = S->ind + 5;
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->func_bound_ind;
greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
S->tccgen_ind = S->tccgen_ind + 5;
gen_static_call(S, TOK___bound_local_new);
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
/* generate bound check local freeing */
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 */
gen_static_call(S, TOK___bound_local_delete);
o(S, 0x585a); /* restore returned value, if any */

View file

@ -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",
(*pf)->filename, (*pf)->line_num);
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) {
cstr_printf(S, &cs, "%s: ", S->current_filename);
}
@ -744,7 +744,7 @@ ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen)
bf->fd = -1;
bf->prev = S->tccpp_file;
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)

View file

@ -23,13 +23,13 @@ ST_FUNC void gen_le32(TCCState *S, int c);
ST_FUNC void g(TCCState* S, int c)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 1;
ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c;
S->ind = ind1;
cur_text_section->data[S->tccgen_ind] = c;
S->tccgen_ind = ind1;
}
ST_FUNC void gen_le16 (TCCState* S, int i)
@ -41,15 +41,15 @@ ST_FUNC void gen_le16 (TCCState *S, int i)
ST_FUNC void gen_le32 (TCCState* S, int i)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 4;
ind1 = S->tccgen_ind + 4;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind++] = i & 0xFF;
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF;
cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
}
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
@ -128,12 +128,12 @@ static void parse_operand(TCCState *S, Operand *op)
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
op->type = OP_REG;
op->reg = (uint8_t) reg;
return;
} else if (S->tok == '$') {
} else if (S->tccpp_tok == '$') {
/* constant value */
next(S); // skip '#' or '$'
}
@ -211,7 +211,7 @@ static void asm_binary_opcode(TCCState *S, int token)
{
Operand ops[2];
parse_operand(S, &ops[0]);
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -283,12 +283,12 @@ static void asm_shift_opcode(TCCState *S, int token)
{
Operand ops[3];
parse_operand(S, &ops[0]);
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
parse_operand(S, &ops[1]);
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -340,12 +340,12 @@ static void asm_data_processing_opcode(TCCState *S, int token)
{
Operand ops[3];
parse_operand(S, &ops[0]);
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
parse_operand(S, &ops[1]);
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -450,7 +450,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
expect(S, "register");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -459,7 +459,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
expect(S, "register");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -522,7 +522,7 @@ static void asm_branch_opcode(TCCState *S, int token)
expect(S, "register");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");
@ -531,7 +531,7 @@ static void asm_branch_opcode(TCCState *S, int token)
expect(S, "register");
return;
}
if (S->tok == ',')
if (S->tccpp_tok == ',')
next(S);
else
expect(S, "','");

View file

@ -102,13 +102,13 @@ static int is_freg(int r)
ST_FUNC void o(TCCState* S, unsigned int c)
{
int ind1 = S->ind + 4;
if (S->nocode_wanted)
int ind1 = S->tccgen_ind + 4;
if (S->tccgen_nocode_wanted)
return;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
write32le(cur_text_section->data + S->ind, c);
S->ind = ind1;
write32le(cur_text_section->data + S->tccgen_ind, c);
S->tccgen_ind = ind1;
}
static void EIu(TCCState* S, uint32_t opcode, uint32_t func3,
@ -166,21 +166,21 @@ static int load_symofs(TCCState *S, int r, SValue *sv, int forstore)
Sym label = {0};
assert(v == VT_CONST);
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);
sv->c.i = 0;
} else {
if (((unsigned)fc + (1 << 11)) >> 12)
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);
doload = 1;
}
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;
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
? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
if (doload) {
@ -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
}
} else if (v == VT_CMP) {
int op = S->vtop->cmp_op;
int a = S->vtop->cmp_r & 0xff;
int b = (S->vtop->cmp_r >> 8) & 0xff;
int op = S->tccgen_vtop->cmp_op;
int a = S->tccgen_vtop->cmp_r & 0xff;
int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
int inv = 0;
switch (op) {
case TOK_ULT:
@ -353,7 +353,7 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv)
int t = v & 1;
assert(is_ireg(r));
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);
EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
} else
@ -406,19 +406,19 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv)
static void gcall_or_jmp(TCCState* S, int docall)
{
int tr = docall ? 1 : 5; // ra or t0
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((S->vtop->r & VT_SYM) && S->vtop->c.i == (int)S->vtop->c.i)) {
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->c.i == (int)S->tccgen_vtop->c.i)) {
/* constant symbolic case -> simple relocation */
greloca(S, cur_text_section, S->vtop->sym, S->ind,
R_RISCV_CALL_PLT, (int)S->vtop->c.i);
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
R_RISCV_CALL_PLT, (int)S->tccgen_vtop->c.i);
o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func)
EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR)
} else if (S->vtop->r < VT_CONST) {
int r = ireg(S->vtop->r);
} else if (S->tccgen_vtop->r < VT_CONST) {
int r = ireg(S->tccgen_vtop->r);
EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
} else {
int r = TREG_RA;
load(S, r, S->vtop);
load(S, r, S->tccgen_vtop);
r = ireg(r);
EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
}
@ -430,7 +430,7 @@ static void gen_bounds_call(TCCState *S, int 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)
EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR)
}
@ -439,7 +439,7 @@ static void gen_bounds_prolog(TCCState *S)
{
/* leave some room for bound checking code */
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;
o(S, 0x00000013); /* ld a0,#lbound section pointer */
o(S, 0x00000013);
@ -463,31 +463,31 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*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);
label.type.t = VT_VOID | VT_STATIC;
/* generate bound local allocation */
if (offset_modified) {
saved_ind = S->ind;
S->ind = S->func_bound_ind;
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
greloca(S, cur_text_section, sym_data, S->ind, R_RISCV_GOT_HI20, 0);
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->func_bound_ind;
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 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
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)
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 */
}
/* generate bound check local freeing */
o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */
o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
greloca(S, cur_text_section, sym_data, S->ind, R_RISCV_GOT_HI20, 0);
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 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
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)
gen_bounds_call(S, TOK___bound_local_delete);
o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */
@ -556,11 +556,11 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
areg[0] = 0; /* int 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++) {
int nregs, byref = 0, tempofs;
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
size = type_size(&sv->type, &align);
if (size > 16) {
@ -617,7 +617,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
stack_add = stack_adj + tempspace;
/* 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);
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++) {
if (info[i] & (64 | 32)) {
vrotb(S, nb_args - i);
size = type_size(&S->vtop->type, &align);
size = type_size(&S->tccgen_vtop->type, &align);
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));
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);
indir(S);
S->vtop->type = S->vtop[-1].type;
S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
vswap(S);
vstore(S);
vpop(S);
@ -649,18 +649,18 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
if (align < XLEN)
align = XLEN;
/* 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,
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;
vpushi(S, ofs);
gen_op(S, '+');
indir(S);
S->vtop->type = S->vtop[-1].type;
S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
vswap(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;
}
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;
assert(r2 <= 16);
vrotb(S, i+1);
origtype = S->vtop->type;
size = type_size(&S->vtop->type, &align);
origtype = S->tccgen_vtop->type;
size = type_size(&S->tccgen_vtop->type, &align);
if (size == 0)
goto done;
loadt = S->vtop->type.t & VT_BTYPE;
loadt = S->tccgen_vtop->type.t & VT_BTYPE;
if (loadt == VT_STRUCT) {
loadt = (ii >> 12) & VT_BTYPE;
}
@ -697,18 +697,18 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
r2--;
} else if (r2) {
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));
S->vtop->type = origtype;
S->tccgen_vtop->type = origtype;
if (r2 && loadt != VT_LDOUBLE) {
r2--;
assert(r2 < 16 || r2 == TREG_RA);
vswap(S);
gaddrof(S);
S->vtop->type = S->char_pointer_type;
S->tccgen_vtop->type = S->tccgen_char_pointer_type;
vpushi(S, ii >> 20);
#ifdef CONFIG_TCC_BCHECK
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;
#endif
indir(S);
S->vtop->type = origtype;
loadt = S->vtop->type.t & VT_BTYPE;
S->tccgen_vtop->type = origtype;
loadt = S->tccgen_vtop->type.t & VT_BTYPE;
if (loadt == VT_STRUCT) {
loadt = (ii >> 16) & VT_BTYPE;
}
save_reg_upstack(S, r2, 1);
S->vtop->type.t = loadt | (S->vtop->type.t & VT_UNSIGNED);
load(S, r2, S->vtop);
S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
load(S, r2, S->tccgen_vtop);
assert(r2 < VT_CONST);
S->vtop--;
S->vtop->r2 = r2;
S->tccgen_vtop--;
S->tccgen_vtop->r2 = r2;
}
if (info[nb_args - 1 - i] & 16) {
ES(S, 0x23, 3, 2, ireg(S->vtop->r2), splitofs); // sd t0, ofs(sp)
S->vtop->r2 = VT_CONST;
} else if (loadt == VT_LDOUBLE && S->vtop->r2 != r2) {
assert(S->vtop->r2 <= 7 && r2 <= 7);
ES(S, 0x23, 3, 2, ireg(S->tccgen_vtop->r2), splitofs); // sd t0, ofs(sp)
S->tccgen_vtop->r2 = VT_CONST;
} else if (loadt == VT_LDOUBLE && S->tccgen_vtop->r2 != r2) {
assert(S->tccgen_vtop->r2 <= 7 && r2 <= 7);
/* XXX we'd like to have 'gv' move directly into
the right class instead of us fixing it up. */
EI(S, 0x13, 0, ireg(r2), ireg(S->vtop->r2), 0); // mv Ra+1, RR2
S->vtop->r2 = r2;
EI(S, 0x13, 0, ireg(r2), ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
S->tccgen_vtop->r2 = r2;
}
done:
vrott(S, i+1);
@ -748,7 +748,7 @@ done:
vrotb(S, nb_args + 1);
save_regs(S, nb_args + 1);
gcall_or_jmp(S, 1);
S->vtop -= nb_args + 1;
S->tccgen_vtop -= nb_args + 1;
if (stack_add) {
if (stack_add >= 0x1000) {
o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)
@ -773,9 +773,9 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
CType *type;
sym = func_type->ref;
S->loc = -16; // for ra and s0
func_sub_sp_offset = S->ind;
S->ind += 5 * 4;
S->tccgen_loc = -16; // for ra and s0
func_sub_sp_offset = S->tccgen_ind;
S->tccgen_ind += 5 * 4;
areg[0] = 0, areg[1] = 0;
addr = 0;
@ -783,9 +783,9 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
implicit pointer parameter */
size = type_size(&S->tccgen_func_vt, &align);
if (size > 2 * XLEN) {
S->loc -= 8;
S->tccgen_func_vc = S->loc;
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->loc); // sd a0, loc(s0)
S->tccgen_loc -= 8;
S->tccgen_func_vc = S->tccgen_loc;
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc); // sd a0, loc(s0)
}
/* define parameters */
while ((sym = sym->next) != NULL) {
@ -795,7 +795,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
type = &sym->type;
size = type_size(type, &align);
if (size > 2 * XLEN) {
type = &S->char_pointer_type;
type = &S->tccgen_char_pointer_type;
size = align = byref = 8;
}
reg_pass(type, prc, fieldofs, 1);
@ -810,18 +810,18 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
param_addr = addr;
addr += size;
} else {
S->loc -= regcount * 8; // XXX could reserve only 'size' bytes
param_addr = S->loc;
S->tccgen_loc -= regcount * 8; // XXX could reserve only 'size' bytes
param_addr = S->tccgen_loc;
for (i = 0; i < regcount; i++) {
if (areg[prc[1+i] - 1] >= 8) {
assert(i == 1 && regcount == 2 && !(addr & 7));
EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0)
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) {
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 {
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
}
}
}
@ -867,16 +867,16 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
ST_FUNC void arch_transfer_ret_regs(TCCState* S, int aftercall)
{
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(S->vtop->r == (VT_LOCAL | VT_LVAL));
vpushv(S, S->vtop);
S->vtop->type.t = fieldofs[1] & VT_BTYPE;
(aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->vtop);
S->vtop->c.i += fieldofs[2] >> 4;
S->vtop->type.t = fieldofs[2] & VT_BTYPE;
(aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->vtop);
S->vtop--;
assert(S->tccgen_vtop->r == (VT_LOCAL | VT_LVAL));
vpushv(S, S->tccgen_vtop);
S->tccgen_vtop->type.t = fieldofs[1] & VT_BTYPE;
(aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
S->tccgen_vtop->c.i += fieldofs[2] >> 4;
S->tccgen_vtop->type.t = fieldofs[2] & VT_BTYPE;
(aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
S->tccgen_vtop--;
}
ST_FUNC void gfunc_epilog(TCCState* S)
@ -888,8 +888,8 @@ ST_FUNC void gfunc_epilog(TCCState *S)
gen_bounds_epilog(S);
#endif
S->loc = (S->loc - num_va_regs * 8);
d = v = (-S->loc + 15) & -16;
S->tccgen_loc = (S->tccgen_loc - num_va_regs * 8);
d = v = (-S->tccgen_loc + 15) & -16;
if (v >= (1 << 11)) {
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, 0x13, 0, 2, 2, d); // addi sp, sp, v
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)) {
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)
@ -909,9 +909,9 @@ ST_FUNC void gfunc_epilog(TCCState *S)
ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0
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
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)
@ -919,15 +919,15 @@ ST_FUNC void gfunc_epilog(TCCState *S)
EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
else
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
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
ST_FUNC void gen_va_start(TCCState *S)
{
S->vtop--;
vset(S, &S->char_pointer_type, VT_LOCAL, func_va_list_ofs);
S->tccgen_vtop--;
vset(S, &S->tccgen_char_pointer_type, VT_LOCAL, func_va_list_ofs);
}
ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
@ -943,16 +943,16 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
// Generate forward branch to label:
ST_FUNC int gjmp(TCCState* S, int t)
{
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return t;
o(S, t);
return S->ind - 4;
return S->tccgen_ind - 4;
}
// Generate branch to known address:
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)) {
o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)
r = (int)r << 20 >> 20;
@ -969,8 +969,8 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
{
int tmp;
int a = S->vtop->cmp_r & 0xff;
int b = (S->vtop->cmp_r >> 8) & 0xff;
int a = S->tccgen_vtop->cmp_r & 0xff;
int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
switch (op) {
case TOK_ULT: op = 6; break;
case TOK_UGE: op = 7; break;
@ -1006,17 +1006,17 @@ static void gen_opil(TCCState *S, int op, int ll)
int a, b, d;
int func3 = 0;
ll = ll ? 0 : 8;
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
int fc = S->vtop->c.i;
if (fc == S->vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
int fc = S->tccgen_vtop->c.i;
if (fc == S->tccgen_vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
int cll = 0;
int m = ll ? 31 : 63;
vswap(S);
gv(S, RC_INT);
a = ireg(S->vtop[0].r);
--S->vtop;
a = ireg(S->tccgen_vtop[0].r);
--S->tccgen_vtop;
d = get_reg(S, RC_INT);
++S->vtop;
++S->tccgen_vtop;
vswap(S);
switch (op) {
case '-':
@ -1028,12 +1028,12 @@ static void gen_opil(TCCState *S, int op, int ll)
cll = ll;
do_cop:
EI(S, 0x13 | cll, func3, ireg(d), a, fc);
--S->vtop;
--S->tccgen_vtop;
if (op >= TOK_ULT && op <= TOK_GT) {
vset_VT_CMP(S, TOK_NE);
S->vtop->cmp_r = ireg(d) | 0 << 8;
S->tccgen_vtop->cmp_r = ireg(d) | 0 << 8;
} else
S->vtop[0].r = d;
S->tccgen_vtop[0].r = d;
return;
case TOK_LE:
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_GT: /* -> TOK_LE */
gen_opil(S, op - 1, !ll);
S->vtop->cmp_op ^= 1;
S->tccgen_vtop->cmp_op ^= 1;
return;
case TOK_NE:
case TOK_EQ:
if (fc)
gen_opil(S, '-', !ll), a = ireg(S->vtop++->r);
--S->vtop;
gen_opil(S, '-', !ll), a = ireg(S->tccgen_vtop++->r);
--S->tccgen_vtop;
vset_VT_CMP(S, op);
S->vtop->cmp_r = a | 0 << 8;
S->tccgen_vtop->cmp_r = a | 0 << 8;
return;
}
}
}
gv2(S, RC_INT, RC_INT);
a = ireg(S->vtop[-1].r);
b = ireg(S->vtop[0].r);
S->vtop -= 2;
a = ireg(S->tccgen_vtop[-1].r);
b = ireg(S->tccgen_vtop[0].r);
S->tccgen_vtop -= 2;
d = get_reg(S, RC_INT);
S->vtop++;
S->vtop[0].r = d;
S->tccgen_vtop++;
S->tccgen_vtop[0].r = d;
d = ireg(d);
switch (op) {
default:
if (op >= TOK_ULT && op <= TOK_GT) {
vset_VT_CMP(S, op);
S->vtop->cmp_r = a | b << 8;
S->tccgen_vtop->cmp_r = a | b << 8;
break;
}
tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL));
@ -1145,8 +1145,8 @@ ST_FUNC void gen_opl(TCCState *S, int op)
ST_FUNC void gen_opf(TCCState* S, int op)
{
int rs1, rs2, rd, dbl, invert;
if (S->vtop[0].type.t == VT_LDOUBLE) {
CType type = S->vtop[0].type;
if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
CType type = S->tccgen_vtop[0].type;
int func = 0;
int cond = -1;
switch (op) {
@ -1166,10 +1166,10 @@ ST_FUNC void gen_opf(TCCState *S, int op)
vrott(S, 3);
gfunc_call(S, 2);
vpushi(S, 0);
S->vtop->r = REG_IRET;
S->vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
S->tccgen_vtop->r = REG_IRET;
S->tccgen_vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
if (cond < 0)
S->vtop->type = type;
S->tccgen_vtop->type = type;
else {
vpushi(S, 0);
gen_opil(S, op, 1);
@ -1178,11 +1178,11 @@ ST_FUNC void gen_opf(TCCState *S, int op)
}
gv2(S, RC_FLOAT, RC_FLOAT);
assert(S->vtop->type.t == VT_DOUBLE || S->vtop->type.t == VT_FLOAT);
dbl = S->vtop->type.t == VT_DOUBLE;
rs1 = freg(S->vtop[-1].r);
rs2 = freg(S->vtop->r);
S->vtop--;
assert(S->tccgen_vtop->type.t == VT_DOUBLE || S->tccgen_vtop->type.t == VT_FLOAT);
dbl = S->tccgen_vtop->type.t == VT_DOUBLE;
rs1 = freg(S->tccgen_vtop[-1].r);
rs2 = freg(S->tccgen_vtop->r);
S->tccgen_vtop--;
invert = 0;
switch(op) {
default:
@ -1191,7 +1191,7 @@ ST_FUNC void gen_opf(TCCState *S, int op)
op = 0; // fadd
arithop:
rd = get_reg(S, RC_FLOAT);
S->vtop->r = rd;
S->tccgen_vtop->r = rd;
rd = freg(rd);
ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)
break;
@ -1208,7 +1208,7 @@ ST_FUNC void gen_opf(TCCState *S, int op)
op = 2; // EQ
cmpop:
rd = get_reg(S, RC_INT);
S->vtop->r = rd;
S->tccgen_vtop->r = rd;
rd = ireg(rd);
ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
if (invert)
@ -1244,8 +1244,8 @@ ST_FUNC void gen_cvt_sxtw(TCCState *S)
ST_FUNC void gen_cvt_itof(TCCState* S, int t)
{
int rr = ireg(gv(S, RC_INT)), dr;
int u = S->vtop->type.t & VT_UNSIGNED;
int l = (S->vtop->type.t & VT_BTYPE) == VT_LLONG;
int u = S->tccgen_vtop->type.t & VT_UNSIGNED;
int l = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;
if (t == VT_LDOUBLE) {
int func = l ?
(u ? TOK___floatunditf : TOK___floatditf) :
@ -1254,14 +1254,14 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
vrott(S, 2);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->type.t = t;
S->vtop->r = REG_IRET;
S->vtop->r2 = TREG_R(1);
S->tccgen_vtop->type.t = t;
S->tccgen_vtop->r = REG_IRET;
S->tccgen_vtop->r2 = TREG_R(1);
} else {
S->vtop--;
S->tccgen_vtop--;
dr = get_reg(S, RC_FLOAT);
S->vtop++;
S->vtop->r = dr;
S->tccgen_vtop++;
S->tccgen_vtop->r = 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]
}
@ -1269,7 +1269,7 @@ ST_FUNC void gen_cvt_itof(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 u = t & VT_UNSIGNED;
if (ft == VT_LDOUBLE) {
@ -1280,14 +1280,14 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
vrott(S, 2);
gfunc_call(S, 1);
vpushi(S, 0);
S->vtop->type.t = t;
S->vtop->r = REG_IRET;
S->tccgen_vtop->type.t = t;
S->tccgen_vtop->r = REG_IRET;
} else {
int rr = freg(gv(S, RC_FLOAT)), dr;
S->vtop--;
S->tccgen_vtop--;
dr = get_reg(S, RC_INT);
S->vtop++;
S->vtop->r = dr;
S->tccgen_vtop++;
S->tccgen_vtop->r = 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
}
@ -1295,7 +1295,7 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
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;
if (st == dt)
return;
@ -1312,21 +1312,21 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int dt)
gv(S, RC_F(0));
else {
gv(S, RC_R(0));
assert(S->vtop->r2 < 7);
if (S->vtop->r2 != 1 + S->vtop->r) {
EI(S, 0x13, 0, ireg(S->vtop->r) + 1, ireg(S->vtop->r2), 0); // mv Ra+1, RR2
S->vtop->r2 = 1 + S->vtop->r;
assert(S->tccgen_vtop->r2 < 7);
if (S->tccgen_vtop->r2 != 1 + S->tccgen_vtop->r) {
EI(S, 0x13, 0, ireg(S->tccgen_vtop->r) + 1, ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
S->tccgen_vtop->r2 = 1 + S->tccgen_vtop->r;
}
}
vpush_helper_func(S, func);
gcall_or_jmp(S, 1);
S->vtop -= 2;
S->tccgen_vtop -= 2;
vpushi(S, 0);
S->vtop->type.t = dt;
S->tccgen_vtop->type.t = dt;
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
S->vtop->r = REG_FRET;
S->tccgen_vtop->r = REG_FRET;
} else {
assert (dt == VT_FLOAT || dt == VT_DOUBLE);
assert (st == VT_FLOAT || st == VT_DOUBLE);
@ -1336,7 +1336,7 @@ 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)
else
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;
}
}
@ -1348,21 +1348,21 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
label.type.t = VT_VOID | VT_STATIC;
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);
r1 = ireg(r1);
r2 = ireg(r2);
greloca(S, cur_text_section, sv->sym, S->ind, R_RISCV_PCREL_HI20, 0);
put_extern_sym(S, &label, cur_text_section, S->ind, 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->tccgen_ind, 0);
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, 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 */
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)
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]
vpop(S);
}
@ -1370,7 +1370,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
ST_FUNC void ggoto(TCCState* S)
{
gcall_or_jmp(S, 0);
S->vtop--;
S->tccgen_vtop--;
}
ST_FUNC void gen_vla_sp_save(TCCState* S, int addr)
@ -1388,7 +1388,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align)
int rr;
#if defined(CONFIG_TCC_BCHECK)
if (S->do_bounds_check)
vpushv(S, S->vtop);
vpushv(S, S->tccgen_vtop);
#endif
rr = ireg(gv(S, RC_INT));
#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 (S->do_bounds_check) {
vpushi(S, 0);
S->vtop->r = TREG_R(0);
S->tccgen_vtop->r = TREG_R(0);
o(S, 0x00010513); /* mv a0,sp */
vswap(S);
vpush_helper_func(S, TOK___bound_new_region);

35
tcc.h
View file

@ -1074,21 +1074,21 @@ struct TCCState {
/* ------------ tccpp.c ------------ */
struct BufferedFile *tccpp_file;
int tccpp_ch, tok;
CValue tokc;
int tccpp_ch, tccpp_tok;
CValue tccpp_tokc;
const int *tccpp_macro_ptr;
int tccpp_parse_flags;
int tok_flags;
CString tokcstr; /* current parsed string, if any */
int tccpp_tok_flags;
CString tccpp_tokcstr; /* current parsed string, if any */
CString tccpp_cstr_buf;
CString tccpp_macro_equal_buf;
TokenString tokstr_buf;
TokenString tccpp_tokstr_buf;
TokenString *tccpp_macro_stack;
/* display benchmark infos */
int tccpp_total_lines;
int tccpp_total_bytes;
int tok_ident;
int tccpp_tok_ident;
TokenSym **tccpp_table_ident;
int *tccpp_macro_ptr_allocated;
@ -1096,7 +1096,7 @@ struct TCCState {
int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1];
int tccpp_unget_buffer_enabled;
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) */
unsigned char tccpp_isidnum_table[256-CH_EOF];
@ -1105,8 +1105,8 @@ struct TCCState {
int tccpp_pp_expr;
int tccpp_pp_counter;
TinyAlloc *toksym_alloc;
TinyAlloc *tokstr_alloc;
TinyAlloc *tccpp_toksym_alloc;
TinyAlloc *tccpp_tokstr_alloc;
/*----------- tccasm.c --------*/
Section *tccasm_last_text_section; /* to handle .previous asm directive */
@ -1114,18 +1114,18 @@ struct TCCState {
/* ------------ tccgen.c ------------ */
Sym *tccgen_global_stack;
Sym *local_stack;
Sym *local_label_stack;
Sym *tccgen_local_stack;
Sym *tccgen_local_label_stack;
Sym *tccgen_global_label_stack;
Sym *tccgen_define_stack;
CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, char_pointer_type;
SValue *vtop;
CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, tccgen_char_pointer_type;
SValue *tccgen_vtop;
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;
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 */
CType tccgen_func_vt; /* current function return type (used by return instruction) */
int tccgen_func_var; /* true if current function is variadic */
@ -1136,7 +1136,7 @@ struct TCCState {
void **tccgen_sym_pools;
int tccgen_nb_sym_pools;
Sym *tccgen_all_cleanups, *tccgen_pending_gotos;
int local_scope;
int tccgen_local_scope;
int tccgen_in_sizeof;
int tccgen_in_generic;
int tccgen_section_sym;
@ -1155,7 +1155,7 @@ struct TCCState {
int tccgen_debug_next_type;
debug_hash_t *tccgen_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];
@ -1629,6 +1629,7 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty);
#endif
#ifdef CONFIG_TCC_BCHECK
ST_FUNC void gbound_args(TCCState* S, int nb_args);
ST_DATA int func_bound_add_epilog;
#endif
/* ------------ tccelf.c ------------ */

228
tccasm.c
View file

@ -122,9 +122,9 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
uint64_t n;
const char *p;
switch(S->tok) {
switch(S->tccpp_tok) {
case TOK_PPNUM:
p = S->tokc.str.data;
p = S->tccpp_tokc.str.data;
n = strtoull(p, (char **)&p, 0);
if (*p == 'b' || *p == 'f') {
/* backward or forward label */
@ -161,7 +161,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
break;
case '-':
case '~':
op = S->tok;
op = S->tccpp_tok;
next(S);
asm_expr_unary(S, pe);
if (pe->sym)
@ -173,7 +173,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
break;
case TOK_CCHAR:
case TOK_LCHAR:
pe->v = S->tokc.i;
pe->v = S->tccpp_tokc.i;
pe->sym = NULL;
pe->pcrel = 0;
next(S);
@ -184,16 +184,16 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
skip(S, ')');
break;
case '.':
pe->v = S->ind;
pe->v = S->tccgen_ind;
pe->sym = asm_section_sym(S, cur_text_section);
pe->pcrel = 0;
next(S);
break;
default:
if (S->tok >= TOK_IDENT) {
if (S->tccpp_tok >= TOK_IDENT) {
ElfSym *esym;
/* 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);
if (esym && esym->st_shndx == SHN_ABS) {
/* 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);
} 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;
}
@ -220,7 +220,7 @@ static void asm_expr_prod(TCCState *S, ExprValue *pe)
asm_expr_unary(S, pe);
for(;;) {
op = S->tok;
op = S->tccpp_tok;
if (op != '*' && op != '/' && op != '%' &&
op != TOK_SHL && op != TOK_SAR)
break;
@ -262,7 +262,7 @@ static void asm_expr_logic(TCCState *S, ExprValue *pe)
asm_expr_prod(S, pe);
for(;;) {
op = S->tok;
op = S->tccpp_tok;
if (op != '&' && op != '|' && op != '^')
break;
next(S);
@ -291,7 +291,7 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe)
asm_expr_logic(S, pe);
for(;;) {
op = S->tok;
op = S->tccpp_tok;
if (op != '+' && op != '-')
break;
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) {
/* When subtracting a defined symbol in current section
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;
e2.sym = NULL;
} else {
@ -342,7 +342,7 @@ static inline void asm_expr_cmp(TCCState *S, ExprValue *pe)
asm_expr_sum(S, pe);
for(;;) {
op = S->tok;
op = S->tccpp_tok;
if (op != TOK_EQ && op != TOK_NE
&& (op > TOK_GT || op < TOK_ULE))
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)
{
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
@ -452,9 +452,9 @@ static Sym* set_symbol(TCCState *S, int label)
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;
S->ind = cur_text_section->data_offset;
S->tccgen_ind = cur_text_section->data_offset;
}
static void use_section(TCCState *S, const char *name)
@ -488,13 +488,13 @@ static void asm_parse_directive(TCCState *S, int global)
/* assembler directive */
sec = cur_text_section;
switch(S->tok) {
switch(S->tccpp_tok) {
case TOK_ASMDIR_align:
case TOK_ASMDIR_balign:
case TOK_ASMDIR_p2align:
case TOK_ASMDIR_skip:
case TOK_ASMDIR_space:
tok1 = S->tok;
tok1 = S->tccpp_tok;
next(S);
n = asm_int_expr(S);
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 (n < 0 || (n & (n-1)) != 0)
tcc_error(S, "alignment must be a positive power of two");
offset = (S->ind + n - 1) & -n;
size = offset - S->ind;
offset = (S->tccgen_ind + n - 1) & -n;
size = offset - S->tccgen_ind;
/* the section must have a compatible alignment */
if (sec->sh_addralign < n)
sec->sh_addralign = n;
@ -518,17 +518,17 @@ static void asm_parse_directive(TCCState *S, int global)
size = n;
}
v = 0;
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
v = asm_int_expr(S);
}
zero_pad:
if (sec->sh_type != SHT_NOBITS) {
sec->data_offset = S->ind;
sec->data_offset = S->tccgen_ind;
ptr = section_ptr_add(S, sec, size);
memset(ptr, v, size);
}
S->ind += size;
S->tccgen_ind += size;
break;
case TOK_ASMDIR_quad:
#ifdef TCC_TARGET_X86_64
@ -540,8 +540,8 @@ static void asm_parse_directive(TCCState *S, int global)
uint64_t vl;
const char *p;
p = S->tokc.str.data;
if (S->tok != TOK_PPNUM) {
p = S->tccpp_tokc.str.data;
if (S->tccpp_tok != TOK_PPNUM) {
error_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 >> 32);
} else {
S->ind += 8;
S->tccgen_ind += 8;
}
if (S->tok != ',')
if (S->tccpp_tok != ',')
break;
next(S);
}
@ -593,9 +593,9 @@ static void asm_parse_directive(TCCState *S, int global)
gen_le16(S, e.v);
}
} else {
S->ind += size;
S->tccgen_ind += size;
}
if (S->tok != ',')
if (S->tccpp_tok != ',')
break;
next(S);
}
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *S, int global)
}
size = 1;
val = 0;
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
size = asm_int_expr(S);
if (size < 0) {
@ -621,7 +621,7 @@ static void asm_parse_directive(TCCState *S, int global)
}
if (size > 8)
size = 8;
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
val = asm_int_expr(S);
}
@ -649,8 +649,8 @@ static void asm_parse_directive(TCCState *S, int global)
next(S);
repeat = asm_int_expr(S);
init_str = tok_str_alloc(S);
while (next(S), S->tok != TOK_ASMDIR_endr) {
if (S->tok == CH_EOF)
while (next(S), S->tccpp_tok != TOK_ASMDIR_endr) {
if (S->tccpp_tok == CH_EOF)
tcc_error(S, "we at end of file, .endr not found");
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");
n += esym->st_value;
}
if (n < S->ind)
if (n < S->tccgen_ind)
tcc_error(S, "attempt to .org backwards");
v = 0;
size = n - S->ind;
size = n - S->tccgen_ind;
goto zero_pad;
}
break;
case TOK_ASMDIR_set:
next(S);
tok1 = S->tok;
tok1 = S->tccpp_tok;
next(S);
/* Also accept '.set stuff', but don't do anything with this.
It's used in GAS to set various features like '.set mips16'. */
if (S->tok == ',')
if (S->tccpp_tok == ',')
set_symbol(S, tok1);
break;
case TOK_ASMDIR_globl:
case TOK_ASMDIR_global:
case TOK_ASMDIR_weak:
case TOK_ASMDIR_hidden:
tok1 = S->tok;
tok1 = S->tccpp_tok;
do {
Sym *sym;
next(S);
sym = get_asm_sym(S, S->tok, NULL);
sym = get_asm_sym(S, S->tccpp_tok, NULL);
if (tok1 != TOK_ASMDIR_hidden)
sym->type.t &= ~VT_STATIC;
if (tok1 == TOK_ASMDIR_weak)
@ -713,7 +713,7 @@ static void asm_parse_directive(TCCState *S, int global)
sym->a.visibility = STV_HIDDEN;
update_storage(S, sym);
next(S);
} while (S->tok == ',');
} while (S->tccpp_tok == ',');
break;
case TOK_ASMDIR_string:
case TOK_ASMDIR_ascii:
@ -722,21 +722,21 @@ static void asm_parse_directive(TCCState *S, int global)
const uint8_t *p;
int i, size, t;
t = S->tok;
t = S->tccpp_tok;
next(S);
for(;;) {
if (S->tok != TOK_STR)
if (S->tccpp_tok != TOK_STR)
expect(S, "string constant");
p = S->tokc.str.data;
size = S->tokc.str.size;
p = S->tccpp_tokc.str.data;
size = S->tccpp_tokc.str.size;
if (t == TOK_ASMDIR_ascii && size > 0)
size--;
for(i = 0; i < size; i++)
g(S, p[i]);
next(S);
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
} else if (S->tok != TOK_STR) {
} else if (S->tccpp_tok != TOK_STR) {
break;
}
}
@ -747,10 +747,10 @@ static void asm_parse_directive(TCCState *S, int global)
case TOK_ASMDIR_bss:
{
char sname[64];
tok1 = S->tok;
tok1 = S->tccpp_tok;
n = 0;
next(S);
if (S->tok != ';' && S->tok != TOK_LINEFEED) {
if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) {
n = asm_int_expr(S);
next(S);
}
@ -767,10 +767,10 @@ static void asm_parse_directive(TCCState *S, int global)
filename[0] = '\0';
next(S);
if (S->tok == TOK_STR)
pstrcat(filename, sizeof(filename), S->tokc.str.data);
if (S->tccpp_tok == TOK_STR)
pstrcat(filename, sizeof(filename), S->tccpp_tokc.str.data);
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);
next(S);
}
@ -781,10 +781,10 @@ static void asm_parse_directive(TCCState *S, int global)
ident[0] = '\0';
next(S);
if (S->tok == TOK_STR)
pstrcat(ident, sizeof(ident), S->tokc.str.data);
if (S->tccpp_tok == TOK_STR)
pstrcat(ident, sizeof(ident), S->tccpp_tokc.str.data);
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);
next(S);
}
@ -794,15 +794,15 @@ static void asm_parse_directive(TCCState *S, int global)
Sym *sym;
next(S);
sym = asm_label_find(S, S->tok);
sym = asm_label_find(S, S->tccpp_tok);
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 */
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);
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);
}
}
@ -813,15 +813,15 @@ static void asm_parse_directive(TCCState *S, int global)
const char *newtype;
next(S);
sym = get_asm_sym(S, S->tok, NULL);
sym = get_asm_sym(S, S->tccpp_tok, NULL);
next(S);
skip(S, ',');
if (S->tok == TOK_STR) {
newtype = S->tokc.str.data;
if (S->tccpp_tok == TOK_STR) {
newtype = S->tccpp_tokc.str.data;
} else {
if (S->tok == '@' || S->tok == '%')
if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
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")) {
@ -839,26 +839,26 @@ static void asm_parse_directive(TCCState *S, int global)
char sname[256];
int old_nb_section = S->nb_sections;
tok1 = S->tok;
tok1 = S->tccpp_tok;
/* XXX: support more options */
next(S);
sname[0] = '\0';
while (S->tok != ';' && S->tok != TOK_LINEFEED && S->tok != ',') {
if (S->tok == TOK_STR)
pstrcat(sname, sizeof(sname), S->tokc.str.data);
while (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ',') {
if (S->tccpp_tok == TOK_STR)
pstrcat(sname, sizeof(sname), S->tccpp_tokc.str.data);
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);
}
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
/* skip section options */
next(S);
if (S->tok != TOK_STR)
if (S->tccpp_tok != TOK_STR)
expect(S, "string constant");
next(S);
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
if (S->tok == '@' || S->tok == '%')
if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
next(S);
next(S);
}
@ -911,7 +911,7 @@ static void asm_parse_directive(TCCState *S, int global)
break;
#endif
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;
}
}
@ -928,20 +928,20 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS;
for(;;) {
next(S);
if (S->tok == TOK_EOF)
if (S->tccpp_tok == TOK_EOF)
break;
S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
redo:
if (S->tok == '#') {
if (S->tccpp_tok == '#') {
/* horrible gas comment */
while (S->tok != TOK_LINEFEED)
while (S->tccpp_tok != TOK_LINEFEED)
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);
} else if (S->tok == TOK_PPNUM) {
} else if (S->tccpp_tok == TOK_PPNUM) {
const char *p;
int n;
p = S->tokc.str.data;
p = S->tccpp_tokc.str.data;
n = strtoul(p, (char **)&p, 10);
if (*p != '\0')
expect(S, "':'");
@ -950,16 +950,16 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
next(S);
skip(S, ':');
goto redo;
} else if (S->tok >= TOK_IDENT) {
} else if (S->tccpp_tok >= TOK_IDENT) {
/* instruction or label */
opcode = S->tok;
opcode = S->tccpp_tok;
next(S);
if (S->tok == ':') {
if (S->tccpp_tok == ':') {
/* new label */
asm_new_label(S, opcode, 0);
next(S);
goto redo;
} else if (S->tok == '=') {
} else if (S->tccpp_tok == '=') {
set_symbol(S, opcode);
goto redo;
} else {
@ -967,7 +967,7 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
}
}
/* end of line */
if (S->tok != ';' && S->tok != TOK_LINEFEED)
if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED)
expect(S, "end of line");
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);
/* default section is text */
cur_text_section = text_section;
S->ind = cur_text_section->data_offset;
S->nocode_wanted = 0;
S->tccgen_ind = cur_text_section->data_offset;
S->tccgen_nocode_wanted = 0;
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);
return ret;
}
@ -1107,7 +1107,7 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
ASMOperand *op;
int nb_operands;
if (S->tok != ':') {
if (S->tccpp_tok != ':') {
nb_operands = *nb_operands_ptr;
for(;;) {
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");
op = &operands[nb_operands++];
op->id = 0;
if (S->tok == '[') {
if (S->tccpp_tok == '[') {
next(S);
if (S->tok < TOK_IDENT)
if (S->tccpp_tok < TOK_IDENT)
expect(S, "identifier");
op->id = S->tok;
op->id = S->tccpp_tok;
next(S);
skip(S, ']');
}
@ -1130,23 +1130,23 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
skip(S, '(');
gexpr(S);
if (is_output) {
if (!(S->vtop->type.t & VT_ARRAY))
if (!(S->tccgen_vtop->type.t & VT_ARRAY))
test_lvalue(S);
} else {
/* we want to avoid LLOCAL case, except when the 'm'
constraint is used. Note that it may come from
register storage, so we need to convert (reg)
case */
if ((S->vtop->r & VT_LVAL) &&
((S->vtop->r & VT_VALMASK) == VT_LLOCAL ||
(S->vtop->r & VT_VALMASK) < VT_CONST) &&
if ((S->tccgen_vtop->r & VT_LVAL) &&
((S->tccgen_vtop->r & VT_VALMASK) == VT_LLOCAL ||
(S->tccgen_vtop->r & VT_VALMASK) < VT_CONST) &&
!strchr(op->constraint, 'm')) {
gv(S, RC_INT);
}
}
op->vt = S->vtop;
op->vt = S->tccgen_vtop;
skip(S, ')');
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
} else {
break;
@ -1167,7 +1167,7 @@ ST_FUNC void asm_instr(TCCState *S)
/* since we always generate the asm() instruction, we can ignore
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);
}
parse_asm_str(S, &astr);
@ -1175,27 +1175,27 @@ ST_FUNC void asm_instr(TCCState *S)
nb_outputs = 0;
must_subst = 0;
memset(clobber_regs, 0, sizeof(clobber_regs));
if (S->tok == ':') {
if (S->tccpp_tok == ':') {
next(S);
must_subst = 1;
/* output args */
parse_asm_operands(S, operands, &nb_operands, 1);
nb_outputs = nb_operands;
if (S->tok == ':') {
if (S->tccpp_tok == ':') {
next(S);
if (S->tok != ')') {
if (S->tccpp_tok != ')') {
/* input args */
parse_asm_operands(S, operands, &nb_operands, 0);
if (S->tok == ':') {
if (S->tccpp_tok == ':') {
/* clobber list */
/* XXX: handle registers */
next(S);
for(;;) {
if (S->tok != TOK_STR)
if (S->tccpp_tok != TOK_STR)
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);
if (S->tok == ',') {
if (S->tccpp_tok == ',') {
next(S);
} else {
break;
@ -1208,7 +1208,7 @@ ST_FUNC void asm_instr(TCCState *S)
skip(S, ')');
/* NOTE: we do not eat the ';' so that we can restore the current
token after the assembler parsing */
if (S->tok != ';')
if (S->tccpp_tok != ';')
expect(S, "';'");
/* save all values in the memory */
@ -1267,34 +1267,34 @@ ST_FUNC void asm_instr(TCCState *S)
ST_FUNC void asm_global_instr(TCCState* S)
{
CString astr;
int saved_nocode_wanted = S->nocode_wanted;
int saved_nocode_wanted = S->tccgen_nocode_wanted;
/* Global asm blocks are always emitted. */
S->nocode_wanted = 0;
S->tccgen_nocode_wanted = 0;
next(S);
parse_asm_str(S, &astr);
skip(S, ')');
/* NOTE: we do not eat the ';' so that we can restore the current
token after the assembler parsing */
if (S->tok != ';')
if (S->tccpp_tok != ';')
expect(S, "';'");
#ifdef ASM_DEBUG
printf("asm_global: \"%s\"\n", (char *)astr.data);
#endif
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 */
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 */
next(S);
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");
}
ST_FUNC void asm_instr(TCCState *S)
ST_FUNC void asm_instr(S)
{
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");
}

1440
tccgen.c

File diff suppressed because it is too large Load diff

View file

@ -865,7 +865,7 @@ ST_FUNC int macho_add_dllref(TCCState *S, int lev, const char* soname)
#ifdef TCC_IS_NATIVE
/* Looks for the active developer SDK set by xcode-select (or the default
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;
void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY);

View file

@ -1512,7 +1512,7 @@ ST_FUNC SValue *pe_getimport(TCCState *S, SValue *sv, SValue *v2)
vpushv(S, v2);
vpushi(S, sv->c.i);
gen_opi(S, '+');
*v2 = *S->vtop--;
*v2 = *S->tccgen_vtop--;
}
v2->type.t = sv->type.t;
v2->r |= sv->r & VT_LVAL;

566
tccpp.c

File diff suppressed because it is too large Load diff

View file

@ -152,13 +152,13 @@ ST_DATA const int reg_classes[NB_REGS] = {
ST_FUNC void g(TCCState* S, int c)
{
int ind1;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return;
ind1 = S->ind + 1;
ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c;
S->ind = ind1;
cur_text_section->data[S->tccgen_ind] = c;
S->tccgen_ind = ind1;
}
ST_FUNC void o(TCCState* S, unsigned int c)
@ -228,10 +228,10 @@ static int is64_type(int t)
static int oad(TCCState *S, int c, int s)
{
int t;
if (S->nocode_wanted)
if (S->tccgen_nocode_wanted)
return s;
o(S, c);
t = S->ind;
t = S->tccgen_ind;
gen_le32(S, s);
return t;
}
@ -242,7 +242,7 @@ static int oad(TCCState *S, int c, int s)
ST_FUNC void gen_addr32(TCCState *S, int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloca(S, cur_text_section, sym, S->ind, R_X86_64_32S, c), c=0;
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_32S, c), c=0;
gen_le32(S, c);
}
@ -250,7 +250,7 @@ ST_FUNC void gen_addr32(TCCState *S, int r, Sym *sym, int c)
ST_FUNC void gen_addr64(TCCState *S, int r, Sym *sym, int64_t c)
{
if (r & VT_SYM)
greloca(S, cur_text_section, sym, S->ind, R_X86_64_64, c), c=0;
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_64, c), c=0;
gen_le64(S, c);
}
@ -258,7 +258,7 @@ ST_FUNC void gen_addr64(TCCState *S, int r, Sym *sym, int64_t c)
ST_FUNC void gen_addrpc32(TCCState *S, int r, Sym *sym, int c)
{
if (r & VT_SYM)
greloca(S, cur_text_section, sym, S->ind, R_X86_64_PC32, c-4), c=4;
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_PC32, c-4), c=4;
gen_le32(S, c-4);
}
@ -268,12 +268,12 @@ static void gen_gotpcrel(TCCState *S, int r, Sym *sym, int c)
#ifdef TCC_TARGET_PE
tcc_error(S, "internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n",
get_tok_str(S, sym->v, NULL), c, r,
cur_text_section->data[S->ind-3],
cur_text_section->data[S->ind-2],
cur_text_section->data[S->ind-1]
cur_text_section->data[S->tccgen_ind-3],
cur_text_section->data[S->tccgen_ind-2],
cur_text_section->data[S->tccgen_ind-1]
);
#endif
greloca(S, cur_text_section, sym, S->ind, R_X86_64_GOTPCREL, -4);
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_GOTPCREL, -4);
gen_le32(S, 0);
if (c) {
/* we use add c, %xxx for displacement */
@ -482,7 +482,7 @@ void load(TCCState *S, int r, SValue *sv)
} else if (v == VT_CMP) {
if (fc & 0x100)
{
v = S->vtop->cmp_r;
v = S->tccgen_vtop->cmp_r;
fc &= ~0x100;
/* This was a float compare. If the parity bit is
set the result was unordered, meaning false for everything
@ -624,19 +624,19 @@ void store(TCCState *S, int r, SValue *v)
static void gcall_or_jmp(TCCState *S, int is_jmp)
{
int r;
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((S->vtop->r & VT_SYM) && (S->vtop->c.i-4) == (int)(S->vtop->c.i-4))) {
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
((S->tccgen_vtop->r & VT_SYM) && (S->tccgen_vtop->c.i-4) == (int)(S->tccgen_vtop->c.i-4))) {
/* constant symbolic case -> simple relocation */
#ifdef TCC_TARGET_PE
greloca(S, cur_text_section, S->vtop->sym, S->ind + 1, R_X86_64_PC32, (int)(S->vtop->c.i-4));
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_X86_64_PC32, (int)(S->tccgen_vtop->c.i-4));
#else
greloca(S, cur_text_section, S->vtop->sym, S->ind + 1, R_X86_64_PLT32, (int)(S->vtop->c.i-4));
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_X86_64_PLT32, (int)(S->tccgen_vtop->c.i-4));
#endif
oad(S, 0xe8 + is_jmp, 0); /* call/jmp im */
} else {
/* otherwise, indirect call */
r = TREG_R11;
load(S, r, S->vtop);
load(S, r, S->tccgen_vtop);
o(S, 0x41); /* REX */
o(S, 0xff); /* call/jmp *r */
o(S, 0xd0 + REG_VALUE(r) + (is_jmp << 4));
@ -650,9 +650,9 @@ static void gen_bounds_call(TCCState *S, int v)
Sym *sym = external_helper_sym(S, v);
oad(S, 0xe8, 0);
#ifdef TCC_TARGET_PE
greloca(S, cur_text_section, sym, S->ind-4, R_X86_64_PC32, -4);
greloca(S, cur_text_section, sym, S->tccgen_ind-4, R_X86_64_PC32, -4);
#else
greloca(S, cur_text_section, sym, S->ind-4, R_X86_64_PLT32, -4);
greloca(S, cur_text_section, sym, S->tccgen_ind-4, R_X86_64_PLT32, -4);
#endif
}
@ -666,7 +666,7 @@ static void gen_bounds_prolog(TCCState *S)
{
/* leave some room for bound checking code */
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;
o(S, 0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /*lbound section pointer */
gen_le32(S, 0);
@ -687,22 +687,22 @@ static void gen_bounds_epilog(TCCState *S)
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
*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);
/* generate bound local allocation */
if (offset_modified) {
saved_ind = S->ind;
S->ind = S->func_bound_ind;
greloca(S, cur_text_section, sym_data, S->ind + 3, R_X86_64_PC32, -4);
S->ind = S->ind + 7;
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->func_bound_ind;
greloca(S, cur_text_section, sym_data, S->tccgen_ind + 3, R_X86_64_PC32, -4);
S->tccgen_ind = S->tccgen_ind + 7;
gen_bounds_call(S, TOK___bound_local_new);
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
/* generate bound check local freeing */
o(S, 0x5250); /* save returned value, if any */
greloca(S, cur_text_section, sym_data, S->ind + 3, R_X86_64_PC32, -4);
greloca(S, cur_text_section, sym_data, S->tccgen_ind + 3, R_X86_64_PC32, -4);
o(S, 0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /* lea xxx(%rip), %rcx/rdi */
gen_le32(S, 0);
gen_bounds_call(S, TOK___bound_local_delete);
@ -804,7 +804,7 @@ void gfunc_call(TCCState *S, int nb_args)
SValue *sv;
--arg;
sv = &S->vtop[-i];
sv = &S->tccgen_vtop[-i];
bt = (sv->type.t & VT_BTYPE);
size = gfunc_arg_size(&sv->type);
@ -823,7 +823,7 @@ void gfunc_call(TCCState *S, int nb_args)
vset(S, &sv->type, r | VT_LVAL, 0);
vpushv(S, sv);
vstore(S);
--S->vtop;
--S->tccgen_vtop;
} else if (bt == VT_LDOUBLE) {
gv(S, RC_ST0);
gen_offs_sp(S, 0xdb, 0x107, struct_size);
@ -839,9 +839,9 @@ void gfunc_call(TCCState *S, int nb_args)
for(i = 0; i < nb_args; i++) {
--arg;
bt = (S->vtop->type.t & VT_BTYPE);
bt = (S->tccgen_vtop->type.t & VT_BTYPE);
size = gfunc_arg_size(&S->vtop->type);
size = gfunc_arg_size(&S->tccgen_vtop->type);
if (!using_regs(size)) {
/* align to stack align size */
size = (size + 15) & ~15;
@ -855,7 +855,7 @@ void gfunc_call(TCCState *S, int nb_args)
}
struct_size += size;
} else {
if (is_sse_float(S->vtop->type.t)) {
if (is_sse_float(S->tccgen_vtop->type.t)) {
if (S->nosse)
tcc_error(S, "SSE disabled");
if (arg >= REGN) {
@ -873,8 +873,8 @@ void gfunc_call(TCCState *S, int nb_args)
}
} else {
if (bt == VT_STRUCT) {
S->vtop->type.ref = NULL;
S->vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
S->tccgen_vtop->type.ref = NULL;
S->tccgen_vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
: size > 1 ? VT_SHORT : VT_BYTE;
}
@ -888,7 +888,7 @@ void gfunc_call(TCCState *S, int nb_args)
}
}
}
S->vtop--;
S->tccgen_vtop--;
}
save_regs(S, 0);
/* Copy R10 and R11 into RCX and RDX, respectively */
@ -901,7 +901,7 @@ void gfunc_call(TCCState *S, int nb_args)
gcall_or_jmp(S, 0);
if ((S->vtop->r & VT_SYM) && S->vtop->sym->v == TOK_alloca) {
if ((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->sym->v == TOK_alloca) {
/* need to add the "func_scratch" area after alloca */
o(S, 0x48); S->x86_64_gen_func_alloca = oad(S, 0x05, S->x86_64_gen_func_alloca); /* add $NN, %rax */
#ifdef CONFIG_TCC_BCHECK
@ -909,7 +909,7 @@ void gfunc_call(TCCState *S, int nb_args)
gen_bounds_call(S, TOK___bound_alloca_nr); /* new region */
#endif
}
S->vtop--;
S->tccgen_vtop--;
}
@ -926,11 +926,11 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
S->x86_64_gen_func_ret_sub = 0;
S->x86_64_gen_func_scratch = 32;
S->x86_64_gen_func_alloca = 0;
S->loc = 0;
S->tccgen_loc = 0;
addr = PTR_SIZE * 2;
S->ind += FUNC_PROLOG_SIZE;
S->x86_64_gen_func_sub_sp_offset = S->ind;
S->tccgen_ind += FUNC_PROLOG_SIZE;
S->x86_64_gen_func_sub_sp_offset = S->tccgen_ind;
reg_param_index = 0;
sym = func_type->ref;
@ -995,7 +995,7 @@ void gfunc_epilog(TCCState *S)
/* align local size to word & save local variables */
S->x86_64_gen_func_scratch = (S->x86_64_gen_func_scratch + 15) & -16;
S->loc = (S->loc & -16) - S->x86_64_gen_func_scratch;
S->tccgen_loc = (S->tccgen_loc & -16) - S->x86_64_gen_func_scratch;
#ifdef CONFIG_TCC_BCHECK
if (S->do_bounds_check)
@ -1011,15 +1011,15 @@ void gfunc_epilog(TCCState *S)
g(S, S->x86_64_gen_func_ret_sub >> 8);
}
saved_ind = S->ind;
S->ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
v = -S->loc;
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
v = -S->tccgen_loc;
if (v >= 4096) {
Sym *sym = external_helper_sym(S, TOK___chkstk);
oad(S, 0xb8, v); /* mov stacksize, %eax */
oad(S, 0xe8, 0); /* call __chkstk, (does the stackframe too) */
greloca(S, cur_text_section, sym, S->ind-4, R_X86_64_PC32, -4);
greloca(S, cur_text_section, sym, S->tccgen_ind-4, R_X86_64_PC32, -4);
o(S, 0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
} else {
o(S, 0xe5894855); /* push %rbp, mov %rsp, %rbp */
@ -1031,8 +1031,8 @@ void gfunc_epilog(TCCState *S)
gsym_addr(S, S->x86_64_gen_func_alloca, -S->x86_64_gen_func_scratch);
cur_text_section->data_offset = saved_ind;
pe_add_unwind_data(S, S->ind, saved_ind, v);
S->ind = cur_text_section->data_offset;
pe_add_unwind_data(S, S->tccgen_ind, saved_ind, v);
S->tccgen_ind = cur_text_section->data_offset;
}
#else
@ -1237,7 +1237,7 @@ void gfunc_call(TCCState *S, int nb_args)
to be done in a left-to-right pass over arguments. */
stack_adjust = 0;
for(i = nb_args - 1; i >= 0; i--) {
mode = classify_x86_64_arg(&S->vtop[-i].type, NULL, &size, &align, &reg_count);
mode = classify_x86_64_arg(&S->tccgen_vtop[-i].type, NULL, &size, &align, &reg_count);
if (size == 0) continue;
if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
nb_sse_args += reg_count;
@ -1261,7 +1261,7 @@ void gfunc_call(TCCState *S, int nb_args)
tcc_error(S, "SSE disabled but floating point arguments passed");
/* 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);
/* for struct arguments, we need to call memcpy and the function
@ -1272,7 +1272,7 @@ void gfunc_call(TCCState *S, int nb_args)
args_size = 0;
stack_adjust &= 15;
for (i = k = 0; i < nb_args;) {
mode = classify_x86_64_arg(&S->vtop[-i].type, NULL, &size, &align, &reg_count);
mode = classify_x86_64_arg(&S->tccgen_vtop[-i].type, NULL, &size, &align, &reg_count);
if (size) {
if (!onstack[i + k]) {
++i;
@ -1293,7 +1293,7 @@ void gfunc_call(TCCState *S, int nb_args)
vrotb(S, i+1);
switch (S->vtop->type.t & VT_BTYPE) {
switch (S->tccgen_vtop->type.t & VT_BTYPE) {
case VT_STRUCT:
/* allocate the necessary size on stack */
o(S, 0x48);
@ -1302,7 +1302,7 @@ void gfunc_call(TCCState *S, int nb_args)
r = get_reg(S, RC_INT);
orex(S, 1, r, 0, 0x89); /* mov %rsp, r */
o(S, 0xe0 + REG_VALUE(r));
vset(S, &S->vtop->type, r | VT_LVAL, 0);
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
vswap(S);
vstore(S);
break;
@ -1353,10 +1353,10 @@ void gfunc_call(TCCState *S, int nb_args)
assert(gen_reg <= REGN);
assert(sse_reg <= 8);
for(i = 0; i < nb_args; i++) {
mode = classify_x86_64_arg(&S->vtop->type, &type, &size, &align, &reg_count);
mode = classify_x86_64_arg(&S->tccgen_vtop->type, &type, &size, &align, &reg_count);
if (size == 0) continue;
/* Alter stack entry type so that gv() knows how to treat it */
S->vtop->type = type;
S->tccgen_vtop->type = type;
if (mode == x86_64_mode_sse) {
if (reg_count == 2) {
sse_reg -= 2;
@ -1386,11 +1386,11 @@ void gfunc_call(TCCState *S, int nb_args)
o(S, 0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
if (reg_count == 2) {
d = arg_prepare_reg(gen_reg+1);
orex(S, 1,d,S->vtop->r2,0x89); /* mov */
o(S, 0xc0 + REG_VALUE(S->vtop->r2) * 8 + REG_VALUE(d));
orex(S, 1,d,S->tccgen_vtop->r2,0x89); /* mov */
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r2) * 8 + REG_VALUE(d));
}
}
S->vtop--;
S->tccgen_vtop--;
}
assert(gen_reg == 0);
assert(sse_reg == 0);
@ -1409,19 +1409,19 @@ void gfunc_call(TCCState *S, int nb_args)
}
}
if (S->vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
if (S->tccgen_vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
oad(S, 0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
gcall_or_jmp(S, 0);
if (args_size)
gadd_sp(S, args_size);
S->vtop--;
S->tccgen_vtop--;
}
#define FUNC_PROLOG_SIZE 11
static void push_arg_reg(TCCState* S, int i) {
S->loc -= 8;
gen_modrm64(S, 0x89, arg_regs[i], VT_LOCAL, NULL, S->loc);
S->tccgen_loc -= 8;
gen_modrm64(S, 0x89, arg_regs[i], VT_LOCAL, NULL, S->tccgen_loc);
}
/* generate function prolog of type 't' */
@ -1436,9 +1436,9 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
sym = func_type->ref;
addr = PTR_SIZE * 2;
S->loc = 0;
S->ind += FUNC_PROLOG_SIZE;
S->x86_64_gen_func_sub_sp_offset = S->ind;
S->tccgen_loc = 0;
S->tccgen_ind += FUNC_PROLOG_SIZE;
S->x86_64_gen_func_sub_sp_offset = S->tccgen_ind;
S->x86_64_gen_func_ret_sub = 0;
ret_mode = classify_x86_64_arg(&S->tccgen_func_vt, NULL, &size, &align, &reg_count);
@ -1473,7 +1473,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
}
}
S->loc -= 24;
S->tccgen_loc -= 24;
/* movl $0x????????, -0x18(%rbp) */
o(S, 0xe845c7);
gen_le32(S, seen_reg_num * 8);
@ -1493,14 +1493,14 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
/* save all register passing arguments */
for (i = 0; i < 8; i++) {
S->loc -= 16;
S->tccgen_loc -= 16;
if (!S->nosse) {
o(S, 0xd60f66); /* movq */
gen_modrm(S, 7 - i, VT_LOCAL, NULL, S->loc);
gen_modrm(S, 7 - i, VT_LOCAL, NULL, S->tccgen_loc);
}
/* movq $0, loc+8(%rbp) */
o(S, 0x85c748);
gen_le32(S, S->loc + 8);
gen_le32(S, S->tccgen_loc + 8);
gen_le32(S, 0);
}
for (i = 0; i < REGN; i++) {
@ -1516,7 +1516,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
implicit pointer parameter */
if (ret_mode == x86_64_mode_memory) {
push_arg_reg(S, reg_param_index);
S->tccgen_func_vc = S->loc;
S->tccgen_func_vc = S->tccgen_loc;
reg_param_index++;
}
/* define parameters */
@ -1529,8 +1529,8 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
tcc_error(S, "SSE disabled but floating point arguments used");
if (sse_param_index + reg_count <= 8) {
/* save arguments passed by register */
S->loc -= reg_count * 8;
param_addr = S->loc;
S->tccgen_loc -= reg_count * 8;
param_addr = S->tccgen_loc;
for (i = 0; i < reg_count; ++i) {
o(S, 0xd60f66); /* movq */
gen_modrm(S, sse_param_index, VT_LOCAL, NULL, param_addr + i*8);
@ -1553,8 +1553,8 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
case x86_64_mode_integer: {
if (reg_param_index + reg_count <= REGN) {
/* save arguments passed by register */
S->loc -= reg_count * 8;
param_addr = S->loc;
S->tccgen_loc -= reg_count * 8;
param_addr = S->tccgen_loc;
for (i = 0; i < reg_count; ++i) {
gen_modrm64(S, 0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8);
++reg_param_index;
@ -1596,13 +1596,13 @@ void gfunc_epilog(TCCState *S)
g(S, S->x86_64_gen_func_ret_sub >> 8);
}
/* align local size to word & save local variables */
v = (-S->loc + 15) & -16;
saved_ind = S->ind;
S->ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
v = (-S->tccgen_loc + 15) & -16;
saved_ind = S->tccgen_ind;
S->tccgen_ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
o(S, 0xe5894855); /* push %rbp, mov %rsp, %rbp */
o(S, 0xec8148); /* sub rsp, stacksize */
gen_le32(S, v);
S->ind = saved_ind;
S->tccgen_ind = saved_ind;
}
#endif /* not PE */
@ -1623,12 +1623,12 @@ int gjmp(TCCState *S, int t)
void gjmp_addr(TCCState* S, int a)
{
int r;
r = a - S->ind - 2;
r = a - S->tccgen_ind - 2;
if (r == (char)r) {
g(S, 0xeb);
g(S, r);
} else {
oad(S, 0xe9, a - S->ind - 5);
oad(S, 0xe9, a - S->tccgen_ind - 5);
}
}
@ -1657,7 +1657,7 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
Take care about inverting the test. We need to jump
to our target if the result was unordered and test wasn't NE,
otherwise if unordered we don't want to jump. */
int v = S->vtop->cmp_r;
int v = S->tccgen_vtop->cmp_r;
op &= ~0x100;
if (op ^ v ^ (v != TOK_NE))
o(S, 0x067a); /* jp +6 */
@ -1678,21 +1678,21 @@ void gen_opi(TCCState *S, int op)
int r, fr, opc, c;
int ll, uu, cc;
ll = is64_type(S->vtop[-1].type.t);
uu = (S->vtop[-1].type.t & VT_UNSIGNED) != 0;
cc = (S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
ll = is64_type(S->tccgen_vtop[-1].type.t);
uu = (S->tccgen_vtop[-1].type.t & VT_UNSIGNED) != 0;
cc = (S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
switch(op) {
case '+':
case TOK_ADDC1: /* add with carry generation */
opc = 0;
gen_op8:
if (cc && (!ll || (int)S->vtop->c.i == S->vtop->c.i)) {
if (cc && (!ll || (int)S->tccgen_vtop->c.i == S->tccgen_vtop->c.i)) {
/* constant case */
vswap(S);
r = gv(S, RC_INT);
vswap(S);
c = S->vtop->c.i;
c = S->tccgen_vtop->c.i;
if (c == (char)c) {
/* XXX: generate inc and dec for smaller code ? */
orex(S, ll, r, 0, 0x83);
@ -1704,12 +1704,12 @@ void gen_opi(TCCState *S, int op)
}
} else {
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
orex(S, ll, r, fr, (opc << 3) | 0x01);
o(S, 0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8);
}
S->vtop--;
S->tccgen_vtop--;
if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(S, op);
break;
@ -1734,11 +1734,11 @@ void gen_opi(TCCState *S, int op)
goto gen_op8;
case '*':
gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
orex(S, ll, fr, r, 0xaf0f); /* imul fr, r */
o(S, 0xc0 + REG_VALUE(fr) + REG_VALUE(r) * 8);
S->vtop--;
S->tccgen_vtop--;
break;
case TOK_SHL:
opc = 4;
@ -1757,15 +1757,15 @@ void gen_opi(TCCState *S, int op)
vswap(S);
orex(S, ll, r, 0, 0xc1); /* shl/shr/sar $xxx, r */
o(S, opc | REG_VALUE(r));
g(S, S->vtop->c.i & (ll ? 63 : 31));
g(S, S->tccgen_vtop->c.i & (ll ? 63 : 31));
} else {
/* we generate the shift in ecx */
gv2(S, RC_INT, RC_RCX);
r = S->vtop[-1].r;
r = S->tccgen_vtop[-1].r;
orex(S, ll, r, 0, 0xd3); /* shl/shr/sar %cl, r */
o(S, opc | REG_VALUE(r));
}
S->vtop--;
S->tccgen_vtop--;
break;
case TOK_UDIV:
case TOK_UMOD:
@ -1779,9 +1779,9 @@ void gen_opi(TCCState *S, int op)
/* first operand must be in eax */
/* XXX: need better constraint for second operand */
gv2(S, RC_RAX, RC_RCX);
r = S->vtop[-1].r;
fr = S->vtop[0].r;
S->vtop--;
r = S->tccgen_vtop[-1].r;
fr = S->tccgen_vtop[0].r;
S->tccgen_vtop--;
save_reg(S, TREG_RDX);
orex(S, ll, 0, 0, uu ? 0xd231 : 0x99); /* xor %edx,%edx : cqto */
orex(S, ll, fr, 0, 0xf7); /* div fr, %eax */
@ -1790,7 +1790,7 @@ void gen_opi(TCCState *S, int op)
r = TREG_RDX;
else
r = TREG_RAX;
S->vtop->r = r;
S->tccgen_vtop->r = r;
break;
default:
opc = 7;
@ -1807,7 +1807,7 @@ void vpush_const(TCCState *S, int t, int v)
{
CType ctype = { t | VT_CONSTANT, 0 };
vpushsym(S, &ctype, external_global_sym(S, v, &ctype));
S->vtop->r |= VT_LVAL;
S->tccgen_vtop->r |= VT_LVAL;
}
/* generate a floating point operation 'v = t1 op t2' instruction. The
@ -1816,7 +1816,7 @@ void vpush_const(TCCState *S, int t, int v)
void gen_opf(TCCState* S, int op)
{
int a, ft, fc, swapped, r;
int bt = S->vtop->type.t & VT_BTYPE;
int bt = S->tccgen_vtop->type.t & VT_BTYPE;
int float_type = bt == VT_LDOUBLE ? RC_ST0 : RC_FLOAT;
if (op == TOK_NEG) { /* unary minus */
@ -1830,24 +1830,24 @@ void gen_opf(TCCState *S, int op)
if (bt == VT_DOUBLE)
o(S, 0x66);
/* xorp[sd] %xmm1, %xmm0 */
o(S, 0xc0570f | (REG_VALUE(S->vtop[0].r) + REG_VALUE(S->vtop[-1].r)*8) << 16);
S->vtop--;
o(S, 0xc0570f | (REG_VALUE(S->tccgen_vtop[0].r) + REG_VALUE(S->tccgen_vtop[-1].r)*8) << 16);
S->tccgen_vtop--;
}
return;
}
/* 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);
gv(S, float_type);
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, float_type);
/* must put at least one value in the floating point register */
if ((S->vtop[-1].r & VT_LVAL) &&
(S->vtop[0].r & VT_LVAL)) {
if ((S->tccgen_vtop[-1].r & VT_LVAL) &&
(S->tccgen_vtop[0].r & VT_LVAL)) {
vswap(S);
gv(S, float_type);
vswap(S);
@ -1855,14 +1855,14 @@ void gen_opf(TCCState *S, int op)
swapped = 0;
/* swap the stack if needed so that t1 is the register and t2 is
the memory reference */
if (S->vtop[-1].r & VT_LVAL) {
if (S->tccgen_vtop[-1].r & VT_LVAL) {
vswap(S);
swapped = 1;
}
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
if (op >= TOK_ULT && op <= TOK_GT) {
/* load on stack second operand */
load(S, TREG_ST0, S->vtop);
load(S, TREG_ST0, S->tccgen_vtop);
save_reg(S, TREG_RAX); /* eax is used by FP comparison code */
if (op == TOK_GE || op == TOK_GT)
swapped = !swapped;
@ -1889,11 +1889,11 @@ void gen_opf(TCCState *S, int op)
o(S, 0x45c4f6); /* test $0x45, %ah */
op = TOK_EQ;
}
S->vtop--;
S->tccgen_vtop--;
vset_VT_CMP(S, op);
} else {
/* no memory reference possible for long double operations */
load(S, TREG_ST0, S->vtop);
load(S, TREG_ST0, S->tccgen_vtop);
swapped = !swapped;
switch(op) {
@ -1915,17 +1915,17 @@ void gen_opf(TCCState *S, int op)
a++;
break;
}
ft = S->vtop->type.t;
fc = S->vtop->c.i;
ft = S->tccgen_vtop->type.t;
fc = S->tccgen_vtop->c.i;
o(S, 0xde); /* fxxxp %st, %st(1) */
o(S, 0xc1 + (a << 3));
S->vtop--;
S->tccgen_vtop--;
}
} else {
if (op >= TOK_ULT && op <= TOK_GT) {
/* if saved lvalue, then we must reload it */
r = S->vtop->r;
fc = S->vtop->c.i;
r = S->tccgen_vtop->r;
fc = S->tccgen_vtop->c.i;
if ((r & VT_VALMASK) == VT_LLOCAL) {
SValue v1;
r = get_reg(S, RC_INT);
@ -1934,7 +1934,7 @@ void gen_opf(TCCState *S, int op)
v1.c.i = fc;
load(S, r, &v1);
fc = 0;
S->vtop->r = r = r | VT_LVAL;
S->tccgen_vtop->r = r = r | VT_LVAL;
}
if (op == TOK_EQ || op == TOK_NE) {
@ -1953,26 +1953,26 @@ void gen_opf(TCCState *S, int op)
gv(S, RC_FLOAT);
vswap(S);
}
assert(!(S->vtop[-1].r & VT_LVAL));
assert(!(S->tccgen_vtop[-1].r & VT_LVAL));
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE)
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
o(S, 0x66);
if (op == TOK_EQ || op == TOK_NE)
o(S, 0x2e0f); /* ucomisd */
else
o(S, 0x2f0f); /* comisd */
if (S->vtop->r & VT_LVAL) {
gen_modrm(S, S->vtop[-1].r, r, S->vtop->sym, fc);
if (S->tccgen_vtop->r & VT_LVAL) {
gen_modrm(S, S->tccgen_vtop[-1].r, r, S->tccgen_vtop->sym, fc);
} else {
o(S, 0xc0 + REG_VALUE(S->vtop[0].r) + REG_VALUE(S->vtop[-1].r)*8);
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop[0].r) + REG_VALUE(S->tccgen_vtop[-1].r)*8);
}
S->vtop--;
S->tccgen_vtop--;
vset_VT_CMP(S, op | 0x100);
S->vtop->cmp_r = op;
S->tccgen_vtop->cmp_r = op;
} else {
assert((S->vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
assert((S->tccgen_vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
switch(op) {
default:
case '+':
@ -1988,13 +1988,13 @@ void gen_opf(TCCState *S, int op)
a = 6;
break;
}
ft = S->vtop->type.t;
fc = S->vtop->c.i;
ft = S->tccgen_vtop->type.t;
fc = S->tccgen_vtop->c.i;
assert((ft & VT_BTYPE) != VT_LDOUBLE);
r = S->vtop->r;
r = S->tccgen_vtop->r;
/* if saved lvalue, then we must reload it */
if ((S->vtop->r & VT_VALMASK) == VT_LLOCAL) {
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_LLOCAL) {
SValue v1;
r = get_reg(S, RC_INT);
v1.type.t = VT_PTR;
@ -2002,12 +2002,12 @@ void gen_opf(TCCState *S, int op)
v1.c.i = fc;
load(S, r, &v1);
fc = 0;
S->vtop->r = r = r | VT_LVAL;
S->tccgen_vtop->r = r = r | VT_LVAL;
}
assert(!(S->vtop[-1].r & VT_LVAL));
assert(!(S->tccgen_vtop[-1].r & VT_LVAL));
if (swapped) {
assert(S->vtop->r & VT_LVAL);
assert(S->tccgen_vtop->r & VT_LVAL);
gv(S, RC_FLOAT);
vswap(S);
}
@ -2020,13 +2020,13 @@ void gen_opf(TCCState *S, int op)
o(S, 0x0f);
o(S, 0x58 + a);
if (S->vtop->r & VT_LVAL) {
gen_modrm(S, S->vtop[-1].r, r, S->vtop->sym, fc);
if (S->tccgen_vtop->r & VT_LVAL) {
gen_modrm(S, S->tccgen_vtop[-1].r, r, S->tccgen_vtop->sym, fc);
} else {
o(S, 0xc0 + REG_VALUE(S->vtop[0].r) + REG_VALUE(S->vtop[-1].r)*8);
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop[0].r) + REG_VALUE(S->tccgen_vtop[-1].r)*8);
}
S->vtop--;
S->tccgen_vtop--;
}
}
}
@ -2038,39 +2038,39 @@ void gen_cvt_itof(TCCState *S, int t)
if ((t & VT_BTYPE) == VT_LDOUBLE) {
save_reg(S, TREG_ST0);
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
is handled generically) */
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 (%rsp) */
o(S, 0x08c48348); /* add $8, %rsp */
} 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)) {
/* unsigned int to float/double/long double */
o(S, 0x6a); /* push $0 */
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 (%rsp) */
o(S, 0x10c48348); /* add $16, %rsp */
} else {
/* 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 (%rsp) */
o(S, 0x08c48348); /* add $8, %rsp */
}
S->vtop->r = TREG_ST0;
S->tccgen_vtop->r = TREG_ST0;
} else {
int r = get_reg(S, RC_FLOAT);
gv(S, RC_INT);
o(S, 0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0));
if ((S->vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED) ||
(S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
(S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
o(S, 0x48); /* REX */
}
o(S, 0x2a0f);
o(S, 0xc0 + (S->vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
S->vtop->r = r;
o(S, 0xc0 + (S->tccgen_vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
S->tccgen_vtop->r = r;
}
}
@ -2079,7 +2079,7 @@ void gen_cvt_ftof(TCCState *S, int t)
{
int ft, bt, tbt;
ft = S->vtop->type.t;
ft = S->tccgen_vtop->type.t;
bt = ft & VT_BTYPE;
tbt = t & VT_BTYPE;
@ -2087,33 +2087,33 @@ void gen_cvt_ftof(TCCState *S, int t)
gv(S, RC_FLOAT);
if (tbt == VT_DOUBLE) {
o(S, 0x140f); /* unpcklps */
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
o(S, 0x5a0f); /* cvtps2pd */
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
} else if (tbt == VT_LDOUBLE) {
save_reg(S, RC_ST0);
/* movss %xmm0,-0x10(%rsp) */
o(S, 0x110ff3);
o(S, 0x44 + REG_VALUE(S->vtop->r)*8);
o(S, 0x44 + REG_VALUE(S->tccgen_vtop->r)*8);
o(S, 0xf024);
o(S, 0xf02444d9); /* flds -0x10(%rsp) */
S->vtop->r = TREG_ST0;
S->tccgen_vtop->r = TREG_ST0;
}
} else if (bt == VT_DOUBLE) {
gv(S, RC_FLOAT);
if (tbt == VT_FLOAT) {
o(S, 0x140f66); /* unpcklpd */
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
o(S, 0x5a0f66); /* cvtpd2ps */
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
} else if (tbt == VT_LDOUBLE) {
save_reg(S, RC_ST0);
/* movsd %xmm0,-0x10(%rsp) */
o(S, 0x110ff2);
o(S, 0x44 + REG_VALUE(S->vtop->r)*8);
o(S, 0x44 + REG_VALUE(S->tccgen_vtop->r)*8);
o(S, 0xf024);
o(S, 0xf02444dd); /* fldl -0x10(%rsp) */
S->vtop->r = TREG_ST0;
S->tccgen_vtop->r = TREG_ST0;
}
} else {
int r;
@ -2125,14 +2125,14 @@ void gen_cvt_ftof(TCCState *S, int t)
o(S, 0x100ff2);
o(S, 0x44 + REG_VALUE(r)*8);
o(S, 0xf024);
S->vtop->r = r;
S->tccgen_vtop->r = r;
} else if (tbt == VT_FLOAT) {
o(S, 0xf0245cd9); /* fstps -0x10(%rsp) */
/* movss -0x10(%rsp),%xmm0 */
o(S, 0x100ff3);
o(S, 0x44 + REG_VALUE(r)*8);
o(S, 0xf024);
S->vtop->r = r;
S->tccgen_vtop->r = r;
}
}
}
@ -2141,7 +2141,7 @@ void gen_cvt_ftof(TCCState *S, int t)
void gen_cvt_ftoi(TCCState* S, int t)
{
int ft, bt, size, r;
ft = S->vtop->type.t;
ft = S->tccgen_vtop->type.t;
bt = ft & VT_BTYPE;
if (bt == VT_LDOUBLE) {
gen_cvt_ftof(S, VT_DOUBLE);
@ -2163,8 +2163,8 @@ void gen_cvt_ftoi(TCCState *S, int t)
assert(0);
}
orex(S, size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */
o(S, 0xc0 + REG_VALUE(S->vtop->r) + REG_VALUE(r)*8);
S->vtop->r = r;
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r) + REG_VALUE(r)*8);
S->tccgen_vtop->r = r;
}
// Generate sign extension from 32 to 64 bits:
@ -2183,7 +2183,7 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
r = gv(S, RC_INT);
sz = !(t & VT_UNSIGNED);
xl = (t & VT_BTYPE) == VT_SHORT;
ll = (S->vtop->type.t & VT_BTYPE) == VT_LLONG;
ll = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;
orex(S, ll, r, 0, 0xc0b60f /* mov[sz] %a[xl], %eax */
| (sz << 3 | xl) << 8
| (REG_VALUE(r) << 3 | REG_VALUE(r)) << 16
@ -2194,7 +2194,7 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
{
o(S, 0x058348); /* addq $1, xxx(%rip) */
greloca(S, cur_text_section, sv->sym, S->ind, R_X86_64_PC32, -5);
greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_X86_64_PC32, -5);
gen_le32(S, 0);
o(S, 1);
}
@ -2203,7 +2203,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
void ggoto(TCCState* S)
{
gcall_or_jmp(S, 1);
S->vtop--;
S->tccgen_vtop--;
}
/* Save the stack pointer onto the stack and return the location of its address */