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; op->type = 0;
if (S->tok == '{') { // regset literal if (S->tccpp_tok == '{') { // regset literal
next(S); // skip '{' next(S); // skip '{'
while (S->tok != '}' && S->tok != TOK_EOF) { while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {
reg = asm_parse_regvar(S, S->tok); reg = asm_parse_regvar(S, S->tccpp_tok);
if (reg == -1) { if (reg == -1) {
expect(S, "register"); expect(S, "register");
return; return;
@ -113,11 +113,11 @@ static void parse_operand(TCCState *S, Operand *op)
if ((1 << reg) < regset) if ((1 << reg) < regset)
tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here"); tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
regset |= 1 << reg; regset |= 1 << reg;
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); // skip ',' next(S); // skip ','
} }
if (S->tok != '}') if (S->tccpp_tok != '}')
expect(S, "'}'"); expect(S, "'}'");
next(S); // skip '}' next(S); // skip '}'
if (regset == 0) { if (regset == 0) {
@ -128,22 +128,22 @@ static void parse_operand(TCCState *S, Operand *op)
op->regset = regset; op->regset = regset;
} }
return; return;
} else if ((reg = asm_parse_regvar(S, S->tok)) != -1) { } else if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_REG32; op->type = OP_REG32;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if ((reg = asm_parse_vfp_regvar(S->tok, 0)) != -1) { } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_VREG32; op->type = OP_VREG32;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if ((reg = asm_parse_vfp_regvar(S->tok, 1)) != -1) { } else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
next(S); // skip register name next(S); // skip register name
op->type = OP_VREG64; op->type = OP_VREG64;
op->reg = (uint8_t) reg; op->reg = (uint8_t) reg;
return; return;
} else if (S->tok == '#' || S->tok == '$') { } else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
/* constant value */ /* constant value */
next(S); // skip '#' or '$' next(S); // skip '#' or '$'
} }
@ -163,13 +163,13 @@ static void parse_operand(TCCState *S, Operand *op)
ST_FUNC void g(TCCState* S, int c) ST_FUNC void g(TCCState* S, int c)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 1; ind1 = S->tccgen_ind + 1;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c; cur_text_section->data[S->tccgen_ind] = c;
S->ind = ind1; S->tccgen_ind = ind1;
} }
ST_FUNC void gen_le16 (TCCState* S, int i) ST_FUNC void gen_le16 (TCCState* S, int i)
@ -181,15 +181,15 @@ ST_FUNC void gen_le16 (TCCState *S, int i)
ST_FUNC void gen_le32 (TCCState* S, int i) ST_FUNC void gen_le32 (TCCState* S, int i)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
ind1 = S->ind + 4; ind1 = S->tccgen_ind + 4;
if (ind1 > cur_text_section->data_allocated) if (ind1 > cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind++] = i & 0xFF; cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF; cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
} }
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe) ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
@ -276,7 +276,7 @@ static void asm_binary_opcode(TCCState *S, int token)
uint32_t encoded_rotation = 0; uint32_t encoded_rotation = 0;
uint64_t amount; uint64_t amount;
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -328,9 +328,9 @@ static void asm_binary_opcode(TCCState *S, int token)
if (ops[1].reg == 13) if (ops[1].reg == 13)
tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL)); tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == TOK_ASM_ror) { if (S->tccpp_tok == TOK_ASM_ror) {
next(S); // skip 'ror' next(S); // skip 'ror'
parse_operand(S, &rotation); parse_operand(S, &rotation);
if (rotation.type != OP_IM8) { if (rotation.type != OP_IM8) {
@ -387,15 +387,15 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
uint8_t high_nibble; uint8_t high_nibble;
uint8_t mrc = 0; uint8_t mrc = 0;
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) { if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
coprocessor = S->tok - TOK_ASM_p0; coprocessor = S->tccpp_tok - TOK_ASM_p0;
next(S); next(S);
} else { } else {
expect(S, "'p<number>'"); expect(S, "'p<number>'");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -407,21 +407,21 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
} }
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) { if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {
if (S->tok >= TOK_ASM_r0 && S->tok <= TOK_ASM_r15) { if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {
registers[i] = S->tok - TOK_ASM_r0; registers[i] = S->tccpp_tok - TOK_ASM_r0;
next(S); next(S);
} else { } else {
expect(S, "'r<number>'"); expect(S, "'r<number>'");
return; return;
} }
} else { } else {
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) { if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
registers[i] = S->tok - TOK_ASM_c0; registers[i] = S->tccpp_tok - TOK_ASM_c0;
next(S); next(S);
} else { } else {
expect(S, "'c<number>'"); expect(S, "'c<number>'");
@ -429,7 +429,7 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
} }
} }
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
parse_operand(S, &opcode2); parse_operand(S, &opcode2);
} else { } else {
@ -493,11 +493,11 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
Operand ops[2]; Operand ops[2];
int nb_ops = 1; int nb_ops = 1;
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == '!') { if (S->tccpp_tok == '!') {
op0_exclam = 1; op0_exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip comma next(S); // skip comma
parse_operand(S, &ops[1]); parse_operand(S, &ops[1]);
++nb_ops; ++nb_ops;
@ -604,13 +604,13 @@ static uint32_t asm_parse_optional_shift(TCCState *S, int* nb_shift, Operand* sh
{ {
uint32_t opcode = 0; uint32_t opcode = 0;
*nb_shift = 0; *nb_shift = 0;
switch (S->tok) { switch (S->tccpp_tok) {
case TOK_ASM_asl: case TOK_ASM_asl:
case TOK_ASM_lsl: case TOK_ASM_lsl:
case TOK_ASM_asr: case TOK_ASM_asr:
case TOK_ASM_lsr: case TOK_ASM_lsr:
case TOK_ASM_ror: case TOK_ASM_ror:
switch (S->tok) { switch (S->tccpp_tok) {
case TOK_ASM_asl: case TOK_ASM_asl:
/* fallthrough */ /* fallthrough */
case TOK_ASM_lsl: case TOK_ASM_lsl:
@ -677,15 +677,15 @@ static void asm_data_processing_opcode(TCCState *S, int token)
uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
if (S->tok == TOK_ASM_asl || S->tok == TOK_ASM_lsl || S->tok == TOK_ASM_lsr || S->tok == TOK_ASM_asr || S->tok == TOK_ASM_ror || S->tok == TOK_ASM_rrx) if (S->tccpp_tok == TOK_ASM_asl || S->tccpp_tok == TOK_ASM_lsl || S->tccpp_tok == TOK_ASM_lsr || S->tccpp_tok == TOK_ASM_asr || S->tccpp_tok == TOK_ASM_ror || S->tccpp_tok == TOK_ASM_rrx)
break; break;
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
++nb_ops; ++nb_ops;
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); // skip ',' next(S); // skip ','
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
operands |= asm_parse_optional_shift(S, &nb_shift, &shift); operands |= asm_parse_optional_shift(S, &nb_shift, &shift);
if (nb_ops < 2) if (nb_ops < 2)
@ -852,7 +852,7 @@ static void asm_shift_opcode(TCCState *S, int token)
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
++nb_ops; ++nb_ops;
break; break;
} }
@ -961,7 +961,7 @@ static void asm_multiplication_opcode(TCCState *S, int token)
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
++nb_ops; ++nb_ops;
break; break;
} }
@ -1043,7 +1043,7 @@ static void asm_long_multiplication_opcode(TCCState *S, int token)
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) { for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
parse_operand(S, &ops[nb_ops]); parse_operand(S, &ops[nb_ops]);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
++nb_ops; ++nb_ops;
break; break;
} }
@ -1133,7 +1133,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(destination operand) register"); expect(S, "(destination operand) register");
return; return;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "at least two arguments"); expect(S, "at least two arguments");
else else
next(S); // skip ',' next(S); // skip ','
@ -1146,14 +1146,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "register"); expect(S, "register");
return; return;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "at least three arguments"); expect(S, "at least three arguments");
else else
next(S); // skip ',' next(S); // skip ','
break; break;
} }
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -1165,14 +1165,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ']') { if (S->tccpp_tok == ']') {
next(S); next(S);
closed_bracket = 1; closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software // exclam = 1; // implicit in hardware; don't do it in software
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op2_minus = 1; op2_minus = 1;
next(S); next(S);
} }
@ -1182,7 +1182,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL)); tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
return; return;
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
opcode |= asm_parse_optional_shift(S, &nb_shift, &shift); opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);
if (opcode == 0) if (opcode == 0)
@ -1196,12 +1196,12 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
} }
if (!closed_bracket) { if (!closed_bracket) {
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
if (S->tok == '!') { if (S->tccpp_tok == '!') {
exclam = 1; exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
@ -1389,33 +1389,33 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
// Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4 // Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
// Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4 // Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) { if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
coprocessor = S->tok - TOK_ASM_p0; coprocessor = S->tccpp_tok - TOK_ASM_p0;
next(S); next(S);
} else { } else {
expect(S, "'c<number>'"); expect(S, "'c<number>'");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) { if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
coprocessor_destination_register = S->tok - TOK_ASM_c0; coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;
next(S); next(S);
} else { } else {
expect(S, "'c<number>'"); expect(S, "'c<number>'");
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -1425,14 +1425,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ']') { if (S->tccpp_tok == ']') {
next(S); next(S);
closed_bracket = 1; closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software // exclam = 1; // implicit in hardware; don't do it in software
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op2_minus = 1; op2_minus = 1;
next(S); next(S);
} }
@ -1453,12 +1453,12 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
preincrement = 1; // add offset before transfer preincrement = 1; // add offset before transfer
} }
if (!closed_bracket) { if (!closed_bracket) {
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
preincrement = 1; // add offset before transfer preincrement = 1; // add offset before transfer
if (S->tok == '!') { if (S->tccpp_tok == '!') {
exclam = 1; exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
@ -1528,12 +1528,12 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
return; return;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -1543,7 +1543,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
parse_operand(S, &ops[2]); parse_operand(S, &ops[2]);
if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) { if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
@ -1555,7 +1555,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
ops[2].type = OP_IM8; ops[2].type = OP_IM8;
ops[2].e.v = 0; ops[2].e.v = 0;
} }
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
@ -1593,11 +1593,11 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
break; break;
default: default:
parse_operand(S, &ops[0]); parse_operand(S, &ops[0]);
if (S->tok == '!') { if (S->tccpp_tok == '!') {
op0_exclam = 1; op0_exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); // skip comma next(S); // skip comma
else { else {
expect(S, "','"); expect(S, "','");
@ -1605,16 +1605,16 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
} }
} }
if (S->tok != '{') { if (S->tccpp_tok != '{') {
expect(S, "'{'"); expect(S, "'{'");
return; return;
} }
next(S); // skip '{' next(S); // skip '{'
first_regset_register = asm_parse_vfp_regvar(S->tok, 1); first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);
if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 1)) != -1) { if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
coprocessor = CP_DOUBLE_PRECISION_FLOAT; coprocessor = CP_DOUBLE_PRECISION_FLOAT;
next(S); next(S);
} else if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 0)) != -1) { } else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
coprocessor = CP_SINGLE_PRECISION_FLOAT; coprocessor = CP_SINGLE_PRECISION_FLOAT;
next(S); next(S);
} else { } else {
@ -1622,9 +1622,9 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
return; return;
} }
if (S->tok == '-') { if (S->tccpp_tok == '-') {
next(S); next(S);
if ((last_regset_register = asm_parse_vfp_regvar(S->tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1) if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
next(S); next(S);
else { else {
expect(S, "floating-point register"); expect(S, "floating-point register");
@ -1637,7 +1637,7 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here"); tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
return; return;
} }
if (S->tok != '}') { if (S->tccpp_tok != '}') {
expect(S, "'}'"); expect(S, "'}'");
return; return;
} }
@ -1725,11 +1725,11 @@ static uint32_t vmov_parse_immediate_value(TCCState *S) {
unsigned long integral_value; unsigned long integral_value;
const char *p; const char *p;
if (S->tok != TOK_PPNUM) { if (S->tccpp_tok != TOK_PPNUM) {
expect(S, "immediate value"); expect(S, "immediate value");
return 0; return 0;
} }
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
errno = 0; errno = 0;
integral_value = strtoul(p, (char **)&p, 0); integral_value = strtoul(p, (char **)&p, 0);
@ -1785,10 +1785,10 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
operands[0] = CRd; operands[0] = CRd;
if (S->tok == '#' || S->tok == '$') { if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
next(S); next(S);
} }
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op_minus = 1; op_minus = 1;
next(S); next(S);
} }
@ -1956,7 +1956,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
break; break;
} }
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
expect(S, "','"); expect(S, "','");
@ -2078,7 +2078,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
for (nb_ops = 0; nb_ops < 3; ) { for (nb_ops = 0; nb_ops < 3; ) {
// Note: Necessary because parse_operand can't parse decimal numerals. // Note: Necessary because parse_operand can't parse decimal numerals.
if (nb_ops == 1 && (S->tok == '#' || S->tok == '$' || S->tok == TOK_PPNUM || S->tok == '-')) { if (nb_ops == 1 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) {
asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg); asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg);
return; return;
} }
@ -2100,7 +2100,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
return; return;
} }
++nb_ops; ++nb_ops;
if (S->tok == ',') if (S->tccpp_tok == ',')
next(S); next(S);
else else
break; break;
@ -2248,7 +2248,7 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
switch (ARM_INSTRUCTION_GROUP(token)) { switch (ARM_INSTRUCTION_GROUP(token)) {
case TOK_ASM_vmrseq: case TOK_ASM_vmrseq:
opcode = 0xf; opcode = 0xf;
if (S->tok == TOK_ASM_apsr_nzcv) { if (S->tccpp_tok == TOK_ASM_apsr_nzcv) {
arm_operand.type = OP_REG32; arm_operand.type = OP_REG32;
arm_operand.reg = 15; // not PC arm_operand.reg = 15; // not PC
next(S); // skip apsr_nzcv next(S); // skip apsr_nzcv
@ -2260,11 +2260,11 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
} }
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "','"); expect(S, "','");
else else
next(S); // skip ',' next(S); // skip ','
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tok); vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
next(S); // skip vfp sys reg next(S); // skip vfp sys reg
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) { if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {
tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL)); tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL));
@ -2273,9 +2273,9 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
break; break;
case TOK_ASM_vmsreq: case TOK_ASM_vmsreq:
opcode = 0xe; opcode = 0xe;
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tok); vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
next(S); // skip vfp sys reg next(S); // skip vfp sys reg
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "','"); expect(S, "','");
else else
next(S); // skip ',' next(S); // skip ','
@ -2329,12 +2329,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(destination operand) register"); expect(S, "(destination operand) register");
return; return;
} }
if (S->tok != ',') if (S->tccpp_tok != ',')
expect(S, "at least two arguments"); expect(S, "at least two arguments");
else else
next(S); // skip ',' next(S); // skip ','
if (S->tok != '[') if (S->tccpp_tok != '[')
expect(S, "'['"); expect(S, "'['");
else else
next(S); // skip '[' next(S); // skip '['
@ -2346,14 +2346,14 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
expect(S, "(first source operand) register"); expect(S, "(first source operand) register");
return; return;
} }
if (S->tok == ']') { if (S->tccpp_tok == ']') {
next(S); next(S);
closed_bracket = 1; closed_bracket = 1;
// exclam = 1; // implicit in hardware; don't do it in software // exclam = 1; // implicit in hardware; don't do it in software
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); // skip ',' next(S); // skip ','
if (S->tok == '-') { if (S->tccpp_tok == '-') {
op2_minus = 1; op2_minus = 1;
next(S); next(S);
} }
@ -2365,12 +2365,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
} }
if (!closed_bracket) { if (!closed_bracket) {
if (S->tok != ']') if (S->tccpp_tok != ']')
expect(S, "']'"); expect(S, "']'");
else else
next(S); // skip ']' next(S); // skip ']'
opcode |= 1 << 24; // add offset before transfer opcode |= 1 << 24; // add offset before transfer
if (S->tok == '!') { if (S->tccpp_tok == '!') {
exclam = 1; exclam = 1;
next(S); // skip '!' next(S); // skip '!'
} }
@ -2467,7 +2467,7 @@ static void asm_branch_opcode(TCCState *S, int token)
tcc_error(S, "invalid branch target"); tcc_error(S, "invalid branch target");
return; return;
} }
jmp_disp = encbranchoffset(S, S->ind, e.v + esym->st_value, 1); jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1);
break; break;
default: default:
parse_operand(S, &op); parse_operand(S, &op);
@ -2501,7 +2501,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
{ {
while (token == TOK_LINEFEED) { while (token == TOK_LINEFEED) {
next(S); next(S);
token = S->tok; token = S->tccpp_tok;
} }
if (token == TOK_EOF) if (token == TOK_EOF)
return; return;

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

View file

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

View file

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

178
c67-gen.c
View file

@ -189,19 +189,19 @@ FILE *f = NULL;
void C67_g(TCCState* S, int c) void C67_g(TCCState* S, int c)
{ {
int ind1; int ind1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return; return;
#ifdef ASSEMBLY_LISTING_C67 #ifdef ASSEMBLY_LISTING_C67
fprintf(f, " %08X", c); fprintf(f, " %08X", c);
#endif #endif
ind1 = S->ind + 4; ind1 = S->tccgen_ind + 4;
if (ind1 > (int) cur_text_section->data_allocated) if (ind1 > (int) cur_text_section->data_allocated)
section_realloc(S, cur_text_section, ind1); section_realloc(S, cur_text_section, ind1);
cur_text_section->data[S->ind] = c & 0xff; cur_text_section->data[S->tccgen_ind] = c & 0xff;
cur_text_section->data[S->ind + 1] = (c >> 8) & 0xff; cur_text_section->data[S->tccgen_ind + 1] = (c >> 8) & 0xff;
cur_text_section->data[S->ind + 2] = (c >> 16) & 0xff; cur_text_section->data[S->tccgen_ind + 2] = (c >> 16) & 0xff;
cur_text_section->data[S->ind + 3] = (c >> 24) & 0xff; cur_text_section->data[S->tccgen_ind + 3] = (c >> 24) & 0xff;
S->ind = ind1; S->tccgen_ind = ind1;
} }
@ -220,7 +220,7 @@ void gsym_addr(TCCState *S, int t, int a)
// define a label that will be relocated // 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, R_C60LO16);
greloc(S, cur_text_section, sym, t + 4, R_C60HI16); 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 // 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) 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 C67_NOP(S, 4); // NOP 4
return; return;
} else if (fr & VT_SYM) { } 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->tccgen_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 + 4, R_C60HI16);
C67_MVKL(S, C67_A0, fc); //r=reg to load, constant C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
@ -1681,8 +1681,8 @@ void load(TCCState *S, int r, SValue * sv)
} else { } else {
if (v == VT_CONST) { if (v == VT_CONST) {
if (fr & VT_SYM) { 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->tccgen_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 + 4, R_C60HI16);
} }
C67_MVKL(S, r, fc); //r=reg to load, constant C67_MVKL(S, r, fc); //r=reg to load, constant
C67_MVKH(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 */ /* constant memory reference */
if (v->r & VT_SYM) { 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->tccgen_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 + 4, R_C60HI16);
} }
C67_MVKL(S, C67_A0, fc); //r=reg to load, constant C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
C67_MVKH(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; int r;
Sym *sym; 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 */ /* constant case */
if (S->vtop->r & VT_SYM) { if (S->tccgen_vtop->r & VT_SYM) {
/* relocation case */ /* relocation case */
// get add into A0, then start the jump B3 // 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->tccgen_vtop->sym, S->tccgen_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 + 4, R_C60HI16);
C67_MVKL(S, C67_A0, 0); //r=reg to load, constant C67_MVKL(S, C67_A0, 0); //r=reg to load, constant
C67_MVKH(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 { } else {
// Call, must load return address into B3 during delay slots // 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 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->ind, R_C60LO16); // rem the inst need to be patched 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->ind + 4, R_C60HI16); greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
C67_MVKL(S, C67_B3, 0); //r=reg to load, constant C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
C67_MVKH(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 C67_NOP(S, 3); // put remaining NOPs
@ -1858,9 +1858,9 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
} else { } else {
// Call, must load return address into B3 during delay slots // 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 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->ind, R_C60LO16); // rem the inst need to be patched 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->ind + 4, R_C60HI16); greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
C67_MVKL(S, C67_B3, 0); //r=reg to load, constant C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
C67_MVKH(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 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++) { 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); ALWAYS_ASSERT(FALSE);
} else { } else {
/* simple type (currently always same size) */ /* simple type (currently always same size) */
/* XXX: implicit cast ? */ /* 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"); 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"); 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; size = 8;
} else { } else {
size = 4; size = 4;
@ -1919,7 +1919,7 @@ void gfunc_call(TCCState *S, int nb_args)
} }
args_sizes[i] = size; args_sizes[i] = size;
} }
S->vtop--; S->tccgen_vtop--;
} }
// POP all the params on the stack into registers for the // POP all the params on the stack into registers for the
// immediate call (in reverse order) // 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); C67_POP(S, TREG_C67_A4 + i * 2);
} }
gcall_or_jmp(S, 0); 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 // place all the args passed in regs onto the stack
S->loc = 0; S->tccgen_loc = 0;
for (i = 0; i < NoOfCurFuncArgs; i++) { for (i = 0; i < NoOfCurFuncArgs; i++) {
ParamLocOnStack[i] = S->loc; // remember where the param is ParamLocOnStack[i] = S->tccgen_loc; // remember where the param is
S->loc += -8; S->tccgen_loc += -8;
C67_PUSH(S, TREG_C67_A4 + i * 2); 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_ADDK(S, 0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
C67_PUSH(S, C67_A0); C67_PUSH(S, C67_A0);
@ -2023,7 +2023,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
void gfunc_epilog(TCCState* S) 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_POP(S, C67_B3);
C67_NOP(S, 4); // NOP wait for load C67_NOP(S, 4); // NOP wait for load
C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_B3); // B.S2 B3 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 */ /* generate a jump to a label */
int gjmp(TCCState* S, int t) int gjmp(TCCState* S, int t)
{ {
int ind1 = S->ind; int ind1 = S->tccgen_ind;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return t; return t;
C67_MVKL(S, C67_A0, t); //r=reg to load, constant 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 // 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, S->ind, R_C60LO16); greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16);
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16); 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 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 ind1;
int inv = op & 1; int inv = op & 1;
if (S->nocode_wanted) if (S->tccgen_nocode_wanted)
return t; return t;
/* fast case : can jump directly since flags are set */ /* fast case : can jump directly since flags are set */
// C67 uses B2 sort of as flags register // 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_MVKL(S, C67_A0, t); //r=reg to load, constant
C67_MVKH(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 else
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
C67_compare_reg = C67_B2; C67_compare_reg = C67_B2;
@ -2199,7 +2199,7 @@ void gen_opi(TCCState *S, int op)
else else
ALWAYS_ASSERT(FALSE); ALWAYS_ASSERT(FALSE);
S->vtop--; S->tccgen_vtop--;
if (op >= TOK_ULT && op <= TOK_GT) if (op >= TOK_ULT && op <= TOK_GT)
vset_VT_CMP(S, 0x80); vset_VT_CMP(S, 0x80);
break; break;
@ -2225,33 +2225,33 @@ void gen_opi(TCCState *S, int op)
case '*': case '*':
case TOK_UMULL: case TOK_UMULL:
gv2(S, RC_INT, RC_INT); gv2(S, RC_INT, RC_INT);
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
S->vtop--; S->tccgen_vtop--;
C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr
C67_NOP(S, 8); // NOP 8 for worst case C67_NOP(S, 8); // NOP 8 for worst case
break; break;
case TOK_SHL: case TOK_SHL:
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
S->vtop--; S->tccgen_vtop--;
C67_SHL(S, fr, r); // arithmetic/logical shift C67_SHL(S, fr, r); // arithmetic/logical shift
break; break;
case TOK_SHR: case TOK_SHR:
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
S->vtop--; S->tccgen_vtop--;
C67_SHRU(S, fr, r); // logical shift C67_SHRU(S, fr, r); // logical shift
break; break;
case TOK_SAR: case TOK_SAR:
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
S->vtop--; S->tccgen_vtop--;
C67_SHR(S, fr, r); // arithmetic shift C67_SHR(S, fr, r); // arithmetic shift
break; break;
@ -2264,8 +2264,8 @@ void gen_opi(TCCState *S, int op)
vrott(S, 3); vrott(S, 3);
gfunc_call(S, 2); gfunc_call(S, 2);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = REG_IRET; S->tccgen_vtop->r = REG_IRET;
S->vtop->r2 = VT_CONST; S->tccgen_vtop->r2 = VT_CONST;
break; break;
case TOK_UDIV: case TOK_UDIV:
case TOK_PDIV: case TOK_PDIV:
@ -2296,10 +2296,10 @@ void gen_opf(TCCState *S, int op)
else else
gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
ft = S->vtop->type.t; ft = S->tccgen_vtop->type.t;
fc = S->vtop->c.i; fc = S->tccgen_vtop->c.i;
r = S->vtop->r; r = S->tccgen_vtop->r;
fr = S->vtop[-1].r; fr = S->tccgen_vtop[-1].r;
if ((ft & VT_BTYPE) == VT_LDOUBLE) if ((ft & VT_BTYPE) == VT_LDOUBLE)
@ -2307,8 +2307,8 @@ void gen_opf(TCCState *S, int op)
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
r = S->vtop[-1].r; r = S->tccgen_vtop[-1].r;
fr = S->vtop[0].r; fr = S->tccgen_vtop[0].r;
C67_compare_reg = C67_B2; 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_ADDSP(S, r, fr); // ADD fr,r,fr
C67_NOP(S, 3); C67_NOP(S, 3);
} }
S->vtop--; S->tccgen_vtop--;
} else if (op == '-') { } else if (op == '-') {
if ((ft & VT_BTYPE) == VT_DOUBLE) { if ((ft & VT_BTYPE) == VT_DOUBLE) {
C67_SUBDP(S, r, fr); // SUB fr,r,fr 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_SUBSP(S, r, fr); // SUB fr,r,fr
C67_NOP(S, 3); C67_NOP(S, 3);
} }
S->vtop--; S->tccgen_vtop--;
} else if (op == '*') { } else if (op == '*') {
if ((ft & VT_BTYPE) == VT_DOUBLE) { if ((ft & VT_BTYPE) == VT_DOUBLE) {
C67_MPYDP(S, r, fr); // MPY fr,r,fr 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_MPYSP(S, r, fr); // MPY fr,r,fr
C67_NOP(S, 3); C67_NOP(S, 3);
} }
S->vtop--; S->tccgen_vtop--;
} else if (op == '/') { } else if (op == '/') {
if ((ft & VT_BTYPE) == VT_DOUBLE) { if ((ft & VT_BTYPE) == VT_DOUBLE) {
// must call intrinsic DP floating point divide // must call intrinsic DP floating point divide
@ -2395,8 +2395,8 @@ void gen_opf(TCCState *S, int op)
vrott(S, 3); vrott(S, 3);
gfunc_call(S, 2); gfunc_call(S, 2);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = REG_FRET; S->tccgen_vtop->r = REG_FRET;
S->vtop->r2 = REG_IRE2; S->tccgen_vtop->r2 = REG_IRE2;
} else { } else {
// must call intrinsic SP floating point divide // must call intrinsic SP floating point divide
@ -2406,8 +2406,8 @@ void gen_opf(TCCState *S, int op)
vrott(S, 3); vrott(S, 3);
gfunc_call(S, 2); gfunc_call(S, 2);
vpushi(S, 0); vpushi(S, 0);
S->vtop->r = REG_FRET; S->tccgen_vtop->r = REG_FRET;
S->vtop->r2 = VT_CONST; S->tccgen_vtop->r2 = VT_CONST;
} }
} else } else
ALWAYS_ASSERT(FALSE); ALWAYS_ASSERT(FALSE);
@ -2424,7 +2424,7 @@ void gen_cvt_itof(TCCState *S, int t)
int r; int r;
gv(S, RC_INT); gv(S, RC_INT);
r = S->vtop->r; r = S->tccgen_vtop->r;
if ((t & VT_BTYPE) == VT_DOUBLE) { if ((t & VT_BTYPE) == VT_DOUBLE) {
if (t & VT_UNSIGNED) if (t & VT_UNSIGNED)
@ -2433,14 +2433,14 @@ void gen_cvt_itof(TCCState *S, int t)
C67_INTDP(S, r, r); C67_INTDP(S, r, r);
C67_NOP(S, 4); C67_NOP(S, 4);
S->vtop->type.t = VT_DOUBLE; S->tccgen_vtop->type.t = VT_DOUBLE;
} else { } else {
if (t & VT_UNSIGNED) if (t & VT_UNSIGNED)
C67_INTSPU(S, r, r); C67_INTSPU(S, r, r);
else else
C67_INTSP(S, r, r); C67_INTSP(S, r, r);
C67_NOP(S, 3); 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; int r;
gv(S, RC_FLOAT); gv(S, RC_FLOAT);
r = S->vtop->r; r = S->tccgen_vtop->r;
if (t != VT_INT) if (t != VT_INT)
tcc_error(S, "long long not supported"); tcc_error(S, "long long not supported");
else { 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_DPTRUNC(S, r, r);
C67_NOP(S, 3); C67_NOP(S, 3);
} else { } else {
@ -2465,7 +2465,7 @@ void gen_cvt_ftoi(TCCState *S, int t)
C67_NOP(S, 3); 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; 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) { (t & VT_BTYPE) == VT_FLOAT) {
// convert double to float // convert double to float
gv(S, RC_FLOAT); // get it in a register pair 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_DPSP(S, r, r); // convert it to SP same register
C67_NOP(S, 3); C67_NOP(S, 3);
S->vtop->type.t = VT_FLOAT; S->tccgen_vtop->type.t = VT_FLOAT;
S->vtop->r2 = VT_CONST; // set this as unused S->tccgen_vtop->r2 = VT_CONST; // set this as unused
} else if ((S->vtop->type.t & VT_BTYPE) == VT_FLOAT && } else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT &&
(t & VT_BTYPE) == VT_DOUBLE) { (t & VT_BTYPE) == VT_DOUBLE) {
// convert float to double // convert float to double
gv(S, RC_FLOAT); // get it in a register 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 if (r == TREG_EAX) { // make sure the paired reg is avail
r2 = get_reg(S, RC_ECX); 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_SPDP(S, r, r); // convert it to DP same register
C67_NOP(S, 1); C67_NOP(S, 1);
S->vtop->type.t = VT_DOUBLE; S->tccgen_vtop->type.t = VT_DOUBLE;
S->vtop->r2 = r2; // set this as unused S->tccgen_vtop->r2 = r2; // set this as unused
} else { } else {
ALWAYS_ASSERT(FALSE); ALWAYS_ASSERT(FALSE);
} }
@ -2519,7 +2519,7 @@ void gen_cvt_ftof(TCCState *S, int t)
void ggoto(TCCState* S) void ggoto(TCCState* S)
{ {
gcall_or_jmp(S, 1); gcall_or_jmp(S, 1);
S->vtop--; S->tccgen_vtop--;
} }
/* Save the stack pointer onto the stack and return the location of its address */ /* 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) static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
{ {
int reg = -1; int reg = -1;
if (t >= TOK_IDENT && t < S->tok_ident) { if (t >= TOK_IDENT && t < S->tccpp_tok_ident) {
const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str; const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str;
char c; char c;
*type = OP_REG64; *type = OP_REG64;
@ -322,20 +322,20 @@ static int asm_parse_reg(TCCState *S, unsigned int *type)
{ {
int reg = 0; int reg = 0;
*type = 0; *type = 0;
if (S->tok != '%') if (S->tccpp_tok != '%')
goto error_32; goto error_32;
next(S); next(S);
if (S->tok >= TOK_ASM_eax && S->tok <= TOK_ASM_edi) { if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {
reg = S->tok - TOK_ASM_eax; reg = S->tccpp_tok - TOK_ASM_eax;
*type = OP_REG32; *type = OP_REG32;
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
} else if (S->tok >= TOK_ASM_rax && S->tok <= TOK_ASM_rdi) { } else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {
reg = S->tok - TOK_ASM_rax; reg = S->tccpp_tok - TOK_ASM_rax;
*type = OP_REG64; *type = OP_REG64;
} else if (S->tok == TOK_ASM_rip) { } else if (S->tccpp_tok == TOK_ASM_rip) {
reg = -2; /* Probably should use different escape code. */ reg = -2; /* Probably should use different escape code. */
*type = OP_REG64; *type = OP_REG64;
} else if ((reg = asm_parse_numeric_reg(S, S->tok, type)) >= 0 } else if ((reg = asm_parse_numeric_reg(S, S->tccpp_tok, type)) >= 0
&& (*type == OP_REG32 || *type == OP_REG64)) { && (*type == OP_REG32 || *type == OP_REG64)) {
; ;
#endif #endif
@ -354,15 +354,15 @@ static void parse_operand(TCCState *S, Operand *op)
const char *p; const char *p;
indir = 0; indir = 0;
if (S->tok == '*') { if (S->tccpp_tok == '*') {
next(S); next(S);
indir = OP_INDIR; indir = OP_INDIR;
} }
if (S->tok == '%') { if (S->tccpp_tok == '%') {
next(S); next(S);
if (S->tok >= TOK_ASM_al && S->tok <= TOK_ASM_db7) { if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {
reg = S->tok - TOK_ASM_al; reg = S->tccpp_tok - TOK_ASM_al;
op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */ op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
op->reg = reg & 7; op->reg = reg & 7;
if ((op->type & OP_REG) && op->reg == TREG_XAX) if ((op->type & OP_REG) && op->reg == TREG_XAX)
@ -371,21 +371,21 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_CL; op->type |= OP_CL;
else if (op->type == OP_REG16 && op->reg == TREG_XDX) else if (op->type == OP_REG16 && op->reg == TREG_XDX)
op->type |= OP_DX; op->type |= OP_DX;
} else if (S->tok >= TOK_ASM_dr0 && S->tok <= TOK_ASM_dr7) { } else if (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) {
op->type = OP_DB; op->type = OP_DB;
op->reg = S->tok - TOK_ASM_dr0; op->reg = S->tccpp_tok - TOK_ASM_dr0;
} else if (S->tok >= TOK_ASM_es && S->tok <= TOK_ASM_gs) { } else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {
op->type = OP_SEG; op->type = OP_SEG;
op->reg = S->tok - TOK_ASM_es; op->reg = S->tccpp_tok - TOK_ASM_es;
} else if (S->tok == TOK_ASM_st) { } else if (S->tccpp_tok == TOK_ASM_st) {
op->type = OP_ST; op->type = OP_ST;
op->reg = 0; op->reg = 0;
next(S); next(S);
if (S->tok == '(') { if (S->tccpp_tok == '(') {
next(S); next(S);
if (S->tok != TOK_PPNUM) if (S->tccpp_tok != TOK_PPNUM)
goto reg_error; goto reg_error;
p = S->tokc.str.data; p = S->tccpp_tokc.str.data;
reg = p[0] - '0'; reg = p[0] - '0';
if ((unsigned)reg >= 8 || p[1] != '\0') if ((unsigned)reg >= 8 || p[1] != '\0')
goto reg_error; goto reg_error;
@ -397,19 +397,19 @@ static void parse_operand(TCCState *S, Operand *op)
op->type |= OP_ST0; op->type |= OP_ST0;
goto no_skip; goto no_skip;
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
} else if (S->tok >= TOK_ASM_spl && S->tok <= TOK_ASM_dil) { } else if (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) {
op->type = OP_REG8 | OP_REG8_LOW; op->type = OP_REG8 | OP_REG8_LOW;
op->reg = 4 + S->tok - TOK_ASM_spl; op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;
} else if ((op->reg = asm_parse_numeric_reg(S, S->tok, &op->type)) >= 0) { } else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {
; ;
#endif #endif
} else { } else {
reg_error: reg_error:
tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tok, &S->tokc)); tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
} }
next(S); next(S);
no_skip: ; no_skip: ;
} else if (S->tok == '$') { } else if (S->tccpp_tok == '$') {
/* constant value */ /* constant value */
next(S); next(S);
asm_expr(S, &e); asm_expr(S, &e);
@ -433,19 +433,19 @@ static void parse_operand(TCCState *S, Operand *op)
op->reg = -1; op->reg = -1;
op->reg2 = -1; op->reg2 = -1;
op->shift = 0; op->shift = 0;
if (S->tok != '(') { if (S->tccpp_tok != '(') {
asm_expr(S, &e); asm_expr(S, &e);
op->e = e; op->e = e;
} else { } else {
next(S); next(S);
if (S->tok == '%') { if (S->tccpp_tok == '%') {
unget_tok(S, '('); unget_tok(S, '(');
op->e.v = 0; op->e.v = 0;
op->e.sym = NULL; op->e.sym = NULL;
} else { } else {
/* bracketed offset expression */ /* bracketed offset expression */
asm_expr(S, &e); asm_expr(S, &e);
if (S->tok != ')') if (S->tccpp_tok != ')')
expect(S, ")"); expect(S, ")");
next(S); next(S);
op->e.v = e.v; op->e.v = e.v;
@ -453,18 +453,18 @@ static void parse_operand(TCCState *S, Operand *op)
} }
op->e.pcrel = 0; op->e.pcrel = 0;
} }
if (S->tok == '(') { if (S->tccpp_tok == '(') {
unsigned int type = 0; unsigned int type = 0;
next(S); next(S);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
op->reg = asm_parse_reg(S, &type); op->reg = asm_parse_reg(S, &type);
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
if (S->tok != ',') { if (S->tccpp_tok != ',') {
op->reg2 = asm_parse_reg(S, &type); op->reg2 = asm_parse_reg(S, &type);
} }
if (S->tok == ',') { if (S->tccpp_tok == ',') {
next(S); next(S);
op->shift = get_reg_shift(S); op->shift = get_reg_shift(S);
} }
@ -507,7 +507,7 @@ static void gen_disp32(TCCState *S, ExprValue *pe)
that the TCC compiler behaves differently here because that the TCC compiler behaves differently here because
it always outputs a relocation to ease (future) code it always outputs a relocation to ease (future) code
elimination in the linker */ elimination in the linker */
gen_le32(S, pe->v + esym->st_value - S->ind - 4); gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4);
} else { } else {
if (sym && sym->type.t == VT_VOID) { if (sym && sym->type.t == VT_VOID) {
sym->type.t = VT_FUNC; sym->type.t = VT_FUNC;
@ -538,7 +538,7 @@ static inline int asm_modrm(TCCState *S, int reg, Operand *op)
ExprValue *pe = &op->e; ExprValue *pe = &op->e;
g(S, 0x05 + (reg << 3)); g(S, 0x05 + (reg << 3));
gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v); gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
return S->ind; return S->tccgen_ind;
#endif #endif
} else { } else {
sib_reg1 = op->reg; sib_reg1 = op->reg;
@ -705,13 +705,13 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
seg_prefix = 0; seg_prefix = 0;
alltypes = 0; alltypes = 0;
for(;;) { for(;;) {
if (S->tok == ';' || S->tok == TOK_LINEFEED) if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)
break; break;
if (nb_ops >= MAX_OPERANDS) { if (nb_ops >= MAX_OPERANDS) {
tcc_error(S, "incorrect number of operands"); tcc_error(S, "incorrect number of operands");
} }
parse_operand(S, pop); parse_operand(S, pop);
if (S->tok == ':') { if (S->tccpp_tok == ':') {
if (pop->type != OP_SEG || seg_prefix) if (pop->type != OP_SEG || seg_prefix)
tcc_error(S, "incorrect prefix"); tcc_error(S, "incorrect prefix");
seg_prefix = segment_prefixes[pop->reg]; seg_prefix = segment_prefixes[pop->reg];
@ -723,7 +723,7 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
} }
pop++; pop++;
nb_ops++; nb_ops++;
if (S->tok != ',') if (S->tccpp_tok != ',')
break; break;
next(S); next(S);
} }
@ -1038,7 +1038,7 @@ again:
esym = elfsym(S, ops[0].e.sym); esym = elfsym(S, ops[0].e.sym);
if (!esym || esym->st_shndx != cur_text_section->sh_num) if (!esym || esym->st_shndx != cur_text_section->sh_num)
goto no_short_jump; goto no_short_jump;
jmp_disp = ops[0].e.v + esym->st_value - S->ind - 2 - (v >= 0xff); jmp_disp = ops[0].e.v + esym->st_value - S->tccgen_ind - 2 - (v >= 0xff);
if (jmp_disp == (int8_t)jmp_disp) { if (jmp_disp == (int8_t)jmp_disp) {
/* OK to generate jump */ /* OK to generate jump */
ops[0].e.sym = 0; ops[0].e.sym = 0;
@ -1136,7 +1136,7 @@ again:
/* after immediate operands, adjust pc-relative address */ /* after immediate operands, adjust pc-relative address */
if (pc) if (pc)
add32le(cur_text_section->data + pc - 4, pc - S->ind); add32le(cur_text_section->data + pc - 4, pc - S->tccgen_ind);
} }
/* return the constraint priority (we allocate first the lowest /* return the constraint priority (we allocate first the lowest

View file

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

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", cstr_printf(S, &cs, "In file included from %s:%d:\n",
(*pf)->filename, (*pf)->line_num); (*pf)->filename, (*pf)->line_num);
cstr_printf(S, &cs, "%s:%d: ", cstr_printf(S, &cs, "%s:%d: ",
f->filename, (*pf)->line_num - !!(S->tok_flags & TOK_FLAG_BOL)); f->filename, (*pf)->line_num - !!(S->tccpp_tok_flags & TOK_FLAG_BOL));
} else if (S->current_filename) { } else if (S->current_filename) {
cstr_printf(S, &cs, "%s: ", S->current_filename); cstr_printf(S, &cs, "%s: ", S->current_filename);
} }
@ -744,7 +744,7 @@ ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen)
bf->fd = -1; bf->fd = -1;
bf->prev = S->tccpp_file; bf->prev = S->tccpp_file;
S->tccpp_file = bf; S->tccpp_file = bf;
S->tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF; S->tccpp_tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
} }
ST_FUNC void tcc_close(TCCState* S) ST_FUNC void tcc_close(TCCState* S)

View file

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

View file

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

35
tcc.h
View file

@ -1074,21 +1074,21 @@ struct TCCState {
/* ------------ tccpp.c ------------ */ /* ------------ tccpp.c ------------ */
struct BufferedFile *tccpp_file; struct BufferedFile *tccpp_file;
int tccpp_ch, tok; int tccpp_ch, tccpp_tok;
CValue tokc; CValue tccpp_tokc;
const int *tccpp_macro_ptr; const int *tccpp_macro_ptr;
int tccpp_parse_flags; int tccpp_parse_flags;
int tok_flags; int tccpp_tok_flags;
CString tokcstr; /* current parsed string, if any */ CString tccpp_tokcstr; /* current parsed string, if any */
CString tccpp_cstr_buf; CString tccpp_cstr_buf;
CString tccpp_macro_equal_buf; CString tccpp_macro_equal_buf;
TokenString tokstr_buf; TokenString tccpp_tokstr_buf;
TokenString *tccpp_macro_stack; TokenString *tccpp_macro_stack;
/* display benchmark infos */ /* display benchmark infos */
int tccpp_total_lines; int tccpp_total_lines;
int tccpp_total_bytes; int tccpp_total_bytes;
int tok_ident; int tccpp_tok_ident;
TokenSym **tccpp_table_ident; TokenSym **tccpp_table_ident;
int *tccpp_macro_ptr_allocated; int *tccpp_macro_ptr_allocated;
@ -1096,7 +1096,7 @@ struct TCCState {
int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1]; int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1];
int tccpp_unget_buffer_enabled; int tccpp_unget_buffer_enabled;
TokenSym *tccpp_hash_ident[TOK_HASH_SIZE]; TokenSym *tccpp_hash_ident[TOK_HASH_SIZE];
char token_buf[STRING_MAX_SIZE + 1]; char tccpp_token_buf[STRING_MAX_SIZE + 1];
/* true if isid(c) || isnum(c) */ /* true if isid(c) || isnum(c) */
unsigned char tccpp_isidnum_table[256-CH_EOF]; unsigned char tccpp_isidnum_table[256-CH_EOF];
@ -1105,8 +1105,8 @@ struct TCCState {
int tccpp_pp_expr; int tccpp_pp_expr;
int tccpp_pp_counter; int tccpp_pp_counter;
TinyAlloc *toksym_alloc; TinyAlloc *tccpp_toksym_alloc;
TinyAlloc *tokstr_alloc; TinyAlloc *tccpp_tokstr_alloc;
/*----------- tccasm.c --------*/ /*----------- tccasm.c --------*/
Section *tccasm_last_text_section; /* to handle .previous asm directive */ Section *tccasm_last_text_section; /* to handle .previous asm directive */
@ -1114,18 +1114,18 @@ struct TCCState {
/* ------------ tccgen.c ------------ */ /* ------------ tccgen.c ------------ */
Sym *tccgen_global_stack; Sym *tccgen_global_stack;
Sym *local_stack; Sym *tccgen_local_stack;
Sym *local_label_stack; Sym *tccgen_local_label_stack;
Sym *tccgen_global_label_stack; Sym *tccgen_global_label_stack;
Sym *tccgen_define_stack; Sym *tccgen_define_stack;
CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, char_pointer_type; CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, tccgen_char_pointer_type;
SValue *vtop; SValue *tccgen_vtop;
SValue tccgen__vstack[1 + VSTACK_SIZE]; SValue tccgen__vstack[1 + VSTACK_SIZE];
int tccgen_rsym, tccgen_anon_sym, ind, loc; int tccgen_rsym, tccgen_anon_sym, tccgen_ind, tccgen_loc;
char tccgen_debug_modes; char tccgen_debug_modes;
int tccgen_const_wanted; /* true if constant wanted */ int tccgen_const_wanted; /* true if constant wanted */
int nocode_wanted; /* true if no code generation wanted for an expression */ int tccgen_nocode_wanted; /* true if no code generation wanted for an expression */
int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
CType tccgen_func_vt; /* current function return type (used by return instruction) */ CType tccgen_func_vt; /* current function return type (used by return instruction) */
int tccgen_func_var; /* true if current function is variadic */ int tccgen_func_var; /* true if current function is variadic */
@ -1136,7 +1136,7 @@ struct TCCState {
void **tccgen_sym_pools; void **tccgen_sym_pools;
int tccgen_nb_sym_pools; int tccgen_nb_sym_pools;
Sym *tccgen_all_cleanups, *tccgen_pending_gotos; Sym *tccgen_all_cleanups, *tccgen_pending_gotos;
int local_scope; int tccgen_local_scope;
int tccgen_in_sizeof; int tccgen_in_sizeof;
int tccgen_in_generic; int tccgen_in_generic;
int tccgen_section_sym; int tccgen_section_sym;
@ -1155,7 +1155,7 @@ struct TCCState {
int tccgen_debug_next_type; int tccgen_debug_next_type;
debug_hash_t *tccgen_debug_hash; debug_hash_t *tccgen_debug_hash;
int tccgen_n_debug_hash; int tccgen_n_debug_hash;
debug_info_t *debug_info, *debug_info_root; debug_info_t *tccgen_debug_info, *tccgen_debug_info_root;
unsigned char tccgen_prec[256]; unsigned char tccgen_prec[256];
@ -1629,6 +1629,7 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty);
#endif #endif
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
ST_FUNC void gbound_args(TCCState* S, int nb_args); ST_FUNC void gbound_args(TCCState* S, int nb_args);
ST_DATA int func_bound_add_epilog;
#endif #endif
/* ------------ tccelf.c ------------ */ /* ------------ tccelf.c ------------ */

228
tccasm.c
View file

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

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 #ifdef TCC_IS_NATIVE
/* Looks for the active developer SDK set by xcode-select (or the default /* Looks for the active developer SDK set by xcode-select (or the default
one set during installation.) */ one set during installation.) */
ST_FUNC void tcc_add_macos_sdkpath(TCCState *S) ST_FUNC void tcc_add_macos_sdkpath(TCCState* s)
{ {
char *sdkroot = NULL, *pos = NULL; char *sdkroot = NULL, *pos = NULL;
void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY); void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY);

View file

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

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