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:
parent
d33f582e25
commit
2ce2dbcb09
18 changed files with 2852 additions and 2851 deletions
192
arm-asm.c
192
arm-asm.c
|
@ -100,10 +100,10 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
|
||||
op->type = 0;
|
||||
|
||||
if (S->tok == '{') { // regset literal
|
||||
if (S->tccpp_tok == '{') { // regset literal
|
||||
next(S); // skip '{'
|
||||
while (S->tok != '}' && S->tok != TOK_EOF) {
|
||||
reg = asm_parse_regvar(S, S->tok);
|
||||
while (S->tccpp_tok != '}' && S->tccpp_tok != TOK_EOF) {
|
||||
reg = asm_parse_regvar(S, S->tccpp_tok);
|
||||
if (reg == -1) {
|
||||
expect(S, "register");
|
||||
return;
|
||||
|
@ -113,11 +113,11 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
if ((1 << reg) < regset)
|
||||
tcc_warning(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
|
||||
regset |= 1 << reg;
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
break;
|
||||
next(S); // skip ','
|
||||
}
|
||||
if (S->tok != '}')
|
||||
if (S->tccpp_tok != '}')
|
||||
expect(S, "'}'");
|
||||
next(S); // skip '}'
|
||||
if (regset == 0) {
|
||||
|
@ -128,22 +128,22 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
op->regset = regset;
|
||||
}
|
||||
return;
|
||||
} else if ((reg = asm_parse_regvar(S, S->tok)) != -1) {
|
||||
} else if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
|
||||
next(S); // skip register name
|
||||
op->type = OP_REG32;
|
||||
op->reg = (uint8_t) reg;
|
||||
return;
|
||||
} else if ((reg = asm_parse_vfp_regvar(S->tok, 0)) != -1) {
|
||||
} else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
|
||||
next(S); // skip register name
|
||||
op->type = OP_VREG32;
|
||||
op->reg = (uint8_t) reg;
|
||||
return;
|
||||
} else if ((reg = asm_parse_vfp_regvar(S->tok, 1)) != -1) {
|
||||
} else if ((reg = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
|
||||
next(S); // skip register name
|
||||
op->type = OP_VREG64;
|
||||
op->reg = (uint8_t) reg;
|
||||
return;
|
||||
} else if (S->tok == '#' || S->tok == '$') {
|
||||
} else if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
|
||||
/* constant value */
|
||||
next(S); // skip '#' or '$'
|
||||
}
|
||||
|
@ -163,13 +163,13 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
ST_FUNC void g(TCCState* S, int c)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 1;
|
||||
ind1 = S->tccgen_ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind] = c;
|
||||
S->ind = ind1;
|
||||
cur_text_section->data[S->tccgen_ind] = c;
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_le16 (TCCState* S, int i)
|
||||
|
@ -181,15 +181,15 @@ ST_FUNC void gen_le16 (TCCState *S, int i)
|
|||
ST_FUNC void gen_le32 (TCCState* S, int i)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 4;
|
||||
ind1 = S->tccgen_ind + 4;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind++] = i & 0xFF;
|
||||
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF;
|
||||
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF;
|
||||
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
|
||||
|
@ -276,7 +276,7 @@ static void asm_binary_opcode(TCCState *S, int token)
|
|||
uint32_t encoded_rotation = 0;
|
||||
uint64_t amount;
|
||||
parse_operand(S, &ops[0]);
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -328,9 +328,9 @@ static void asm_binary_opcode(TCCState *S, int token)
|
|||
if (ops[1].reg == 13)
|
||||
tcc_warning(S, "Using 'sp' as operand with '%s' is deprecated by ARM", get_tok_str(S, token, NULL));
|
||||
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S); // skip ','
|
||||
if (S->tok == TOK_ASM_ror) {
|
||||
if (S->tccpp_tok == TOK_ASM_ror) {
|
||||
next(S); // skip 'ror'
|
||||
parse_operand(S, &rotation);
|
||||
if (rotation.type != OP_IM8) {
|
||||
|
@ -387,15 +387,15 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
|
|||
uint8_t high_nibble;
|
||||
uint8_t mrc = 0;
|
||||
|
||||
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) {
|
||||
coprocessor = S->tok - TOK_ASM_p0;
|
||||
if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
|
||||
coprocessor = S->tccpp_tok - TOK_ASM_p0;
|
||||
next(S);
|
||||
} else {
|
||||
expect(S, "'p<number>'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -407,21 +407,21 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
|
|||
}
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
if (i == 0 && token != TOK_ASM_cdp2 && (ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mrceq || ARM_INSTRUCTION_GROUP(token) == TOK_ASM_mcreq)) {
|
||||
if (S->tok >= TOK_ASM_r0 && S->tok <= TOK_ASM_r15) {
|
||||
registers[i] = S->tok - TOK_ASM_r0;
|
||||
if (S->tccpp_tok >= TOK_ASM_r0 && S->tccpp_tok <= TOK_ASM_r15) {
|
||||
registers[i] = S->tccpp_tok - TOK_ASM_r0;
|
||||
next(S);
|
||||
} else {
|
||||
expect(S, "'r<number>'");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) {
|
||||
registers[i] = S->tok - TOK_ASM_c0;
|
||||
if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
|
||||
registers[i] = S->tccpp_tok - TOK_ASM_c0;
|
||||
next(S);
|
||||
} else {
|
||||
expect(S, "'c<number>'");
|
||||
|
@ -429,7 +429,7 @@ static void asm_coprocessor_opcode(TCCState *S, int token) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
parse_operand(S, &opcode2);
|
||||
} else {
|
||||
|
@ -493,11 +493,11 @@ static void asm_block_data_transfer_opcode(TCCState *S, int token)
|
|||
Operand ops[2];
|
||||
int nb_ops = 1;
|
||||
parse_operand(S, &ops[0]);
|
||||
if (S->tok == '!') {
|
||||
if (S->tccpp_tok == '!') {
|
||||
op0_exclam = 1;
|
||||
next(S); // skip '!'
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S); // skip comma
|
||||
parse_operand(S, &ops[1]);
|
||||
++nb_ops;
|
||||
|
@ -604,13 +604,13 @@ static uint32_t asm_parse_optional_shift(TCCState *S, int* nb_shift, Operand* sh
|
|||
{
|
||||
uint32_t opcode = 0;
|
||||
*nb_shift = 0;
|
||||
switch (S->tok) {
|
||||
switch (S->tccpp_tok) {
|
||||
case TOK_ASM_asl:
|
||||
case TOK_ASM_lsl:
|
||||
case TOK_ASM_asr:
|
||||
case TOK_ASM_lsr:
|
||||
case TOK_ASM_ror:
|
||||
switch (S->tok) {
|
||||
switch (S->tccpp_tok) {
|
||||
case TOK_ASM_asl:
|
||||
/* fallthrough */
|
||||
case TOK_ASM_lsl:
|
||||
|
@ -677,15 +677,15 @@ static void asm_data_processing_opcode(TCCState *S, int token)
|
|||
uint32_t opcode_nos = opcode_idx >> 1; // without "s"; "OpCode" in ARM docs
|
||||
|
||||
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ) {
|
||||
if (S->tok == TOK_ASM_asl || S->tok == TOK_ASM_lsl || S->tok == TOK_ASM_lsr || S->tok == TOK_ASM_asr || S->tok == TOK_ASM_ror || S->tok == TOK_ASM_rrx)
|
||||
if (S->tccpp_tok == TOK_ASM_asl || S->tccpp_tok == TOK_ASM_lsl || S->tccpp_tok == TOK_ASM_lsr || S->tccpp_tok == TOK_ASM_asr || S->tccpp_tok == TOK_ASM_ror || S->tccpp_tok == TOK_ASM_rrx)
|
||||
break;
|
||||
parse_operand(S, &ops[nb_ops]);
|
||||
++nb_ops;
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
break;
|
||||
next(S); // skip ','
|
||||
}
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
operands |= asm_parse_optional_shift(S, &nb_shift, &shift);
|
||||
if (nb_ops < 2)
|
||||
|
@ -852,7 +852,7 @@ static void asm_shift_opcode(TCCState *S, int token)
|
|||
|
||||
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
|
||||
parse_operand(S, &ops[nb_ops]);
|
||||
if (S->tok != ',') {
|
||||
if (S->tccpp_tok != ',') {
|
||||
++nb_ops;
|
||||
break;
|
||||
}
|
||||
|
@ -961,7 +961,7 @@ static void asm_multiplication_opcode(TCCState *S, int token)
|
|||
|
||||
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
|
||||
parse_operand(S, &ops[nb_ops]);
|
||||
if (S->tok != ',') {
|
||||
if (S->tccpp_tok != ',') {
|
||||
++nb_ops;
|
||||
break;
|
||||
}
|
||||
|
@ -1043,7 +1043,7 @@ static void asm_long_multiplication_opcode(TCCState *S, int token)
|
|||
|
||||
for (nb_ops = 0; nb_ops < sizeof(ops)/sizeof(ops[0]); ++nb_ops) {
|
||||
parse_operand(S, &ops[nb_ops]);
|
||||
if (S->tok != ',') {
|
||||
if (S->tccpp_tok != ',') {
|
||||
++nb_ops;
|
||||
break;
|
||||
}
|
||||
|
@ -1133,7 +1133,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "(destination operand) register");
|
||||
return;
|
||||
}
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
expect(S, "at least two arguments");
|
||||
else
|
||||
next(S); // skip ','
|
||||
|
@ -1146,14 +1146,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "register");
|
||||
return;
|
||||
}
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
expect(S, "at least three arguments");
|
||||
else
|
||||
next(S); // skip ','
|
||||
break;
|
||||
}
|
||||
|
||||
if (S->tok != '[')
|
||||
if (S->tccpp_tok != '[')
|
||||
expect(S, "'['");
|
||||
else
|
||||
next(S); // skip '['
|
||||
|
@ -1165,14 +1165,14 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "(first source operand) register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ']') {
|
||||
if (S->tccpp_tok == ']') {
|
||||
next(S);
|
||||
closed_bracket = 1;
|
||||
// exclam = 1; // implicit in hardware; don't do it in software
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S); // skip ','
|
||||
if (S->tok == '-') {
|
||||
if (S->tccpp_tok == '-') {
|
||||
op2_minus = 1;
|
||||
next(S);
|
||||
}
|
||||
|
@ -1182,7 +1182,7 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
|
|||
tcc_error(S, "Using 'pc' for register offset in '%s' is not implemented by ARM", get_tok_str(S, token, NULL));
|
||||
return;
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
opcode |= asm_parse_optional_shift(S, &nb_shift, &shift);
|
||||
if (opcode == 0)
|
||||
|
@ -1196,12 +1196,12 @@ static void asm_single_data_transfer_opcode(TCCState *S, int token)
|
|||
opcode |= 1 << 24; // add offset before transfer
|
||||
}
|
||||
if (!closed_bracket) {
|
||||
if (S->tok != ']')
|
||||
if (S->tccpp_tok != ']')
|
||||
expect(S, "']'");
|
||||
else
|
||||
next(S); // skip ']'
|
||||
opcode |= 1 << 24; // add offset before transfer
|
||||
if (S->tok == '!') {
|
||||
if (S->tccpp_tok == '!') {
|
||||
exclam = 1;
|
||||
next(S); // skip '!'
|
||||
}
|
||||
|
@ -1389,33 +1389,33 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
|
|||
// Note: ldc p2, c0, [r4, #4]! ; pre-indexed: r0 = *(int*)(r4+4); r4 = r4+4
|
||||
// Note: ldc p3, c0, [r4], #4 ; post-indexed: r0 = *(int*)(r4+0); r4 = r4+4
|
||||
|
||||
if (S->tok >= TOK_ASM_p0 && S->tok <= TOK_ASM_p15) {
|
||||
coprocessor = S->tok - TOK_ASM_p0;
|
||||
if (S->tccpp_tok >= TOK_ASM_p0 && S->tccpp_tok <= TOK_ASM_p15) {
|
||||
coprocessor = S->tccpp_tok - TOK_ASM_p0;
|
||||
next(S);
|
||||
} else {
|
||||
expect(S, "'c<number>'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
||||
if (S->tok >= TOK_ASM_c0 && S->tok <= TOK_ASM_c15) {
|
||||
coprocessor_destination_register = S->tok - TOK_ASM_c0;
|
||||
if (S->tccpp_tok >= TOK_ASM_c0 && S->tccpp_tok <= TOK_ASM_c15) {
|
||||
coprocessor_destination_register = S->tccpp_tok - TOK_ASM_c0;
|
||||
next(S);
|
||||
} else {
|
||||
expect(S, "'c<number>'");
|
||||
return;
|
||||
}
|
||||
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
||||
if (S->tok != '[')
|
||||
if (S->tccpp_tok != '[')
|
||||
expect(S, "'['");
|
||||
else
|
||||
next(S); // skip '['
|
||||
|
@ -1425,14 +1425,14 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "(first source operand) register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ']') {
|
||||
if (S->tccpp_tok == ']') {
|
||||
next(S);
|
||||
closed_bracket = 1;
|
||||
// exclam = 1; // implicit in hardware; don't do it in software
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S); // skip ','
|
||||
if (S->tok == '-') {
|
||||
if (S->tccpp_tok == '-') {
|
||||
op2_minus = 1;
|
||||
next(S);
|
||||
}
|
||||
|
@ -1453,12 +1453,12 @@ static void asm_coprocessor_data_transfer_opcode(TCCState *S, int token)
|
|||
preincrement = 1; // add offset before transfer
|
||||
}
|
||||
if (!closed_bracket) {
|
||||
if (S->tok != ']')
|
||||
if (S->tccpp_tok != ']')
|
||||
expect(S, "']'");
|
||||
else
|
||||
next(S); // skip ']'
|
||||
preincrement = 1; // add offset before transfer
|
||||
if (S->tok == '!') {
|
||||
if (S->tccpp_tok == '!') {
|
||||
exclam = 1;
|
||||
next(S); // skip '!'
|
||||
}
|
||||
|
@ -1528,12 +1528,12 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
|
|||
return;
|
||||
}
|
||||
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
||||
if (S->tok != '[')
|
||||
if (S->tccpp_tok != '[')
|
||||
expect(S, "'['");
|
||||
else
|
||||
next(S); // skip '['
|
||||
|
@ -1543,7 +1543,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
|
|||
expect(S, "(first source operand) register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S); // skip ','
|
||||
parse_operand(S, &ops[2]);
|
||||
if (ops[2].type != OP_IM8 && ops[2].type != OP_IM8N) {
|
||||
|
@ -1555,7 +1555,7 @@ static void asm_floating_point_single_data_transfer_opcode(TCCState *S, int toke
|
|||
ops[2].type = OP_IM8;
|
||||
ops[2].e.v = 0;
|
||||
}
|
||||
if (S->tok != ']')
|
||||
if (S->tccpp_tok != ']')
|
||||
expect(S, "']'");
|
||||
else
|
||||
next(S); // skip ']'
|
||||
|
@ -1593,11 +1593,11 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
|
|||
break;
|
||||
default:
|
||||
parse_operand(S, &ops[0]);
|
||||
if (S->tok == '!') {
|
||||
if (S->tccpp_tok == '!') {
|
||||
op0_exclam = 1;
|
||||
next(S); // skip '!'
|
||||
}
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S); // skip comma
|
||||
else {
|
||||
expect(S, "','");
|
||||
|
@ -1605,16 +1605,16 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
|
|||
}
|
||||
}
|
||||
|
||||
if (S->tok != '{') {
|
||||
if (S->tccpp_tok != '{') {
|
||||
expect(S, "'{'");
|
||||
return;
|
||||
}
|
||||
next(S); // skip '{'
|
||||
first_regset_register = asm_parse_vfp_regvar(S->tok, 1);
|
||||
if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 1)) != -1) {
|
||||
first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1);
|
||||
if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 1)) != -1) {
|
||||
coprocessor = CP_DOUBLE_PRECISION_FLOAT;
|
||||
next(S);
|
||||
} else if ((first_regset_register = asm_parse_vfp_regvar(S->tok, 0)) != -1) {
|
||||
} else if ((first_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, 0)) != -1) {
|
||||
coprocessor = CP_SINGLE_PRECISION_FLOAT;
|
||||
next(S);
|
||||
} else {
|
||||
|
@ -1622,9 +1622,9 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
|
|||
return;
|
||||
}
|
||||
|
||||
if (S->tok == '-') {
|
||||
if (S->tccpp_tok == '-') {
|
||||
next(S);
|
||||
if ((last_regset_register = asm_parse_vfp_regvar(S->tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
|
||||
if ((last_regset_register = asm_parse_vfp_regvar(S->tccpp_tok, coprocessor == CP_DOUBLE_PRECISION_FLOAT)) != -1)
|
||||
next(S);
|
||||
else {
|
||||
expect(S, "floating-point register");
|
||||
|
@ -1637,7 +1637,7 @@ static void asm_floating_point_block_data_transfer_opcode(TCCState *S, int token
|
|||
tcc_error(S, "registers will be processed in ascending order by hardware--but are not specified in ascending order here");
|
||||
return;
|
||||
}
|
||||
if (S->tok != '}') {
|
||||
if (S->tccpp_tok != '}') {
|
||||
expect(S, "'}'");
|
||||
return;
|
||||
}
|
||||
|
@ -1725,11 +1725,11 @@ static uint32_t vmov_parse_immediate_value(TCCState *S) {
|
|||
unsigned long integral_value;
|
||||
const char *p;
|
||||
|
||||
if (S->tok != TOK_PPNUM) {
|
||||
if (S->tccpp_tok != TOK_PPNUM) {
|
||||
expect(S, "immediate value");
|
||||
return 0;
|
||||
}
|
||||
p = S->tokc.str.data;
|
||||
p = S->tccpp_tokc.str.data;
|
||||
errno = 0;
|
||||
integral_value = strtoul(p, (char **)&p, 0);
|
||||
|
||||
|
@ -1785,10 +1785,10 @@ static void asm_floating_point_immediate_data_processing_opcode_tail(TCCState *S
|
|||
|
||||
operands[0] = CRd;
|
||||
|
||||
if (S->tok == '#' || S->tok == '$') {
|
||||
if (S->tccpp_tok == '#' || S->tccpp_tok == '$') {
|
||||
next(S);
|
||||
}
|
||||
if (S->tok == '-') {
|
||||
if (S->tccpp_tok == '-') {
|
||||
op_minus = 1;
|
||||
next(S);
|
||||
}
|
||||
|
@ -1956,7 +1956,7 @@ static void asm_floating_point_vcvt_data_processing_opcode(TCCState *S, int toke
|
|||
break;
|
||||
}
|
||||
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -2078,7 +2078,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
|
|||
|
||||
for (nb_ops = 0; nb_ops < 3; ) {
|
||||
// Note: Necessary because parse_operand can't parse decimal numerals.
|
||||
if (nb_ops == 1 && (S->tok == '#' || S->tok == '$' || S->tok == TOK_PPNUM || S->tok == '-')) {
|
||||
if (nb_ops == 1 && (S->tccpp_tok == '#' || S->tccpp_tok == '$' || S->tccpp_tok == TOK_PPNUM || S->tccpp_tok == '-')) {
|
||||
asm_floating_point_immediate_data_processing_opcode_tail(S, token, coprocessor, ops[0].reg);
|
||||
return;
|
||||
}
|
||||
|
@ -2100,7 +2100,7 @@ static void asm_floating_point_data_processing_opcode(TCCState *S, int token) {
|
|||
return;
|
||||
}
|
||||
++nb_ops;
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
break;
|
||||
|
@ -2248,7 +2248,7 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
|
|||
switch (ARM_INSTRUCTION_GROUP(token)) {
|
||||
case TOK_ASM_vmrseq:
|
||||
opcode = 0xf;
|
||||
if (S->tok == TOK_ASM_apsr_nzcv) {
|
||||
if (S->tccpp_tok == TOK_ASM_apsr_nzcv) {
|
||||
arm_operand.type = OP_REG32;
|
||||
arm_operand.reg = 15; // not PC
|
||||
next(S); // skip apsr_nzcv
|
||||
|
@ -2260,11 +2260,11 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
|
|||
}
|
||||
}
|
||||
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
expect(S, "','");
|
||||
else
|
||||
next(S); // skip ','
|
||||
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tok);
|
||||
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
|
||||
next(S); // skip vfp sys reg
|
||||
if (arm_operand.type == OP_REG32 && arm_operand.reg == 15 && vfp_sys_reg != 1) {
|
||||
tcc_error(S, "'%s' only supports the variant 'vmrs apsr_nzcv, fpscr' here", get_tok_str(S, token, NULL));
|
||||
|
@ -2273,9 +2273,9 @@ static void asm_floating_point_status_register_opcode(TCCState *S, int token)
|
|||
break;
|
||||
case TOK_ASM_vmsreq:
|
||||
opcode = 0xe;
|
||||
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tok);
|
||||
vfp_sys_reg = asm_parse_vfp_status_regvar(S->tccpp_tok);
|
||||
next(S); // skip vfp sys reg
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
expect(S, "','");
|
||||
else
|
||||
next(S); // skip ','
|
||||
|
@ -2329,12 +2329,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "(destination operand) register");
|
||||
return;
|
||||
}
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
expect(S, "at least two arguments");
|
||||
else
|
||||
next(S); // skip ','
|
||||
|
||||
if (S->tok != '[')
|
||||
if (S->tccpp_tok != '[')
|
||||
expect(S, "'['");
|
||||
else
|
||||
next(S); // skip '['
|
||||
|
@ -2346,14 +2346,14 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "(first source operand) register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ']') {
|
||||
if (S->tccpp_tok == ']') {
|
||||
next(S);
|
||||
closed_bracket = 1;
|
||||
// exclam = 1; // implicit in hardware; don't do it in software
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S); // skip ','
|
||||
if (S->tok == '-') {
|
||||
if (S->tccpp_tok == '-') {
|
||||
op2_minus = 1;
|
||||
next(S);
|
||||
}
|
||||
|
@ -2365,12 +2365,12 @@ static void asm_misc_single_data_transfer_opcode(TCCState *S, int token)
|
|||
opcode |= 1 << 24; // add offset before transfer
|
||||
}
|
||||
if (!closed_bracket) {
|
||||
if (S->tok != ']')
|
||||
if (S->tccpp_tok != ']')
|
||||
expect(S, "']'");
|
||||
else
|
||||
next(S); // skip ']'
|
||||
opcode |= 1 << 24; // add offset before transfer
|
||||
if (S->tok == '!') {
|
||||
if (S->tccpp_tok == '!') {
|
||||
exclam = 1;
|
||||
next(S); // skip '!'
|
||||
}
|
||||
|
@ -2467,7 +2467,7 @@ static void asm_branch_opcode(TCCState *S, int token)
|
|||
tcc_error(S, "invalid branch target");
|
||||
return;
|
||||
}
|
||||
jmp_disp = encbranchoffset(S, S->ind, e.v + esym->st_value, 1);
|
||||
jmp_disp = encbranchoffset(S, S->tccgen_ind, e.v + esym->st_value, 1);
|
||||
break;
|
||||
default:
|
||||
parse_operand(S, &op);
|
||||
|
@ -2501,7 +2501,7 @@ ST_FUNC void asm_opcode(TCCState *S, int token)
|
|||
{
|
||||
while (token == TOK_LINEFEED) {
|
||||
next(S);
|
||||
token = S->tok;
|
||||
token = S->tccpp_tok;
|
||||
}
|
||||
if (token == TOK_EOF)
|
||||
return;
|
||||
|
|
288
arm-gen.c
288
arm-gen.c
|
@ -244,21 +244,21 @@ void o(TCCState *S, uint32_t i)
|
|||
{
|
||||
/* this is a good place to start adding big-endian support*/
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 4;
|
||||
ind1 = S->tccgen_ind + 4;
|
||||
if (!cur_text_section)
|
||||
tcc_error(S, "compiler error! This happens f.ex. if the compiler\n"
|
||||
"can't evaluate constant expressions outside of a function.");
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind++] = i&255;
|
||||
cur_text_section->data[S->tccgen_ind++] = i&255;
|
||||
i>>=8;
|
||||
cur_text_section->data[S->ind++] = i&255;
|
||||
cur_text_section->data[S->tccgen_ind++] = i&255;
|
||||
i>>=8;
|
||||
cur_text_section->data[S->ind++] = i&255;
|
||||
cur_text_section->data[S->tccgen_ind++] = i&255;
|
||||
i>>=8;
|
||||
cur_text_section->data[S->ind++] = i;
|
||||
cur_text_section->data[S->tccgen_ind++] = i;
|
||||
}
|
||||
|
||||
static uint32_t stuff_const(uint32_t op, uint32_t c)
|
||||
|
@ -538,7 +538,7 @@ static void load_value(TCCState *S, SValue *sv, int r)
|
|||
o(S, 0xEA000000); /* b $+4 */
|
||||
#ifndef CONFIG_TCC_PIE
|
||||
if(sv->r & VT_SYM)
|
||||
greloc(S, cur_text_section, sv->sym, S->ind, R_ARM_ABS32);
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_ABS32);
|
||||
o(S, sv->c.i);
|
||||
#else
|
||||
if(sv->r & VT_SYM) {
|
||||
|
@ -787,17 +787,17 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
|
|||
{
|
||||
int r;
|
||||
uint32_t x;
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
/* constant case */
|
||||
if(S->vtop->r & VT_SYM){
|
||||
x=encbranch(S, S->ind, S->ind+S->vtop->c.i,0);
|
||||
if(S->tccgen_vtop->r & VT_SYM){
|
||||
x=encbranch(S, S->tccgen_ind, S->tccgen_ind+S->tccgen_vtop->c.i,0);
|
||||
if(x) {
|
||||
/* relocation case */
|
||||
greloc(S, cur_text_section, S->vtop->sym, S->ind, R_ARM_PC24);
|
||||
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_ARM_PC24);
|
||||
o(S, x|(is_jmp?0xE0000000:0xE1000000));
|
||||
} else {
|
||||
r = TREG_LR;
|
||||
load_value(S, S->vtop, r);
|
||||
load_value(S, S->tccgen_vtop, r);
|
||||
if(is_jmp)
|
||||
o(S, 0xE1A0F000 | intr(S, r)); // mov pc, r
|
||||
else
|
||||
|
@ -807,12 +807,12 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
|
|||
if(!is_jmp)
|
||||
o(S, 0xE28FE004); // add lr,pc,#4
|
||||
o(S, 0xE51FF004); // ldr pc,[pc,#-4]
|
||||
o(S, S->vtop->c.i);
|
||||
o(S, S->tccgen_vtop->c.i);
|
||||
}
|
||||
} else {
|
||||
/* otherwise, indirect call */
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
S->vtop->r &= ~VT_MUSTBOUND;
|
||||
S->tccgen_vtop->r &= ~VT_MUSTBOUND;
|
||||
#endif
|
||||
r = gv(S, RC_INT);
|
||||
if(!is_jmp)
|
||||
|
@ -827,7 +827,7 @@ static void gen_bounds_call(TCCState *S, int v)
|
|||
{
|
||||
Sym *sym = external_helper_sym(S, v);
|
||||
|
||||
greloc(S, cur_text_section, sym, S->ind, R_ARM_PC24);
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind, R_ARM_PC24);
|
||||
o(S, 0xebfffffe);
|
||||
}
|
||||
|
||||
|
@ -835,7 +835,7 @@ static void gen_bounds_prolog(TCCState *S)
|
|||
{
|
||||
/* leave some room for bound checking code */
|
||||
S->func_bound_offset = lbounds_section->data_offset;
|
||||
S->func_bound_ind = S->ind;
|
||||
S->func_bound_ind = S->tccgen_ind;
|
||||
S->func_bound_add_epilog = 0;
|
||||
o(S, 0xe1a00000); /* ld r0,lbounds_section->data_offset */
|
||||
o(S, 0xe1a00000);
|
||||
|
@ -858,20 +858,20 @@ static void gen_bounds_epilog(TCCState *S)
|
|||
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
|
||||
*bounds_ptr = 0;
|
||||
|
||||
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section,
|
||||
sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
|
||||
S->func_bound_offset, lbounds_section->data_offset);
|
||||
|
||||
/* generate bound local allocation */
|
||||
if (offset_modified) {
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->func_bound_ind;
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->func_bound_ind;
|
||||
o(S, 0xe59f0000); /* ldr r0, [pc] */
|
||||
o(S, 0xea000000); /* b $+4 */
|
||||
greloc(S, cur_text_section, sym_data, S->ind, R_ARM_REL32);
|
||||
greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
|
||||
o(S, -12); /* lbounds_section->data_offset */
|
||||
o(S, 0xe080000f); /* add r0,r0,pc */
|
||||
gen_bounds_call(S, TOK___bound_local_new);
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
/* generate bound check local freeing */
|
||||
|
@ -879,7 +879,7 @@ static void gen_bounds_epilog(TCCState *S)
|
|||
o(S, 0xed2d0b02); /* vpush {d0} */
|
||||
o(S, 0xe59f0000); /* ldr r0, [pc] */
|
||||
o(S, 0xea000000); /* b $+4 */
|
||||
greloc(S, cur_text_section, sym_data, S->ind, R_ARM_REL32);
|
||||
greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
|
||||
o(S, -12); /* lbounds_section->data_offset */
|
||||
o(S, 0xe080000f); /* add r0,r0,pc */
|
||||
gen_bounds_call(S, TOK___bound_local_delete);
|
||||
|
@ -1081,12 +1081,12 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
|
|||
|
||||
for(i = nb_args; i-- ;) {
|
||||
int j, start_vfpreg = 0;
|
||||
CType type = S->vtop[-i].type;
|
||||
CType type = S->tccgen_vtop[-i].type;
|
||||
type.t &= ~VT_ARRAY;
|
||||
size = type_size(&type, &align);
|
||||
size = (size + 3) & ~3;
|
||||
align = (align + 3) & ~3;
|
||||
switch(S->vtop[-i].type.t & VT_BTYPE) {
|
||||
switch(S->tccgen_vtop[-i].type.t & VT_BTYPE) {
|
||||
case VT_STRUCT:
|
||||
case VT_FLOAT:
|
||||
case VT_DOUBLE:
|
||||
|
@ -1094,15 +1094,15 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
|
|||
if (float_abi == ARM_HARD_FLOAT) {
|
||||
int is_hfa = 0; /* Homogeneous float aggregate */
|
||||
|
||||
if (is_float(S->vtop[-i].type.t)
|
||||
|| (is_hfa = is_hgen_float_aggr(&S->vtop[-i].type))) {
|
||||
if (is_float(S->tccgen_vtop[-i].type.t)
|
||||
|| (is_hfa = is_hgen_float_aggr(&S->tccgen_vtop[-i].type))) {
|
||||
int end_vfpreg;
|
||||
|
||||
start_vfpreg = assign_vfpreg(&avregs, align, size);
|
||||
end_vfpreg = start_vfpreg + ((size - 1) >> 2);
|
||||
if (start_vfpreg >= 0) {
|
||||
add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,
|
||||
start_vfpreg, end_vfpreg, &S->vtop[-i]);
|
||||
start_vfpreg, end_vfpreg, &S->tccgen_vtop[-i]);
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
|
@ -1115,7 +1115,7 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
|
|||
* CORE_STRUCT_CLASS or the first of STACK_CLASS. */
|
||||
for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
|
||||
*todo|=(1<<j);
|
||||
add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->vtop[-i]);
|
||||
add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->tccgen_vtop[-i]);
|
||||
ncrn += size/4;
|
||||
if (ncrn > 4)
|
||||
nsaa = (ncrn - 4) * 4;
|
||||
|
@ -1126,20 +1126,20 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
|
|||
continue;
|
||||
default:
|
||||
if (ncrn < 4) {
|
||||
int is_long = (S->vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
|
||||
int is_long = (S->tccgen_vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
|
||||
|
||||
if (is_long) {
|
||||
ncrn = (ncrn + 1) & -2;
|
||||
if (ncrn == 4)
|
||||
break;
|
||||
}
|
||||
add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->vtop[-i]);
|
||||
add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->tccgen_vtop[-i]);
|
||||
ncrn += 1 + is_long;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
nsaa = (nsaa + (align - 1)) & ~(align - 1);
|
||||
add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->vtop[-i]);
|
||||
add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->tccgen_vtop[-i]);
|
||||
nsaa += size; /* size already rounded up before */
|
||||
}
|
||||
return nsaa;
|
||||
|
@ -1201,7 +1201,7 @@ again:
|
|||
/* generate structure store */
|
||||
r = get_reg(S, RC_INT);
|
||||
o(S, 0xE28D0000|(intr(S, r)<<12)|padding); /* add r, sp, padding */
|
||||
vset(S, &S->vtop->type, r | VT_LVAL, 0);
|
||||
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
|
||||
vswap(S);
|
||||
/* XXX: optimize. Save all register because memcpy can use them */
|
||||
o(S, 0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */
|
||||
|
@ -1255,7 +1255,7 @@ again:
|
|||
size = 8;
|
||||
r = gv(S, RC_INT);
|
||||
o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
r = gv(S, RC_INT);
|
||||
o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
|
||||
|
@ -1269,7 +1269,7 @@ again:
|
|||
gv(S, regmask(S, TREG_F0 + (pplan->start >> 1)));
|
||||
if (pplan->start & 1) { /* Must be in upper part of double register */
|
||||
o(S, 0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
|
||||
S->vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
|
||||
S->tccgen_vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1277,16 +1277,16 @@ again:
|
|||
if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
lexpand(S);
|
||||
gv(S, regmask(S, pplan->end));
|
||||
pplan->sval->r2 = S->vtop->r;
|
||||
S->vtop--;
|
||||
pplan->sval->r2 = S->tccgen_vtop->r;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
gv(S, regmask(S, pplan->start));
|
||||
/* Mark register as used so that gcall_or_jmp use another one
|
||||
(regs >=4 are free as never used to pass parameters) */
|
||||
pplan->sval->r = S->vtop->r;
|
||||
pplan->sval->r = S->tccgen_vtop->r;
|
||||
break;
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1312,7 +1312,7 @@ again:
|
|||
if (todo & (1 << r)) {
|
||||
nb_extra_sval++;
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = r;
|
||||
S->tccgen_vtop->r = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1340,15 +1340,15 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
#ifdef TCC_ARM_EABI
|
||||
if (float_abi == ARM_HARD_FLOAT) {
|
||||
variadic = (S->vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
|
||||
if (variadic || floats_in_core_regs(&S->vtop[-nb_args]))
|
||||
variadic = (S->tccgen_vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
|
||||
if (variadic || floats_in_core_regs(&S->tccgen_vtop[-nb_args]))
|
||||
float_abi = ARM_SOFTFP_FLOAT;
|
||||
}
|
||||
#endif
|
||||
/* cannot let cpu flags if other instruction are generated. Also avoid leaving
|
||||
VT_JMP anywhere except on the top of the stack because it would complicate
|
||||
the code generator. */
|
||||
r = S->vtop->r & VT_VALMASK;
|
||||
r = S->tccgen_vtop->r & VT_VALMASK;
|
||||
if (r == VT_CMP || (r & ~1) == VT_JMP)
|
||||
gv(S, RC_INT);
|
||||
|
||||
|
@ -1374,8 +1374,8 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
if (args_size)
|
||||
gadd_sp(S, args_size); /* pop all parameters passed on the stack */
|
||||
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
|
||||
if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->vtop->type.ref->type.t)) {
|
||||
if((S->vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
|
||||
if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->tccgen_vtop->type.ref->type.t)) {
|
||||
if((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
|
||||
o(S, 0xEE000A10); /*vmov s0, r0 */
|
||||
} else {
|
||||
o(S, 0xEE000B10); /* vmov.32 d0[0], r0 */
|
||||
|
@ -1383,7 +1383,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
S->vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
|
||||
S->tccgen_vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
|
||||
leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
|
||||
float_abi = def_float_abi;
|
||||
}
|
||||
|
@ -1443,7 +1443,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
}
|
||||
o(S, 0xE92D5800); /* save fp, ip, lr */
|
||||
o(S, 0xE1A0B00D); /* mov fp, sp */
|
||||
func_sub_sp_offset = S->ind;
|
||||
func_sub_sp_offset = S->tccgen_ind;
|
||||
o(S, 0xE1A00000); /* nop, leave space for stack adjustment in epilog */
|
||||
|
||||
#ifdef TCC_ARM_EABI
|
||||
|
@ -1490,7 +1490,7 @@ from_stack:
|
|||
}
|
||||
last_itod_magic=0;
|
||||
leaffunc = 1;
|
||||
S->loc = 0;
|
||||
S->tccgen_loc = 0;
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (S->do_bounds_check)
|
||||
gen_bounds_prolog(S);
|
||||
|
@ -1520,7 +1520,7 @@ void gfunc_epilog(TCCState *S)
|
|||
}
|
||||
#endif
|
||||
o(S, 0xE89BA800); /* restore fp, sp, pc */
|
||||
diff = (-S->loc + 3) & -4;
|
||||
diff = (-S->tccgen_loc + 3) & -4;
|
||||
#ifdef TCC_ARM_EABI
|
||||
if(!leaffunc)
|
||||
diff = ((diff + 11) & -8) - 4;
|
||||
|
@ -1531,7 +1531,7 @@ void gfunc_epilog(TCCState *S)
|
|||
*(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
|
||||
else {
|
||||
int addr;
|
||||
addr=S->ind;
|
||||
addr=S->tccgen_ind;
|
||||
o(S, 0xE59FC004); /* ldr ip,[pc+4] */
|
||||
o(S, 0xE04BD00C); /* sub sp,fp,ip */
|
||||
o(S, 0xE1A0F00E); /* mov pc,lr */
|
||||
|
@ -1555,9 +1555,9 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
|
|||
ST_FUNC int gjmp(TCCState* S, int t)
|
||||
{
|
||||
int r;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return t;
|
||||
r=S->ind;
|
||||
r=S->tccgen_ind;
|
||||
o(S, 0xE0000000|encbranch(S, r,t,1));
|
||||
return r;
|
||||
}
|
||||
|
@ -1571,9 +1571,9 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
|
|||
ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
|
||||
{
|
||||
int r;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return t;
|
||||
r=S->ind;
|
||||
r=S->tccgen_ind;
|
||||
op=mapcc(S, op);
|
||||
op|=encbranch(S, r,t,1);
|
||||
o(S, op);
|
||||
|
@ -1644,9 +1644,9 @@ void gen_opi(TCCState *S, int op)
|
|||
break;
|
||||
case '*':
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
o(S, 0xE0000090|(intr(S, r)<<16)|(intr(S, r)<<8)|intr(S, fr));
|
||||
return;
|
||||
case TOK_SHL:
|
||||
|
@ -1690,11 +1690,11 @@ void gen_opi(TCCState *S, int op)
|
|||
break;
|
||||
case TOK_UMULL:
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r=intr(S, S->vtop[-1].r2=get_reg(S, RC_INT));
|
||||
c=S->vtop[-1].r;
|
||||
S->vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));
|
||||
S->vtop--;
|
||||
o(S, 0xE0800090|(r<<16)|(intr(S, S->vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->vtop[1].r));
|
||||
r=intr(S, S->tccgen_vtop[-1].r2=get_reg(S, RC_INT));
|
||||
c=S->tccgen_vtop[-1].r;
|
||||
S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));
|
||||
S->tccgen_vtop--;
|
||||
o(S, 0xE0800090|(r<<16)|(intr(S, S->tccgen_vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->tccgen_vtop[1].r));
|
||||
return;
|
||||
default:
|
||||
opc = 0x15;
|
||||
|
@ -1703,27 +1703,27 @@ void gen_opi(TCCState *S, int op)
|
|||
}
|
||||
switch(c) {
|
||||
case 1:
|
||||
if((S->vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
if((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
if(opc == 4 || opc == 5 || opc == 0xc) {
|
||||
vswap(S);
|
||||
opc|=2; // sub -> rsb
|
||||
}
|
||||
}
|
||||
if ((S->vtop->r & VT_VALMASK) == VT_CMP ||
|
||||
(S->vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
|
||||
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
|
||||
(S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
|
||||
gv(S, RC_INT);
|
||||
vswap(S);
|
||||
c=intr(S, gv(S, RC_INT));
|
||||
vswap(S);
|
||||
opc=0xE0000000|(opc<<20);
|
||||
if((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
uint32_t x;
|
||||
x=stuff_const(opc|0x2000000|(c<<16),S->vtop->c.i);
|
||||
x=stuff_const(opc|0x2000000|(c<<16),S->tccgen_vtop->c.i);
|
||||
if(x) {
|
||||
if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c
|
||||
o(S, x);
|
||||
else {
|
||||
r=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->vtop[-1].r)));
|
||||
r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
|
||||
o(S, x|(r<<12));
|
||||
}
|
||||
goto done;
|
||||
|
@ -1731,7 +1731,7 @@ void gen_opi(TCCState *S, int op)
|
|||
}
|
||||
fr=intr(S, gv(S, RC_INT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
c=intr(S, gv(S, RC_INT));
|
||||
vswap(S);
|
||||
|
@ -1740,46 +1740,46 @@ void gen_opi(TCCState *S, int op)
|
|||
if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
|
||||
o(S, opc|(c<<16)|fr);
|
||||
else {
|
||||
r=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->vtop->r,S->vtop[-1].r)));
|
||||
r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
|
||||
o(S, opc|(c<<16)|(r<<12)|fr);
|
||||
}
|
||||
done:
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
if (op >= TOK_ULT && op <= TOK_GT)
|
||||
vset_VT_CMP(S, op);
|
||||
break;
|
||||
case 2:
|
||||
opc=0xE1A00000|(opc<<5);
|
||||
if ((S->vtop->r & VT_VALMASK) == VT_CMP ||
|
||||
(S->vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
|
||||
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
|
||||
(S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
|
||||
gv(S, RC_INT);
|
||||
vswap(S);
|
||||
r=intr(S, gv(S, RC_INT));
|
||||
vswap(S);
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
fr=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->vtop[-1].r)));
|
||||
c = S->vtop->c.i & 0x1f;
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
fr=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
|
||||
c = S->tccgen_vtop->c.i & 0x1f;
|
||||
o(S, opc|r|(c<<7)|(fr<<12));
|
||||
} else {
|
||||
fr=intr(S, gv(S, RC_INT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=intr(S, gv(S, RC_INT));
|
||||
vswap(S);
|
||||
}
|
||||
#endif
|
||||
c=intr(S, S->vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->vtop->r,S->vtop[-1].r)));
|
||||
c=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
|
||||
o(S, opc|r|(c<<12)|(fr<<8)|0x10);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
break;
|
||||
case 3:
|
||||
vpush_helper_func(S, func);
|
||||
vrott(S, 3);
|
||||
gfunc_call(S, 2);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = retreg;
|
||||
S->tccgen_vtop->r = retreg;
|
||||
break;
|
||||
default:
|
||||
tcc_error(S, "gen_opi %i unimplemented!",op);
|
||||
|
@ -1789,13 +1789,13 @@ done:
|
|||
#ifdef TCC_ARM_VFP
|
||||
static int is_zero(TCCState* S, int i)
|
||||
{
|
||||
if((S->vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
if((S->tccgen_vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
return 0;
|
||||
if (S->vtop[i].type.t == VT_FLOAT)
|
||||
return (S->vtop[i].c.f == 0.f);
|
||||
else if (S->vtop[i].type.t == VT_DOUBLE)
|
||||
return (S->vtop[i].c.d == 0.0);
|
||||
return (S->vtop[i].c.ld == 0.l);
|
||||
if (S->tccgen_vtop[i].type.t == VT_FLOAT)
|
||||
return (S->tccgen_vtop[i].c.f == 0.f);
|
||||
else if (S->tccgen_vtop[i].type.t == VT_DOUBLE)
|
||||
return (S->tccgen_vtop[i].c.d == 0.0);
|
||||
return (S->tccgen_vtop[i].c.ld == 0.l);
|
||||
}
|
||||
|
||||
/* generate a floating point operation 'v = t1 op t2' instruction. The
|
||||
|
@ -1804,13 +1804,13 @@ void gen_opf(TCCState *S, int op)
|
|||
{
|
||||
uint32_t x;
|
||||
int fneg=0,r;
|
||||
x=0xEE000A00|T2CPR(S->vtop->type.t);
|
||||
x=0xEE000A00|T2CPR(S->tccgen_vtop->type.t);
|
||||
switch(op) {
|
||||
case '+':
|
||||
if(is_zero(S, -1))
|
||||
vswap(S);
|
||||
if(is_zero(S, 0)) {
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
return;
|
||||
}
|
||||
x|=0x300000;
|
||||
|
@ -1818,13 +1818,13 @@ void gen_opf(TCCState *S, int op)
|
|||
case '-':
|
||||
x|=0x300040;
|
||||
if(is_zero(S, 0)) {
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
return;
|
||||
}
|
||||
if(is_zero(S, -1)) {
|
||||
x|=0x810000; /* fsubX -> fnegX */
|
||||
vswap(S);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
fneg=1;
|
||||
}
|
||||
break;
|
||||
|
@ -1852,13 +1852,13 @@ void gen_opf(TCCState *S, int op)
|
|||
if(op!=TOK_EQ && op!=TOK_NE)
|
||||
x|=0x80; /* fcmpX -> fcmpeX */
|
||||
if(is_zero(S, 0)) {
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
o(S, x|0x10000|(vfpr(S, gv(S, RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
|
||||
} else {
|
||||
gv2(S, RC_FLOAT,RC_FLOAT);
|
||||
x|=vfpr(S, S->vtop[0].r);
|
||||
o(S, x|(vfpr(S, S->vtop[-1].r) << 12));
|
||||
S->vtop--;
|
||||
x|=vfpr(S, S->tccgen_vtop[0].r);
|
||||
o(S, x|(vfpr(S, S->tccgen_vtop[-1].r) << 12));
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
o(S, 0xEEF1FA10); /* fmstat */
|
||||
|
||||
|
@ -1881,7 +1881,7 @@ void gen_opf(TCCState *S, int op)
|
|||
x|=vfpr(S, r2)<<16;
|
||||
r|=regmask(S, r2);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=gv(S, RC_FLOAT);
|
||||
vswap(S);
|
||||
|
@ -1889,10 +1889,10 @@ void gen_opf(TCCState *S, int op)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
S->vtop->r=get_reg_ex(S, RC_FLOAT,r);
|
||||
S->tccgen_vtop->r=get_reg_ex(S, RC_FLOAT,r);
|
||||
if(!fneg)
|
||||
S->vtop--;
|
||||
o(S, x|(vfpr(S, S->vtop->r)<<12));
|
||||
S->tccgen_vtop--;
|
||||
o(S, x|(vfpr(S, S->tccgen_vtop->r)<<12));
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -1900,14 +1900,14 @@ static uint32_t is_fconst(TCCState *S)
|
|||
{
|
||||
long double f;
|
||||
uint32_t r;
|
||||
if((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
return 0;
|
||||
if (S->vtop->type.t == VT_FLOAT)
|
||||
f = S->vtop->c.f;
|
||||
else if (S->vtop->type.t == VT_DOUBLE)
|
||||
f = S->vtop->c.d;
|
||||
if (S->tccgen_vtop->type.t == VT_FLOAT)
|
||||
f = S->tccgen_vtop->c.f;
|
||||
else if (S->tccgen_vtop->type.t == VT_DOUBLE)
|
||||
f = S->tccgen_vtop->c.d;
|
||||
else
|
||||
f = S->vtop->c.ld;
|
||||
f = S->tccgen_vtop->c.ld;
|
||||
if(!ieee_finite(f))
|
||||
return 0;
|
||||
r=0x8;
|
||||
|
@ -1946,12 +1946,12 @@ void gen_opf(TCCState *S, int op)
|
|||
c2 = is_fconst(S);
|
||||
x=0xEE000100;
|
||||
#if LDOUBLE_SIZE == 8
|
||||
if ((S->vtop->type.t & VT_BTYPE) != VT_FLOAT)
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT)
|
||||
x|=0x80;
|
||||
#else
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
x|=0x80;
|
||||
else if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
|
||||
else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
|
||||
x|=0x80000;
|
||||
#endif
|
||||
switch(op)
|
||||
|
@ -1971,7 +1971,7 @@ void gen_opf(TCCState *S, int op)
|
|||
} else {
|
||||
r2=fpr(S, gv(S, RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=fpr(S, gv(S, RC_FLOAT));
|
||||
vswap(S);
|
||||
|
@ -1999,7 +1999,7 @@ void gen_opf(TCCState *S, int op)
|
|||
vswap(S);
|
||||
r2=fpr(S, gv(S, RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=fpr(S, gv(S, RC_FLOAT));
|
||||
vswap(S);
|
||||
|
@ -2020,7 +2020,7 @@ void gen_opf(TCCState *S, int op)
|
|||
else {
|
||||
r2=fpr(S, gv(S, RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=fpr(S, gv(S, RC_FLOAT));
|
||||
vswap(S);
|
||||
|
@ -2048,7 +2048,7 @@ void gen_opf(TCCState *S, int op)
|
|||
vswap(S);
|
||||
r2=fpr(S, gv(S, RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=fpr(S, gv(S, RC_FLOAT));
|
||||
vswap(S);
|
||||
|
@ -2107,31 +2107,31 @@ void gen_opf(TCCState *S, int op)
|
|||
} else {
|
||||
r2=fpr(S, gv(S, RC_FLOAT));
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((S->vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
|
||||
vswap(S);
|
||||
r=fpr(S, gv(S, RC_FLOAT));
|
||||
vswap(S);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
vset_VT_CMP(S, op);
|
||||
++S->vtop;
|
||||
++S->tccgen_vtop;
|
||||
} else {
|
||||
tcc_error(S, "unknown fp op %x!",op);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(S->vtop[-1].r == VT_CMP)
|
||||
if(S->tccgen_vtop[-1].r == VT_CMP)
|
||||
c1=15;
|
||||
else {
|
||||
c1=S->vtop->r;
|
||||
c1=S->tccgen_vtop->r;
|
||||
if(r2&0x8)
|
||||
c1=S->vtop[-1].r;
|
||||
S->vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->vtop[-1].r,c1));
|
||||
c1=fpr(S, S->vtop[-1].r);
|
||||
c1=S->tccgen_vtop[-1].r;
|
||||
S->tccgen_vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->tccgen_vtop[-1].r,c1));
|
||||
c1=fpr(S, S->tccgen_vtop[-1].r);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
o(S, x|(r<<16)|(c1<<12)|r2);
|
||||
}
|
||||
#endif
|
||||
|
@ -2142,30 +2142,30 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
{
|
||||
uint32_t r, r2;
|
||||
int bt;
|
||||
bt=S->vtop->type.t & VT_BTYPE;
|
||||
bt=S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
|
||||
#ifndef TCC_ARM_VFP
|
||||
uint32_t dsize = 0;
|
||||
#endif
|
||||
r=intr(S, gv(S, RC_INT));
|
||||
#ifdef TCC_ARM_VFP
|
||||
r2=vfpr(S, S->vtop->r=get_reg(S, RC_FLOAT));
|
||||
r2=vfpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
|
||||
o(S, 0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
|
||||
r2|=r2<<12;
|
||||
if(!(S->vtop->type.t & VT_UNSIGNED))
|
||||
if(!(S->tccgen_vtop->type.t & VT_UNSIGNED))
|
||||
r2|=0x80; /* fuitoX -> fsituX */
|
||||
o(S, 0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
|
||||
#else
|
||||
r2=fpr(S, S->vtop->r=get_reg(S, RC_FLOAT));
|
||||
r2=fpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
|
||||
if((t & VT_BTYPE) != VT_FLOAT)
|
||||
dsize=0x80; /* flts -> fltd */
|
||||
o(S, 0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
|
||||
if((S->vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
|
||||
if((S->tccgen_vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
|
||||
uint32_t off = 0;
|
||||
o(S, 0xE3500000|(r<<12)); /* cmp */
|
||||
r=fpr(S, get_reg(S, RC_FLOAT));
|
||||
if(last_itod_magic) {
|
||||
off=S->ind+8-last_itod_magic;
|
||||
off=S->tccgen_ind+8-last_itod_magic;
|
||||
off/=4;
|
||||
if(off>255)
|
||||
off=0;
|
||||
|
@ -2173,7 +2173,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
o(S, 0xBD1F0100|(r<<12)|off); /* ldflts */
|
||||
if(!off) {
|
||||
o(S, 0xEA000000); /* b */
|
||||
last_itod_magic=S->ind;
|
||||
last_itod_magic=S->tccgen_ind;
|
||||
o(S, 0x4F800000); /* 4294967296.0f */
|
||||
}
|
||||
o(S, 0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
|
||||
|
@ -2185,14 +2185,14 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
CType *func_type = 0;
|
||||
if((t & VT_BTYPE) == VT_FLOAT) {
|
||||
func_type = &S->armgen_func_float_type;
|
||||
if(S->vtop->type.t & VT_UNSIGNED)
|
||||
if(S->tccgen_vtop->type.t & VT_UNSIGNED)
|
||||
func=TOK___floatundisf;
|
||||
else
|
||||
func=TOK___floatdisf;
|
||||
#if LDOUBLE_SIZE != 8
|
||||
} else if((t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
func_type = &S->armgen_func_ldouble_type;
|
||||
if(S->vtop->type.t & VT_UNSIGNED)
|
||||
if(S->tccgen_vtop->type.t & VT_UNSIGNED)
|
||||
func=TOK___floatundixf;
|
||||
else
|
||||
func=TOK___floatdixf;
|
||||
|
@ -2201,7 +2201,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
} else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
#endif
|
||||
func_type = &S->armgen_func_double_type;
|
||||
if(S->vtop->type.t & VT_UNSIGNED)
|
||||
if(S->tccgen_vtop->type.t & VT_UNSIGNED)
|
||||
func=TOK___floatundidf;
|
||||
else
|
||||
func=TOK___floatdidf;
|
||||
|
@ -2211,11 +2211,11 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
vswap(S);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r=TREG_F0;
|
||||
S->tccgen_vtop->r=TREG_F0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
tcc_error(S, "unimplemented gen_cvt_itof %x!",S->vtop->type.t);
|
||||
tcc_error(S, "unimplemented gen_cvt_itof %x!",S->tccgen_vtop->type.t);
|
||||
}
|
||||
|
||||
/* convert fp to int 't' type */
|
||||
|
@ -2225,13 +2225,13 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
int u, func = 0;
|
||||
u=t&VT_UNSIGNED;
|
||||
t&=VT_BTYPE;
|
||||
r2=S->vtop->type.t & VT_BTYPE;
|
||||
r2=S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
if(t==VT_INT) {
|
||||
#ifdef TCC_ARM_VFP
|
||||
r=vfpr(S, gv(S, RC_FLOAT));
|
||||
u=u?0:0x10000;
|
||||
o(S, 0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
|
||||
r2=intr(S, S->vtop->r=get_reg(S, RC_INT));
|
||||
r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
|
||||
o(S, 0xEE100A10|(r<<16)|(r2<<12));
|
||||
return;
|
||||
#else
|
||||
|
@ -2248,7 +2248,7 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
func=TOK___fixunsdfsi;
|
||||
} else {
|
||||
r=fpr(S, gv(S, RC_FLOAT));
|
||||
r2=intr(S, S->vtop->r=get_reg(S, RC_INT));
|
||||
r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
|
||||
o(S, 0xEE100170|(r2<<12)|r);
|
||||
return;
|
||||
}
|
||||
|
@ -2271,8 +2271,8 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
if(t == VT_LLONG)
|
||||
S->vtop->r2 = REG_IRE2;
|
||||
S->vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->r2 = REG_IRE2;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
return;
|
||||
}
|
||||
tcc_error(S, "unimplemented gen_cvt_ftoi!");
|
||||
|
@ -2282,9 +2282,9 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
void gen_cvt_ftof(TCCState* S, int t)
|
||||
{
|
||||
#ifdef TCC_ARM_VFP
|
||||
if(((S->vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
|
||||
if(((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
|
||||
uint32_t r = vfpr(S, gv(S, RC_FLOAT));
|
||||
o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->vtop->type.t));
|
||||
o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->tccgen_vtop->type.t));
|
||||
}
|
||||
#else
|
||||
/* all we have to do on i386 and FPA ARM is to put the float in a register */
|
||||
|
@ -2298,11 +2298,11 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
int r1, r2;
|
||||
|
||||
vpushv(S, sv);
|
||||
S->vtop->r = r1 = get_reg(S, RC_INT);
|
||||
S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
|
||||
r2 = get_reg(S, RC_INT);
|
||||
o(S, 0xE59F0000 | (intr(S, r1)<<12)); // ldr r1,[pc]
|
||||
o(S, 0xEA000000); // b $+4
|
||||
greloc(S, cur_text_section, sv->sym, S->ind, R_ARM_REL32);
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_REL32);
|
||||
o(S, -12);
|
||||
o(S, 0xe080000f | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1,r1,pc
|
||||
o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]
|
||||
|
@ -2319,7 +2319,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
void ggoto(TCCState* S)
|
||||
{
|
||||
gcall_or_jmp(S, 1);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
/* Save the stack pointer onto the stack and return the location of its address */
|
||||
|
@ -2345,7 +2345,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
|
|||
int r;
|
||||
#if defined(CONFIG_TCC_BCHECK)
|
||||
if (S->do_bounds_check)
|
||||
vpushv(S, S->vtop);
|
||||
vpushv(S, S->tccgen_vtop);
|
||||
#endif
|
||||
r = intr(S, gv(S, RC_INT));
|
||||
#if defined(CONFIG_TCC_BCHECK)
|
||||
|
@ -2367,8 +2367,8 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
|
|||
#if defined(CONFIG_TCC_BCHECK)
|
||||
if (S->do_bounds_check) {
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = TREG_R0;
|
||||
o(S, 0xe1a0000d | (S->vtop->r << 12)); // mov r0,sp
|
||||
S->tccgen_vtop->r = TREG_R0;
|
||||
o(S, 0xe1a0000d | (S->tccgen_vtop->r << 12)); // mov r0,sp
|
||||
vswap(S);
|
||||
vpush_helper_func(S, TOK___bound_new_region);
|
||||
vrott(S, 3);
|
||||
|
|
32
arm64-asm.c
32
arm64-asm.c
|
@ -19,22 +19,22 @@ ST_FUNC void gen_le32(TCCState *S, int c);
|
|||
#define USING_GLOBALS
|
||||
#include "tcc.h"
|
||||
|
||||
static void asm_error(TCCState *S)
|
||||
static void asm_error(void)
|
||||
{
|
||||
tcc_error(S, "ARM asm not implemented.");
|
||||
tcc_error("ARM asm not implemented.");
|
||||
}
|
||||
|
||||
/* XXX: make it faster ? */
|
||||
ST_FUNC void g(TCCState* S, int c)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 1;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind] = c;
|
||||
S->ind = ind1;
|
||||
section_realloc(cur_text_section, ind1);
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_le16 (TCCState* S, int i)
|
||||
|
@ -56,37 +56,37 @@ ST_FUNC void gen_expr32(TCCState *S, ExprValue *pe)
|
|||
|
||||
ST_FUNC void asm_opcode(TCCState *S, int opcode)
|
||||
{
|
||||
asm_error(S);
|
||||
asm_error();
|
||||
}
|
||||
|
||||
ST_FUNC void subst_asm_operand(TCCState *S, CString *add_str, SValue *sv, int modifier)
|
||||
ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
|
||||
{
|
||||
asm_error(S);
|
||||
asm_error();
|
||||
}
|
||||
|
||||
/* generate prolog and epilog code for asm statement */
|
||||
ST_FUNC void asm_gen_code(TCCState *S, ASMOperand *operands, int nb_operands,
|
||||
ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
||||
int nb_outputs, int is_output,
|
||||
uint8_t *clobber_regs,
|
||||
int out_reg)
|
||||
{
|
||||
}
|
||||
|
||||
ST_FUNC void asm_compute_constraints(TCCState *S, ASMOperand *operands,
|
||||
ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
||||
int nb_operands, int nb_outputs,
|
||||
const uint8_t *clobber_regs,
|
||||
int *pout_reg)
|
||||
{
|
||||
}
|
||||
|
||||
ST_FUNC void asm_clobber(TCCState *S, uint8_t *clobber_regs, const char *str)
|
||||
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
||||
{
|
||||
asm_error(S);
|
||||
asm_error();
|
||||
}
|
||||
|
||||
ST_FUNC int asm_parse_regvar (TCCState *S, int t)
|
||||
ST_FUNC int asm_parse_regvar (int t)
|
||||
{
|
||||
asm_error(S);
|
||||
asm_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
280
arm64-gen.c
280
arm64-gen.c
|
@ -107,13 +107,13 @@ static uint32_t fltr(int r)
|
|||
// Add an instruction to text section:
|
||||
ST_FUNC void o(TCCState *S, unsigned int c)
|
||||
{
|
||||
int ind1 = S->ind + 4;
|
||||
if (S->nocode_wanted)
|
||||
int ind1 = S->tccgen_ind + 4;
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
write32le(cur_text_section->data + S->ind, c);
|
||||
S->ind = ind1;
|
||||
write32le(cur_text_section->data + S->tccgen_ind, c);
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
static int arm64_encode_bimm64(uint64_t x)
|
||||
|
@ -452,9 +452,9 @@ static void arm64_strv(TCCState *S, int sz_, int dst, int bas, uint64_t off)
|
|||
|
||||
static void arm64_sym(TCCState *S, int r, Sym *sym, unsigned long addend)
|
||||
{
|
||||
greloca(S, cur_text_section, sym, S->ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
o(S, 0x90000000 | r); // adrp xr, #sym
|
||||
greloca(S, cur_text_section, sym, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
o(S, 0xf9400000 | r | (r << 5)); // ld xr,[xr, #sym]
|
||||
if (addend) {
|
||||
// add xr, xr, #addend
|
||||
|
@ -654,14 +654,14 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv)
|
|||
|
||||
static void arm64_gen_bl_or_b(TCCState *S, int b)
|
||||
{
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->vtop->r & VT_SYM)) {
|
||||
greloca(S, cur_text_section, S->vtop->sym, S->ind,
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
|
||||
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
|
||||
b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
|
||||
o(S, 0x14000000 | (uint32_t)!b << 31); // b/bl .
|
||||
}
|
||||
else {
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
S->vtop->r &= ~VT_MUSTBOUND;
|
||||
S->tccgen_vtop->r &= ~VT_MUSTBOUND;
|
||||
#endif
|
||||
o(S, 0xd61f0000 | (uint32_t)!b << 21 | intr(S, gv(S, RC_R30)) << 5); // br/blr
|
||||
}
|
||||
|
@ -673,7 +673,7 @@ static void gen_bounds_call(TCCState *S, int v)
|
|||
{
|
||||
Sym *sym = external_helper_sym(S, v);
|
||||
|
||||
greloca(S, cur_text_section, sym, S->ind, R_AARCH64_CALL26, 0);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_AARCH64_CALL26, 0);
|
||||
o(S, 0x94000000); // bl
|
||||
}
|
||||
|
||||
|
@ -681,7 +681,7 @@ static void gen_bounds_prolog(TCCState *S)
|
|||
{
|
||||
/* leave some room for bound checking code */
|
||||
S->func_bound_offset = lbounds_section->data_offset;
|
||||
S->func_bound_ind = S->ind;
|
||||
S->func_bound_ind = S->tccgen_ind;
|
||||
S->func_bound_add_epilog = 0;
|
||||
o(S, 0xd503201f); /* nop -> mov x0, lbound section pointer */
|
||||
o(S, 0xd503201f);
|
||||
|
@ -703,27 +703,27 @@ static void gen_bounds_epilog(TCCState *S)
|
|||
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
|
||||
*bounds_ptr = 0;
|
||||
|
||||
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section,
|
||||
sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
|
||||
S->func_bound_offset, lbounds_section->data_offset);
|
||||
|
||||
/* generate bound local allocation */
|
||||
if (offset_modified) {
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->func_bound_ind;
|
||||
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->func_bound_ind;
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
o(S, 0x90000000 | 0); // adrp x0, #sym_data
|
||||
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
|
||||
gen_bounds_call(S, TOK___bound_local_new);
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
/* generate bound check local freeing */
|
||||
o(S, 0xf81f0fe0); /* str x0, [sp, #-16]! */
|
||||
o(S, 0x3c9f0fe0); /* str q0, [sp, #-16]! */
|
||||
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
o(S, 0x90000000 | 0); // adrp x0, #sym_data
|
||||
greloca(S, cur_text_section, sym_data, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
o(S, 0xf9400000 | 0 | (0 << 5)); // ld x0,[x0, #sym_data]
|
||||
gen_bounds_call(S, TOK___bound_local_delete);
|
||||
o(S, 0x3cc107e0); /* ldr q0, [sp], #16 */
|
||||
|
@ -977,7 +977,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
gbound_args(S, nb_args);
|
||||
#endif
|
||||
|
||||
return_type = &S->vtop[-nb_args].type.ref->type;
|
||||
return_type = &S->tccgen_vtop[-nb_args].type.ref->type;
|
||||
if ((return_type->t & VT_BTYPE) == VT_STRUCT)
|
||||
--nb_args;
|
||||
|
||||
|
@ -987,14 +987,14 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
t[0] = return_type;
|
||||
for (i = 0; i < nb_args; i++)
|
||||
t[nb_args - i] = &S->vtop[-i].type;
|
||||
t[nb_args - i] = &S->tccgen_vtop[-i].type;
|
||||
|
||||
stack = arm64_pcs(nb_args, t, a);
|
||||
|
||||
// Allocate space for structs replaced by pointer:
|
||||
for (i = nb_args; i; i--)
|
||||
if (a[i] & 1) {
|
||||
SValue *arg = &S->vtop[i - nb_args];
|
||||
SValue *arg = &S->tccgen_vtop[i - nb_args];
|
||||
int align, size = type_size(&arg->type, &align);
|
||||
assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
|
||||
stack = (stack + align - 1) & -align;
|
||||
|
@ -1005,7 +1005,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
stack = (stack + 15) >> 4 << 4;
|
||||
|
||||
/* fetch cpu flag before generating any code */
|
||||
if ((S->vtop->r & VT_VALMASK) == VT_CMP)
|
||||
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
|
||||
gv(S, RC_INT);
|
||||
|
||||
if (stack >= 0x1000000) // 16Mb
|
||||
|
@ -1017,13 +1017,13 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
// First pass: set all values on stack
|
||||
for (i = nb_args; i; i--) {
|
||||
vpushv(S, S->vtop - nb_args + i);
|
||||
vpushv(S, S->tccgen_vtop - nb_args + i);
|
||||
|
||||
if (a[i] & 1) {
|
||||
// struct replaced by pointer
|
||||
int r = get_reg(S, RC_INT);
|
||||
arm64_spoff(S, intr(S, r), a1[i]);
|
||||
vset(S, &S->vtop->type, r | VT_LVAL, 0);
|
||||
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
|
||||
vswap(S);
|
||||
vstore(S);
|
||||
if (a[i] >= 32) {
|
||||
|
@ -1035,36 +1035,36 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
else if (a[i] >= 32) {
|
||||
// value on stack
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
int r = get_reg(S, RC_INT);
|
||||
arm64_spoff(S, intr(S, r), a[i] - 32);
|
||||
vset(S, &S->vtop->type, r | VT_LVAL, 0);
|
||||
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
|
||||
vswap(S);
|
||||
vstore(S);
|
||||
}
|
||||
else if (is_float(S->vtop->type.t)) {
|
||||
else if (is_float(S->tccgen_vtop->type.t)) {
|
||||
gv(S, RC_FLOAT);
|
||||
arm64_strv(S, arm64_type_size(S->vtop[0].type.t),
|
||||
fltr(S->vtop[0].r), 31, a[i] - 32);
|
||||
arm64_strv(S, arm64_type_size(S->tccgen_vtop[0].type.t),
|
||||
fltr(S->tccgen_vtop[0].r), 31, a[i] - 32);
|
||||
}
|
||||
else {
|
||||
gv(S, RC_INT);
|
||||
arm64_strx(S, arm64_type_size(S->vtop[0].type.t),
|
||||
intr(S, S->vtop[0].r), 31, a[i] - 32);
|
||||
arm64_strx(S, arm64_type_size(S->tccgen_vtop[0].type.t),
|
||||
intr(S, S->tccgen_vtop[0].r), 31, a[i] - 32);
|
||||
}
|
||||
}
|
||||
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
}
|
||||
|
||||
// Second pass: assign values to registers
|
||||
for (i = nb_args; i; i--, S->vtop--) {
|
||||
for (i = nb_args; i; i--, S->tccgen_vtop--) {
|
||||
if (a[i] < 16 && !(a[i] & 1)) {
|
||||
// value in general-purpose registers
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
int align, size = type_size(&S->vtop->type, &align);
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
int align, size = type_size(&S->tccgen_vtop->type, &align);
|
||||
if (size) {
|
||||
S->vtop->type.t = VT_PTR;
|
||||
S->tccgen_vtop->type.t = VT_PTR;
|
||||
gaddrof(S);
|
||||
gv(S, RC_R(a[i] / 2));
|
||||
arm64_ldrs(S, a[i] / 2, size);
|
||||
|
@ -1078,9 +1078,9 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
arm64_spoff(S, a[i] / 2, a1[i]);
|
||||
else if (a[i] < 32) {
|
||||
// value in floating-point registers
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
uint32_t j, sz, n = arm64_hfa(&S->vtop->type, &sz);
|
||||
S->vtop->type.t = VT_PTR;
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
|
||||
S->tccgen_vtop->type.t = VT_PTR;
|
||||
gaddrof(S);
|
||||
gv(S, RC_R30);
|
||||
for (j = 0; j < n; j++)
|
||||
|
@ -1098,7 +1098,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
if (a[0] == 1) {
|
||||
// indirect return: set x8 and discard the stack value
|
||||
gv(S, RC_R(8));
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
}
|
||||
else
|
||||
// return in registers: keep the address for after the call
|
||||
|
@ -1107,7 +1107,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
save_regs(S, 0);
|
||||
arm64_gen_bl_or_b(S, 0);
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
if (stack & 0xfff)
|
||||
o(S, 0x910003ff | (stack & 0xfff) << 10); // add sp,sp,#(n)
|
||||
if (stack >> 12)
|
||||
|
@ -1119,7 +1119,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
if (bt == VT_STRUCT && !(a[0] & 1)) {
|
||||
// A struct was returned in registers, so write it out:
|
||||
gv(S, RC_R(8));
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
if (a[0] == 0) {
|
||||
int align, size = type_size(return_type, &align);
|
||||
assert(size <= 16);
|
||||
|
@ -1220,11 +1220,11 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
tcc_free(S, t);
|
||||
|
||||
o(S, 0x910003fd); // mov x29,sp
|
||||
arm64_func_sub_sp_offset = S->ind;
|
||||
arm64_func_sub_sp_offset = S->tccgen_ind;
|
||||
// In gfunc_epilog these will be replaced with code to decrement SP:
|
||||
o(S, 0xd503201f); // nop
|
||||
o(S, 0xd503201f); // nop
|
||||
S->loc = 0;
|
||||
S->tccgen_loc = 0;
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (S->do_bounds_check)
|
||||
gen_bounds_prolog(S);
|
||||
|
@ -1234,7 +1234,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
ST_FUNC void gen_va_start(TCCState *S)
|
||||
{
|
||||
int r;
|
||||
--S->vtop; // we don't need the "arg"
|
||||
--S->tccgen_vtop; // we don't need the "arg"
|
||||
gaddrof(S);
|
||||
r = intr(S, gv(S, RC_INT));
|
||||
|
||||
|
@ -1264,7 +1264,7 @@ ST_FUNC void gen_va_start(TCCState *S)
|
|||
arm64_movimm(S, 30, arm64_func_va_list_vr_offs);
|
||||
o(S, 0xb9001c1e | r << 5); // str w30,[x(r),#28]
|
||||
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_va_arg(TCCState *S, CType *t)
|
||||
|
@ -1281,7 +1281,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
|
|||
gaddrof(S);
|
||||
r0 = intr(S, gv(S, RC_INT));
|
||||
r1 = get_reg(S, RC_INT);
|
||||
S->vtop[0].r = r1 | VT_LVAL;
|
||||
S->tccgen_vtop[0].r = r1 | VT_LVAL;
|
||||
r1 = intr(S, r1);
|
||||
|
||||
if (!hfa) {
|
||||
|
@ -1310,7 +1310,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
|
|||
uint32_t b1, b2;
|
||||
o(S, 0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
|
||||
o(S, 0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
|
||||
b1 = S->ind; o(S, 0x5400000d); // b.le lab1
|
||||
b1 = S->tccgen_ind; o(S, 0x5400000d); // b.le lab1
|
||||
o(S, 0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
|
||||
if (fsize == 16) {
|
||||
o(S, 0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
|
||||
|
@ -1318,9 +1318,9 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
|
|||
}
|
||||
o(S, 0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
|
||||
o(S, 0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
|
||||
b2 = S->ind; o(S, 0x14000000); // b lab2
|
||||
b2 = S->tccgen_ind; o(S, 0x14000000); // b lab2
|
||||
// lab1:
|
||||
write32le(cur_text_section->data + b1, 0x5400000d | (S->ind - b1) << 3);
|
||||
write32le(cur_text_section->data + b1, 0x5400000d | (S->tccgen_ind - b1) << 3);
|
||||
o(S, 0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
|
||||
o(S, 0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
|
||||
if (hfa == 1 || fsize == 16)
|
||||
|
@ -1328,9 +1328,9 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
|
|||
else {
|
||||
// We need to change the layout of this HFA.
|
||||
// Get some space on the stack using global variable "loc":
|
||||
S->loc = (S->loc - size) & -(uint32_t)align;
|
||||
S->tccgen_loc = (S->tccgen_loc - size) & -(uint32_t)align;
|
||||
o(S, 0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
|
||||
arm64_movimm(S, r1, S->loc);
|
||||
arm64_movimm(S, r1, S->tccgen_loc);
|
||||
o(S, 0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
|
||||
o(S, 0x4c402bdc | (uint32_t)fsize << 7 |
|
||||
(uint32_t)(hfa == 2) << 15 |
|
||||
|
@ -1340,7 +1340,7 @@ ST_FUNC void gen_va_arg(TCCState *S, CType *t)
|
|||
(uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
|
||||
}
|
||||
// lab2:
|
||||
write32le(cur_text_section->data + b2, 0x14000000 | (S->ind - b2) >> 2);
|
||||
write32le(cur_text_section->data + b2, 0x14000000 | (S->tccgen_ind - b2) >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1380,7 +1380,7 @@ ST_FUNC void gfunc_return(TCCState *S, CType *func_type)
|
|||
}
|
||||
case 16:
|
||||
if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
|
||||
uint32_t j, sz, n = arm64_hfa(&S->vtop->type, &sz);
|
||||
uint32_t j, sz, n = arm64_hfa(&S->tccgen_vtop->type, &sz);
|
||||
gaddrof(S);
|
||||
gv(S, RC_R(0));
|
||||
for (j = 0; j < n; j++)
|
||||
|
@ -1394,7 +1394,7 @@ ST_FUNC void gfunc_return(TCCState *S, CType *func_type)
|
|||
default:
|
||||
assert(0);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
ST_FUNC void gfunc_epilog(TCCState *S)
|
||||
|
@ -1404,10 +1404,10 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
gen_bounds_epilog(S);
|
||||
#endif
|
||||
|
||||
if (S->loc) {
|
||||
if (S->tccgen_loc) {
|
||||
// Insert instructions to subtract size of stack frame from SP.
|
||||
unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
|
||||
uint64_t diff = (-S->loc + 15) & ~15;
|
||||
uint64_t diff = (-S->tccgen_loc + 15) & ~15;
|
||||
if (!(diff >> 24)) {
|
||||
if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
|
||||
write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
|
||||
|
@ -1452,8 +1452,8 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
|
|||
// Generate forward branch to label:
|
||||
ST_FUNC int gjmp(TCCState *S, int t)
|
||||
{
|
||||
int r = S->ind;
|
||||
if (S->nocode_wanted)
|
||||
int r = S->tccgen_ind;
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return t;
|
||||
o(S, t);
|
||||
return r;
|
||||
|
@ -1462,8 +1462,8 @@ ST_FUNC int gjmp(TCCState *S, int t)
|
|||
// Generate branch to known address:
|
||||
ST_FUNC void gjmp_addr(TCCState *S, int a)
|
||||
{
|
||||
assert(a - S->ind + 0x8000000 < 0x10000000);
|
||||
o(S, 0x14000000 | ((a - S->ind) >> 2 & 0x3ffffff));
|
||||
assert(a - S->tccgen_ind + 0x8000000 < 0x10000000);
|
||||
o(S, 0x14000000 | ((a - S->tccgen_ind) >> 2 & 0x3ffffff));
|
||||
}
|
||||
|
||||
ST_FUNC int gjmp_append(TCCState *S, int n, int t)
|
||||
|
@ -1483,7 +1483,7 @@ ST_FUNC int gjmp_append(TCCState *S, int n, int t)
|
|||
void arm64_vset_VT_CMP(TCCState *S, int op)
|
||||
{
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
S->vtop->cmp_r = S->vtop->r;
|
||||
S->tccgen_vtop->cmp_r = S->tccgen_vtop->r;
|
||||
vset_VT_CMP(S, 0x80);
|
||||
}
|
||||
}
|
||||
|
@ -1505,16 +1505,16 @@ static void arm64_load_cmp(TCCState *S, int r, SValue *sv)
|
|||
|
||||
ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
|
||||
{
|
||||
int bt = S->vtop->type.t & VT_BTYPE;
|
||||
int bt = S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
|
||||
int inv = op & 1;
|
||||
S->vtop->r = S->vtop->cmp_r;
|
||||
S->tccgen_vtop->r = S->tccgen_vtop->cmp_r;
|
||||
|
||||
if (bt == VT_LDOUBLE) {
|
||||
uint32_t a, b, f = fltr(gv(S, RC_FLOAT));
|
||||
a = get_reg(S, RC_INT);
|
||||
vpushi(S, 0);
|
||||
S->vtop[0].r = a;
|
||||
S->tccgen_vtop[0].r = a;
|
||||
b = get_reg(S, RC_INT);
|
||||
a = intr(S, a);
|
||||
b = intr(S, b);
|
||||
|
@ -1522,7 +1522,7 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
|
|||
o(S, 0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
|
||||
o(S, 0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
|
||||
o(S, 0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
}
|
||||
else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
|
||||
uint32_t a = fltr(gv(S, RC_FLOAT));
|
||||
|
@ -1639,20 +1639,20 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l)
|
|||
uint64_t val;
|
||||
int rev = 1;
|
||||
|
||||
if (arm64_iconst(0, &S->vtop[0])) {
|
||||
if (arm64_iconst(0, &S->tccgen_vtop[0])) {
|
||||
vswap(S);
|
||||
rev = 0;
|
||||
}
|
||||
if (arm64_iconst(&val, &S->vtop[-1])) {
|
||||
if (arm64_iconst(&val, &S->tccgen_vtop[-1])) {
|
||||
gv(S, RC_INT);
|
||||
a = intr(S, S->vtop[0].r);
|
||||
--S->vtop;
|
||||
a = intr(S, S->tccgen_vtop[0].r);
|
||||
--S->tccgen_vtop;
|
||||
x = get_reg(S, RC_INT);
|
||||
++S->vtop;
|
||||
++S->tccgen_vtop;
|
||||
if (arm64_gen_opic(S, op, l, rev, val, intr(S, x), a)) {
|
||||
S->vtop[0].r = x;
|
||||
S->tccgen_vtop[0].r = x;
|
||||
vswap(S);
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1661,13 +1661,13 @@ static void arm64_gen_opil(TCCState *S, int op, uint32_t l)
|
|||
}
|
||||
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
assert(S->vtop[-1].r < VT_CONST && S->vtop[0].r < VT_CONST);
|
||||
a = intr(S, S->vtop[-1].r);
|
||||
b = intr(S, S->vtop[0].r);
|
||||
S->vtop -= 2;
|
||||
assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
|
||||
a = intr(S, S->tccgen_vtop[-1].r);
|
||||
b = intr(S, S->tccgen_vtop[0].r);
|
||||
S->tccgen_vtop -= 2;
|
||||
x = get_reg(S, RC_INT);
|
||||
++S->vtop;
|
||||
S->vtop[0].r = x;
|
||||
++S->tccgen_vtop;
|
||||
S->tccgen_vtop[0].r = x;
|
||||
x = intr(S, x);
|
||||
|
||||
switch (op) {
|
||||
|
@ -1778,8 +1778,8 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
{
|
||||
uint32_t x, a, b, dbl;
|
||||
|
||||
if (S->vtop[0].type.t == VT_LDOUBLE) {
|
||||
CType type = S->vtop[0].type;
|
||||
if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
|
||||
CType type = S->tccgen_vtop[0].type;
|
||||
int func = 0;
|
||||
int cond = -1;
|
||||
switch (op) {
|
||||
|
@ -1799,9 +1799,9 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
vrott(S, 3);
|
||||
gfunc_call(S, 2);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = cond < 0 ? REG_FRET : REG_IRET;
|
||||
S->tccgen_vtop->r = cond < 0 ? REG_FRET : REG_IRET;
|
||||
if (cond < 0)
|
||||
S->vtop->type = type;
|
||||
S->tccgen_vtop->type = type;
|
||||
else {
|
||||
o(S, 0x7100001f); // cmp w0,#0
|
||||
o(S, 0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
|
||||
|
@ -1809,24 +1809,24 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
return;
|
||||
}
|
||||
|
||||
dbl = S->vtop[0].type.t != VT_FLOAT;
|
||||
dbl = S->tccgen_vtop[0].type.t != VT_FLOAT;
|
||||
gv2(S, RC_FLOAT, RC_FLOAT);
|
||||
assert(S->vtop[-1].r < VT_CONST && S->vtop[0].r < VT_CONST);
|
||||
a = fltr(S->vtop[-1].r);
|
||||
b = fltr(S->vtop[0].r);
|
||||
S->vtop -= 2;
|
||||
assert(S->tccgen_vtop[-1].r < VT_CONST && S->tccgen_vtop[0].r < VT_CONST);
|
||||
a = fltr(S->tccgen_vtop[-1].r);
|
||||
b = fltr(S->tccgen_vtop[0].r);
|
||||
S->tccgen_vtop -= 2;
|
||||
switch (op) {
|
||||
case TOK_EQ: case TOK_NE:
|
||||
case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
|
||||
x = get_reg(S, RC_INT);
|
||||
++S->vtop;
|
||||
S->vtop[0].r = x;
|
||||
++S->tccgen_vtop;
|
||||
S->tccgen_vtop[0].r = x;
|
||||
x = intr(S, x);
|
||||
break;
|
||||
default:
|
||||
x = get_reg(S, RC_FLOAT);
|
||||
++S->vtop;
|
||||
S->vtop[0].r = x;
|
||||
++S->tccgen_vtop;
|
||||
S->tccgen_vtop[0].r = x;
|
||||
x = fltr(x);
|
||||
break;
|
||||
}
|
||||
|
@ -1894,7 +1894,7 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
|
|||
ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
||||
{
|
||||
if (t == VT_LDOUBLE) {
|
||||
int f = S->vtop->type.t;
|
||||
int f = S->tccgen_vtop->type.t;
|
||||
int func = (f & VT_BTYPE) == VT_LLONG ?
|
||||
(f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
|
||||
(f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
|
||||
|
@ -1902,18 +1902,18 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
vrott(S, 2);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->type.t = t;
|
||||
S->vtop->r = REG_FRET;
|
||||
S->tccgen_vtop->type.t = t;
|
||||
S->tccgen_vtop->r = REG_FRET;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
int d, n = intr(S, gv(S, RC_INT));
|
||||
int s = !(S->vtop->type.t & VT_UNSIGNED);
|
||||
uint32_t l = ((S->vtop->type.t & VT_BTYPE) == VT_LLONG);
|
||||
--S->vtop;
|
||||
int s = !(S->tccgen_vtop->type.t & VT_UNSIGNED);
|
||||
uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG);
|
||||
--S->tccgen_vtop;
|
||||
d = get_reg(S, RC_FLOAT);
|
||||
++S->vtop;
|
||||
S->vtop[0].r = d;
|
||||
++S->tccgen_vtop;
|
||||
S->tccgen_vtop[0].r = d;
|
||||
o(S, 0x1e220000 | (uint32_t)!s << 16 |
|
||||
(uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
|
||||
l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
|
||||
|
@ -1922,7 +1922,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
|
||||
ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
|
||||
{
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
int func = (t & VT_BTYPE) == VT_LLONG ?
|
||||
(t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
|
||||
(t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
|
||||
|
@ -1930,17 +1930,17 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
|
|||
vrott(S, 2);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->type.t = t;
|
||||
S->vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->type.t = t;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
int d, n = fltr(gv(S, RC_FLOAT));
|
||||
uint32_t l = ((S->vtop->type.t & VT_BTYPE) != VT_FLOAT);
|
||||
--S->vtop;
|
||||
uint32_t l = ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT);
|
||||
--S->tccgen_vtop;
|
||||
d = get_reg(S, RC_INT);
|
||||
++S->vtop;
|
||||
S->vtop[0].r = d;
|
||||
++S->tccgen_vtop;
|
||||
S->tccgen_vtop[0].r = d;
|
||||
o(S, 0x1e380000 |
|
||||
(uint32_t)!!(t & VT_UNSIGNED) << 16 |
|
||||
(uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(S, d) |
|
||||
|
@ -1950,7 +1950,7 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
|
|||
|
||||
ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
|
||||
{
|
||||
int f = S->vtop[0].type.t & VT_BTYPE;
|
||||
int f = S->tccgen_vtop[0].type.t & VT_BTYPE;
|
||||
assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
|
||||
assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
|
||||
if (t == f)
|
||||
|
@ -1964,18 +1964,18 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int t)
|
|||
vrott(S, 2);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->type.t = t;
|
||||
S->vtop->r = REG_FRET;
|
||||
S->tccgen_vtop->type.t = t;
|
||||
S->tccgen_vtop->r = REG_FRET;
|
||||
}
|
||||
else {
|
||||
int x, a;
|
||||
gv(S, RC_FLOAT);
|
||||
assert(S->vtop[0].r < VT_CONST);
|
||||
a = fltr(S->vtop[0].r);
|
||||
--S->vtop;
|
||||
assert(S->tccgen_vtop[0].r < VT_CONST);
|
||||
a = fltr(S->tccgen_vtop[0].r);
|
||||
--S->tccgen_vtop;
|
||||
x = get_reg(S, RC_FLOAT);
|
||||
++S->vtop;
|
||||
S->vtop[0].r = x;
|
||||
++S->tccgen_vtop;
|
||||
S->tccgen_vtop[0].r = x;
|
||||
x = fltr(x);
|
||||
|
||||
if (f == VT_FLOAT)
|
||||
|
@ -1991,11 +1991,11 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
int r1, r2;
|
||||
|
||||
vpushv(S, sv);
|
||||
S->vtop->r = r1 = get_reg(S, RC_INT);
|
||||
S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
|
||||
r2 = get_reg(S, RC_INT);
|
||||
greloca(S, cur_text_section, sv->sym, S->ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||
o(S, 0x90000000 | r1); // adrp r1, #sym
|
||||
greloca(S, cur_text_section, sv->sym, S->ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||
o(S, 0xf9400000 | r1 | (r1 << 5)); // ld xr,[xr, #sym]
|
||||
o(S, 0xf9400000 | (intr(S, r1)<<5) | intr(S, r2)); // ldr r2, [r1]
|
||||
o(S, 0x91000400 | (intr(S, r2)<<5) | intr(S, r2)); // add r2, r2, #1
|
||||
|
@ -2006,7 +2006,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
ST_FUNC void ggoto(TCCState *S)
|
||||
{
|
||||
arm64_gen_bl_or_b(S, 1);
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_clear_cache(TCCState *S)
|
||||
|
@ -2014,17 +2014,17 @@ ST_FUNC void gen_clear_cache(TCCState *S)
|
|||
uint32_t beg, end, dsz, isz, p, lab1, b1;
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = get_reg(S, RC_INT);
|
||||
S->tccgen_vtop->r = get_reg(S, RC_INT);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = get_reg(S, RC_INT);
|
||||
S->tccgen_vtop->r = get_reg(S, RC_INT);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = get_reg(S, RC_INT);
|
||||
beg = intr(S, S->vtop[-4].r); // x0
|
||||
end = intr(S, S->vtop[-3].r); // x1
|
||||
dsz = intr(S, S->vtop[-2].r); // x2
|
||||
isz = intr(S, S->vtop[-1].r); // x3
|
||||
p = intr(S, S->vtop[0].r); // x4
|
||||
S->vtop -= 5;
|
||||
S->tccgen_vtop->r = get_reg(S, RC_INT);
|
||||
beg = intr(S, S->tccgen_vtop[-4].r); // x0
|
||||
end = intr(S, S->tccgen_vtop[-3].r); // x1
|
||||
dsz = intr(S, S->tccgen_vtop[-2].r); // x2
|
||||
isz = intr(S, S->tccgen_vtop[-1].r); // x3
|
||||
p = intr(S, S->tccgen_vtop[0].r); // x4
|
||||
S->tccgen_vtop -= 5;
|
||||
|
||||
o(S, 0xd53b0020 | isz); // mrs x(isz),ctr_el0
|
||||
o(S, 0x52800080 | p); // mov w(p),#4
|
||||
|
@ -2034,23 +2034,23 @@ ST_FUNC void gen_clear_cache(TCCState *S)
|
|||
o(S, 0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
|
||||
o(S, 0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
|
||||
o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
|
||||
b1 = S->ind; o(S, 0x14000000); // b
|
||||
lab1 = S->ind;
|
||||
b1 = S->tccgen_ind; o(S, 0x14000000); // b
|
||||
lab1 = S->tccgen_ind;
|
||||
o(S, 0xd50b7b20 | p); // dc cvau,x(p)
|
||||
o(S, 0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
|
||||
write32le(cur_text_section->data + b1, 0x14000000 | (S->ind - b1) >> 2);
|
||||
write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);
|
||||
o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
|
||||
o(S, 0x54ffffa3 | ((lab1 - S->ind) << 3 & 0xffffe0)); // b.cc lab1
|
||||
o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1
|
||||
o(S, 0xd5033b9f); // dsb ish
|
||||
o(S, 0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
|
||||
o(S, 0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
|
||||
b1 = S->ind; o(S, 0x14000000); // b
|
||||
lab1 = S->ind;
|
||||
b1 = S->tccgen_ind; o(S, 0x14000000); // b
|
||||
lab1 = S->tccgen_ind;
|
||||
o(S, 0xd50b7520 | p); // ic ivau,x(p)
|
||||
o(S, 0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
|
||||
write32le(cur_text_section->data + b1, 0x14000000 | (S->ind - b1) >> 2);
|
||||
write32le(cur_text_section->data + b1, 0x14000000 | (S->tccgen_ind - b1) >> 2);
|
||||
o(S, 0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
|
||||
o(S, 0x54ffffa3 | ((lab1 - S->ind) << 3 & 0xffffe0)); // b.cc lab1
|
||||
o(S, 0x54ffffa3 | ((lab1 - S->tccgen_ind) << 3 & 0xffffe0)); // b.cc lab1
|
||||
o(S, 0xd5033b9f); // dsb ish
|
||||
o(S, 0xd5033fdf); // isb
|
||||
}
|
||||
|
@ -2074,7 +2074,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
|
|||
uint32_t r;
|
||||
#if defined(CONFIG_TCC_BCHECK)
|
||||
if (S->do_bounds_check)
|
||||
vpushv(S, S->vtop);
|
||||
vpushv(S, S->tccgen_vtop);
|
||||
#endif
|
||||
r = intr(S, gv(S, RC_INT));
|
||||
#if defined(CONFIG_TCC_BCHECK)
|
||||
|
@ -2089,8 +2089,8 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align) {
|
|||
#if defined(CONFIG_TCC_BCHECK)
|
||||
if (S->do_bounds_check) {
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = TREG_R(0);
|
||||
o(S, 0x910003e0 | S->vtop->r); // mov r0,sp
|
||||
S->tccgen_vtop->r = TREG_R(0);
|
||||
o(S, 0x910003e0 | S->tccgen_vtop->r); // mov r0,sp
|
||||
vswap(S);
|
||||
vpush_helper_func(S, TOK___bound_new_region);
|
||||
vrott(S, 3);
|
||||
|
|
178
c67-gen.c
178
c67-gen.c
|
@ -189,19 +189,19 @@ FILE *f = NULL;
|
|||
void C67_g(TCCState* S, int c)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
#ifdef ASSEMBLY_LISTING_C67
|
||||
fprintf(f, " %08X", c);
|
||||
#endif
|
||||
ind1 = S->ind + 4;
|
||||
ind1 = S->tccgen_ind + 4;
|
||||
if (ind1 > (int) cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind] = c & 0xff;
|
||||
cur_text_section->data[S->ind + 1] = (c >> 8) & 0xff;
|
||||
cur_text_section->data[S->ind + 2] = (c >> 16) & 0xff;
|
||||
cur_text_section->data[S->ind + 3] = (c >> 24) & 0xff;
|
||||
S->ind = ind1;
|
||||
cur_text_section->data[S->tccgen_ind] = c & 0xff;
|
||||
cur_text_section->data[S->tccgen_ind + 1] = (c >> 8) & 0xff;
|
||||
cur_text_section->data[S->tccgen_ind + 2] = (c >> 16) & 0xff;
|
||||
cur_text_section->data[S->tccgen_ind + 3] = (c >> 24) & 0xff;
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,7 +220,7 @@ void gsym_addr(TCCState *S, int t, int a)
|
|||
|
||||
// define a label that will be relocated
|
||||
|
||||
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, a, 0);
|
||||
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);
|
||||
greloc(S, cur_text_section, sym, t, R_C60LO16);
|
||||
greloc(S, cur_text_section, sym, t + 4, R_C60HI16);
|
||||
|
||||
|
@ -1395,7 +1395,7 @@ void C67_B_DISP(TCCState *S, int disp) // B +2 Branch with constant displacem
|
|||
// so add in how many words into the fetch packet the branch is
|
||||
|
||||
|
||||
C67_asm(S, "B DISP", disp + ((S->ind & 31) >> 2), 0, 0);
|
||||
C67_asm(S, "B DISP", disp + ((S->tccgen_ind & 31) >> 2), 0, 0);
|
||||
}
|
||||
|
||||
void C67_NOP(TCCState* S, int n)
|
||||
|
@ -1625,8 +1625,8 @@ void load(TCCState *S, int r, SValue * sv)
|
|||
C67_NOP(S, 4); // NOP 4
|
||||
return;
|
||||
} else if (fr & VT_SYM) {
|
||||
greloc(S, cur_text_section, sv->sym, S->ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sv->sym, S->ind + 4, R_C60HI16);
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
|
||||
|
||||
C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
|
||||
|
@ -1681,8 +1681,8 @@ void load(TCCState *S, int r, SValue * sv)
|
|||
} else {
|
||||
if (v == VT_CONST) {
|
||||
if (fr & VT_SYM) {
|
||||
greloc(S, cur_text_section, sv->sym, S->ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sv->sym, S->ind + 4, R_C60HI16);
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
}
|
||||
C67_MVKL(S, r, fc); //r=reg to load, constant
|
||||
C67_MVKH(S, r, fc); //r=reg to load, constant
|
||||
|
@ -1736,8 +1736,8 @@ void store(TCCState *S, int r, SValue * v)
|
|||
/* constant memory reference */
|
||||
|
||||
if (v->r & VT_SYM) {
|
||||
greloc(S, cur_text_section, v->sym, S->ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, v->sym, S->ind + 4, R_C60HI16);
|
||||
greloc(S, cur_text_section, v->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, v->sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
}
|
||||
C67_MVKL(S, C67_A0, fc); //r=reg to load, constant
|
||||
C67_MVKH(S, C67_A0, fc); //r=reg to load, constant
|
||||
|
@ -1818,15 +1818,15 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
|
|||
int r;
|
||||
Sym *sym;
|
||||
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
/* constant case */
|
||||
if (S->vtop->r & VT_SYM) {
|
||||
if (S->tccgen_vtop->r & VT_SYM) {
|
||||
/* relocation case */
|
||||
|
||||
// get add into A0, then start the jump B3
|
||||
|
||||
greloc(S, cur_text_section, S->vtop->sym, S->ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, S->vtop->sym, S->ind + 4, R_C60HI16);
|
||||
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
|
||||
C67_MVKL(S, C67_A0, 0); //r=reg to load, constant
|
||||
C67_MVKH(S, C67_A0, 0); //r=reg to load, constant
|
||||
|
@ -1837,9 +1837,9 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
|
|||
} else {
|
||||
// Call, must load return address into B3 during delay slots
|
||||
|
||||
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, S->ind + 12, 0); // symbol for return address
|
||||
greloc(S, cur_text_section, sym, S->ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16);
|
||||
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
|
||||
C67_MVKH(S, C67_B3, 0); //r=reg to load, constant
|
||||
C67_NOP(S, 3); // put remaining NOPs
|
||||
|
@ -1858,9 +1858,9 @@ static void gcall_or_jmp(TCCState *S, int is_jmp)
|
|||
} else {
|
||||
// Call, must load return address into B3 during delay slots
|
||||
|
||||
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, S->ind + 12, 0); // symbol for return address
|
||||
greloc(S, cur_text_section, sym, S->ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16);
|
||||
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, S->tccgen_ind + 12, 0); // symbol for return address
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16); // rem the inst need to be patched
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
C67_MVKL(S, C67_B3, 0); //r=reg to load, constant
|
||||
C67_MVKH(S, C67_B3, 0); //r=reg to load, constant
|
||||
C67_NOP(S, 3); // put remaining NOPs
|
||||
|
@ -1888,18 +1888,18 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
|
||||
for (i = 0; i < nb_args; i++) {
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
ALWAYS_ASSERT(FALSE);
|
||||
} else {
|
||||
/* simple type (currently always same size) */
|
||||
/* XXX: implicit cast ? */
|
||||
|
||||
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
tcc_error(S, "long long not supported");
|
||||
} else if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
} else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
tcc_error(S, "long double not supported");
|
||||
} else if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
|
||||
} else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
|
||||
size = 8;
|
||||
} else {
|
||||
size = 4;
|
||||
|
@ -1919,7 +1919,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
args_sizes[i] = size;
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
// POP all the params on the stack into registers for the
|
||||
// immediate call (in reverse order)
|
||||
|
@ -1932,7 +1932,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
C67_POP(S, TREG_C67_A4 + i * 2);
|
||||
}
|
||||
gcall_or_jmp(S, 0);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1997,11 +1997,11 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
|
||||
// place all the args passed in regs onto the stack
|
||||
|
||||
S->loc = 0;
|
||||
S->tccgen_loc = 0;
|
||||
for (i = 0; i < NoOfCurFuncArgs; i++) {
|
||||
|
||||
ParamLocOnStack[i] = S->loc; // remember where the param is
|
||||
S->loc += -8;
|
||||
ParamLocOnStack[i] = S->tccgen_loc; // remember where the param is
|
||||
S->tccgen_loc += -8;
|
||||
|
||||
C67_PUSH(S, TREG_C67_A4 + i * 2);
|
||||
|
||||
|
@ -2010,9 +2010,9 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
}
|
||||
}
|
||||
|
||||
TotalBytesPushedOnStack = -S->loc;
|
||||
TotalBytesPushedOnStack = -S->tccgen_loc;
|
||||
|
||||
func_sub_sp_offset = S->ind; // remember where we put the stack instruction
|
||||
func_sub_sp_offset = S->tccgen_ind; // remember where we put the stack instruction
|
||||
C67_ADDK(S, 0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
|
||||
|
||||
C67_PUSH(S, C67_A0);
|
||||
|
@ -2023,7 +2023,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
void gfunc_epilog(TCCState* S)
|
||||
{
|
||||
{
|
||||
int local = (-S->loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
|
||||
int local = (-S->tccgen_loc + 7) & -8; // stack must stay aligned to 8 bytes for LDDW instr
|
||||
C67_POP(S, C67_B3);
|
||||
C67_NOP(S, 4); // NOP wait for load
|
||||
C67_IREG_B_REG(S, 0, C67_CREG_ZERO, C67_B3); // B.S2 B3
|
||||
|
@ -2049,8 +2049,8 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
|
|||
/* generate a jump to a label */
|
||||
int gjmp(TCCState* S, int t)
|
||||
{
|
||||
int ind1 = S->ind;
|
||||
if (S->nocode_wanted)
|
||||
int ind1 = S->tccgen_ind;
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return t;
|
||||
|
||||
C67_MVKL(S, C67_A0, t); //r=reg to load, constant
|
||||
|
@ -2070,9 +2070,9 @@ void gjmp_addr(TCCState *S, int a)
|
|||
|
||||
// define a label that will be relocated
|
||||
|
||||
sym = get_sym_ref(S, &S->char_pointer_type, cur_text_section, a, 0);
|
||||
greloc(S, cur_text_section, sym, S->ind, R_C60LO16);
|
||||
greloc(S, cur_text_section, sym, S->ind + 4, R_C60HI16);
|
||||
sym = get_sym_ref(S, &S->tccgen_char_pointer_type, cur_text_section, a, 0);
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind, R_C60LO16);
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind + 4, R_C60HI16);
|
||||
|
||||
gjmp(S, 0); // place a zero there later the symbol will be added to it
|
||||
}
|
||||
|
@ -2082,12 +2082,12 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
|
|||
{
|
||||
int ind1;
|
||||
int inv = op & 1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return t;
|
||||
|
||||
/* fast case : can jump directly since flags are set */
|
||||
// C67 uses B2 sort of as flags register
|
||||
ind1 = S->ind;
|
||||
ind1 = S->tccgen_ind;
|
||||
C67_MVKL(S, C67_A0, t); //r=reg to load, constant
|
||||
C67_MVKH(S, C67_A0, t); //r=reg to load, constant
|
||||
|
||||
|
@ -2150,8 +2150,8 @@ void gen_opi(TCCState *S, int op)
|
|||
else
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
|
||||
C67_compare_reg = C67_B2;
|
||||
|
||||
|
@ -2199,7 +2199,7 @@ void gen_opi(TCCState *S, int op)
|
|||
else
|
||||
ALWAYS_ASSERT(FALSE);
|
||||
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
if (op >= TOK_ULT && op <= TOK_GT)
|
||||
vset_VT_CMP(S, 0x80);
|
||||
break;
|
||||
|
@ -2225,33 +2225,33 @@ void gen_opi(TCCState *S, int op)
|
|||
case '*':
|
||||
case TOK_UMULL:
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
C67_MPYI(S, fr, r); // 32 bit multiply fr,r,fr
|
||||
C67_NOP(S, 8); // NOP 8 for worst case
|
||||
break;
|
||||
case TOK_SHL:
|
||||
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
C67_SHL(S, fr, r); // arithmetic/logical shift
|
||||
break;
|
||||
|
||||
case TOK_SHR:
|
||||
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
C67_SHRU(S, fr, r); // logical shift
|
||||
break;
|
||||
|
||||
case TOK_SAR:
|
||||
gv2(S, RC_INT_BSIDE, RC_INT_BSIDE); // shift amount must be on same side as dst
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
C67_SHR(S, fr, r); // arithmetic shift
|
||||
break;
|
||||
|
||||
|
@ -2264,8 +2264,8 @@ void gen_opi(TCCState *S, int op)
|
|||
vrott(S, 3);
|
||||
gfunc_call(S, 2);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = REG_IRET;
|
||||
S->vtop->r2 = VT_CONST;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->r2 = VT_CONST;
|
||||
break;
|
||||
case TOK_UDIV:
|
||||
case TOK_PDIV:
|
||||
|
@ -2296,10 +2296,10 @@ void gen_opf(TCCState *S, int op)
|
|||
else
|
||||
gv2(S, RC_FLOAT, RC_FLOAT); // make sure src2 is on b side
|
||||
|
||||
ft = S->vtop->type.t;
|
||||
fc = S->vtop->c.i;
|
||||
r = S->vtop->r;
|
||||
fr = S->vtop[-1].r;
|
||||
ft = S->tccgen_vtop->type.t;
|
||||
fc = S->tccgen_vtop->c.i;
|
||||
r = S->tccgen_vtop->r;
|
||||
fr = S->tccgen_vtop[-1].r;
|
||||
|
||||
|
||||
if ((ft & VT_BTYPE) == VT_LDOUBLE)
|
||||
|
@ -2307,8 +2307,8 @@ void gen_opf(TCCState *S, int op)
|
|||
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
|
||||
C67_compare_reg = C67_B2;
|
||||
|
||||
|
@ -2367,7 +2367,7 @@ void gen_opf(TCCState *S, int op)
|
|||
C67_ADDSP(S, r, fr); // ADD fr,r,fr
|
||||
C67_NOP(S, 3);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
} else if (op == '-') {
|
||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||
C67_SUBDP(S, r, fr); // SUB fr,r,fr
|
||||
|
@ -2376,7 +2376,7 @@ void gen_opf(TCCState *S, int op)
|
|||
C67_SUBSP(S, r, fr); // SUB fr,r,fr
|
||||
C67_NOP(S, 3);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
} else if (op == '*') {
|
||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||
C67_MPYDP(S, r, fr); // MPY fr,r,fr
|
||||
|
@ -2385,7 +2385,7 @@ void gen_opf(TCCState *S, int op)
|
|||
C67_MPYSP(S, r, fr); // MPY fr,r,fr
|
||||
C67_NOP(S, 3);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
} else if (op == '/') {
|
||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||
// must call intrinsic DP floating point divide
|
||||
|
@ -2395,8 +2395,8 @@ void gen_opf(TCCState *S, int op)
|
|||
vrott(S, 3);
|
||||
gfunc_call(S, 2);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = REG_FRET;
|
||||
S->vtop->r2 = REG_IRE2;
|
||||
S->tccgen_vtop->r = REG_FRET;
|
||||
S->tccgen_vtop->r2 = REG_IRE2;
|
||||
|
||||
} else {
|
||||
// must call intrinsic SP floating point divide
|
||||
|
@ -2406,8 +2406,8 @@ void gen_opf(TCCState *S, int op)
|
|||
vrott(S, 3);
|
||||
gfunc_call(S, 2);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = REG_FRET;
|
||||
S->vtop->r2 = VT_CONST;
|
||||
S->tccgen_vtop->r = REG_FRET;
|
||||
S->tccgen_vtop->r2 = VT_CONST;
|
||||
}
|
||||
} else
|
||||
ALWAYS_ASSERT(FALSE);
|
||||
|
@ -2424,7 +2424,7 @@ void gen_cvt_itof(TCCState *S, int t)
|
|||
int r;
|
||||
|
||||
gv(S, RC_INT);
|
||||
r = S->vtop->r;
|
||||
r = S->tccgen_vtop->r;
|
||||
|
||||
if ((t & VT_BTYPE) == VT_DOUBLE) {
|
||||
if (t & VT_UNSIGNED)
|
||||
|
@ -2433,14 +2433,14 @@ void gen_cvt_itof(TCCState *S, int t)
|
|||
C67_INTDP(S, r, r);
|
||||
|
||||
C67_NOP(S, 4);
|
||||
S->vtop->type.t = VT_DOUBLE;
|
||||
S->tccgen_vtop->type.t = VT_DOUBLE;
|
||||
} else {
|
||||
if (t & VT_UNSIGNED)
|
||||
C67_INTSPU(S, r, r);
|
||||
else
|
||||
C67_INTSP(S, r, r);
|
||||
C67_NOP(S, 3);
|
||||
S->vtop->type.t = VT_FLOAT;
|
||||
S->tccgen_vtop->type.t = VT_FLOAT;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2452,12 +2452,12 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
int r;
|
||||
|
||||
gv(S, RC_FLOAT);
|
||||
r = S->vtop->r;
|
||||
r = S->tccgen_vtop->r;
|
||||
|
||||
if (t != VT_INT)
|
||||
tcc_error(S, "long long not supported");
|
||||
else {
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
|
||||
C67_DPTRUNC(S, r, r);
|
||||
C67_NOP(S, 3);
|
||||
} else {
|
||||
|
@ -2465,7 +2465,7 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
C67_NOP(S, 3);
|
||||
}
|
||||
|
||||
S->vtop->type.t = VT_INT;
|
||||
S->tccgen_vtop->type.t = VT_INT;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2475,26 +2475,26 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
{
|
||||
int r, r2;
|
||||
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
|
||||
(t & VT_BTYPE) == VT_FLOAT) {
|
||||
// convert double to float
|
||||
|
||||
gv(S, RC_FLOAT); // get it in a register pair
|
||||
|
||||
r = S->vtop->r;
|
||||
r = S->tccgen_vtop->r;
|
||||
|
||||
C67_DPSP(S, r, r); // convert it to SP same register
|
||||
C67_NOP(S, 3);
|
||||
|
||||
S->vtop->type.t = VT_FLOAT;
|
||||
S->vtop->r2 = VT_CONST; // set this as unused
|
||||
} else if ((S->vtop->type.t & VT_BTYPE) == VT_FLOAT &&
|
||||
S->tccgen_vtop->type.t = VT_FLOAT;
|
||||
S->tccgen_vtop->r2 = VT_CONST; // set this as unused
|
||||
} else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT &&
|
||||
(t & VT_BTYPE) == VT_DOUBLE) {
|
||||
// convert float to double
|
||||
|
||||
gv(S, RC_FLOAT); // get it in a register
|
||||
|
||||
r = S->vtop->r;
|
||||
r = S->tccgen_vtop->r;
|
||||
|
||||
if (r == TREG_EAX) { // make sure the paired reg is avail
|
||||
r2 = get_reg(S, RC_ECX);
|
||||
|
@ -2508,8 +2508,8 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
C67_SPDP(S, r, r); // convert it to DP same register
|
||||
C67_NOP(S, 1);
|
||||
|
||||
S->vtop->type.t = VT_DOUBLE;
|
||||
S->vtop->r2 = r2; // set this as unused
|
||||
S->tccgen_vtop->type.t = VT_DOUBLE;
|
||||
S->tccgen_vtop->r2 = r2; // set this as unused
|
||||
} else {
|
||||
ALWAYS_ASSERT(FALSE);
|
||||
}
|
||||
|
@ -2519,7 +2519,7 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
void ggoto(TCCState* S)
|
||||
{
|
||||
gcall_or_jmp(S, 1);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
/* Save the stack pointer onto the stack and return the location of its address */
|
||||
|
|
80
i386-asm.c
80
i386-asm.c
|
@ -282,7 +282,7 @@ static inline int get_reg_shift(TCCState *S)
|
|||
static int asm_parse_numeric_reg(TCCState *S, int t, unsigned int *type)
|
||||
{
|
||||
int reg = -1;
|
||||
if (t >= TOK_IDENT && t < S->tok_ident) {
|
||||
if (t >= TOK_IDENT && t < S->tccpp_tok_ident) {
|
||||
const char *s = S->tccpp_table_ident[t - TOK_IDENT]->str;
|
||||
char c;
|
||||
*type = OP_REG64;
|
||||
|
@ -322,20 +322,20 @@ static int asm_parse_reg(TCCState *S, unsigned int *type)
|
|||
{
|
||||
int reg = 0;
|
||||
*type = 0;
|
||||
if (S->tok != '%')
|
||||
if (S->tccpp_tok != '%')
|
||||
goto error_32;
|
||||
next(S);
|
||||
if (S->tok >= TOK_ASM_eax && S->tok <= TOK_ASM_edi) {
|
||||
reg = S->tok - TOK_ASM_eax;
|
||||
if (S->tccpp_tok >= TOK_ASM_eax && S->tccpp_tok <= TOK_ASM_edi) {
|
||||
reg = S->tccpp_tok - TOK_ASM_eax;
|
||||
*type = OP_REG32;
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
} else if (S->tok >= TOK_ASM_rax && S->tok <= TOK_ASM_rdi) {
|
||||
reg = S->tok - TOK_ASM_rax;
|
||||
} else if (S->tccpp_tok >= TOK_ASM_rax && S->tccpp_tok <= TOK_ASM_rdi) {
|
||||
reg = S->tccpp_tok - TOK_ASM_rax;
|
||||
*type = OP_REG64;
|
||||
} else if (S->tok == TOK_ASM_rip) {
|
||||
} else if (S->tccpp_tok == TOK_ASM_rip) {
|
||||
reg = -2; /* Probably should use different escape code. */
|
||||
*type = OP_REG64;
|
||||
} else if ((reg = asm_parse_numeric_reg(S, S->tok, type)) >= 0
|
||||
} else if ((reg = asm_parse_numeric_reg(S, S->tccpp_tok, type)) >= 0
|
||||
&& (*type == OP_REG32 || *type == OP_REG64)) {
|
||||
;
|
||||
#endif
|
||||
|
@ -354,15 +354,15 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
const char *p;
|
||||
|
||||
indir = 0;
|
||||
if (S->tok == '*') {
|
||||
if (S->tccpp_tok == '*') {
|
||||
next(S);
|
||||
indir = OP_INDIR;
|
||||
}
|
||||
|
||||
if (S->tok == '%') {
|
||||
if (S->tccpp_tok == '%') {
|
||||
next(S);
|
||||
if (S->tok >= TOK_ASM_al && S->tok <= TOK_ASM_db7) {
|
||||
reg = S->tok - TOK_ASM_al;
|
||||
if (S->tccpp_tok >= TOK_ASM_al && S->tccpp_tok <= TOK_ASM_db7) {
|
||||
reg = S->tccpp_tok - TOK_ASM_al;
|
||||
op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
|
||||
op->reg = reg & 7;
|
||||
if ((op->type & OP_REG) && op->reg == TREG_XAX)
|
||||
|
@ -371,21 +371,21 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
op->type |= OP_CL;
|
||||
else if (op->type == OP_REG16 && op->reg == TREG_XDX)
|
||||
op->type |= OP_DX;
|
||||
} else if (S->tok >= TOK_ASM_dr0 && S->tok <= TOK_ASM_dr7) {
|
||||
} else if (S->tccpp_tok >= TOK_ASM_dr0 && S->tccpp_tok <= TOK_ASM_dr7) {
|
||||
op->type = OP_DB;
|
||||
op->reg = S->tok - TOK_ASM_dr0;
|
||||
} else if (S->tok >= TOK_ASM_es && S->tok <= TOK_ASM_gs) {
|
||||
op->reg = S->tccpp_tok - TOK_ASM_dr0;
|
||||
} else if (S->tccpp_tok >= TOK_ASM_es && S->tccpp_tok <= TOK_ASM_gs) {
|
||||
op->type = OP_SEG;
|
||||
op->reg = S->tok - TOK_ASM_es;
|
||||
} else if (S->tok == TOK_ASM_st) {
|
||||
op->reg = S->tccpp_tok - TOK_ASM_es;
|
||||
} else if (S->tccpp_tok == TOK_ASM_st) {
|
||||
op->type = OP_ST;
|
||||
op->reg = 0;
|
||||
next(S);
|
||||
if (S->tok == '(') {
|
||||
if (S->tccpp_tok == '(') {
|
||||
next(S);
|
||||
if (S->tok != TOK_PPNUM)
|
||||
if (S->tccpp_tok != TOK_PPNUM)
|
||||
goto reg_error;
|
||||
p = S->tokc.str.data;
|
||||
p = S->tccpp_tokc.str.data;
|
||||
reg = p[0] - '0';
|
||||
if ((unsigned)reg >= 8 || p[1] != '\0')
|
||||
goto reg_error;
|
||||
|
@ -397,19 +397,19 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
op->type |= OP_ST0;
|
||||
goto no_skip;
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
} else if (S->tok >= TOK_ASM_spl && S->tok <= TOK_ASM_dil) {
|
||||
} else if (S->tccpp_tok >= TOK_ASM_spl && S->tccpp_tok <= TOK_ASM_dil) {
|
||||
op->type = OP_REG8 | OP_REG8_LOW;
|
||||
op->reg = 4 + S->tok - TOK_ASM_spl;
|
||||
} else if ((op->reg = asm_parse_numeric_reg(S, S->tok, &op->type)) >= 0) {
|
||||
op->reg = 4 + S->tccpp_tok - TOK_ASM_spl;
|
||||
} else if ((op->reg = asm_parse_numeric_reg(S, S->tccpp_tok, &op->type)) >= 0) {
|
||||
;
|
||||
#endif
|
||||
} else {
|
||||
reg_error:
|
||||
tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tok, &S->tokc));
|
||||
tcc_error(S, "unknown register %%%s", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
|
||||
}
|
||||
next(S);
|
||||
no_skip: ;
|
||||
} else if (S->tok == '$') {
|
||||
} else if (S->tccpp_tok == '$') {
|
||||
/* constant value */
|
||||
next(S);
|
||||
asm_expr(S, &e);
|
||||
|
@ -433,19 +433,19 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
op->reg = -1;
|
||||
op->reg2 = -1;
|
||||
op->shift = 0;
|
||||
if (S->tok != '(') {
|
||||
if (S->tccpp_tok != '(') {
|
||||
asm_expr(S, &e);
|
||||
op->e = e;
|
||||
} else {
|
||||
next(S);
|
||||
if (S->tok == '%') {
|
||||
if (S->tccpp_tok == '%') {
|
||||
unget_tok(S, '(');
|
||||
op->e.v = 0;
|
||||
op->e.sym = NULL;
|
||||
} else {
|
||||
/* bracketed offset expression */
|
||||
asm_expr(S, &e);
|
||||
if (S->tok != ')')
|
||||
if (S->tccpp_tok != ')')
|
||||
expect(S, ")");
|
||||
next(S);
|
||||
op->e.v = e.v;
|
||||
|
@ -453,18 +453,18 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
}
|
||||
op->e.pcrel = 0;
|
||||
}
|
||||
if (S->tok == '(') {
|
||||
if (S->tccpp_tok == '(') {
|
||||
unsigned int type = 0;
|
||||
next(S);
|
||||
if (S->tok != ',') {
|
||||
if (S->tccpp_tok != ',') {
|
||||
op->reg = asm_parse_reg(S, &type);
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
if (S->tok != ',') {
|
||||
if (S->tccpp_tok != ',') {
|
||||
op->reg2 = asm_parse_reg(S, &type);
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
op->shift = get_reg_shift(S);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ static void gen_disp32(TCCState *S, ExprValue *pe)
|
|||
that the TCC compiler behaves differently here because
|
||||
it always outputs a relocation to ease (future) code
|
||||
elimination in the linker */
|
||||
gen_le32(S, pe->v + esym->st_value - S->ind - 4);
|
||||
gen_le32(S, pe->v + esym->st_value - S->tccgen_ind - 4);
|
||||
} else {
|
||||
if (sym && sym->type.t == VT_VOID) {
|
||||
sym->type.t = VT_FUNC;
|
||||
|
@ -538,7 +538,7 @@ static inline int asm_modrm(TCCState *S, int reg, Operand *op)
|
|||
ExprValue *pe = &op->e;
|
||||
g(S, 0x05 + (reg << 3));
|
||||
gen_addrpc32(S, pe->sym ? VT_SYM : 0, pe->sym, pe->v);
|
||||
return S->ind;
|
||||
return S->tccgen_ind;
|
||||
#endif
|
||||
} else {
|
||||
sib_reg1 = op->reg;
|
||||
|
@ -705,13 +705,13 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
|
|||
seg_prefix = 0;
|
||||
alltypes = 0;
|
||||
for(;;) {
|
||||
if (S->tok == ';' || S->tok == TOK_LINEFEED)
|
||||
if (S->tccpp_tok == ';' || S->tccpp_tok == TOK_LINEFEED)
|
||||
break;
|
||||
if (nb_ops >= MAX_OPERANDS) {
|
||||
tcc_error(S, "incorrect number of operands");
|
||||
}
|
||||
parse_operand(S, pop);
|
||||
if (S->tok == ':') {
|
||||
if (S->tccpp_tok == ':') {
|
||||
if (pop->type != OP_SEG || seg_prefix)
|
||||
tcc_error(S, "incorrect prefix");
|
||||
seg_prefix = segment_prefixes[pop->reg];
|
||||
|
@ -723,7 +723,7 @@ ST_FUNC void asm_opcode(TCCState *S, int opcode)
|
|||
}
|
||||
pop++;
|
||||
nb_ops++;
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
break;
|
||||
next(S);
|
||||
}
|
||||
|
@ -1038,7 +1038,7 @@ again:
|
|||
esym = elfsym(S, ops[0].e.sym);
|
||||
if (!esym || esym->st_shndx != cur_text_section->sh_num)
|
||||
goto no_short_jump;
|
||||
jmp_disp = ops[0].e.v + esym->st_value - S->ind - 2 - (v >= 0xff);
|
||||
jmp_disp = ops[0].e.v + esym->st_value - S->tccgen_ind - 2 - (v >= 0xff);
|
||||
if (jmp_disp == (int8_t)jmp_disp) {
|
||||
/* OK to generate jump */
|
||||
ops[0].e.sym = 0;
|
||||
|
@ -1136,7 +1136,7 @@ again:
|
|||
|
||||
/* after immediate operands, adjust pc-relative address */
|
||||
if (pc)
|
||||
add32le(cur_text_section->data + pc - 4, pc - S->ind);
|
||||
add32le(cur_text_section->data + pc - 4, pc - S->tccgen_ind);
|
||||
}
|
||||
|
||||
/* return the constraint priority (we allocate first the lowest
|
||||
|
|
182
i386-gen.c
182
i386-gen.c
|
@ -108,13 +108,13 @@ static void gen_bounds_epilog(TCCState *S);
|
|||
ST_FUNC void g(TCCState* S, int c)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 1;
|
||||
ind1 = S->tccgen_ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind] = c;
|
||||
S->ind = ind1;
|
||||
cur_text_section->data[S->tccgen_ind] = c;
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
ST_FUNC void o(TCCState* S, unsigned int c)
|
||||
|
@ -154,10 +154,10 @@ ST_FUNC void gsym_addr(TCCState *S, int t, int a)
|
|||
static int oad(TCCState* S, int c, int s)
|
||||
{
|
||||
int t;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return s;
|
||||
o(S, c);
|
||||
t = S->ind;
|
||||
t = S->tccgen_ind;
|
||||
gen_le32(S, s);
|
||||
return t;
|
||||
}
|
||||
|
@ -175,14 +175,14 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
|
|||
ST_FUNC void gen_addr32(TCCState* S, int r, Sym *sym, int c)
|
||||
{
|
||||
if (r & VT_SYM)
|
||||
greloc(S, cur_text_section, sym, S->ind, R_386_32);
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_32);
|
||||
gen_le32(S, c);
|
||||
}
|
||||
|
||||
ST_FUNC void gen_addrpc32(TCCState* S, int r, Sym *sym, int c)
|
||||
{
|
||||
if (r & VT_SYM)
|
||||
greloc(S, cur_text_section, sym, S->ind, R_386_PC32);
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind, R_386_PC32);
|
||||
gen_le32(S, c - 4);
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ static void gen_static_call(TCCState *S, int v)
|
|||
|
||||
sym = external_helper_sym(S, v);
|
||||
oad(S, 0xe8, -4);
|
||||
greloc(S, cur_text_section, sym, S->ind-4, R_386_PC32);
|
||||
greloc(S, cur_text_section, sym, S->tccgen_ind-4, R_386_PC32);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -357,10 +357,10 @@ static void gen_static_call(TCCState *S, int v)
|
|||
static void gcall_or_jmp(TCCState* S, int is_jmp)
|
||||
{
|
||||
int r;
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->vtop->r & VT_SYM)) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (S->tccgen_vtop->r & VT_SYM)) {
|
||||
/* constant and relocation case */
|
||||
greloc(S, cur_text_section, S->vtop->sym, S->ind + 1, R_386_PC32);
|
||||
oad(S, 0xe8 + is_jmp, S->vtop->c.i - 4); /* call/jmp im */
|
||||
greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_386_PC32);
|
||||
oad(S, 0xe8 + is_jmp, S->tccgen_vtop->c.i - 4); /* call/jmp im */
|
||||
} else {
|
||||
/* otherwise, indirect call */
|
||||
r = gv(S, RC_INT);
|
||||
|
@ -414,8 +414,8 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
args_size = 0;
|
||||
for(i = 0;i < nb_args; i++) {
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
size = type_size(&S->vtop->type, &align);
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
size = type_size(&S->tccgen_vtop->type, &align);
|
||||
/* align to stack align size */
|
||||
size = (size + 3) & ~3;
|
||||
/* allocate the necessary size on stack */
|
||||
|
@ -434,15 +434,15 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
r = get_reg(S, RC_INT);
|
||||
o(S, 0xe089 + (r << 8)); /* mov %esp, r */
|
||||
}
|
||||
vset(S, &S->vtop->type, r | VT_LVAL, 0);
|
||||
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
|
||||
vswap(S);
|
||||
vstore(S);
|
||||
args_size += size;
|
||||
} else if (is_float(S->vtop->type.t)) {
|
||||
} else if (is_float(S->tccgen_vtop->type.t)) {
|
||||
gv(S, RC_FLOAT); /* only one float register */
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_FLOAT)
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT)
|
||||
size = 4;
|
||||
else if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
size = 8;
|
||||
else
|
||||
size = 12;
|
||||
|
@ -458,19 +458,19 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
/* simple type (currently always same size) */
|
||||
/* XXX: implicit cast ? */
|
||||
r = gv(S, RC_INT);
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
size = 8;
|
||||
o(S, 0x50 + S->vtop->r2); /* push r */
|
||||
o(S, 0x50 + S->tccgen_vtop->r2); /* push r */
|
||||
} else {
|
||||
size = 4;
|
||||
}
|
||||
o(S, 0x50 + r); /* push r */
|
||||
args_size += size;
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
save_regs(S, 0); /* save used temporary registers */
|
||||
func_sym = S->vtop->type.ref;
|
||||
func_sym = S->tccgen_vtop->type.ref;
|
||||
func_call = func_sym->f.func_call;
|
||||
/* fast call case */
|
||||
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
|
||||
|
@ -493,7 +493,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
}
|
||||
#if !defined(TCC_TARGET_PE) && !TARGETOS_FreeBSD || TARGETOS_OpenBSD
|
||||
else if ((S->vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
|
||||
else if ((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
|
||||
args_size -= 4;
|
||||
#endif
|
||||
|
||||
|
@ -501,7 +501,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
|
||||
gadd_sp(S, args_size);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
|
@ -523,7 +523,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
sym = func_type->ref;
|
||||
func_call = sym->f.func_call;
|
||||
addr = 8;
|
||||
S->loc = 0;
|
||||
S->tccgen_loc = 0;
|
||||
S->tccgen_func_vc = 0;
|
||||
|
||||
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
||||
|
@ -538,8 +538,8 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
}
|
||||
param_index = 0;
|
||||
|
||||
S->ind += FUNC_PROLOG_SIZE;
|
||||
func_sub_sp_offset = S->ind;
|
||||
S->tccgen_ind += FUNC_PROLOG_SIZE;
|
||||
func_sub_sp_offset = S->tccgen_ind;
|
||||
/* if the function returns a structure, then add an
|
||||
implicit pointer parameter */
|
||||
#if defined(TCC_TARGET_PE) || TARGETOS_FreeBSD || TARGETOS_OpenBSD
|
||||
|
@ -567,10 +567,10 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
#endif
|
||||
if (param_index < fastcall_nb_regs) {
|
||||
/* save FASTCALL register */
|
||||
S->loc -= 4;
|
||||
S->tccgen_loc -= 4;
|
||||
o(S, 0x89); /* movl */
|
||||
gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->loc);
|
||||
param_addr = S->loc;
|
||||
gen_modrm(S, fastcall_regs_ptr[param_index], VT_LOCAL, NULL, S->tccgen_loc);
|
||||
param_addr = S->tccgen_loc;
|
||||
} else {
|
||||
param_addr = addr;
|
||||
addr += size;
|
||||
|
@ -605,7 +605,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
#endif
|
||||
|
||||
/* align local size to word & save local variables */
|
||||
v = (-S->loc + 3) & -4;
|
||||
v = (-S->tccgen_loc + 3) & -4;
|
||||
|
||||
#if USE_EBX
|
||||
o(S, 0x8b);
|
||||
|
@ -620,8 +620,8 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
g(S, func_ret_sub);
|
||||
g(S, func_ret_sub >> 8);
|
||||
}
|
||||
saved_ind = S->ind;
|
||||
S->ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (v >= 4096) {
|
||||
oad(S, 0xb8, v); /* mov stacksize, %eax */
|
||||
|
@ -637,7 +637,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
#endif
|
||||
}
|
||||
o(S, 0x53 * USE_EBX); /* push ebx */
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
/* generate a jump to a label */
|
||||
|
@ -650,12 +650,12 @@ ST_FUNC int gjmp(TCCState *S, int t)
|
|||
ST_FUNC void gjmp_addr(TCCState* S, int a)
|
||||
{
|
||||
int r;
|
||||
r = a - S->ind - 2;
|
||||
r = a - S->tccgen_ind - 2;
|
||||
if (r == (char)r) {
|
||||
g(S, 0xeb);
|
||||
g(S, r);
|
||||
} else {
|
||||
oad(S, 0xe9, a - S->ind - 5);
|
||||
oad(S, 0xe9, a - S->tccgen_ind - 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,7 +663,7 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
|
|||
/* generate a jump to a fixed address */
|
||||
ST_FUNC void gjmp_cond_addr(TCCState* S, int a, int op)
|
||||
{
|
||||
int r = a - S->ind - 2;
|
||||
int r = a - S->tccgen_ind - 2;
|
||||
if (r == (char)r)
|
||||
g(S, op - 32), g(r);
|
||||
else
|
||||
|
@ -701,12 +701,12 @@ ST_FUNC void gen_opi(TCCState *S, int op)
|
|||
case TOK_ADDC1: /* add with carry generation */
|
||||
opc = 0;
|
||||
gen_op8:
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
/* constant case */
|
||||
vswap(S);
|
||||
r = gv(S, RC_INT);
|
||||
vswap(S);
|
||||
c = S->vtop->c.i;
|
||||
c = S->tccgen_vtop->c.i;
|
||||
if (c == (char)c) {
|
||||
/* generate inc and dec for smaller code */
|
||||
if ((c == 1 || c == -1) && (op == '+' || op == '-')) {
|
||||
|
@ -723,12 +723,12 @@ ST_FUNC void gen_opi(TCCState *S, int op)
|
|||
}
|
||||
} else {
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
o(S, (opc << 3) | 0x01);
|
||||
o(S, 0xc0 + r + fr * 8);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
if (op >= TOK_ULT && op <= TOK_GT)
|
||||
vset_VT_CMP(S, op);
|
||||
break;
|
||||
|
@ -753,9 +753,9 @@ ST_FUNC void gen_opi(TCCState *S, int op)
|
|||
goto gen_op8;
|
||||
case '*':
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
o(S, 0xaf0f); /* imul fr, r */
|
||||
o(S, 0xc0 + fr + r * 8);
|
||||
break;
|
||||
|
@ -769,23 +769,23 @@ ST_FUNC void gen_opi(TCCState *S, int op)
|
|||
opc = 7;
|
||||
gen_shift:
|
||||
opc = 0xc0 | (opc << 3);
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
/* constant case */
|
||||
vswap(S);
|
||||
r = gv(S, RC_INT);
|
||||
vswap(S);
|
||||
c = S->vtop->c.i & 0x1f;
|
||||
c = S->tccgen_vtop->c.i & 0x1f;
|
||||
o(S, 0xc1); /* shl/shr/sar $xxx, r */
|
||||
o(S, opc | r);
|
||||
g(S, c);
|
||||
} else {
|
||||
/* we generate the shift in ecx */
|
||||
gv2(S, RC_INT, RC_ECX);
|
||||
r = S->vtop[-1].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
o(S, 0xd3); /* shl/shr/sar %cl, r */
|
||||
o(S, opc | r);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
break;
|
||||
case '/':
|
||||
case TOK_UDIV:
|
||||
|
@ -796,16 +796,16 @@ ST_FUNC void gen_opi(TCCState *S, int op)
|
|||
/* first operand must be in eax */
|
||||
/* XXX: need better constraint for second operand */
|
||||
gv2(S, RC_EAX, RC_ECX);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
save_reg(S, TREG_EDX);
|
||||
/* save EAX too if used otherwise */
|
||||
save_reg_upstack(S, TREG_EAX, 1);
|
||||
if (op == TOK_UMULL) {
|
||||
o(S, 0xf7); /* mul fr */
|
||||
o(S, 0xe0 + fr);
|
||||
S->vtop->r2 = TREG_EDX;
|
||||
S->tccgen_vtop->r2 = TREG_EDX;
|
||||
r = TREG_EAX;
|
||||
} else {
|
||||
if (op == TOK_UDIV || op == TOK_UMOD) {
|
||||
|
@ -820,7 +820,7 @@ ST_FUNC void gen_opi(TCCState *S, int op)
|
|||
else
|
||||
r = TREG_EAX;
|
||||
}
|
||||
S->vtop->r = r;
|
||||
S->tccgen_vtop->r = r;
|
||||
break;
|
||||
default:
|
||||
opc = 7;
|
||||
|
@ -842,17 +842,17 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
}
|
||||
|
||||
/* convert constants to memory references */
|
||||
if ((S->vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
vswap(S);
|
||||
gv(S, RC_FLOAT);
|
||||
vswap(S);
|
||||
}
|
||||
if ((S->vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
|
||||
if ((S->tccgen_vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
|
||||
gv(S, RC_FLOAT);
|
||||
|
||||
/* must put at least one value in the floating point register */
|
||||
if ((S->vtop[-1].r & VT_LVAL) &&
|
||||
(S->vtop[0].r & VT_LVAL)) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_LVAL) &&
|
||||
(S->tccgen_vtop[0].r & VT_LVAL)) {
|
||||
vswap(S);
|
||||
gv(S, RC_FLOAT);
|
||||
vswap(S);
|
||||
|
@ -860,13 +860,13 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
swapped = 0;
|
||||
/* swap the stack if needed so that t1 is the register and t2 is
|
||||
the memory reference */
|
||||
if (S->vtop[-1].r & VT_LVAL) {
|
||||
if (S->tccgen_vtop[-1].r & VT_LVAL) {
|
||||
vswap(S);
|
||||
swapped = 1;
|
||||
}
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
/* load on stack second operand */
|
||||
load(S, TREG_ST0, S->vtop);
|
||||
load(S, TREG_ST0, S->tccgen_vtop);
|
||||
save_reg(S, TREG_EAX); /* eax is used by FP comparison code */
|
||||
if (op == TOK_GE || op == TOK_GT)
|
||||
swapped = !swapped;
|
||||
|
@ -893,12 +893,12 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
o(S, 0x45c4f6); /* test $0x45, %ah */
|
||||
op = TOK_EQ;
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
vset_VT_CMP(S, op);
|
||||
} else {
|
||||
/* no memory reference possible for long double operations */
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
load(S, TREG_ST0, S->vtop);
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
load(S, TREG_ST0, S->tccgen_vtop);
|
||||
swapped = !swapped;
|
||||
}
|
||||
|
||||
|
@ -921,14 +921,14 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
a++;
|
||||
break;
|
||||
}
|
||||
ft = S->vtop->type.t;
|
||||
fc = S->vtop->c.i;
|
||||
ft = S->tccgen_vtop->type.t;
|
||||
fc = S->tccgen_vtop->c.i;
|
||||
if ((ft & VT_BTYPE) == VT_LDOUBLE) {
|
||||
o(S, 0xde); /* fxxxp %st, %st(1) */
|
||||
o(S, 0xc1 + (a << 3));
|
||||
} else {
|
||||
/* if saved lvalue, then we must reload it */
|
||||
r = S->vtop->r;
|
||||
r = S->tccgen_vtop->r;
|
||||
if ((r & VT_VALMASK) == VT_LLOCAL) {
|
||||
SValue v1;
|
||||
r = get_reg(S, RC_INT);
|
||||
|
@ -944,9 +944,9 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
o(S, 0xdc);
|
||||
else
|
||||
o(S, 0xd8);
|
||||
gen_modrm(S, a, r, S->vtop->sym, fc);
|
||||
gen_modrm(S, a, r, S->tccgen_vtop->sym, fc);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -956,36 +956,36 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
{
|
||||
save_reg(S, TREG_ST0);
|
||||
gv(S, RC_INT);
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
/* signed long long to float/double/long double (unsigned case
|
||||
is handled generically) */
|
||||
o(S, 0x50 + S->vtop->r2); /* push r2 */
|
||||
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x50 + S->tccgen_vtop->r2); /* push r2 */
|
||||
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x242cdf); /* fildll (%esp) */
|
||||
o(S, 0x08c483); /* add $8, %esp */
|
||||
S->vtop->r2 = VT_CONST;
|
||||
} else if ((S->vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||
S->tccgen_vtop->r2 = VT_CONST;
|
||||
} else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||
(VT_INT | VT_UNSIGNED)) {
|
||||
/* unsigned int to float/double/long double */
|
||||
o(S, 0x6a); /* push $0 */
|
||||
g(S, 0x00);
|
||||
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x242cdf); /* fildll (%esp) */
|
||||
o(S, 0x08c483); /* add $8, %esp */
|
||||
} else {
|
||||
/* int to float/double/long double */
|
||||
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x2404db); /* fildl (%esp) */
|
||||
o(S, 0x04c483); /* add $4, %esp */
|
||||
}
|
||||
S->vtop->r2 = VT_CONST;
|
||||
S->vtop->r = TREG_ST0;
|
||||
S->tccgen_vtop->r2 = VT_CONST;
|
||||
S->tccgen_vtop->r = TREG_ST0;
|
||||
}
|
||||
|
||||
/* convert fp to int 't' type */
|
||||
ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)
|
||||
{
|
||||
int bt = S->vtop->type.t & VT_BTYPE;
|
||||
int bt = S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
if (bt == VT_FLOAT)
|
||||
vpush_helper_func(S, TOK___fixsfdi);
|
||||
else if (bt == VT_LDOUBLE)
|
||||
|
@ -995,9 +995,9 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
|
|||
vswap(S);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
if ((t & VT_BTYPE) == VT_LLONG)
|
||||
S->vtop->r2 = REG_IRE2;
|
||||
S->tccgen_vtop->r2 = REG_IRE2;
|
||||
}
|
||||
|
||||
/* convert from one floating point type to another */
|
||||
|
@ -1024,11 +1024,11 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
|
|||
ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
|
||||
{
|
||||
o(S, 0x0583); /* addl $1, xxx */
|
||||
greloc(S, cur_text_section, sv->sym, S->ind, R_386_32);
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);
|
||||
gen_le32(S, 0);
|
||||
o(S, 1);
|
||||
o(S, 0x1583); /* addcl $0, xxx */
|
||||
greloc(S, cur_text_section, sv->sym, S->ind, R_386_32);
|
||||
greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_386_32);
|
||||
gen_le32(S, 4);
|
||||
g(S, 0);
|
||||
}
|
||||
|
@ -1037,7 +1037,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
ST_FUNC void ggoto(TCCState* S)
|
||||
{
|
||||
gcall_or_jmp(S, 1);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
/* bound check support functions */
|
||||
|
@ -1047,7 +1047,7 @@ static void gen_bounds_prolog(TCCState *S)
|
|||
{
|
||||
/* leave some room for bound checking code */
|
||||
S->func_bound_offset = lbounds_section->data_offset;
|
||||
S->func_bound_ind = S->ind;
|
||||
S->func_bound_ind = S->tccgen_ind;
|
||||
S->func_bound_add_epilog = 0;
|
||||
oad(S, 0xb8, 0); /* lbound section pointer */
|
||||
oad(S, 0xb8, 0); /* call to function */
|
||||
|
@ -1067,22 +1067,22 @@ static void gen_bounds_epilog(TCCState *S)
|
|||
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
|
||||
*bounds_ptr = 0;
|
||||
|
||||
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section,
|
||||
sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
|
||||
S->func_bound_offset, lbounds_section->data_offset);
|
||||
|
||||
/* generate bound local allocation */
|
||||
if (offset_modified) {
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->func_bound_ind;
|
||||
greloc(S, cur_text_section, sym_data, S->ind + 1, R_386_32);
|
||||
S->ind = S->ind + 5;
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->func_bound_ind;
|
||||
greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
|
||||
S->tccgen_ind = S->tccgen_ind + 5;
|
||||
gen_static_call(S, TOK___bound_local_new);
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
/* generate bound check local freeing */
|
||||
o(S, 0x5250); /* save returned value, if any */
|
||||
greloc(S, cur_text_section, sym_data, S->ind + 1, R_386_32);
|
||||
greloc(S, cur_text_section, sym_data, S->tccgen_ind + 1, R_386_32);
|
||||
oad(S, 0xb8, 0); /* mov %eax, xxx */
|
||||
gen_static_call(S, TOK___bound_local_delete);
|
||||
o(S, 0x585a); /* restore returned value, if any */
|
||||
|
|
4
libtcc.c
4
libtcc.c
|
@ -650,7 +650,7 @@ static void error1(TCCState *S, int mode, const char *fmt, va_list ap)
|
|||
cstr_printf(S, &cs, "In file included from %s:%d:\n",
|
||||
(*pf)->filename, (*pf)->line_num);
|
||||
cstr_printf(S, &cs, "%s:%d: ",
|
||||
f->filename, (*pf)->line_num - !!(S->tok_flags & TOK_FLAG_BOL));
|
||||
f->filename, (*pf)->line_num - !!(S->tccpp_tok_flags & TOK_FLAG_BOL));
|
||||
} else if (S->current_filename) {
|
||||
cstr_printf(S, &cs, "%s: ", S->current_filename);
|
||||
}
|
||||
|
@ -744,7 +744,7 @@ ST_FUNC void tcc_open_bf(TCCState *S, const char *filename, int initlen)
|
|||
bf->fd = -1;
|
||||
bf->prev = S->tccpp_file;
|
||||
S->tccpp_file = bf;
|
||||
S->tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||
S->tccpp_tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||
}
|
||||
|
||||
ST_FUNC void tcc_close(TCCState* S)
|
||||
|
|
|
@ -23,13 +23,13 @@ ST_FUNC void gen_le32(TCCState *S, int c);
|
|||
ST_FUNC void g(TCCState* S, int c)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 1;
|
||||
ind1 = S->tccgen_ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind] = c;
|
||||
S->ind = ind1;
|
||||
cur_text_section->data[S->tccgen_ind] = c;
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_le16 (TCCState* S, int i)
|
||||
|
@ -41,15 +41,15 @@ ST_FUNC void gen_le16 (TCCState *S, int i)
|
|||
ST_FUNC void gen_le32 (TCCState* S, int i)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 4;
|
||||
ind1 = S->tccgen_ind + 4;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind++] = i & 0xFF;
|
||||
cur_text_section->data[S->ind++] = (i >> 8) & 0xFF;
|
||||
cur_text_section->data[S->ind++] = (i >> 16) & 0xFF;
|
||||
cur_text_section->data[S->ind++] = (i >> 24) & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = i & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = (i >> 8) & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = (i >> 16) & 0xFF;
|
||||
cur_text_section->data[S->tccgen_ind++] = (i >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_expr32(TCCState* S, ExprValue *pe)
|
||||
|
@ -128,12 +128,12 @@ static void parse_operand(TCCState *S, Operand *op)
|
|||
|
||||
op->type = 0;
|
||||
|
||||
if ((reg = asm_parse_regvar(S, S->tok)) != -1) {
|
||||
if ((reg = asm_parse_regvar(S, S->tccpp_tok)) != -1) {
|
||||
next(S); // skip register name
|
||||
op->type = OP_REG;
|
||||
op->reg = (uint8_t) reg;
|
||||
return;
|
||||
} else if (S->tok == '$') {
|
||||
} else if (S->tccpp_tok == '$') {
|
||||
/* constant value */
|
||||
next(S); // skip '#' or '$'
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ static void asm_binary_opcode(TCCState *S, int token)
|
|||
{
|
||||
Operand ops[2];
|
||||
parse_operand(S, &ops[0]);
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -283,12 +283,12 @@ static void asm_shift_opcode(TCCState *S, int token)
|
|||
{
|
||||
Operand ops[3];
|
||||
parse_operand(S, &ops[0]);
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
parse_operand(S, &ops[1]);
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -340,12 +340,12 @@ static void asm_data_processing_opcode(TCCState *S, int token)
|
|||
{
|
||||
Operand ops[3];
|
||||
parse_operand(S, &ops[0]);
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
parse_operand(S, &ops[1]);
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -450,7 +450,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -459,7 +459,7 @@ static void asm_data_transfer_opcode(TCCState *S, int token)
|
|||
expect(S, "register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -522,7 +522,7 @@ static void asm_branch_opcode(TCCState *S, int token)
|
|||
expect(S, "register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
@ -531,7 +531,7 @@ static void asm_branch_opcode(TCCState *S, int token)
|
|||
expect(S, "register");
|
||||
return;
|
||||
}
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
next(S);
|
||||
else
|
||||
expect(S, "','");
|
||||
|
|
324
riscv64-gen.c
324
riscv64-gen.c
|
@ -102,13 +102,13 @@ static int is_freg(int r)
|
|||
|
||||
ST_FUNC void o(TCCState* S, unsigned int c)
|
||||
{
|
||||
int ind1 = S->ind + 4;
|
||||
if (S->nocode_wanted)
|
||||
int ind1 = S->tccgen_ind + 4;
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
write32le(cur_text_section->data + S->ind, c);
|
||||
S->ind = ind1;
|
||||
write32le(cur_text_section->data + S->tccgen_ind, c);
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
static void EIu(TCCState* S, uint32_t opcode, uint32_t func3,
|
||||
|
@ -166,21 +166,21 @@ static int load_symofs(TCCState *S, int r, SValue *sv, int forstore)
|
|||
Sym label = {0};
|
||||
assert(v == VT_CONST);
|
||||
if (sv->sym->type.t & VT_STATIC) { // XXX do this per linker relax
|
||||
greloca(S, cur_text_section, sv->sym, S->ind,
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind,
|
||||
R_RISCV_PCREL_HI20, sv->c.i);
|
||||
sv->c.i = 0;
|
||||
} else {
|
||||
if (((unsigned)fc + (1 << 11)) >> 12)
|
||||
tcc_error(S, "unimp: large addend for global address (0x%lx)", (long)sv->c.i);
|
||||
greloca(S, cur_text_section, sv->sym, S->ind,
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind,
|
||||
R_RISCV_GOT_HI20, 0);
|
||||
doload = 1;
|
||||
}
|
||||
label.type.t = VT_VOID | VT_STATIC;
|
||||
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
|
||||
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
|
||||
rr = is_ireg(r) ? ireg(r) : 5;
|
||||
o(S, 0x17 | (rr << 7)); // auipc RR, 0 %pcrel_hi(sym)+addend
|
||||
greloca(S, cur_text_section, &label, S->ind,
|
||||
greloca(S, cur_text_section, &label, S->tccgen_ind,
|
||||
doload || !forstore
|
||||
? R_RISCV_PCREL_LO12_I : R_RISCV_PCREL_LO12_S, 0);
|
||||
if (doload) {
|
||||
|
@ -314,9 +314,9 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv)
|
|||
| (func7 << 25)); // fmv.{w.x, x.w, d.x, x.d} RR, VR
|
||||
}
|
||||
} else if (v == VT_CMP) {
|
||||
int op = S->vtop->cmp_op;
|
||||
int a = S->vtop->cmp_r & 0xff;
|
||||
int b = (S->vtop->cmp_r >> 8) & 0xff;
|
||||
int op = S->tccgen_vtop->cmp_op;
|
||||
int a = S->tccgen_vtop->cmp_r & 0xff;
|
||||
int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
|
||||
int inv = 0;
|
||||
switch (op) {
|
||||
case TOK_ULT:
|
||||
|
@ -353,7 +353,7 @@ ST_FUNC void load(TCCState *S, int r, SValue *sv)
|
|||
int t = v & 1;
|
||||
assert(is_ireg(r));
|
||||
EI(S, 0x13, 0, rr, 0, t); // addi RR, x0, t
|
||||
gjmp_addr(S, S->ind + 8);
|
||||
gjmp_addr(S, S->tccgen_ind + 8);
|
||||
gsym(S, fc);
|
||||
EI(S, 0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
|
||||
} else
|
||||
|
@ -406,19 +406,19 @@ ST_FUNC void store(TCCState *S, int r, SValue *sv)
|
|||
static void gcall_or_jmp(TCCState* S, int docall)
|
||||
{
|
||||
int tr = docall ? 1 : 5; // ra or t0
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
||||
((S->vtop->r & VT_SYM) && S->vtop->c.i == (int)S->vtop->c.i)) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
||||
((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->c.i == (int)S->tccgen_vtop->c.i)) {
|
||||
/* constant symbolic case -> simple relocation */
|
||||
greloca(S, cur_text_section, S->vtop->sym, S->ind,
|
||||
R_RISCV_CALL_PLT, (int)S->vtop->c.i);
|
||||
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind,
|
||||
R_RISCV_CALL_PLT, (int)S->tccgen_vtop->c.i);
|
||||
o(S, 0x17 | (tr << 7)); // auipc TR, 0 %call(func)
|
||||
EI(S, 0x67, 0, tr, tr, 0);// jalr TR, r(TR)
|
||||
} else if (S->vtop->r < VT_CONST) {
|
||||
int r = ireg(S->vtop->r);
|
||||
} else if (S->tccgen_vtop->r < VT_CONST) {
|
||||
int r = ireg(S->tccgen_vtop->r);
|
||||
EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
|
||||
} else {
|
||||
int r = TREG_RA;
|
||||
load(S, r, S->vtop);
|
||||
load(S, r, S->tccgen_vtop);
|
||||
r = ireg(r);
|
||||
EI(S, 0x67, 0, tr, r, 0); // jalr TR, 0(R)
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ static void gen_bounds_call(TCCState *S, int v)
|
|||
{
|
||||
Sym *sym = external_helper_sym(S, v);
|
||||
|
||||
greloca(S, cur_text_section, sym, S->ind, R_RISCV_CALL_PLT, 0);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_RISCV_CALL_PLT, 0);
|
||||
o(S, 0x17 | (1 << 7)); // auipc TR, 0 %call(func)
|
||||
EI(S, 0x67, 0, 1, 1, 0); // jalr TR, r(TR)
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ static void gen_bounds_prolog(TCCState *S)
|
|||
{
|
||||
/* leave some room for bound checking code */
|
||||
S->func_bound_offset = lbounds_section->data_offset;
|
||||
S->func_bound_ind = S->ind;
|
||||
S->func_bound_ind = S->tccgen_ind;
|
||||
S->func_bound_add_epilog = 0;
|
||||
o(S, 0x00000013); /* ld a0,#lbound section pointer */
|
||||
o(S, 0x00000013);
|
||||
|
@ -463,31 +463,31 @@ static void gen_bounds_epilog(TCCState *S)
|
|||
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
|
||||
*bounds_ptr = 0;
|
||||
|
||||
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section,
|
||||
sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
|
||||
S->func_bound_offset, lbounds_section->data_offset);
|
||||
|
||||
label.type.t = VT_VOID | VT_STATIC;
|
||||
/* generate bound local allocation */
|
||||
if (offset_modified) {
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->func_bound_ind;
|
||||
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->ind, R_RISCV_GOT_HI20, 0);
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->func_bound_ind;
|
||||
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);
|
||||
o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
|
||||
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)
|
||||
gen_bounds_call(S, TOK___bound_local_new);
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
}
|
||||
|
||||
/* generate bound check local freeing */
|
||||
o(S, 0xe02a1101); /* addi sp,sp,-32 sd a0,0(sp) */
|
||||
o(S, 0xa82ae42e); /* sd a1,8(sp) fsd fa0,16(sp) */
|
||||
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->ind, R_RISCV_GOT_HI20, 0);
|
||||
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind, R_RISCV_GOT_HI20, 0);
|
||||
o(S, 0x17 | (10 << 7)); // auipc a0, 0 %pcrel_hi(sym)+addend
|
||||
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
EI(S, 0x03, 3, 10, 10, 0); // ld a0, 0(a0)
|
||||
gen_bounds_call(S, TOK___bound_local_delete);
|
||||
o(S, 0x65a26502); /* ld a0,0(sp) ld a1,8(sp) */
|
||||
|
@ -556,11 +556,11 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
areg[0] = 0; /* int arg regs */
|
||||
areg[1] = 8; /* float arg regs */
|
||||
sa = S->vtop[-nb_args].type.ref->next;
|
||||
sa = S->tccgen_vtop[-nb_args].type.ref->next;
|
||||
for (i = 0; i < nb_args; i++) {
|
||||
int nregs, byref = 0, tempofs;
|
||||
int prc[3], fieldofs[3];
|
||||
sv = &S->vtop[1 + i - nb_args];
|
||||
sv = &S->tccgen_vtop[1 + i - nb_args];
|
||||
sv->type.t &= ~VT_ARRAY; // XXX this should be done in tccgen.c
|
||||
size = type_size(&sv->type, &align);
|
||||
if (size > 16) {
|
||||
|
@ -617,7 +617,7 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
stack_add = stack_adj + tempspace;
|
||||
|
||||
/* fetch cpu flag before generating any code */
|
||||
if ((S->vtop->r & VT_VALMASK) == VT_CMP)
|
||||
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
|
||||
gv(S, RC_INT);
|
||||
|
||||
if (stack_add) {
|
||||
|
@ -631,15 +631,15 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
for (i = ofs = 0; i < nb_args; i++) {
|
||||
if (info[i] & (64 | 32)) {
|
||||
vrotb(S, nb_args - i);
|
||||
size = type_size(&S->vtop->type, &align);
|
||||
size = type_size(&S->tccgen_vtop->type, &align);
|
||||
if (info[i] & 64) {
|
||||
vset(S, &S->char_pointer_type, TREG_SP, 0);
|
||||
vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);
|
||||
vpushi(S, stack_adj + (info[i] >> 7));
|
||||
gen_op(S, '+');
|
||||
vpushv(S, S->vtop); // this replaces the old argument
|
||||
vpushv(S, S->tccgen_vtop); // this replaces the old argument
|
||||
vrott(S, 3);
|
||||
indir(S);
|
||||
S->vtop->type = S->vtop[-1].type;
|
||||
S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
|
||||
vswap(S);
|
||||
vstore(S);
|
||||
vpop(S);
|
||||
|
@ -649,18 +649,18 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
if (align < XLEN)
|
||||
align = XLEN;
|
||||
/* Once we support offseted regs we can do this:
|
||||
vset(S, &S->vtop->type, TREG_SP | VT_LVAL, ofs);
|
||||
vset(S, &S->tccgen_vtop->type, TREG_SP | VT_LVAL, ofs);
|
||||
to construct the lvalue for the outgoing stack slot,
|
||||
until then we have to jump through hoops. */
|
||||
vset(S, &S->char_pointer_type, TREG_SP, 0);
|
||||
vset(S, &S->tccgen_char_pointer_type, TREG_SP, 0);
|
||||
ofs = (ofs + align - 1) & -align;
|
||||
vpushi(S, ofs);
|
||||
gen_op(S, '+');
|
||||
indir(S);
|
||||
S->vtop->type = S->vtop[-1].type;
|
||||
S->tccgen_vtop->type = S->tccgen_vtop[-1].type;
|
||||
vswap(S);
|
||||
vstore(S);
|
||||
S->vtop->r = S->vtop->r2 = VT_CONST; // this arg is done
|
||||
S->tccgen_vtop->r = S->tccgen_vtop->r2 = VT_CONST; // this arg is done
|
||||
ofs += size;
|
||||
}
|
||||
vrott(S, nb_args - i);
|
||||
|
@ -680,11 +680,11 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
r2 = r2 & 64 ? 0 : (r2 >> 7) & 31;
|
||||
assert(r2 <= 16);
|
||||
vrotb(S, i+1);
|
||||
origtype = S->vtop->type;
|
||||
size = type_size(&S->vtop->type, &align);
|
||||
origtype = S->tccgen_vtop->type;
|
||||
size = type_size(&S->tccgen_vtop->type, &align);
|
||||
if (size == 0)
|
||||
goto done;
|
||||
loadt = S->vtop->type.t & VT_BTYPE;
|
||||
loadt = S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
if (loadt == VT_STRUCT) {
|
||||
loadt = (ii >> 12) & VT_BTYPE;
|
||||
}
|
||||
|
@ -697,18 +697,18 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
r2--;
|
||||
} else if (r2) {
|
||||
test_lvalue(S);
|
||||
vpushv(S, S->vtop);
|
||||
vpushv(S, S->tccgen_vtop);
|
||||
}
|
||||
S->vtop->type.t = loadt | (S->vtop->type.t & VT_UNSIGNED);
|
||||
S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
|
||||
gv(S, r < 8 ? RC_R(r) : RC_F(r - 8));
|
||||
S->vtop->type = origtype;
|
||||
S->tccgen_vtop->type = origtype;
|
||||
|
||||
if (r2 && loadt != VT_LDOUBLE) {
|
||||
r2--;
|
||||
assert(r2 < 16 || r2 == TREG_RA);
|
||||
vswap(S);
|
||||
gaddrof(S);
|
||||
S->vtop->type = S->char_pointer_type;
|
||||
S->tccgen_vtop->type = S->tccgen_char_pointer_type;
|
||||
vpushi(S, ii >> 20);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if ((origtype.t & VT_BTYPE) == VT_STRUCT)
|
||||
|
@ -719,27 +719,27 @@ ST_FUNC void gfunc_call(TCCState *S, int nb_args)
|
|||
S->do_bounds_check = bc_save;
|
||||
#endif
|
||||
indir(S);
|
||||
S->vtop->type = origtype;
|
||||
loadt = S->vtop->type.t & VT_BTYPE;
|
||||
S->tccgen_vtop->type = origtype;
|
||||
loadt = S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
if (loadt == VT_STRUCT) {
|
||||
loadt = (ii >> 16) & VT_BTYPE;
|
||||
}
|
||||
save_reg_upstack(S, r2, 1);
|
||||
S->vtop->type.t = loadt | (S->vtop->type.t & VT_UNSIGNED);
|
||||
load(S, r2, S->vtop);
|
||||
S->tccgen_vtop->type.t = loadt | (S->tccgen_vtop->type.t & VT_UNSIGNED);
|
||||
load(S, r2, S->tccgen_vtop);
|
||||
assert(r2 < VT_CONST);
|
||||
S->vtop--;
|
||||
S->vtop->r2 = r2;
|
||||
S->tccgen_vtop--;
|
||||
S->tccgen_vtop->r2 = r2;
|
||||
}
|
||||
if (info[nb_args - 1 - i] & 16) {
|
||||
ES(S, 0x23, 3, 2, ireg(S->vtop->r2), splitofs); // sd t0, ofs(sp)
|
||||
S->vtop->r2 = VT_CONST;
|
||||
} else if (loadt == VT_LDOUBLE && S->vtop->r2 != r2) {
|
||||
assert(S->vtop->r2 <= 7 && r2 <= 7);
|
||||
ES(S, 0x23, 3, 2, ireg(S->tccgen_vtop->r2), splitofs); // sd t0, ofs(sp)
|
||||
S->tccgen_vtop->r2 = VT_CONST;
|
||||
} else if (loadt == VT_LDOUBLE && S->tccgen_vtop->r2 != r2) {
|
||||
assert(S->tccgen_vtop->r2 <= 7 && r2 <= 7);
|
||||
/* XXX we'd like to have 'gv' move directly into
|
||||
the right class instead of us fixing it up. */
|
||||
EI(S, 0x13, 0, ireg(r2), ireg(S->vtop->r2), 0); // mv Ra+1, RR2
|
||||
S->vtop->r2 = r2;
|
||||
EI(S, 0x13, 0, ireg(r2), ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
|
||||
S->tccgen_vtop->r2 = r2;
|
||||
}
|
||||
done:
|
||||
vrott(S, i+1);
|
||||
|
@ -748,7 +748,7 @@ done:
|
|||
vrotb(S, nb_args + 1);
|
||||
save_regs(S, nb_args + 1);
|
||||
gcall_or_jmp(S, 1);
|
||||
S->vtop -= nb_args + 1;
|
||||
S->tccgen_vtop -= nb_args + 1;
|
||||
if (stack_add) {
|
||||
if (stack_add >= 0x1000) {
|
||||
o(S, 0x37 | (5 << 7) | (stack_add & 0xfffff000)); //lui t0, upper(v)
|
||||
|
@ -773,9 +773,9 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
CType *type;
|
||||
|
||||
sym = func_type->ref;
|
||||
S->loc = -16; // for ra and s0
|
||||
func_sub_sp_offset = S->ind;
|
||||
S->ind += 5 * 4;
|
||||
S->tccgen_loc = -16; // for ra and s0
|
||||
func_sub_sp_offset = S->tccgen_ind;
|
||||
S->tccgen_ind += 5 * 4;
|
||||
|
||||
areg[0] = 0, areg[1] = 0;
|
||||
addr = 0;
|
||||
|
@ -783,9 +783,9 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
implicit pointer parameter */
|
||||
size = type_size(&S->tccgen_func_vt, &align);
|
||||
if (size > 2 * XLEN) {
|
||||
S->loc -= 8;
|
||||
S->tccgen_func_vc = S->loc;
|
||||
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->loc); // sd a0, loc(s0)
|
||||
S->tccgen_loc -= 8;
|
||||
S->tccgen_func_vc = S->tccgen_loc;
|
||||
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc); // sd a0, loc(s0)
|
||||
}
|
||||
/* define parameters */
|
||||
while ((sym = sym->next) != NULL) {
|
||||
|
@ -795,7 +795,7 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
type = &sym->type;
|
||||
size = type_size(type, &align);
|
||||
if (size > 2 * XLEN) {
|
||||
type = &S->char_pointer_type;
|
||||
type = &S->tccgen_char_pointer_type;
|
||||
size = align = byref = 8;
|
||||
}
|
||||
reg_pass(type, prc, fieldofs, 1);
|
||||
|
@ -810,18 +810,18 @@ ST_FUNC void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
param_addr = addr;
|
||||
addr += size;
|
||||
} else {
|
||||
S->loc -= regcount * 8; // XXX could reserve only 'size' bytes
|
||||
param_addr = S->loc;
|
||||
S->tccgen_loc -= regcount * 8; // XXX could reserve only 'size' bytes
|
||||
param_addr = S->tccgen_loc;
|
||||
for (i = 0; i < regcount; i++) {
|
||||
if (areg[prc[1+i] - 1] >= 8) {
|
||||
assert(i == 1 && regcount == 2 && !(addr & 7));
|
||||
EI(S, 0x03, 3, 5, 8, addr); // ld t0, addr(s0)
|
||||
addr += 8;
|
||||
ES(S, 0x23, 3, 8, 5, S->loc + i*8); // sd t0, loc(s0)
|
||||
ES(S, 0x23, 3, 8, 5, S->tccgen_loc + i*8); // sd t0, loc(s0)
|
||||
} else if (prc[1+i] == RC_FLOAT) {
|
||||
ES(S, 0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, S->loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0)
|
||||
ES(S, 0x27, (size / regcount) == 4 ? 2 : 3, 8, 10 + areg[1]++, S->tccgen_loc + (fieldofs[i+1] >> 4)); // fs[wd] FAi, loc(s0)
|
||||
} else {
|
||||
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->loc + i*8); // sd aX, loc(s0) // XXX
|
||||
ES(S, 0x23, 3, 8, 10 + areg[0]++, S->tccgen_loc + i*8); // sd aX, loc(s0) // XXX
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -867,16 +867,16 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
|
|||
ST_FUNC void arch_transfer_ret_regs(TCCState* S, int aftercall)
|
||||
{
|
||||
int prc[3], fieldofs[3];
|
||||
reg_pass(&S->vtop->type, prc, fieldofs, 1);
|
||||
reg_pass(&S->tccgen_vtop->type, prc, fieldofs, 1);
|
||||
assert(prc[0] == 2 && prc[1] != prc[2] && !(fieldofs[1] >> 4));
|
||||
assert(S->vtop->r == (VT_LOCAL | VT_LVAL));
|
||||
vpushv(S, S->vtop);
|
||||
S->vtop->type.t = fieldofs[1] & VT_BTYPE;
|
||||
(aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->vtop);
|
||||
S->vtop->c.i += fieldofs[2] >> 4;
|
||||
S->vtop->type.t = fieldofs[2] & VT_BTYPE;
|
||||
(aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->vtop);
|
||||
S->vtop--;
|
||||
assert(S->tccgen_vtop->r == (VT_LOCAL | VT_LVAL));
|
||||
vpushv(S, S->tccgen_vtop);
|
||||
S->tccgen_vtop->type.t = fieldofs[1] & VT_BTYPE;
|
||||
(aftercall ? store : load)(S, prc[1] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
|
||||
S->tccgen_vtop->c.i += fieldofs[2] >> 4;
|
||||
S->tccgen_vtop->type.t = fieldofs[2] & VT_BTYPE;
|
||||
(aftercall ? store : load)(S, prc[2] == RC_INT ? REG_IRET : REG_FRET, S->tccgen_vtop);
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
ST_FUNC void gfunc_epilog(TCCState* S)
|
||||
|
@ -888,8 +888,8 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
gen_bounds_epilog(S);
|
||||
#endif
|
||||
|
||||
S->loc = (S->loc - num_va_regs * 8);
|
||||
d = v = (-S->loc + 15) & -16;
|
||||
S->tccgen_loc = (S->tccgen_loc - num_va_regs * 8);
|
||||
d = v = (-S->tccgen_loc + 15) & -16;
|
||||
|
||||
if (v >= (1 << 11)) {
|
||||
d = 16;
|
||||
|
@ -901,7 +901,7 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
EI(S, 0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)
|
||||
EI(S, 0x13, 0, 2, 2, d); // addi sp, sp, v
|
||||
EI(S, 0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
|
||||
large_ofs_ind = S->ind;
|
||||
large_ofs_ind = S->tccgen_ind;
|
||||
if (v >= (1 << 11)) {
|
||||
EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
|
||||
o(S, 0x37 | (5 << 7) | ((0x800 + (v-16)) & 0xfffff000)); //lui t0, upper(v)
|
||||
|
@ -909,9 +909,9 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
ER(S, 0x33, 0, 2, 2, 5, 0x20); // sub sp, sp, t0
|
||||
gjmp_addr(S, func_sub_sp_offset + 5*4);
|
||||
}
|
||||
saved_ind = S->ind;
|
||||
saved_ind = S->tccgen_ind;
|
||||
|
||||
S->ind = func_sub_sp_offset;
|
||||
S->tccgen_ind = func_sub_sp_offset;
|
||||
EI(S, 0x13, 0, 2, 2, -d); // addi sp, sp, -d
|
||||
ES(S, 0x23, 3, 2, 1, d - 8 - num_va_regs * 8); // sd ra, d-8(sp)
|
||||
ES(S, 0x23, 3, 2, 8, d - 16 - num_va_regs * 8); // sd s0, d-16(sp)
|
||||
|
@ -919,15 +919,15 @@ ST_FUNC void gfunc_epilog(TCCState *S)
|
|||
EI(S, 0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
|
||||
else
|
||||
gjmp_addr(S, large_ofs_ind);
|
||||
if ((S->ind - func_sub_sp_offset) != 5*4)
|
||||
if ((S->tccgen_ind - func_sub_sp_offset) != 5*4)
|
||||
EI(S, 0x13, 0, 0, 0, 0); // addi x0, x0, 0 == nop
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_va_start(TCCState *S)
|
||||
{
|
||||
S->vtop--;
|
||||
vset(S, &S->char_pointer_type, VT_LOCAL, func_va_list_ofs);
|
||||
S->tccgen_vtop--;
|
||||
vset(S, &S->tccgen_char_pointer_type, VT_LOCAL, func_va_list_ofs);
|
||||
}
|
||||
|
||||
ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
|
||||
|
@ -943,16 +943,16 @@ ST_FUNC void gen_fill_nops(TCCState *S, int bytes)
|
|||
// Generate forward branch to label:
|
||||
ST_FUNC int gjmp(TCCState* S, int t)
|
||||
{
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return t;
|
||||
o(S, t);
|
||||
return S->ind - 4;
|
||||
return S->tccgen_ind - 4;
|
||||
}
|
||||
|
||||
// Generate branch to known address:
|
||||
ST_FUNC void gjmp_addr(TCCState* S, int a)
|
||||
{
|
||||
uint32_t r = a - S->ind, imm;
|
||||
uint32_t r = a - S->tccgen_ind, imm;
|
||||
if ((r + (1 << 21)) & ~((1U << 22) - 2)) {
|
||||
o(S, 0x17 | (5 << 7) | (((r + 0x800) & 0xfffff000))); // lui RR, up(r)
|
||||
r = (int)r << 20 >> 20;
|
||||
|
@ -969,8 +969,8 @@ ST_FUNC void gjmp_addr(TCCState *S, int a)
|
|||
ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
|
||||
{
|
||||
int tmp;
|
||||
int a = S->vtop->cmp_r & 0xff;
|
||||
int b = (S->vtop->cmp_r >> 8) & 0xff;
|
||||
int a = S->tccgen_vtop->cmp_r & 0xff;
|
||||
int b = (S->tccgen_vtop->cmp_r >> 8) & 0xff;
|
||||
switch (op) {
|
||||
case TOK_ULT: op = 6; break;
|
||||
case TOK_UGE: op = 7; break;
|
||||
|
@ -1006,17 +1006,17 @@ static void gen_opil(TCCState *S, int op, int ll)
|
|||
int a, b, d;
|
||||
int func3 = 0;
|
||||
ll = ll ? 0 : 8;
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
int fc = S->vtop->c.i;
|
||||
if (fc == S->vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||
int fc = S->tccgen_vtop->c.i;
|
||||
if (fc == S->tccgen_vtop->c.i && !(((unsigned)fc + (1 << 11)) >> 12)) {
|
||||
int cll = 0;
|
||||
int m = ll ? 31 : 63;
|
||||
vswap(S);
|
||||
gv(S, RC_INT);
|
||||
a = ireg(S->vtop[0].r);
|
||||
--S->vtop;
|
||||
a = ireg(S->tccgen_vtop[0].r);
|
||||
--S->tccgen_vtop;
|
||||
d = get_reg(S, RC_INT);
|
||||
++S->vtop;
|
||||
++S->tccgen_vtop;
|
||||
vswap(S);
|
||||
switch (op) {
|
||||
case '-':
|
||||
|
@ -1028,12 +1028,12 @@ static void gen_opil(TCCState *S, int op, int ll)
|
|||
cll = ll;
|
||||
do_cop:
|
||||
EI(S, 0x13 | cll, func3, ireg(d), a, fc);
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
vset_VT_CMP(S, TOK_NE);
|
||||
S->vtop->cmp_r = ireg(d) | 0 << 8;
|
||||
S->tccgen_vtop->cmp_r = ireg(d) | 0 << 8;
|
||||
} else
|
||||
S->vtop[0].r = d;
|
||||
S->tccgen_vtop[0].r = d;
|
||||
return;
|
||||
case TOK_LE:
|
||||
if (fc >= (1 << 11) - 1)
|
||||
|
@ -1057,33 +1057,33 @@ static void gen_opil(TCCState *S, int op, int ll)
|
|||
case TOK_GE: /* -> TOK_LT */
|
||||
case TOK_GT: /* -> TOK_LE */
|
||||
gen_opil(S, op - 1, !ll);
|
||||
S->vtop->cmp_op ^= 1;
|
||||
S->tccgen_vtop->cmp_op ^= 1;
|
||||
return;
|
||||
|
||||
case TOK_NE:
|
||||
case TOK_EQ:
|
||||
if (fc)
|
||||
gen_opil(S, '-', !ll), a = ireg(S->vtop++->r);
|
||||
--S->vtop;
|
||||
gen_opil(S, '-', !ll), a = ireg(S->tccgen_vtop++->r);
|
||||
--S->tccgen_vtop;
|
||||
vset_VT_CMP(S, op);
|
||||
S->vtop->cmp_r = a | 0 << 8;
|
||||
S->tccgen_vtop->cmp_r = a | 0 << 8;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
a = ireg(S->vtop[-1].r);
|
||||
b = ireg(S->vtop[0].r);
|
||||
S->vtop -= 2;
|
||||
a = ireg(S->tccgen_vtop[-1].r);
|
||||
b = ireg(S->tccgen_vtop[0].r);
|
||||
S->tccgen_vtop -= 2;
|
||||
d = get_reg(S, RC_INT);
|
||||
S->vtop++;
|
||||
S->vtop[0].r = d;
|
||||
S->tccgen_vtop++;
|
||||
S->tccgen_vtop[0].r = d;
|
||||
d = ireg(d);
|
||||
switch (op) {
|
||||
default:
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
vset_VT_CMP(S, op);
|
||||
S->vtop->cmp_r = a | b << 8;
|
||||
S->tccgen_vtop->cmp_r = a | b << 8;
|
||||
break;
|
||||
}
|
||||
tcc_error(S, "implement me: %s(%s)", __FUNCTION__, get_tok_str(S, op, NULL));
|
||||
|
@ -1145,8 +1145,8 @@ ST_FUNC void gen_opl(TCCState *S, int op)
|
|||
ST_FUNC void gen_opf(TCCState* S, int op)
|
||||
{
|
||||
int rs1, rs2, rd, dbl, invert;
|
||||
if (S->vtop[0].type.t == VT_LDOUBLE) {
|
||||
CType type = S->vtop[0].type;
|
||||
if (S->tccgen_vtop[0].type.t == VT_LDOUBLE) {
|
||||
CType type = S->tccgen_vtop[0].type;
|
||||
int func = 0;
|
||||
int cond = -1;
|
||||
switch (op) {
|
||||
|
@ -1166,10 +1166,10 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
vrott(S, 3);
|
||||
gfunc_call(S, 2);
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = REG_IRET;
|
||||
S->vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->r2 = cond < 0 ? TREG_R(1) : VT_CONST;
|
||||
if (cond < 0)
|
||||
S->vtop->type = type;
|
||||
S->tccgen_vtop->type = type;
|
||||
else {
|
||||
vpushi(S, 0);
|
||||
gen_opil(S, op, 1);
|
||||
|
@ -1178,11 +1178,11 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
}
|
||||
|
||||
gv2(S, RC_FLOAT, RC_FLOAT);
|
||||
assert(S->vtop->type.t == VT_DOUBLE || S->vtop->type.t == VT_FLOAT);
|
||||
dbl = S->vtop->type.t == VT_DOUBLE;
|
||||
rs1 = freg(S->vtop[-1].r);
|
||||
rs2 = freg(S->vtop->r);
|
||||
S->vtop--;
|
||||
assert(S->tccgen_vtop->type.t == VT_DOUBLE || S->tccgen_vtop->type.t == VT_FLOAT);
|
||||
dbl = S->tccgen_vtop->type.t == VT_DOUBLE;
|
||||
rs1 = freg(S->tccgen_vtop[-1].r);
|
||||
rs2 = freg(S->tccgen_vtop->r);
|
||||
S->tccgen_vtop--;
|
||||
invert = 0;
|
||||
switch(op) {
|
||||
default:
|
||||
|
@ -1191,7 +1191,7 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
op = 0; // fadd
|
||||
arithop:
|
||||
rd = get_reg(S, RC_FLOAT);
|
||||
S->vtop->r = rd;
|
||||
S->tccgen_vtop->r = rd;
|
||||
rd = freg(rd);
|
||||
ER(S, 0x53, 7, rd, rs1, rs2, dbl | (op << 2)); // fop.[sd] RD, RS1, RS2 (dyn rm)
|
||||
break;
|
||||
|
@ -1208,7 +1208,7 @@ ST_FUNC void gen_opf(TCCState *S, int op)
|
|||
op = 2; // EQ
|
||||
cmpop:
|
||||
rd = get_reg(S, RC_INT);
|
||||
S->vtop->r = rd;
|
||||
S->tccgen_vtop->r = rd;
|
||||
rd = ireg(rd);
|
||||
ER(S, 0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
|
||||
if (invert)
|
||||
|
@ -1244,8 +1244,8 @@ ST_FUNC void gen_cvt_sxtw(TCCState *S)
|
|||
ST_FUNC void gen_cvt_itof(TCCState* S, int t)
|
||||
{
|
||||
int rr = ireg(gv(S, RC_INT)), dr;
|
||||
int u = S->vtop->type.t & VT_UNSIGNED;
|
||||
int l = (S->vtop->type.t & VT_BTYPE) == VT_LLONG;
|
||||
int u = S->tccgen_vtop->type.t & VT_UNSIGNED;
|
||||
int l = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;
|
||||
if (t == VT_LDOUBLE) {
|
||||
int func = l ?
|
||||
(u ? TOK___floatunditf : TOK___floatditf) :
|
||||
|
@ -1254,14 +1254,14 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
vrott(S, 2);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->type.t = t;
|
||||
S->vtop->r = REG_IRET;
|
||||
S->vtop->r2 = TREG_R(1);
|
||||
S->tccgen_vtop->type.t = t;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->r2 = TREG_R(1);
|
||||
} else {
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
dr = get_reg(S, RC_FLOAT);
|
||||
S->vtop++;
|
||||
S->vtop->r = dr;
|
||||
S->tccgen_vtop++;
|
||||
S->tccgen_vtop->r = dr;
|
||||
dr = freg(dr);
|
||||
EIu(S, 0x53, 7, dr, rr, ((0x68 | (t == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[sd].[wl][u]
|
||||
}
|
||||
|
@ -1269,7 +1269,7 @@ ST_FUNC void gen_cvt_itof(TCCState *S, int t)
|
|||
|
||||
ST_FUNC void gen_cvt_ftoi(TCCState* S, int t)
|
||||
{
|
||||
int ft = S->vtop->type.t & VT_BTYPE;
|
||||
int ft = S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
int l = (t & VT_BTYPE) == VT_LLONG;
|
||||
int u = t & VT_UNSIGNED;
|
||||
if (ft == VT_LDOUBLE) {
|
||||
|
@ -1280,14 +1280,14 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
|
|||
vrott(S, 2);
|
||||
gfunc_call(S, 1);
|
||||
vpushi(S, 0);
|
||||
S->vtop->type.t = t;
|
||||
S->vtop->r = REG_IRET;
|
||||
S->tccgen_vtop->type.t = t;
|
||||
S->tccgen_vtop->r = REG_IRET;
|
||||
} else {
|
||||
int rr = freg(gv(S, RC_FLOAT)), dr;
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
dr = get_reg(S, RC_INT);
|
||||
S->vtop++;
|
||||
S->vtop->r = dr;
|
||||
S->tccgen_vtop++;
|
||||
S->tccgen_vtop->r = dr;
|
||||
dr = ireg(dr);
|
||||
EIu(S, 0x53, 1, dr, rr, ((0x60 | (ft == VT_DOUBLE ? 1 : 0)) << 5) | (u ? 1 : 0) | (l ? 2 : 0)); // fcvt.[wl][u].[sd] rtz
|
||||
}
|
||||
|
@ -1295,7 +1295,7 @@ ST_FUNC void gen_cvt_ftoi(TCCState *S, int t)
|
|||
|
||||
ST_FUNC void gen_cvt_ftof(TCCState* S, int dt)
|
||||
{
|
||||
int st = S->vtop->type.t & VT_BTYPE, rs, rd;
|
||||
int st = S->tccgen_vtop->type.t & VT_BTYPE, rs, rd;
|
||||
dt &= VT_BTYPE;
|
||||
if (st == dt)
|
||||
return;
|
||||
|
@ -1312,21 +1312,21 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int dt)
|
|||
gv(S, RC_F(0));
|
||||
else {
|
||||
gv(S, RC_R(0));
|
||||
assert(S->vtop->r2 < 7);
|
||||
if (S->vtop->r2 != 1 + S->vtop->r) {
|
||||
EI(S, 0x13, 0, ireg(S->vtop->r) + 1, ireg(S->vtop->r2), 0); // mv Ra+1, RR2
|
||||
S->vtop->r2 = 1 + S->vtop->r;
|
||||
assert(S->tccgen_vtop->r2 < 7);
|
||||
if (S->tccgen_vtop->r2 != 1 + S->tccgen_vtop->r) {
|
||||
EI(S, 0x13, 0, ireg(S->tccgen_vtop->r) + 1, ireg(S->tccgen_vtop->r2), 0); // mv Ra+1, RR2
|
||||
S->tccgen_vtop->r2 = 1 + S->tccgen_vtop->r;
|
||||
}
|
||||
}
|
||||
vpush_helper_func(S, func);
|
||||
gcall_or_jmp(S, 1);
|
||||
S->vtop -= 2;
|
||||
S->tccgen_vtop -= 2;
|
||||
vpushi(S, 0);
|
||||
S->vtop->type.t = dt;
|
||||
S->tccgen_vtop->type.t = dt;
|
||||
if (dt == VT_LDOUBLE)
|
||||
S->vtop->r = REG_IRET, S->vtop->r2 = REG_IRET+1;
|
||||
S->tccgen_vtop->r = REG_IRET, S->tccgen_vtop->r2 = REG_IRET+1;
|
||||
else
|
||||
S->vtop->r = REG_FRET;
|
||||
S->tccgen_vtop->r = REG_FRET;
|
||||
} else {
|
||||
assert (dt == VT_FLOAT || dt == VT_DOUBLE);
|
||||
assert (st == VT_FLOAT || st == VT_DOUBLE);
|
||||
|
@ -1336,7 +1336,7 @@ ST_FUNC void gen_cvt_ftof(TCCState *S, int dt)
|
|||
EI(S, 0x53, 0, freg(rd), freg(rs), 0x21 << 5); // fcvt.d.s RD, RS (no rm)
|
||||
else
|
||||
EI(S, 0x53, 7, freg(rd), freg(rs), (0x20 << 5) | 1); // fcvt.s.d RD, RS (dyn rm)
|
||||
S->vtop->r = rd;
|
||||
S->tccgen_vtop->r = rd;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1348,21 +1348,21 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
label.type.t = VT_VOID | VT_STATIC;
|
||||
|
||||
vpushv(S, sv);
|
||||
S->vtop->r = r1 = get_reg(S, RC_INT);
|
||||
S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
|
||||
r2 = get_reg(S, RC_INT);
|
||||
r1 = ireg(r1);
|
||||
r2 = ireg(r2);
|
||||
greloca(S, cur_text_section, sv->sym, S->ind, R_RISCV_PCREL_HI20, 0);
|
||||
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);
|
||||
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
|
||||
o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
|
||||
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
EI(S, 0x03, 3, r2, r1, 0); // ld r2, x[r1]
|
||||
EI(S, 0x13, 0, r2, r2, 1); // addi r2, r2, #1
|
||||
greloca(S, cur_text_section, sv->sym, S->ind, R_RISCV_PCREL_HI20, 0);
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_RISCV_PCREL_HI20, 0);
|
||||
label.c = 0; /* force new local ELF symbol */
|
||||
put_extern_sym(S, &label, cur_text_section, S->ind, 0);
|
||||
put_extern_sym(S, &label, cur_text_section, S->tccgen_ind, 0);
|
||||
o(S, 0x17 | (r1 << 7)); // auipc RR, 0 %pcrel_hi(sym)
|
||||
greloca(S, cur_text_section, &label, S->ind, R_RISCV_PCREL_LO12_S, 0);
|
||||
greloca(S, cur_text_section, &label, S->tccgen_ind, R_RISCV_PCREL_LO12_S, 0);
|
||||
ES(S, 0x23, 3, r1, r2, 0); // sd r2, [r1]
|
||||
vpop(S);
|
||||
}
|
||||
|
@ -1370,7 +1370,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
ST_FUNC void ggoto(TCCState* S)
|
||||
{
|
||||
gcall_or_jmp(S, 0);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_vla_sp_save(TCCState* S, int addr)
|
||||
|
@ -1388,7 +1388,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align)
|
|||
int rr;
|
||||
#if defined(CONFIG_TCC_BCHECK)
|
||||
if (S->do_bounds_check)
|
||||
vpushv(S, S->vtop);
|
||||
vpushv(S, S->tccgen_vtop);
|
||||
#endif
|
||||
rr = ireg(gv(S, RC_INT));
|
||||
#if defined(CONFIG_TCC_BCHECK)
|
||||
|
@ -1403,7 +1403,7 @@ ST_FUNC void gen_vla_alloc(TCCState *S, CType *type, int align)
|
|||
#if defined(CONFIG_TCC_BCHECK)
|
||||
if (S->do_bounds_check) {
|
||||
vpushi(S, 0);
|
||||
S->vtop->r = TREG_R(0);
|
||||
S->tccgen_vtop->r = TREG_R(0);
|
||||
o(S, 0x00010513); /* mv a0,sp */
|
||||
vswap(S);
|
||||
vpush_helper_func(S, TOK___bound_new_region);
|
||||
|
|
35
tcc.h
35
tcc.h
|
@ -1074,21 +1074,21 @@ struct TCCState {
|
|||
/* ------------ tccpp.c ------------ */
|
||||
|
||||
struct BufferedFile *tccpp_file;
|
||||
int tccpp_ch, tok;
|
||||
CValue tokc;
|
||||
int tccpp_ch, tccpp_tok;
|
||||
CValue tccpp_tokc;
|
||||
const int *tccpp_macro_ptr;
|
||||
int tccpp_parse_flags;
|
||||
int tok_flags;
|
||||
CString tokcstr; /* current parsed string, if any */
|
||||
int tccpp_tok_flags;
|
||||
CString tccpp_tokcstr; /* current parsed string, if any */
|
||||
CString tccpp_cstr_buf;
|
||||
CString tccpp_macro_equal_buf;
|
||||
TokenString tokstr_buf;
|
||||
TokenString tccpp_tokstr_buf;
|
||||
TokenString *tccpp_macro_stack;
|
||||
|
||||
/* display benchmark infos */
|
||||
int tccpp_total_lines;
|
||||
int tccpp_total_bytes;
|
||||
int tok_ident;
|
||||
int tccpp_tok_ident;
|
||||
TokenSym **tccpp_table_ident;
|
||||
|
||||
int *tccpp_macro_ptr_allocated;
|
||||
|
@ -1096,7 +1096,7 @@ struct TCCState {
|
|||
int tccpp_unget_saved_buffer[TOK_MAX_SIZE + 1];
|
||||
int tccpp_unget_buffer_enabled;
|
||||
TokenSym *tccpp_hash_ident[TOK_HASH_SIZE];
|
||||
char token_buf[STRING_MAX_SIZE + 1];
|
||||
char tccpp_token_buf[STRING_MAX_SIZE + 1];
|
||||
/* true if isid(c) || isnum(c) */
|
||||
unsigned char tccpp_isidnum_table[256-CH_EOF];
|
||||
|
||||
|
@ -1105,8 +1105,8 @@ struct TCCState {
|
|||
int tccpp_pp_expr;
|
||||
int tccpp_pp_counter;
|
||||
|
||||
TinyAlloc *toksym_alloc;
|
||||
TinyAlloc *tokstr_alloc;
|
||||
TinyAlloc *tccpp_toksym_alloc;
|
||||
TinyAlloc *tccpp_tokstr_alloc;
|
||||
|
||||
/*----------- tccasm.c --------*/
|
||||
Section *tccasm_last_text_section; /* to handle .previous asm directive */
|
||||
|
@ -1114,18 +1114,18 @@ struct TCCState {
|
|||
/* ------------ tccgen.c ------------ */
|
||||
|
||||
Sym *tccgen_global_stack;
|
||||
Sym *local_stack;
|
||||
Sym *local_label_stack;
|
||||
Sym *tccgen_local_stack;
|
||||
Sym *tccgen_local_label_stack;
|
||||
Sym *tccgen_global_label_stack;
|
||||
Sym *tccgen_define_stack;
|
||||
CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, char_pointer_type;
|
||||
SValue *vtop;
|
||||
CType tccgen_int_type, tccgen_func_old_type, tccgen_char_type, tccgen_char_pointer_type;
|
||||
SValue *tccgen_vtop;
|
||||
SValue tccgen__vstack[1 + VSTACK_SIZE];
|
||||
int tccgen_rsym, tccgen_anon_sym, ind, loc;
|
||||
int tccgen_rsym, tccgen_anon_sym, tccgen_ind, tccgen_loc;
|
||||
char tccgen_debug_modes;
|
||||
|
||||
int tccgen_const_wanted; /* true if constant wanted */
|
||||
int nocode_wanted; /* true if no code generation wanted for an expression */
|
||||
int tccgen_nocode_wanted; /* true if no code generation wanted for an expression */
|
||||
int tccgen_global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */
|
||||
CType tccgen_func_vt; /* current function return type (used by return instruction) */
|
||||
int tccgen_func_var; /* true if current function is variadic */
|
||||
|
@ -1136,7 +1136,7 @@ struct TCCState {
|
|||
void **tccgen_sym_pools;
|
||||
int tccgen_nb_sym_pools;
|
||||
Sym *tccgen_all_cleanups, *tccgen_pending_gotos;
|
||||
int local_scope;
|
||||
int tccgen_local_scope;
|
||||
int tccgen_in_sizeof;
|
||||
int tccgen_in_generic;
|
||||
int tccgen_section_sym;
|
||||
|
@ -1155,7 +1155,7 @@ struct TCCState {
|
|||
int tccgen_debug_next_type;
|
||||
debug_hash_t *tccgen_debug_hash;
|
||||
int tccgen_n_debug_hash;
|
||||
debug_info_t *debug_info, *debug_info_root;
|
||||
debug_info_t *tccgen_debug_info, *tccgen_debug_info_root;
|
||||
|
||||
unsigned char tccgen_prec[256];
|
||||
|
||||
|
@ -1629,6 +1629,7 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty);
|
|||
#endif
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
ST_FUNC void gbound_args(TCCState* S, int nb_args);
|
||||
ST_DATA int func_bound_add_epilog;
|
||||
#endif
|
||||
|
||||
/* ------------ tccelf.c ------------ */
|
||||
|
|
228
tccasm.c
228
tccasm.c
|
@ -122,9 +122,9 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
|
|||
uint64_t n;
|
||||
const char *p;
|
||||
|
||||
switch(S->tok) {
|
||||
switch(S->tccpp_tok) {
|
||||
case TOK_PPNUM:
|
||||
p = S->tokc.str.data;
|
||||
p = S->tccpp_tokc.str.data;
|
||||
n = strtoull(p, (char **)&p, 0);
|
||||
if (*p == 'b' || *p == 'f') {
|
||||
/* backward or forward label */
|
||||
|
@ -161,7 +161,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
|
|||
break;
|
||||
case '-':
|
||||
case '~':
|
||||
op = S->tok;
|
||||
op = S->tccpp_tok;
|
||||
next(S);
|
||||
asm_expr_unary(S, pe);
|
||||
if (pe->sym)
|
||||
|
@ -173,7 +173,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
|
|||
break;
|
||||
case TOK_CCHAR:
|
||||
case TOK_LCHAR:
|
||||
pe->v = S->tokc.i;
|
||||
pe->v = S->tccpp_tokc.i;
|
||||
pe->sym = NULL;
|
||||
pe->pcrel = 0;
|
||||
next(S);
|
||||
|
@ -184,16 +184,16 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
|
|||
skip(S, ')');
|
||||
break;
|
||||
case '.':
|
||||
pe->v = S->ind;
|
||||
pe->v = S->tccgen_ind;
|
||||
pe->sym = asm_section_sym(S, cur_text_section);
|
||||
pe->pcrel = 0;
|
||||
next(S);
|
||||
break;
|
||||
default:
|
||||
if (S->tok >= TOK_IDENT) {
|
||||
if (S->tccpp_tok >= TOK_IDENT) {
|
||||
ElfSym *esym;
|
||||
/* label case : if the label was not found, add one */
|
||||
sym = get_asm_sym(S, S->tok, NULL);
|
||||
sym = get_asm_sym(S, S->tccpp_tok, NULL);
|
||||
esym = elfsym(S, sym);
|
||||
if (esym && esym->st_shndx == SHN_ABS) {
|
||||
/* if absolute symbol, no need to put a symbol value */
|
||||
|
@ -207,7 +207,7 @@ static void asm_expr_unary(TCCState *S, ExprValue *pe)
|
|||
}
|
||||
next(S);
|
||||
} else {
|
||||
tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tok, &S->tokc));
|
||||
tcc_error(S, "bad expression syntax [%s]", get_tok_str(S, S->tccpp_tok, &S->tccpp_tokc));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ static void asm_expr_prod(TCCState *S, ExprValue *pe)
|
|||
|
||||
asm_expr_unary(S, pe);
|
||||
for(;;) {
|
||||
op = S->tok;
|
||||
op = S->tccpp_tok;
|
||||
if (op != '*' && op != '/' && op != '%' &&
|
||||
op != TOK_SHL && op != TOK_SAR)
|
||||
break;
|
||||
|
@ -262,7 +262,7 @@ static void asm_expr_logic(TCCState *S, ExprValue *pe)
|
|||
|
||||
asm_expr_prod(S, pe);
|
||||
for(;;) {
|
||||
op = S->tok;
|
||||
op = S->tccpp_tok;
|
||||
if (op != '&' && op != '|' && op != '^')
|
||||
break;
|
||||
next(S);
|
||||
|
@ -291,7 +291,7 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe)
|
|||
|
||||
asm_expr_logic(S, pe);
|
||||
for(;;) {
|
||||
op = S->tok;
|
||||
op = S->tccpp_tok;
|
||||
if (op != '+' && op != '-')
|
||||
break;
|
||||
next(S);
|
||||
|
@ -323,7 +323,7 @@ static inline void asm_expr_sum(TCCState *S, ExprValue *pe)
|
|||
} else if (esym2->st_shndx == cur_text_section->sh_num) {
|
||||
/* When subtracting a defined symbol in current section
|
||||
this actually makes the value PC-relative. */
|
||||
pe->v -= esym2->st_value - S->ind - 4;
|
||||
pe->v -= esym2->st_value - S->tccgen_ind - 4;
|
||||
pe->pcrel = 1;
|
||||
e2.sym = NULL;
|
||||
} else {
|
||||
|
@ -342,7 +342,7 @@ static inline void asm_expr_cmp(TCCState *S, ExprValue *pe)
|
|||
|
||||
asm_expr_sum(S, pe);
|
||||
for(;;) {
|
||||
op = S->tok;
|
||||
op = S->tccpp_tok;
|
||||
if (op != TOK_EQ && op != TOK_NE
|
||||
&& (op > TOK_GT || op < TOK_ULE))
|
||||
break;
|
||||
|
@ -428,7 +428,7 @@ static Sym* asm_new_label1(TCCState *S, int label, int is_local,
|
|||
|
||||
static Sym* asm_new_label(TCCState *S, int label, int is_local)
|
||||
{
|
||||
return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->ind);
|
||||
return asm_new_label1(S, label, is_local, cur_text_section->sh_num, S->tccgen_ind);
|
||||
}
|
||||
|
||||
/* Set the value of LABEL to that of some expression (possibly
|
||||
|
@ -452,9 +452,9 @@ static Sym* set_symbol(TCCState *S, int label)
|
|||
|
||||
static void use_section1(TCCState *S, Section *sec)
|
||||
{
|
||||
cur_text_section->data_offset = S->ind;
|
||||
cur_text_section->data_offset = S->tccgen_ind;
|
||||
cur_text_section = sec;
|
||||
S->ind = cur_text_section->data_offset;
|
||||
S->tccgen_ind = cur_text_section->data_offset;
|
||||
}
|
||||
|
||||
static void use_section(TCCState *S, const char *name)
|
||||
|
@ -488,13 +488,13 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
|
||||
/* assembler directive */
|
||||
sec = cur_text_section;
|
||||
switch(S->tok) {
|
||||
switch(S->tccpp_tok) {
|
||||
case TOK_ASMDIR_align:
|
||||
case TOK_ASMDIR_balign:
|
||||
case TOK_ASMDIR_p2align:
|
||||
case TOK_ASMDIR_skip:
|
||||
case TOK_ASMDIR_space:
|
||||
tok1 = S->tok;
|
||||
tok1 = S->tccpp_tok;
|
||||
next(S);
|
||||
n = asm_int_expr(S);
|
||||
if (tok1 == TOK_ASMDIR_p2align)
|
||||
|
@ -507,8 +507,8 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
|
||||
if (n < 0 || (n & (n-1)) != 0)
|
||||
tcc_error(S, "alignment must be a positive power of two");
|
||||
offset = (S->ind + n - 1) & -n;
|
||||
size = offset - S->ind;
|
||||
offset = (S->tccgen_ind + n - 1) & -n;
|
||||
size = offset - S->tccgen_ind;
|
||||
/* the section must have a compatible alignment */
|
||||
if (sec->sh_addralign < n)
|
||||
sec->sh_addralign = n;
|
||||
|
@ -518,17 +518,17 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
size = n;
|
||||
}
|
||||
v = 0;
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
v = asm_int_expr(S);
|
||||
}
|
||||
zero_pad:
|
||||
if (sec->sh_type != SHT_NOBITS) {
|
||||
sec->data_offset = S->ind;
|
||||
sec->data_offset = S->tccgen_ind;
|
||||
ptr = section_ptr_add(S, sec, size);
|
||||
memset(ptr, v, size);
|
||||
}
|
||||
S->ind += size;
|
||||
S->tccgen_ind += size;
|
||||
break;
|
||||
case TOK_ASMDIR_quad:
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
|
@ -540,8 +540,8 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
uint64_t vl;
|
||||
const char *p;
|
||||
|
||||
p = S->tokc.str.data;
|
||||
if (S->tok != TOK_PPNUM) {
|
||||
p = S->tccpp_tokc.str.data;
|
||||
if (S->tccpp_tok != TOK_PPNUM) {
|
||||
error_constant:
|
||||
tcc_error(S, "64 bit constant");
|
||||
}
|
||||
|
@ -554,9 +554,9 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
gen_le32(S, vl);
|
||||
gen_le32(S, vl >> 32);
|
||||
} else {
|
||||
S->ind += 8;
|
||||
S->tccgen_ind += 8;
|
||||
}
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
break;
|
||||
next(S);
|
||||
}
|
||||
|
@ -593,9 +593,9 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
gen_le16(S, e.v);
|
||||
}
|
||||
} else {
|
||||
S->ind += size;
|
||||
S->tccgen_ind += size;
|
||||
}
|
||||
if (S->tok != ',')
|
||||
if (S->tccpp_tok != ',')
|
||||
break;
|
||||
next(S);
|
||||
}
|
||||
|
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
}
|
||||
size = 1;
|
||||
val = 0;
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
size = asm_int_expr(S);
|
||||
if (size < 0) {
|
||||
|
@ -621,7 +621,7 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
}
|
||||
if (size > 8)
|
||||
size = 8;
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
val = asm_int_expr(S);
|
||||
}
|
||||
|
@ -649,8 +649,8 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
next(S);
|
||||
repeat = asm_int_expr(S);
|
||||
init_str = tok_str_alloc(S);
|
||||
while (next(S), S->tok != TOK_ASMDIR_endr) {
|
||||
if (S->tok == CH_EOF)
|
||||
while (next(S), S->tccpp_tok != TOK_ASMDIR_endr) {
|
||||
if (S->tccpp_tok == CH_EOF)
|
||||
tcc_error(S, "we at end of file, .endr not found");
|
||||
tok_str_add_tok(S, init_str);
|
||||
}
|
||||
|
@ -680,31 +680,31 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
expect(S, "constant or same-section symbol");
|
||||
n += esym->st_value;
|
||||
}
|
||||
if (n < S->ind)
|
||||
if (n < S->tccgen_ind)
|
||||
tcc_error(S, "attempt to .org backwards");
|
||||
v = 0;
|
||||
size = n - S->ind;
|
||||
size = n - S->tccgen_ind;
|
||||
goto zero_pad;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_set:
|
||||
next(S);
|
||||
tok1 = S->tok;
|
||||
tok1 = S->tccpp_tok;
|
||||
next(S);
|
||||
/* Also accept '.set stuff', but don't do anything with this.
|
||||
It's used in GAS to set various features like '.set mips16'. */
|
||||
if (S->tok == ',')
|
||||
if (S->tccpp_tok == ',')
|
||||
set_symbol(S, tok1);
|
||||
break;
|
||||
case TOK_ASMDIR_globl:
|
||||
case TOK_ASMDIR_global:
|
||||
case TOK_ASMDIR_weak:
|
||||
case TOK_ASMDIR_hidden:
|
||||
tok1 = S->tok;
|
||||
tok1 = S->tccpp_tok;
|
||||
do {
|
||||
Sym *sym;
|
||||
next(S);
|
||||
sym = get_asm_sym(S, S->tok, NULL);
|
||||
sym = get_asm_sym(S, S->tccpp_tok, NULL);
|
||||
if (tok1 != TOK_ASMDIR_hidden)
|
||||
sym->type.t &= ~VT_STATIC;
|
||||
if (tok1 == TOK_ASMDIR_weak)
|
||||
|
@ -713,7 +713,7 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
sym->a.visibility = STV_HIDDEN;
|
||||
update_storage(S, sym);
|
||||
next(S);
|
||||
} while (S->tok == ',');
|
||||
} while (S->tccpp_tok == ',');
|
||||
break;
|
||||
case TOK_ASMDIR_string:
|
||||
case TOK_ASMDIR_ascii:
|
||||
|
@ -722,21 +722,21 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
const uint8_t *p;
|
||||
int i, size, t;
|
||||
|
||||
t = S->tok;
|
||||
t = S->tccpp_tok;
|
||||
next(S);
|
||||
for(;;) {
|
||||
if (S->tok != TOK_STR)
|
||||
if (S->tccpp_tok != TOK_STR)
|
||||
expect(S, "string constant");
|
||||
p = S->tokc.str.data;
|
||||
size = S->tokc.str.size;
|
||||
p = S->tccpp_tokc.str.data;
|
||||
size = S->tccpp_tokc.str.size;
|
||||
if (t == TOK_ASMDIR_ascii && size > 0)
|
||||
size--;
|
||||
for(i = 0; i < size; i++)
|
||||
g(S, p[i]);
|
||||
next(S);
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
} else if (S->tok != TOK_STR) {
|
||||
} else if (S->tccpp_tok != TOK_STR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -747,10 +747,10 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
case TOK_ASMDIR_bss:
|
||||
{
|
||||
char sname[64];
|
||||
tok1 = S->tok;
|
||||
tok1 = S->tccpp_tok;
|
||||
n = 0;
|
||||
next(S);
|
||||
if (S->tok != ';' && S->tok != TOK_LINEFEED) {
|
||||
if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED) {
|
||||
n = asm_int_expr(S);
|
||||
next(S);
|
||||
}
|
||||
|
@ -767,10 +767,10 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
|
||||
filename[0] = '\0';
|
||||
next(S);
|
||||
if (S->tok == TOK_STR)
|
||||
pstrcat(filename, sizeof(filename), S->tokc.str.data);
|
||||
if (S->tccpp_tok == TOK_STR)
|
||||
pstrcat(filename, sizeof(filename), S->tccpp_tokc.str.data);
|
||||
else
|
||||
pstrcat(filename, sizeof(filename), get_tok_str(S, S->tok, NULL));
|
||||
pstrcat(filename, sizeof(filename), get_tok_str(S, S->tccpp_tok, NULL));
|
||||
tcc_warning_c(warn_unsupported)(S, "ignoring .file %s", filename);
|
||||
next(S);
|
||||
}
|
||||
|
@ -781,10 +781,10 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
|
||||
ident[0] = '\0';
|
||||
next(S);
|
||||
if (S->tok == TOK_STR)
|
||||
pstrcat(ident, sizeof(ident), S->tokc.str.data);
|
||||
if (S->tccpp_tok == TOK_STR)
|
||||
pstrcat(ident, sizeof(ident), S->tccpp_tokc.str.data);
|
||||
else
|
||||
pstrcat(ident, sizeof(ident), get_tok_str(S, S->tok, NULL));
|
||||
pstrcat(ident, sizeof(ident), get_tok_str(S, S->tccpp_tok, NULL));
|
||||
tcc_warning_c(warn_unsupported)(S, "ignoring .ident %s", ident);
|
||||
next(S);
|
||||
}
|
||||
|
@ -794,15 +794,15 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
Sym *sym;
|
||||
|
||||
next(S);
|
||||
sym = asm_label_find(S, S->tok);
|
||||
sym = asm_label_find(S, S->tccpp_tok);
|
||||
if (!sym) {
|
||||
tcc_error(S, "label not found: %s", get_tok_str(S, S->tok, NULL));
|
||||
tcc_error(S, "label not found: %s", get_tok_str(S, S->tccpp_tok, NULL));
|
||||
}
|
||||
/* XXX .size name,label2-label1 */
|
||||
tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tok, NULL));
|
||||
tcc_warning_c(warn_unsupported)(S, "ignoring .size %s,*", get_tok_str(S, S->tccpp_tok, NULL));
|
||||
next(S);
|
||||
skip(S, ',');
|
||||
while (S->tok != TOK_LINEFEED && S->tok != ';' && S->tok != CH_EOF) {
|
||||
while (S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ';' && S->tccpp_tok != CH_EOF) {
|
||||
next(S);
|
||||
}
|
||||
}
|
||||
|
@ -813,15 +813,15 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
const char *newtype;
|
||||
|
||||
next(S);
|
||||
sym = get_asm_sym(S, S->tok, NULL);
|
||||
sym = get_asm_sym(S, S->tccpp_tok, NULL);
|
||||
next(S);
|
||||
skip(S, ',');
|
||||
if (S->tok == TOK_STR) {
|
||||
newtype = S->tokc.str.data;
|
||||
if (S->tccpp_tok == TOK_STR) {
|
||||
newtype = S->tccpp_tokc.str.data;
|
||||
} else {
|
||||
if (S->tok == '@' || S->tok == '%')
|
||||
if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
|
||||
next(S);
|
||||
newtype = get_tok_str(S, S->tok, NULL);
|
||||
newtype = get_tok_str(S, S->tccpp_tok, NULL);
|
||||
}
|
||||
|
||||
if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
|
||||
|
@ -839,26 +839,26 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
char sname[256];
|
||||
int old_nb_section = S->nb_sections;
|
||||
|
||||
tok1 = S->tok;
|
||||
tok1 = S->tccpp_tok;
|
||||
/* XXX: support more options */
|
||||
next(S);
|
||||
sname[0] = '\0';
|
||||
while (S->tok != ';' && S->tok != TOK_LINEFEED && S->tok != ',') {
|
||||
if (S->tok == TOK_STR)
|
||||
pstrcat(sname, sizeof(sname), S->tokc.str.data);
|
||||
while (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED && S->tccpp_tok != ',') {
|
||||
if (S->tccpp_tok == TOK_STR)
|
||||
pstrcat(sname, sizeof(sname), S->tccpp_tokc.str.data);
|
||||
else
|
||||
pstrcat(sname, sizeof(sname), get_tok_str(S, S->tok, NULL));
|
||||
pstrcat(sname, sizeof(sname), get_tok_str(S, S->tccpp_tok, NULL));
|
||||
next(S);
|
||||
}
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
/* skip section options */
|
||||
next(S);
|
||||
if (S->tok != TOK_STR)
|
||||
if (S->tccpp_tok != TOK_STR)
|
||||
expect(S, "string constant");
|
||||
next(S);
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
if (S->tok == '@' || S->tok == '%')
|
||||
if (S->tccpp_tok == '@' || S->tccpp_tok == '%')
|
||||
next(S);
|
||||
next(S);
|
||||
}
|
||||
|
@ -911,7 +911,7 @@ static void asm_parse_directive(TCCState *S, int global)
|
|||
break;
|
||||
#endif
|
||||
default:
|
||||
tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tok, NULL));
|
||||
tcc_error(S, "unknown assembler directive '.%s'", get_tok_str(S, S->tccpp_tok, NULL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -928,20 +928,20 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
|
|||
S->tccpp_parse_flags |= PARSE_FLAG_PREPROCESS;
|
||||
for(;;) {
|
||||
next(S);
|
||||
if (S->tok == TOK_EOF)
|
||||
if (S->tccpp_tok == TOK_EOF)
|
||||
break;
|
||||
S->tccpp_parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
|
||||
redo:
|
||||
if (S->tok == '#') {
|
||||
if (S->tccpp_tok == '#') {
|
||||
/* horrible gas comment */
|
||||
while (S->tok != TOK_LINEFEED)
|
||||
while (S->tccpp_tok != TOK_LINEFEED)
|
||||
next(S);
|
||||
} else if (S->tok >= TOK_ASMDIR_FIRST && S->tok <= TOK_ASMDIR_LAST) {
|
||||
} else if (S->tccpp_tok >= TOK_ASMDIR_FIRST && S->tccpp_tok <= TOK_ASMDIR_LAST) {
|
||||
asm_parse_directive(S, global);
|
||||
} else if (S->tok == TOK_PPNUM) {
|
||||
} else if (S->tccpp_tok == TOK_PPNUM) {
|
||||
const char *p;
|
||||
int n;
|
||||
p = S->tokc.str.data;
|
||||
p = S->tccpp_tokc.str.data;
|
||||
n = strtoul(p, (char **)&p, 10);
|
||||
if (*p != '\0')
|
||||
expect(S, "':'");
|
||||
|
@ -950,16 +950,16 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
|
|||
next(S);
|
||||
skip(S, ':');
|
||||
goto redo;
|
||||
} else if (S->tok >= TOK_IDENT) {
|
||||
} else if (S->tccpp_tok >= TOK_IDENT) {
|
||||
/* instruction or label */
|
||||
opcode = S->tok;
|
||||
opcode = S->tccpp_tok;
|
||||
next(S);
|
||||
if (S->tok == ':') {
|
||||
if (S->tccpp_tok == ':') {
|
||||
/* new label */
|
||||
asm_new_label(S, opcode, 0);
|
||||
next(S);
|
||||
goto redo;
|
||||
} else if (S->tok == '=') {
|
||||
} else if (S->tccpp_tok == '=') {
|
||||
set_symbol(S, opcode);
|
||||
goto redo;
|
||||
} else {
|
||||
|
@ -967,7 +967,7 @@ static int tcc_assemble_internal(TCCState *S, int do_preprocess, int global)
|
|||
}
|
||||
}
|
||||
/* end of line */
|
||||
if (S->tok != ';' && S->tok != TOK_LINEFEED)
|
||||
if (S->tccpp_tok != ';' && S->tccpp_tok != TOK_LINEFEED)
|
||||
expect(S, "end of line");
|
||||
S->tccpp_parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
|
||||
}
|
||||
|
@ -983,10 +983,10 @@ ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess)
|
|||
tcc_debug_start(S);
|
||||
/* default section is text */
|
||||
cur_text_section = text_section;
|
||||
S->ind = cur_text_section->data_offset;
|
||||
S->nocode_wanted = 0;
|
||||
S->tccgen_ind = cur_text_section->data_offset;
|
||||
S->tccgen_nocode_wanted = 0;
|
||||
ret = tcc_assemble_internal(S, do_preprocess, 1);
|
||||
cur_text_section->data_offset = S->ind;
|
||||
cur_text_section->data_offset = S->tccgen_ind;
|
||||
tcc_debug_end(S);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1107,7 +1107,7 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
|
|||
ASMOperand *op;
|
||||
int nb_operands;
|
||||
|
||||
if (S->tok != ':') {
|
||||
if (S->tccpp_tok != ':') {
|
||||
nb_operands = *nb_operands_ptr;
|
||||
for(;;) {
|
||||
CString astr;
|
||||
|
@ -1115,11 +1115,11 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
|
|||
tcc_error(S, "too many asm operands");
|
||||
op = &operands[nb_operands++];
|
||||
op->id = 0;
|
||||
if (S->tok == '[') {
|
||||
if (S->tccpp_tok == '[') {
|
||||
next(S);
|
||||
if (S->tok < TOK_IDENT)
|
||||
if (S->tccpp_tok < TOK_IDENT)
|
||||
expect(S, "identifier");
|
||||
op->id = S->tok;
|
||||
op->id = S->tccpp_tok;
|
||||
next(S);
|
||||
skip(S, ']');
|
||||
}
|
||||
|
@ -1130,23 +1130,23 @@ static void parse_asm_operands(TCCState *S, ASMOperand *operands, int *nb_operan
|
|||
skip(S, '(');
|
||||
gexpr(S);
|
||||
if (is_output) {
|
||||
if (!(S->vtop->type.t & VT_ARRAY))
|
||||
if (!(S->tccgen_vtop->type.t & VT_ARRAY))
|
||||
test_lvalue(S);
|
||||
} else {
|
||||
/* we want to avoid LLOCAL case, except when the 'm'
|
||||
constraint is used. Note that it may come from
|
||||
register storage, so we need to convert (reg)
|
||||
case */
|
||||
if ((S->vtop->r & VT_LVAL) &&
|
||||
((S->vtop->r & VT_VALMASK) == VT_LLOCAL ||
|
||||
(S->vtop->r & VT_VALMASK) < VT_CONST) &&
|
||||
if ((S->tccgen_vtop->r & VT_LVAL) &&
|
||||
((S->tccgen_vtop->r & VT_VALMASK) == VT_LLOCAL ||
|
||||
(S->tccgen_vtop->r & VT_VALMASK) < VT_CONST) &&
|
||||
!strchr(op->constraint, 'm')) {
|
||||
gv(S, RC_INT);
|
||||
}
|
||||
}
|
||||
op->vt = S->vtop;
|
||||
op->vt = S->tccgen_vtop;
|
||||
skip(S, ')');
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
} else {
|
||||
break;
|
||||
|
@ -1167,7 +1167,7 @@ ST_FUNC void asm_instr(TCCState *S)
|
|||
|
||||
/* since we always generate the asm() instruction, we can ignore
|
||||
volatile */
|
||||
if (S->tok == TOK_VOLATILE1 || S->tok == TOK_VOLATILE2 || S->tok == TOK_VOLATILE3) {
|
||||
if (S->tccpp_tok == TOK_VOLATILE1 || S->tccpp_tok == TOK_VOLATILE2 || S->tccpp_tok == TOK_VOLATILE3) {
|
||||
next(S);
|
||||
}
|
||||
parse_asm_str(S, &astr);
|
||||
|
@ -1175,27 +1175,27 @@ ST_FUNC void asm_instr(TCCState *S)
|
|||
nb_outputs = 0;
|
||||
must_subst = 0;
|
||||
memset(clobber_regs, 0, sizeof(clobber_regs));
|
||||
if (S->tok == ':') {
|
||||
if (S->tccpp_tok == ':') {
|
||||
next(S);
|
||||
must_subst = 1;
|
||||
/* output args */
|
||||
parse_asm_operands(S, operands, &nb_operands, 1);
|
||||
nb_outputs = nb_operands;
|
||||
if (S->tok == ':') {
|
||||
if (S->tccpp_tok == ':') {
|
||||
next(S);
|
||||
if (S->tok != ')') {
|
||||
if (S->tccpp_tok != ')') {
|
||||
/* input args */
|
||||
parse_asm_operands(S, operands, &nb_operands, 0);
|
||||
if (S->tok == ':') {
|
||||
if (S->tccpp_tok == ':') {
|
||||
/* clobber list */
|
||||
/* XXX: handle registers */
|
||||
next(S);
|
||||
for(;;) {
|
||||
if (S->tok != TOK_STR)
|
||||
if (S->tccpp_tok != TOK_STR)
|
||||
expect(S, "string constant");
|
||||
asm_clobber(S, clobber_regs, S->tokc.str.data);
|
||||
asm_clobber(S, clobber_regs, S->tccpp_tokc.str.data);
|
||||
next(S);
|
||||
if (S->tok == ',') {
|
||||
if (S->tccpp_tok == ',') {
|
||||
next(S);
|
||||
} else {
|
||||
break;
|
||||
|
@ -1208,7 +1208,7 @@ ST_FUNC void asm_instr(TCCState *S)
|
|||
skip(S, ')');
|
||||
/* NOTE: we do not eat the ';' so that we can restore the current
|
||||
token after the assembler parsing */
|
||||
if (S->tok != ';')
|
||||
if (S->tccpp_tok != ';')
|
||||
expect(S, "';'");
|
||||
|
||||
/* save all values in the memory */
|
||||
|
@ -1267,34 +1267,34 @@ ST_FUNC void asm_instr(TCCState *S)
|
|||
ST_FUNC void asm_global_instr(TCCState* S)
|
||||
{
|
||||
CString astr;
|
||||
int saved_nocode_wanted = S->nocode_wanted;
|
||||
int saved_nocode_wanted = S->tccgen_nocode_wanted;
|
||||
|
||||
/* Global asm blocks are always emitted. */
|
||||
S->nocode_wanted = 0;
|
||||
S->tccgen_nocode_wanted = 0;
|
||||
next(S);
|
||||
parse_asm_str(S, &astr);
|
||||
skip(S, ')');
|
||||
/* NOTE: we do not eat the ';' so that we can restore the current
|
||||
token after the assembler parsing */
|
||||
if (S->tok != ';')
|
||||
if (S->tccpp_tok != ';')
|
||||
expect(S, "';'");
|
||||
|
||||
#ifdef ASM_DEBUG
|
||||
printf("asm_global: \"%s\"\n", (char *)astr.data);
|
||||
#endif
|
||||
cur_text_section = text_section;
|
||||
S->ind = cur_text_section->data_offset;
|
||||
S->tccgen_ind = cur_text_section->data_offset;
|
||||
|
||||
/* assemble the string with tcc internal assembler */
|
||||
tcc_assemble_inline(S, astr.data, astr.size - 1, 1);
|
||||
|
||||
cur_text_section->data_offset = S->ind;
|
||||
cur_text_section->data_offset = S->tccgen_ind;
|
||||
|
||||
/* restore the current C token */
|
||||
next(S);
|
||||
|
||||
cstr_free(S, &astr);
|
||||
S->nocode_wanted = saved_nocode_wanted;
|
||||
S->tccgen_nocode_wanted = saved_nocode_wanted;
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
|
@ -1304,12 +1304,12 @@ ST_FUNC int tcc_assemble(TCCState *S, int do_preprocess)
|
|||
tcc_error(S, "asm not supported");
|
||||
}
|
||||
|
||||
ST_FUNC void asm_instr(TCCState *S)
|
||||
ST_FUNC void asm_instr(S)
|
||||
{
|
||||
tcc_error(S, "inline asm() not supported");
|
||||
}
|
||||
|
||||
ST_FUNC void asm_global_instr(TCCState *S)
|
||||
ST_FUNC void asm_global_instr(S)
|
||||
{
|
||||
tcc_error(S, "inline asm() not supported");
|
||||
}
|
||||
|
|
|
@ -865,7 +865,7 @@ ST_FUNC int macho_add_dllref(TCCState *S, int lev, const char* soname)
|
|||
#ifdef TCC_IS_NATIVE
|
||||
/* Looks for the active developer SDK set by xcode-select (or the default
|
||||
one set during installation.) */
|
||||
ST_FUNC void tcc_add_macos_sdkpath(TCCState *S)
|
||||
ST_FUNC void tcc_add_macos_sdkpath(TCCState* s)
|
||||
{
|
||||
char *sdkroot = NULL, *pos = NULL;
|
||||
void* xcs = dlopen("libxcselect.dylib", RTLD_GLOBAL | RTLD_LAZY);
|
||||
|
|
2
tccpe.c
2
tccpe.c
|
@ -1512,7 +1512,7 @@ ST_FUNC SValue *pe_getimport(TCCState *S, SValue *sv, SValue *v2)
|
|||
vpushv(S, v2);
|
||||
vpushi(S, sv->c.i);
|
||||
gen_opi(S, '+');
|
||||
*v2 = *S->vtop--;
|
||||
*v2 = *S->tccgen_vtop--;
|
||||
}
|
||||
v2->type.t = sv->type.t;
|
||||
v2->r |= sv->r & VT_LVAL;
|
||||
|
|
330
x86_64-gen.c
330
x86_64-gen.c
|
@ -152,13 +152,13 @@ ST_DATA const int reg_classes[NB_REGS] = {
|
|||
ST_FUNC void g(TCCState* S, int c)
|
||||
{
|
||||
int ind1;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return;
|
||||
ind1 = S->ind + 1;
|
||||
ind1 = S->tccgen_ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(S, cur_text_section, ind1);
|
||||
cur_text_section->data[S->ind] = c;
|
||||
S->ind = ind1;
|
||||
cur_text_section->data[S->tccgen_ind] = c;
|
||||
S->tccgen_ind = ind1;
|
||||
}
|
||||
|
||||
ST_FUNC void o(TCCState* S, unsigned int c)
|
||||
|
@ -228,10 +228,10 @@ static int is64_type(int t)
|
|||
static int oad(TCCState *S, int c, int s)
|
||||
{
|
||||
int t;
|
||||
if (S->nocode_wanted)
|
||||
if (S->tccgen_nocode_wanted)
|
||||
return s;
|
||||
o(S, c);
|
||||
t = S->ind;
|
||||
t = S->tccgen_ind;
|
||||
gen_le32(S, s);
|
||||
return t;
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ static int oad(TCCState *S, int c, int s)
|
|||
ST_FUNC void gen_addr32(TCCState *S, int r, Sym *sym, int c)
|
||||
{
|
||||
if (r & VT_SYM)
|
||||
greloca(S, cur_text_section, sym, S->ind, R_X86_64_32S, c), c=0;
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_32S, c), c=0;
|
||||
gen_le32(S, c);
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ ST_FUNC void gen_addr32(TCCState *S, int r, Sym *sym, int c)
|
|||
ST_FUNC void gen_addr64(TCCState *S, int r, Sym *sym, int64_t c)
|
||||
{
|
||||
if (r & VT_SYM)
|
||||
greloca(S, cur_text_section, sym, S->ind, R_X86_64_64, c), c=0;
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_64, c), c=0;
|
||||
gen_le64(S, c);
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,7 @@ ST_FUNC void gen_addr64(TCCState *S, int r, Sym *sym, int64_t c)
|
|||
ST_FUNC void gen_addrpc32(TCCState *S, int r, Sym *sym, int c)
|
||||
{
|
||||
if (r & VT_SYM)
|
||||
greloca(S, cur_text_section, sym, S->ind, R_X86_64_PC32, c-4), c=4;
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_PC32, c-4), c=4;
|
||||
gen_le32(S, c-4);
|
||||
}
|
||||
|
||||
|
@ -268,12 +268,12 @@ static void gen_gotpcrel(TCCState *S, int r, Sym *sym, int c)
|
|||
#ifdef TCC_TARGET_PE
|
||||
tcc_error(S, "internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n",
|
||||
get_tok_str(S, sym->v, NULL), c, r,
|
||||
cur_text_section->data[S->ind-3],
|
||||
cur_text_section->data[S->ind-2],
|
||||
cur_text_section->data[S->ind-1]
|
||||
cur_text_section->data[S->tccgen_ind-3],
|
||||
cur_text_section->data[S->tccgen_ind-2],
|
||||
cur_text_section->data[S->tccgen_ind-1]
|
||||
);
|
||||
#endif
|
||||
greloca(S, cur_text_section, sym, S->ind, R_X86_64_GOTPCREL, -4);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind, R_X86_64_GOTPCREL, -4);
|
||||
gen_le32(S, 0);
|
||||
if (c) {
|
||||
/* we use add c, %xxx for displacement */
|
||||
|
@ -482,7 +482,7 @@ void load(TCCState *S, int r, SValue *sv)
|
|||
} else if (v == VT_CMP) {
|
||||
if (fc & 0x100)
|
||||
{
|
||||
v = S->vtop->cmp_r;
|
||||
v = S->tccgen_vtop->cmp_r;
|
||||
fc &= ~0x100;
|
||||
/* This was a float compare. If the parity bit is
|
||||
set the result was unordered, meaning false for everything
|
||||
|
@ -624,19 +624,19 @@ void store(TCCState *S, int r, SValue *v)
|
|||
static void gcall_or_jmp(TCCState *S, int is_jmp)
|
||||
{
|
||||
int r;
|
||||
if ((S->vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
||||
((S->vtop->r & VT_SYM) && (S->vtop->c.i-4) == (int)(S->vtop->c.i-4))) {
|
||||
if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
||||
((S->tccgen_vtop->r & VT_SYM) && (S->tccgen_vtop->c.i-4) == (int)(S->tccgen_vtop->c.i-4))) {
|
||||
/* constant symbolic case -> simple relocation */
|
||||
#ifdef TCC_TARGET_PE
|
||||
greloca(S, cur_text_section, S->vtop->sym, S->ind + 1, R_X86_64_PC32, (int)(S->vtop->c.i-4));
|
||||
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_X86_64_PC32, (int)(S->tccgen_vtop->c.i-4));
|
||||
#else
|
||||
greloca(S, cur_text_section, S->vtop->sym, S->ind + 1, R_X86_64_PLT32, (int)(S->vtop->c.i-4));
|
||||
greloca(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind + 1, R_X86_64_PLT32, (int)(S->tccgen_vtop->c.i-4));
|
||||
#endif
|
||||
oad(S, 0xe8 + is_jmp, 0); /* call/jmp im */
|
||||
} else {
|
||||
/* otherwise, indirect call */
|
||||
r = TREG_R11;
|
||||
load(S, r, S->vtop);
|
||||
load(S, r, S->tccgen_vtop);
|
||||
o(S, 0x41); /* REX */
|
||||
o(S, 0xff); /* call/jmp *r */
|
||||
o(S, 0xd0 + REG_VALUE(r) + (is_jmp << 4));
|
||||
|
@ -650,9 +650,9 @@ static void gen_bounds_call(TCCState *S, int v)
|
|||
Sym *sym = external_helper_sym(S, v);
|
||||
oad(S, 0xe8, 0);
|
||||
#ifdef TCC_TARGET_PE
|
||||
greloca(S, cur_text_section, sym, S->ind-4, R_X86_64_PC32, -4);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind-4, R_X86_64_PC32, -4);
|
||||
#else
|
||||
greloca(S, cur_text_section, sym, S->ind-4, R_X86_64_PLT32, -4);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind-4, R_X86_64_PLT32, -4);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -666,7 +666,7 @@ static void gen_bounds_prolog(TCCState *S)
|
|||
{
|
||||
/* leave some room for bound checking code */
|
||||
S->func_bound_offset = lbounds_section->data_offset;
|
||||
S->func_bound_ind = S->ind;
|
||||
S->func_bound_ind = S->tccgen_ind;
|
||||
S->func_bound_add_epilog = 0;
|
||||
o(S, 0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /*lbound section pointer */
|
||||
gen_le32(S, 0);
|
||||
|
@ -687,22 +687,22 @@ static void gen_bounds_epilog(TCCState *S)
|
|||
bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
|
||||
*bounds_ptr = 0;
|
||||
|
||||
sym_data = get_sym_ref(S, &S->char_pointer_type, lbounds_section,
|
||||
sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
|
||||
S->func_bound_offset, lbounds_section->data_offset);
|
||||
|
||||
/* generate bound local allocation */
|
||||
if (offset_modified) {
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->func_bound_ind;
|
||||
greloca(S, cur_text_section, sym_data, S->ind + 3, R_X86_64_PC32, -4);
|
||||
S->ind = S->ind + 7;
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->func_bound_ind;
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind + 3, R_X86_64_PC32, -4);
|
||||
S->tccgen_ind = S->tccgen_ind + 7;
|
||||
gen_bounds_call(S, TOK___bound_local_new);
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
/* generate bound check local freeing */
|
||||
o(S, 0x5250); /* save returned value, if any */
|
||||
greloca(S, cur_text_section, sym_data, S->ind + 3, R_X86_64_PC32, -4);
|
||||
greloca(S, cur_text_section, sym_data, S->tccgen_ind + 3, R_X86_64_PC32, -4);
|
||||
o(S, 0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /* lea xxx(%rip), %rcx/rdi */
|
||||
gen_le32(S, 0);
|
||||
gen_bounds_call(S, TOK___bound_local_delete);
|
||||
|
@ -804,7 +804,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
SValue *sv;
|
||||
|
||||
--arg;
|
||||
sv = &S->vtop[-i];
|
||||
sv = &S->tccgen_vtop[-i];
|
||||
bt = (sv->type.t & VT_BTYPE);
|
||||
size = gfunc_arg_size(&sv->type);
|
||||
|
||||
|
@ -823,7 +823,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
vset(S, &sv->type, r | VT_LVAL, 0);
|
||||
vpushv(S, sv);
|
||||
vstore(S);
|
||||
--S->vtop;
|
||||
--S->tccgen_vtop;
|
||||
} else if (bt == VT_LDOUBLE) {
|
||||
gv(S, RC_ST0);
|
||||
gen_offs_sp(S, 0xdb, 0x107, struct_size);
|
||||
|
@ -839,9 +839,9 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
for(i = 0; i < nb_args; i++) {
|
||||
--arg;
|
||||
bt = (S->vtop->type.t & VT_BTYPE);
|
||||
bt = (S->tccgen_vtop->type.t & VT_BTYPE);
|
||||
|
||||
size = gfunc_arg_size(&S->vtop->type);
|
||||
size = gfunc_arg_size(&S->tccgen_vtop->type);
|
||||
if (!using_regs(size)) {
|
||||
/* align to stack align size */
|
||||
size = (size + 15) & ~15;
|
||||
|
@ -855,7 +855,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
struct_size += size;
|
||||
} else {
|
||||
if (is_sse_float(S->vtop->type.t)) {
|
||||
if (is_sse_float(S->tccgen_vtop->type.t)) {
|
||||
if (S->nosse)
|
||||
tcc_error(S, "SSE disabled");
|
||||
if (arg >= REGN) {
|
||||
|
@ -873,8 +873,8 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
} else {
|
||||
if (bt == VT_STRUCT) {
|
||||
S->vtop->type.ref = NULL;
|
||||
S->vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
|
||||
S->tccgen_vtop->type.ref = NULL;
|
||||
S->tccgen_vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
|
||||
: size > 1 ? VT_SHORT : VT_BYTE;
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
}
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
save_regs(S, 0);
|
||||
/* Copy R10 and R11 into RCX and RDX, respectively */
|
||||
|
@ -901,7 +901,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
gcall_or_jmp(S, 0);
|
||||
|
||||
if ((S->vtop->r & VT_SYM) && S->vtop->sym->v == TOK_alloca) {
|
||||
if ((S->tccgen_vtop->r & VT_SYM) && S->tccgen_vtop->sym->v == TOK_alloca) {
|
||||
/* need to add the "func_scratch" area after alloca */
|
||||
o(S, 0x48); S->x86_64_gen_func_alloca = oad(S, 0x05, S->x86_64_gen_func_alloca); /* add $NN, %rax */
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
|
@ -909,7 +909,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
gen_bounds_call(S, TOK___bound_alloca_nr); /* new region */
|
||||
#endif
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
|
||||
|
@ -926,11 +926,11 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
S->x86_64_gen_func_ret_sub = 0;
|
||||
S->x86_64_gen_func_scratch = 32;
|
||||
S->x86_64_gen_func_alloca = 0;
|
||||
S->loc = 0;
|
||||
S->tccgen_loc = 0;
|
||||
|
||||
addr = PTR_SIZE * 2;
|
||||
S->ind += FUNC_PROLOG_SIZE;
|
||||
S->x86_64_gen_func_sub_sp_offset = S->ind;
|
||||
S->tccgen_ind += FUNC_PROLOG_SIZE;
|
||||
S->x86_64_gen_func_sub_sp_offset = S->tccgen_ind;
|
||||
reg_param_index = 0;
|
||||
|
||||
sym = func_type->ref;
|
||||
|
@ -995,7 +995,7 @@ void gfunc_epilog(TCCState *S)
|
|||
|
||||
/* align local size to word & save local variables */
|
||||
S->x86_64_gen_func_scratch = (S->x86_64_gen_func_scratch + 15) & -16;
|
||||
S->loc = (S->loc & -16) - S->x86_64_gen_func_scratch;
|
||||
S->tccgen_loc = (S->tccgen_loc & -16) - S->x86_64_gen_func_scratch;
|
||||
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (S->do_bounds_check)
|
||||
|
@ -1011,15 +1011,15 @@ void gfunc_epilog(TCCState *S)
|
|||
g(S, S->x86_64_gen_func_ret_sub >> 8);
|
||||
}
|
||||
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
v = -S->loc;
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
v = -S->tccgen_loc;
|
||||
|
||||
if (v >= 4096) {
|
||||
Sym *sym = external_helper_sym(S, TOK___chkstk);
|
||||
oad(S, 0xb8, v); /* mov stacksize, %eax */
|
||||
oad(S, 0xe8, 0); /* call __chkstk, (does the stackframe too) */
|
||||
greloca(S, cur_text_section, sym, S->ind-4, R_X86_64_PC32, -4);
|
||||
greloca(S, cur_text_section, sym, S->tccgen_ind-4, R_X86_64_PC32, -4);
|
||||
o(S, 0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
|
||||
} else {
|
||||
o(S, 0xe5894855); /* push %rbp, mov %rsp, %rbp */
|
||||
|
@ -1031,8 +1031,8 @@ void gfunc_epilog(TCCState *S)
|
|||
gsym_addr(S, S->x86_64_gen_func_alloca, -S->x86_64_gen_func_scratch);
|
||||
|
||||
cur_text_section->data_offset = saved_ind;
|
||||
pe_add_unwind_data(S, S->ind, saved_ind, v);
|
||||
S->ind = cur_text_section->data_offset;
|
||||
pe_add_unwind_data(S, S->tccgen_ind, saved_ind, v);
|
||||
S->tccgen_ind = cur_text_section->data_offset;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -1237,7 +1237,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
to be done in a left-to-right pass over arguments. */
|
||||
stack_adjust = 0;
|
||||
for(i = nb_args - 1; i >= 0; i--) {
|
||||
mode = classify_x86_64_arg(&S->vtop[-i].type, NULL, &size, &align, ®_count);
|
||||
mode = classify_x86_64_arg(&S->tccgen_vtop[-i].type, NULL, &size, &align, ®_count);
|
||||
if (size == 0) continue;
|
||||
if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
|
||||
nb_sse_args += reg_count;
|
||||
|
@ -1261,7 +1261,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
tcc_error(S, "SSE disabled but floating point arguments passed");
|
||||
|
||||
/* fetch cpu flag before generating any code */
|
||||
if ((S->vtop->r & VT_VALMASK) == VT_CMP)
|
||||
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP)
|
||||
gv(S, RC_INT);
|
||||
|
||||
/* for struct arguments, we need to call memcpy and the function
|
||||
|
@ -1272,7 +1272,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
args_size = 0;
|
||||
stack_adjust &= 15;
|
||||
for (i = k = 0; i < nb_args;) {
|
||||
mode = classify_x86_64_arg(&S->vtop[-i].type, NULL, &size, &align, ®_count);
|
||||
mode = classify_x86_64_arg(&S->tccgen_vtop[-i].type, NULL, &size, &align, ®_count);
|
||||
if (size) {
|
||||
if (!onstack[i + k]) {
|
||||
++i;
|
||||
|
@ -1293,7 +1293,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
|
||||
vrotb(S, i+1);
|
||||
|
||||
switch (S->vtop->type.t & VT_BTYPE) {
|
||||
switch (S->tccgen_vtop->type.t & VT_BTYPE) {
|
||||
case VT_STRUCT:
|
||||
/* allocate the necessary size on stack */
|
||||
o(S, 0x48);
|
||||
|
@ -1302,7 +1302,7 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
r = get_reg(S, RC_INT);
|
||||
orex(S, 1, r, 0, 0x89); /* mov %rsp, r */
|
||||
o(S, 0xe0 + REG_VALUE(r));
|
||||
vset(S, &S->vtop->type, r | VT_LVAL, 0);
|
||||
vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
|
||||
vswap(S);
|
||||
vstore(S);
|
||||
break;
|
||||
|
@ -1353,10 +1353,10 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
assert(gen_reg <= REGN);
|
||||
assert(sse_reg <= 8);
|
||||
for(i = 0; i < nb_args; i++) {
|
||||
mode = classify_x86_64_arg(&S->vtop->type, &type, &size, &align, ®_count);
|
||||
mode = classify_x86_64_arg(&S->tccgen_vtop->type, &type, &size, &align, ®_count);
|
||||
if (size == 0) continue;
|
||||
/* Alter stack entry type so that gv() knows how to treat it */
|
||||
S->vtop->type = type;
|
||||
S->tccgen_vtop->type = type;
|
||||
if (mode == x86_64_mode_sse) {
|
||||
if (reg_count == 2) {
|
||||
sse_reg -= 2;
|
||||
|
@ -1386,11 +1386,11 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
o(S, 0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
|
||||
if (reg_count == 2) {
|
||||
d = arg_prepare_reg(gen_reg+1);
|
||||
orex(S, 1,d,S->vtop->r2,0x89); /* mov */
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop->r2) * 8 + REG_VALUE(d));
|
||||
orex(S, 1,d,S->tccgen_vtop->r2,0x89); /* mov */
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r2) * 8 + REG_VALUE(d));
|
||||
}
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
assert(gen_reg == 0);
|
||||
assert(sse_reg == 0);
|
||||
|
@ -1409,19 +1409,19 @@ void gfunc_call(TCCState *S, int nb_args)
|
|||
}
|
||||
}
|
||||
|
||||
if (S->vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
|
||||
if (S->tccgen_vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
|
||||
oad(S, 0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
|
||||
gcall_or_jmp(S, 0);
|
||||
if (args_size)
|
||||
gadd_sp(S, args_size);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
#define FUNC_PROLOG_SIZE 11
|
||||
|
||||
static void push_arg_reg(TCCState* S, int i) {
|
||||
S->loc -= 8;
|
||||
gen_modrm64(S, 0x89, arg_regs[i], VT_LOCAL, NULL, S->loc);
|
||||
S->tccgen_loc -= 8;
|
||||
gen_modrm64(S, 0x89, arg_regs[i], VT_LOCAL, NULL, S->tccgen_loc);
|
||||
}
|
||||
|
||||
/* generate function prolog of type 't' */
|
||||
|
@ -1436,9 +1436,9 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
|
||||
sym = func_type->ref;
|
||||
addr = PTR_SIZE * 2;
|
||||
S->loc = 0;
|
||||
S->ind += FUNC_PROLOG_SIZE;
|
||||
S->x86_64_gen_func_sub_sp_offset = S->ind;
|
||||
S->tccgen_loc = 0;
|
||||
S->tccgen_ind += FUNC_PROLOG_SIZE;
|
||||
S->x86_64_gen_func_sub_sp_offset = S->tccgen_ind;
|
||||
S->x86_64_gen_func_ret_sub = 0;
|
||||
ret_mode = classify_x86_64_arg(&S->tccgen_func_vt, NULL, &size, &align, ®_count);
|
||||
|
||||
|
@ -1473,7 +1473,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
}
|
||||
}
|
||||
|
||||
S->loc -= 24;
|
||||
S->tccgen_loc -= 24;
|
||||
/* movl $0x????????, -0x18(%rbp) */
|
||||
o(S, 0xe845c7);
|
||||
gen_le32(S, seen_reg_num * 8);
|
||||
|
@ -1493,14 +1493,14 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
|
||||
/* save all register passing arguments */
|
||||
for (i = 0; i < 8; i++) {
|
||||
S->loc -= 16;
|
||||
S->tccgen_loc -= 16;
|
||||
if (!S->nosse) {
|
||||
o(S, 0xd60f66); /* movq */
|
||||
gen_modrm(S, 7 - i, VT_LOCAL, NULL, S->loc);
|
||||
gen_modrm(S, 7 - i, VT_LOCAL, NULL, S->tccgen_loc);
|
||||
}
|
||||
/* movq $0, loc+8(%rbp) */
|
||||
o(S, 0x85c748);
|
||||
gen_le32(S, S->loc + 8);
|
||||
gen_le32(S, S->tccgen_loc + 8);
|
||||
gen_le32(S, 0);
|
||||
}
|
||||
for (i = 0; i < REGN; i++) {
|
||||
|
@ -1516,7 +1516,7 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
implicit pointer parameter */
|
||||
if (ret_mode == x86_64_mode_memory) {
|
||||
push_arg_reg(S, reg_param_index);
|
||||
S->tccgen_func_vc = S->loc;
|
||||
S->tccgen_func_vc = S->tccgen_loc;
|
||||
reg_param_index++;
|
||||
}
|
||||
/* define parameters */
|
||||
|
@ -1529,8 +1529,8 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
tcc_error(S, "SSE disabled but floating point arguments used");
|
||||
if (sse_param_index + reg_count <= 8) {
|
||||
/* save arguments passed by register */
|
||||
S->loc -= reg_count * 8;
|
||||
param_addr = S->loc;
|
||||
S->tccgen_loc -= reg_count * 8;
|
||||
param_addr = S->tccgen_loc;
|
||||
for (i = 0; i < reg_count; ++i) {
|
||||
o(S, 0xd60f66); /* movq */
|
||||
gen_modrm(S, sse_param_index, VT_LOCAL, NULL, param_addr + i*8);
|
||||
|
@ -1553,8 +1553,8 @@ void gfunc_prolog(TCCState *S, Sym *func_sym)
|
|||
case x86_64_mode_integer: {
|
||||
if (reg_param_index + reg_count <= REGN) {
|
||||
/* save arguments passed by register */
|
||||
S->loc -= reg_count * 8;
|
||||
param_addr = S->loc;
|
||||
S->tccgen_loc -= reg_count * 8;
|
||||
param_addr = S->tccgen_loc;
|
||||
for (i = 0; i < reg_count; ++i) {
|
||||
gen_modrm64(S, 0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8);
|
||||
++reg_param_index;
|
||||
|
@ -1596,13 +1596,13 @@ void gfunc_epilog(TCCState *S)
|
|||
g(S, S->x86_64_gen_func_ret_sub >> 8);
|
||||
}
|
||||
/* align local size to word & save local variables */
|
||||
v = (-S->loc + 15) & -16;
|
||||
saved_ind = S->ind;
|
||||
S->ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
v = (-S->tccgen_loc + 15) & -16;
|
||||
saved_ind = S->tccgen_ind;
|
||||
S->tccgen_ind = S->x86_64_gen_func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
o(S, 0xe5894855); /* push %rbp, mov %rsp, %rbp */
|
||||
o(S, 0xec8148); /* sub rsp, stacksize */
|
||||
gen_le32(S, v);
|
||||
S->ind = saved_ind;
|
||||
S->tccgen_ind = saved_ind;
|
||||
}
|
||||
|
||||
#endif /* not PE */
|
||||
|
@ -1623,12 +1623,12 @@ int gjmp(TCCState *S, int t)
|
|||
void gjmp_addr(TCCState* S, int a)
|
||||
{
|
||||
int r;
|
||||
r = a - S->ind - 2;
|
||||
r = a - S->tccgen_ind - 2;
|
||||
if (r == (char)r) {
|
||||
g(S, 0xeb);
|
||||
g(S, r);
|
||||
} else {
|
||||
oad(S, 0xe9, a - S->ind - 5);
|
||||
oad(S, 0xe9, a - S->tccgen_ind - 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1657,7 +1657,7 @@ ST_FUNC int gjmp_cond(TCCState *S, int op, int t)
|
|||
Take care about inverting the test. We need to jump
|
||||
to our target if the result was unordered and test wasn't NE,
|
||||
otherwise if unordered we don't want to jump. */
|
||||
int v = S->vtop->cmp_r;
|
||||
int v = S->tccgen_vtop->cmp_r;
|
||||
op &= ~0x100;
|
||||
if (op ^ v ^ (v != TOK_NE))
|
||||
o(S, 0x067a); /* jp +6 */
|
||||
|
@ -1678,21 +1678,21 @@ void gen_opi(TCCState *S, int op)
|
|||
int r, fr, opc, c;
|
||||
int ll, uu, cc;
|
||||
|
||||
ll = is64_type(S->vtop[-1].type.t);
|
||||
uu = (S->vtop[-1].type.t & VT_UNSIGNED) != 0;
|
||||
cc = (S->vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
ll = is64_type(S->tccgen_vtop[-1].type.t);
|
||||
uu = (S->tccgen_vtop[-1].type.t & VT_UNSIGNED) != 0;
|
||||
cc = (S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
|
||||
switch(op) {
|
||||
case '+':
|
||||
case TOK_ADDC1: /* add with carry generation */
|
||||
opc = 0;
|
||||
gen_op8:
|
||||
if (cc && (!ll || (int)S->vtop->c.i == S->vtop->c.i)) {
|
||||
if (cc && (!ll || (int)S->tccgen_vtop->c.i == S->tccgen_vtop->c.i)) {
|
||||
/* constant case */
|
||||
vswap(S);
|
||||
r = gv(S, RC_INT);
|
||||
vswap(S);
|
||||
c = S->vtop->c.i;
|
||||
c = S->tccgen_vtop->c.i;
|
||||
if (c == (char)c) {
|
||||
/* XXX: generate inc and dec for smaller code ? */
|
||||
orex(S, ll, r, 0, 0x83);
|
||||
|
@ -1704,12 +1704,12 @@ void gen_opi(TCCState *S, int op)
|
|||
}
|
||||
} else {
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
orex(S, ll, r, fr, (opc << 3) | 0x01);
|
||||
o(S, 0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8);
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
if (op >= TOK_ULT && op <= TOK_GT)
|
||||
vset_VT_CMP(S, op);
|
||||
break;
|
||||
|
@ -1734,11 +1734,11 @@ void gen_opi(TCCState *S, int op)
|
|||
goto gen_op8;
|
||||
case '*':
|
||||
gv2(S, RC_INT, RC_INT);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
orex(S, ll, fr, r, 0xaf0f); /* imul fr, r */
|
||||
o(S, 0xc0 + REG_VALUE(fr) + REG_VALUE(r) * 8);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
break;
|
||||
case TOK_SHL:
|
||||
opc = 4;
|
||||
|
@ -1757,15 +1757,15 @@ void gen_opi(TCCState *S, int op)
|
|||
vswap(S);
|
||||
orex(S, ll, r, 0, 0xc1); /* shl/shr/sar $xxx, r */
|
||||
o(S, opc | REG_VALUE(r));
|
||||
g(S, S->vtop->c.i & (ll ? 63 : 31));
|
||||
g(S, S->tccgen_vtop->c.i & (ll ? 63 : 31));
|
||||
} else {
|
||||
/* we generate the shift in ecx */
|
||||
gv2(S, RC_INT, RC_RCX);
|
||||
r = S->vtop[-1].r;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
orex(S, ll, r, 0, 0xd3); /* shl/shr/sar %cl, r */
|
||||
o(S, opc | REG_VALUE(r));
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
break;
|
||||
case TOK_UDIV:
|
||||
case TOK_UMOD:
|
||||
|
@ -1779,9 +1779,9 @@ void gen_opi(TCCState *S, int op)
|
|||
/* first operand must be in eax */
|
||||
/* XXX: need better constraint for second operand */
|
||||
gv2(S, RC_RAX, RC_RCX);
|
||||
r = S->vtop[-1].r;
|
||||
fr = S->vtop[0].r;
|
||||
S->vtop--;
|
||||
r = S->tccgen_vtop[-1].r;
|
||||
fr = S->tccgen_vtop[0].r;
|
||||
S->tccgen_vtop--;
|
||||
save_reg(S, TREG_RDX);
|
||||
orex(S, ll, 0, 0, uu ? 0xd231 : 0x99); /* xor %edx,%edx : cqto */
|
||||
orex(S, ll, fr, 0, 0xf7); /* div fr, %eax */
|
||||
|
@ -1790,7 +1790,7 @@ void gen_opi(TCCState *S, int op)
|
|||
r = TREG_RDX;
|
||||
else
|
||||
r = TREG_RAX;
|
||||
S->vtop->r = r;
|
||||
S->tccgen_vtop->r = r;
|
||||
break;
|
||||
default:
|
||||
opc = 7;
|
||||
|
@ -1807,7 +1807,7 @@ void vpush_const(TCCState *S, int t, int v)
|
|||
{
|
||||
CType ctype = { t | VT_CONSTANT, 0 };
|
||||
vpushsym(S, &ctype, external_global_sym(S, v, &ctype));
|
||||
S->vtop->r |= VT_LVAL;
|
||||
S->tccgen_vtop->r |= VT_LVAL;
|
||||
}
|
||||
|
||||
/* generate a floating point operation 'v = t1 op t2' instruction. The
|
||||
|
@ -1816,7 +1816,7 @@ void vpush_const(TCCState *S, int t, int v)
|
|||
void gen_opf(TCCState* S, int op)
|
||||
{
|
||||
int a, ft, fc, swapped, r;
|
||||
int bt = S->vtop->type.t & VT_BTYPE;
|
||||
int bt = S->tccgen_vtop->type.t & VT_BTYPE;
|
||||
int float_type = bt == VT_LDOUBLE ? RC_ST0 : RC_FLOAT;
|
||||
|
||||
if (op == TOK_NEG) { /* unary minus */
|
||||
|
@ -1830,24 +1830,24 @@ void gen_opf(TCCState *S, int op)
|
|||
if (bt == VT_DOUBLE)
|
||||
o(S, 0x66);
|
||||
/* xorp[sd] %xmm1, %xmm0 */
|
||||
o(S, 0xc0570f | (REG_VALUE(S->vtop[0].r) + REG_VALUE(S->vtop[-1].r)*8) << 16);
|
||||
S->vtop--;
|
||||
o(S, 0xc0570f | (REG_VALUE(S->tccgen_vtop[0].r) + REG_VALUE(S->tccgen_vtop[-1].r)*8) << 16);
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* convert constants to memory references */
|
||||
if ((S->vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
if ((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||
vswap(S);
|
||||
gv(S, float_type);
|
||||
vswap(S);
|
||||
}
|
||||
if ((S->vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
|
||||
if ((S->tccgen_vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
|
||||
gv(S, float_type);
|
||||
|
||||
/* must put at least one value in the floating point register */
|
||||
if ((S->vtop[-1].r & VT_LVAL) &&
|
||||
(S->vtop[0].r & VT_LVAL)) {
|
||||
if ((S->tccgen_vtop[-1].r & VT_LVAL) &&
|
||||
(S->tccgen_vtop[0].r & VT_LVAL)) {
|
||||
vswap(S);
|
||||
gv(S, float_type);
|
||||
vswap(S);
|
||||
|
@ -1855,14 +1855,14 @@ void gen_opf(TCCState *S, int op)
|
|||
swapped = 0;
|
||||
/* swap the stack if needed so that t1 is the register and t2 is
|
||||
the memory reference */
|
||||
if (S->vtop[-1].r & VT_LVAL) {
|
||||
if (S->tccgen_vtop[-1].r & VT_LVAL) {
|
||||
vswap(S);
|
||||
swapped = 1;
|
||||
}
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
/* load on stack second operand */
|
||||
load(S, TREG_ST0, S->vtop);
|
||||
load(S, TREG_ST0, S->tccgen_vtop);
|
||||
save_reg(S, TREG_RAX); /* eax is used by FP comparison code */
|
||||
if (op == TOK_GE || op == TOK_GT)
|
||||
swapped = !swapped;
|
||||
|
@ -1889,11 +1889,11 @@ void gen_opf(TCCState *S, int op)
|
|||
o(S, 0x45c4f6); /* test $0x45, %ah */
|
||||
op = TOK_EQ;
|
||||
}
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
vset_VT_CMP(S, op);
|
||||
} else {
|
||||
/* no memory reference possible for long double operations */
|
||||
load(S, TREG_ST0, S->vtop);
|
||||
load(S, TREG_ST0, S->tccgen_vtop);
|
||||
swapped = !swapped;
|
||||
|
||||
switch(op) {
|
||||
|
@ -1915,17 +1915,17 @@ void gen_opf(TCCState *S, int op)
|
|||
a++;
|
||||
break;
|
||||
}
|
||||
ft = S->vtop->type.t;
|
||||
fc = S->vtop->c.i;
|
||||
ft = S->tccgen_vtop->type.t;
|
||||
fc = S->tccgen_vtop->c.i;
|
||||
o(S, 0xde); /* fxxxp %st, %st(1) */
|
||||
o(S, 0xc1 + (a << 3));
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
} else {
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
/* if saved lvalue, then we must reload it */
|
||||
r = S->vtop->r;
|
||||
fc = S->vtop->c.i;
|
||||
r = S->tccgen_vtop->r;
|
||||
fc = S->tccgen_vtop->c.i;
|
||||
if ((r & VT_VALMASK) == VT_LLOCAL) {
|
||||
SValue v1;
|
||||
r = get_reg(S, RC_INT);
|
||||
|
@ -1934,7 +1934,7 @@ void gen_opf(TCCState *S, int op)
|
|||
v1.c.i = fc;
|
||||
load(S, r, &v1);
|
||||
fc = 0;
|
||||
S->vtop->r = r = r | VT_LVAL;
|
||||
S->tccgen_vtop->r = r = r | VT_LVAL;
|
||||
}
|
||||
|
||||
if (op == TOK_EQ || op == TOK_NE) {
|
||||
|
@ -1953,26 +1953,26 @@ void gen_opf(TCCState *S, int op)
|
|||
gv(S, RC_FLOAT);
|
||||
vswap(S);
|
||||
}
|
||||
assert(!(S->vtop[-1].r & VT_LVAL));
|
||||
assert(!(S->tccgen_vtop[-1].r & VT_LVAL));
|
||||
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
o(S, 0x66);
|
||||
if (op == TOK_EQ || op == TOK_NE)
|
||||
o(S, 0x2e0f); /* ucomisd */
|
||||
else
|
||||
o(S, 0x2f0f); /* comisd */
|
||||
|
||||
if (S->vtop->r & VT_LVAL) {
|
||||
gen_modrm(S, S->vtop[-1].r, r, S->vtop->sym, fc);
|
||||
if (S->tccgen_vtop->r & VT_LVAL) {
|
||||
gen_modrm(S, S->tccgen_vtop[-1].r, r, S->tccgen_vtop->sym, fc);
|
||||
} else {
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop[0].r) + REG_VALUE(S->vtop[-1].r)*8);
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop[0].r) + REG_VALUE(S->tccgen_vtop[-1].r)*8);
|
||||
}
|
||||
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
vset_VT_CMP(S, op | 0x100);
|
||||
S->vtop->cmp_r = op;
|
||||
S->tccgen_vtop->cmp_r = op;
|
||||
} else {
|
||||
assert((S->vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
|
||||
assert((S->tccgen_vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
|
||||
switch(op) {
|
||||
default:
|
||||
case '+':
|
||||
|
@ -1988,13 +1988,13 @@ void gen_opf(TCCState *S, int op)
|
|||
a = 6;
|
||||
break;
|
||||
}
|
||||
ft = S->vtop->type.t;
|
||||
fc = S->vtop->c.i;
|
||||
ft = S->tccgen_vtop->type.t;
|
||||
fc = S->tccgen_vtop->c.i;
|
||||
assert((ft & VT_BTYPE) != VT_LDOUBLE);
|
||||
|
||||
r = S->vtop->r;
|
||||
r = S->tccgen_vtop->r;
|
||||
/* if saved lvalue, then we must reload it */
|
||||
if ((S->vtop->r & VT_VALMASK) == VT_LLOCAL) {
|
||||
if ((S->tccgen_vtop->r & VT_VALMASK) == VT_LLOCAL) {
|
||||
SValue v1;
|
||||
r = get_reg(S, RC_INT);
|
||||
v1.type.t = VT_PTR;
|
||||
|
@ -2002,12 +2002,12 @@ void gen_opf(TCCState *S, int op)
|
|||
v1.c.i = fc;
|
||||
load(S, r, &v1);
|
||||
fc = 0;
|
||||
S->vtop->r = r = r | VT_LVAL;
|
||||
S->tccgen_vtop->r = r = r | VT_LVAL;
|
||||
}
|
||||
|
||||
assert(!(S->vtop[-1].r & VT_LVAL));
|
||||
assert(!(S->tccgen_vtop[-1].r & VT_LVAL));
|
||||
if (swapped) {
|
||||
assert(S->vtop->r & VT_LVAL);
|
||||
assert(S->tccgen_vtop->r & VT_LVAL);
|
||||
gv(S, RC_FLOAT);
|
||||
vswap(S);
|
||||
}
|
||||
|
@ -2020,13 +2020,13 @@ void gen_opf(TCCState *S, int op)
|
|||
o(S, 0x0f);
|
||||
o(S, 0x58 + a);
|
||||
|
||||
if (S->vtop->r & VT_LVAL) {
|
||||
gen_modrm(S, S->vtop[-1].r, r, S->vtop->sym, fc);
|
||||
if (S->tccgen_vtop->r & VT_LVAL) {
|
||||
gen_modrm(S, S->tccgen_vtop[-1].r, r, S->tccgen_vtop->sym, fc);
|
||||
} else {
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop[0].r) + REG_VALUE(S->vtop[-1].r)*8);
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop[0].r) + REG_VALUE(S->tccgen_vtop[-1].r)*8);
|
||||
}
|
||||
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2038,39 +2038,39 @@ void gen_cvt_itof(TCCState *S, int t)
|
|||
if ((t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
save_reg(S, TREG_ST0);
|
||||
gv(S, RC_INT);
|
||||
if ((S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
/* signed long long to float/double/long double (unsigned case
|
||||
is handled generically) */
|
||||
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x242cdf); /* fildll (%rsp) */
|
||||
o(S, 0x08c48348); /* add $8, %rsp */
|
||||
} else if ((S->vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||
} else if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||
(VT_INT | VT_UNSIGNED)) {
|
||||
/* unsigned int to float/double/long double */
|
||||
o(S, 0x6a); /* push $0 */
|
||||
g(S, 0x00);
|
||||
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x242cdf); /* fildll (%rsp) */
|
||||
o(S, 0x10c48348); /* add $16, %rsp */
|
||||
} else {
|
||||
/* int to float/double/long double */
|
||||
o(S, 0x50 + (S->vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x50 + (S->tccgen_vtop->r & VT_VALMASK)); /* push r */
|
||||
o(S, 0x2404db); /* fildl (%rsp) */
|
||||
o(S, 0x08c48348); /* add $8, %rsp */
|
||||
}
|
||||
S->vtop->r = TREG_ST0;
|
||||
S->tccgen_vtop->r = TREG_ST0;
|
||||
} else {
|
||||
int r = get_reg(S, RC_FLOAT);
|
||||
gv(S, RC_INT);
|
||||
o(S, 0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0));
|
||||
if ((S->vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||
if ((S->tccgen_vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||
(VT_INT | VT_UNSIGNED) ||
|
||||
(S->vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
(S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
||||
o(S, 0x48); /* REX */
|
||||
}
|
||||
o(S, 0x2a0f);
|
||||
o(S, 0xc0 + (S->vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
|
||||
S->vtop->r = r;
|
||||
o(S, 0xc0 + (S->tccgen_vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
|
||||
S->tccgen_vtop->r = r;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2079,7 +2079,7 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
{
|
||||
int ft, bt, tbt;
|
||||
|
||||
ft = S->vtop->type.t;
|
||||
ft = S->tccgen_vtop->type.t;
|
||||
bt = ft & VT_BTYPE;
|
||||
tbt = t & VT_BTYPE;
|
||||
|
||||
|
@ -2087,33 +2087,33 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
gv(S, RC_FLOAT);
|
||||
if (tbt == VT_DOUBLE) {
|
||||
o(S, 0x140f); /* unpcklps */
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
|
||||
o(S, 0x5a0f); /* cvtps2pd */
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
|
||||
} else if (tbt == VT_LDOUBLE) {
|
||||
save_reg(S, RC_ST0);
|
||||
/* movss %xmm0,-0x10(%rsp) */
|
||||
o(S, 0x110ff3);
|
||||
o(S, 0x44 + REG_VALUE(S->vtop->r)*8);
|
||||
o(S, 0x44 + REG_VALUE(S->tccgen_vtop->r)*8);
|
||||
o(S, 0xf024);
|
||||
o(S, 0xf02444d9); /* flds -0x10(%rsp) */
|
||||
S->vtop->r = TREG_ST0;
|
||||
S->tccgen_vtop->r = TREG_ST0;
|
||||
}
|
||||
} else if (bt == VT_DOUBLE) {
|
||||
gv(S, RC_FLOAT);
|
||||
if (tbt == VT_FLOAT) {
|
||||
o(S, 0x140f66); /* unpcklpd */
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
|
||||
o(S, 0x5a0f66); /* cvtpd2ps */
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop->r)*9);
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r)*9);
|
||||
} else if (tbt == VT_LDOUBLE) {
|
||||
save_reg(S, RC_ST0);
|
||||
/* movsd %xmm0,-0x10(%rsp) */
|
||||
o(S, 0x110ff2);
|
||||
o(S, 0x44 + REG_VALUE(S->vtop->r)*8);
|
||||
o(S, 0x44 + REG_VALUE(S->tccgen_vtop->r)*8);
|
||||
o(S, 0xf024);
|
||||
o(S, 0xf02444dd); /* fldl -0x10(%rsp) */
|
||||
S->vtop->r = TREG_ST0;
|
||||
S->tccgen_vtop->r = TREG_ST0;
|
||||
}
|
||||
} else {
|
||||
int r;
|
||||
|
@ -2125,14 +2125,14 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
o(S, 0x100ff2);
|
||||
o(S, 0x44 + REG_VALUE(r)*8);
|
||||
o(S, 0xf024);
|
||||
S->vtop->r = r;
|
||||
S->tccgen_vtop->r = r;
|
||||
} else if (tbt == VT_FLOAT) {
|
||||
o(S, 0xf0245cd9); /* fstps -0x10(%rsp) */
|
||||
/* movss -0x10(%rsp),%xmm0 */
|
||||
o(S, 0x100ff3);
|
||||
o(S, 0x44 + REG_VALUE(r)*8);
|
||||
o(S, 0xf024);
|
||||
S->vtop->r = r;
|
||||
S->tccgen_vtop->r = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2141,7 +2141,7 @@ void gen_cvt_ftof(TCCState *S, int t)
|
|||
void gen_cvt_ftoi(TCCState* S, int t)
|
||||
{
|
||||
int ft, bt, size, r;
|
||||
ft = S->vtop->type.t;
|
||||
ft = S->tccgen_vtop->type.t;
|
||||
bt = ft & VT_BTYPE;
|
||||
if (bt == VT_LDOUBLE) {
|
||||
gen_cvt_ftof(S, VT_DOUBLE);
|
||||
|
@ -2163,8 +2163,8 @@ void gen_cvt_ftoi(TCCState *S, int t)
|
|||
assert(0);
|
||||
}
|
||||
orex(S, size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */
|
||||
o(S, 0xc0 + REG_VALUE(S->vtop->r) + REG_VALUE(r)*8);
|
||||
S->vtop->r = r;
|
||||
o(S, 0xc0 + REG_VALUE(S->tccgen_vtop->r) + REG_VALUE(r)*8);
|
||||
S->tccgen_vtop->r = r;
|
||||
}
|
||||
|
||||
// Generate sign extension from 32 to 64 bits:
|
||||
|
@ -2183,7 +2183,7 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
|
|||
r = gv(S, RC_INT);
|
||||
sz = !(t & VT_UNSIGNED);
|
||||
xl = (t & VT_BTYPE) == VT_SHORT;
|
||||
ll = (S->vtop->type.t & VT_BTYPE) == VT_LLONG;
|
||||
ll = (S->tccgen_vtop->type.t & VT_BTYPE) == VT_LLONG;
|
||||
orex(S, ll, r, 0, 0xc0b60f /* mov[sz] %a[xl], %eax */
|
||||
| (sz << 3 | xl) << 8
|
||||
| (REG_VALUE(r) << 3 | REG_VALUE(r)) << 16
|
||||
|
@ -2194,7 +2194,7 @@ ST_FUNC void gen_cvt_csti(TCCState *S, int t)
|
|||
ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
|
||||
{
|
||||
o(S, 0x058348); /* addq $1, xxx(%rip) */
|
||||
greloca(S, cur_text_section, sv->sym, S->ind, R_X86_64_PC32, -5);
|
||||
greloca(S, cur_text_section, sv->sym, S->tccgen_ind, R_X86_64_PC32, -5);
|
||||
gen_le32(S, 0);
|
||||
o(S, 1);
|
||||
}
|
||||
|
@ -2203,7 +2203,7 @@ ST_FUNC void gen_increment_tcov (TCCState *S, SValue *sv)
|
|||
void ggoto(TCCState* S)
|
||||
{
|
||||
gcall_or_jmp(S, 1);
|
||||
S->vtop--;
|
||||
S->tccgen_vtop--;
|
||||
}
|
||||
|
||||
/* Save the stack pointer onto the stack and return the location of its address */
|
||||
|
|
Loading…
Add table
Reference in a new issue