CFILES += ../util/scf_string.c
CFILES += ../lex/scf_lex.c
CFILES += ../lex/scf_lex_util.c
+CFILES += ../lex/scf_macro.c
+CFILES += ../lex/scf_macro_expr.c
CFILES += main.c
CFILES += scf_asm.c
return 0;
}
- if (scf_lex_open(&_asm->lex, path, NULL) < 0)
+ if (scf_lex_open(&_asm->lex, path, NULL, SCF_ASM, NULL) < 0)
return -1;
_asm->lex->next = _asm->lex_list;
static inline int __inst_data_is_reg(scf_inst_data_t* id)
{
- if (!id->flag && id->base && 0 == id->imm_size)
+ if (!id->mem_flag && id->base && 0 == id->imm_size)
return 1;
return 0;
}
static inline int __inst_data_is_const(scf_inst_data_t* id)
{
- if (!id->flag && id->imm_size > 0)
+ if (!id->mem_flag && id->imm_size > 0)
return 1;
return 0;
}
switch (w2->type) {
case SCF_LEX_WORD_LP:
d->operands[d->i].disp = w->data.u64;
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
break;
case SCF_LEX_WORD_RP:
d->operands[d->i].scale = w->data.i;
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
break;
case SCF_LEX_WORD_ID:
d->operands[d->i].imm = w->data.u64;
d->operands[d->i].imm_size = 8;
- d->operands[d->i].flag = 0;
+ d->operands[d->i].mem_flag = 0;
if (SCF_RISC_CALL == d->opcode->type
|| (SCF_RISC_JZ <= d->opcode->type && SCF_RISC_JMP >= d->opcode->type)) {
}
d->operands[d->i].imm = w->data.u64;
- d->operands[d->i].flag = 0;
+ d->operands[d->i].mem_flag = 0;
d->i++;
break;
default:
memcpy(inst->code, (uint8_t*)&w->data, n);
inst->len = n;
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
asm_inst_set_label(inst, d);
}
}
}
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
asm_inst_set_label(inst, d);
return SCF_DFA_NEXT_WORD;
if (d->opcode) {
d->operands[d->i].label = w;
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
w = dfa->ops->pop_word(dfa);
dfa->ops->push_word(dfa, w);
if (!inst)
return -ENOMEM;
inst->len = 8;
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
asm_inst_set_label(inst, d);
scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
dfa_asm_t* d = data;
if (++d->n_rp == d->n_lp) {
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
d->i++;
}
if (__inst_data_is_reg(id2)) {
inst = naja_inst_ADD_G(NULL, id0->base, id1->base, id2->base);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
} else if (__inst_data_is_const(id2)) {
inst = naja_inst_ADD_IMM(NULL, NULL, id0->base, id1->base, id2->imm);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
} else {
inst = naja_inst_ADD_IMM(NULL, NULL, id0->base, id1->base, 0);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id2->label->text);
rela->type = R_AARCH64_ADD_ABS_LO12_NC;
}
scf_instruction_t* inst;
inst = naja_inst_RET(NULL);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
*__inst = inst;
return 0;
if (__inst_data_is_reg(id)) {
inst = naja_inst_BR(NULL, id->base);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
} else {
uint32_t disp = 0;
if (!id->label)
disp = id->imm;
+ scf_loge("\n");
+
inst = __naja_inst_JMP(NULL, disp);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
if (id->label) {
rela = calloc(1, sizeof(scf_rela_t));
if (!rela)
return -ENOMEM;
+ scf_logi("id->label->text: %s\n", id->label->text->data);
RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
rela->type = R_AARCH64_CALL26;
}
if (__inst_data_is_reg(id)) {
inst = naja_inst_BLR(NULL, id->base);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
} else {
uint32_t disp = 0;
disp = id->imm;
inst = __naja_inst_BL(NULL, disp);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
if (id->label) {
rela = calloc(1, sizeof(scf_rela_t));
}
inst = __naja_inst_ADRP(NULL, id0->base);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id1->label->text);
rela->type = R_AARCH64_ADR_PREL_PG_HI21;
scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
return -EINVAL;
}
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
*__inst = inst;
return 0;
}
inst = naja_inst_PUSH(NULL, id->base);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
*__inst = inst;
return 0;
}
inst = naja_inst_POP(NULL, id->base);
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
*__inst = inst;
return 0;
if (scf_asm_fill(&inst, n, size, imm) < 0)
return SCF_DFA_ERROR;
- RISC_INST_ADD_CHECK(_asm->current, inst);
+ RISC_ASM_ADD_CHECK(_asm->current, inst);
asm_inst_set_label(inst, d);
}
d->operands[i].scale = 0;
d->operands[i].disp = 0;
- d->operands[i].flag = 0;
d->operands[i].label = NULL;
d->operands[i].imm = 0;
d->operands[i].imm_size = 0;
+ d->operands[i].mem_flag = 0;
}
d->global = NULL;
switch (w2->type) {
case SCF_LEX_WORD_LP:
d->operands[d->i].disp = w->data.u64;
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
break;
case SCF_LEX_WORD_RP:
d->operands[d->i].scale = w->data.i;
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
break;
case SCF_LEX_WORD_ID:
d->operands[d->i].imm = w->data.u64;
d->operands[d->i].imm_size = 8;
- d->operands[d->i].flag = 0;
+ d->operands[d->i].mem_flag = 0;
if (SCF_X64_CALL == d->opcode->type
|| (SCF_X64_JZ <= d->opcode->type && SCF_X64_JMP >= d->opcode->type)) {
}
d->operands[d->i].imm = w->data.u64;
- d->operands[d->i].flag = 0;
+ d->operands[d->i].mem_flag = 0;
d->i++;
break;
default:
memcpy(inst->code, (uint8_t*)&w->data, n);
inst->len = n;
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
asm_inst_set_label(inst, d);
}
}
}
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
asm_inst_set_label(inst, d);
return SCF_DFA_NEXT_WORD;
if (d->opcode) {
d->operands[d->i].label = w;
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
w = dfa->ops->pop_word(dfa);
dfa->ops->push_word(dfa, w);
if (!inst)
return -ENOMEM;
inst->len = 8;
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
asm_inst_set_label(inst, d);
scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
dfa_asm_t* d = data;
if (++d->n_rp == d->n_lp) {
- d->operands[d->i].flag = 1;
+ d->operands[d->i].mem_flag = 1;
d->i++;
}
inst = x64_make_inst_G2E(opcode, id1->base, id0->base);
} else
inst = x64_make_inst_E2G(opcode, id1->base, id0->base);
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
} else if (__inst_data_is_const(id1)) {
inst = x64_make_inst_G2SIB(opcode, id1->base, id1->index, id1->scale, disp, id0->base);
else
inst = x64_make_inst_G2P(opcode, id1->base, disp, id0->base);
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
if (id0->label) {
scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
}
}
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
}
} else if (__inst_data_is_reg(id1)) {
inst = x64_make_inst_SIB2G(opcode, id1->base, id0->base, id0->index, id0->scale, disp);
else
inst = x64_make_inst_P2G(opcode, id1->base, id0->base, disp);
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
if (id0->label) {
scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
inst = x64_make_inst_E(opcode, id->base);
} else
inst = x64_make_inst_G(opcode, id->base);
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
} else {
scf_rela_t* rela = NULL;
opcode = x64_find_OpCode(d->opcode->type, 4, 4, SCF_X64_I);
inst = x64_make_inst_I(opcode, (uint8_t*)&disp, 4);
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
if (id->label) {
rela = calloc(1, sizeof(scf_rela_t));
}
inst = x64_make_inst_L(&rela, opcode);
- X64_INST_ADD_CHECK(_asm->current, inst, rela);
+ X64_ASM_ADD_CHECK(_asm->current, inst, rela);
X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
}
}
break;
case 0:
inst = x64_make_inst(opcode, 8);
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
break;
default:
break;
if (scf_asm_fill(&inst, n, size, imm) < 0)
return SCF_DFA_ERROR;
- X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ X64_ASM_ADD_CHECK(_asm->current, inst, NULL);
asm_inst_set_label(inst, d);
}
d->operands[i].scale = 0;
d->operands[i].disp = 0;
- d->operands[i].flag = 0;
d->operands[i].label = NULL;
d->operands[i].imm = 0;
d->operands[i].imm_size = 0;
+ d->operands[i].mem_flag = 0;
}
d->global = NULL;
#include"scf_basic_block.h"
#include"scf_graph.h"
-static scf_3ac_operator_t _3ac_operators[] = {
- {SCF_OP_CALL, "call"},
+static scf_3ac_operator_t _3ac_operators[] =
+{
+ {SCF_OP_CALL, "call"},
- {SCF_OP_ARRAY_INDEX, "array_index"},
+ {SCF_OP_ARRAY_INDEX, "array_index"},
{SCF_OP_POINTER, "pointer"},
- {SCF_OP_TYPE_CAST, "cast"},
+ {SCF_OP_TYPE_CAST, "cast"},
- {SCF_OP_LOGIC_NOT, "logic_not"},
+ {SCF_OP_LOGIC_NOT, "logic_not"},
{SCF_OP_BIT_NOT, "not"},
- {SCF_OP_NEG, "neg"},
- {SCF_OP_POSITIVE, "positive"},
+ {SCF_OP_NEG, "neg"},
+ {SCF_OP_POSITIVE, "positive"},
{SCF_OP_INC, "inc"},
{SCF_OP_DEC, "dec"},
{SCF_OP_INC_POST, "inc_post"},
{SCF_OP_DEC_POST, "dec_post"},
- {SCF_OP_DEREFERENCE, "dereference"},
- {SCF_OP_ADDRESS_OF, "address_of"},
+ {SCF_OP_DEREFERENCE, "dereference"},
+ {SCF_OP_ADDRESS_OF, "address_of"},
- {SCF_OP_MUL, "mul"},
- {SCF_OP_DIV, "div"},
+ {SCF_OP_MUL, "mul"},
+ {SCF_OP_DIV, "div"},
{SCF_OP_MOD, "mod"},
- {SCF_OP_ADD, "add"},
- {SCF_OP_SUB, "sub"},
+ {SCF_OP_ADD, "add"},
+ {SCF_OP_SUB, "sub"},
{SCF_OP_SHL, "shl"},
{SCF_OP_SHR, "shr"},
{SCF_OP_BIT_AND, "and"},
{SCF_OP_BIT_OR, "or"},
+ {SCF_OP_BIT_XOR, "xor"},
- {SCF_OP_EQ, "eq"},
+ {SCF_OP_EQ, "eq"},
{SCF_OP_NE, "neq"},
- {SCF_OP_GT, "gt"},
- {SCF_OP_LT, "lt"},
- {SCF_OP_GE, "ge"},
- {SCF_OP_LE, "le"},
+ {SCF_OP_GT, "gt"},
+ {SCF_OP_LT, "lt"},
+ {SCF_OP_GE, "ge"},
+ {SCF_OP_LE, "le"},
{SCF_OP_ASSIGN, "assign"},
{SCF_OP_ADD_ASSIGN, "+="},
{SCF_OP_SHR_ASSIGN, ">>="},
{SCF_OP_AND_ASSIGN, "&="},
{SCF_OP_OR_ASSIGN, "|="},
+ {SCF_OP_XOR_ASSIGN, "^="},
{SCF_OP_COMMA, "comma"},
{SCF_OP_VA_ARG, "va_arg"},
{SCF_OP_VA_END, "va_end"},
- {SCF_OP_RETURN, "return"},
- {SCF_OP_GOTO, "jmp"},
+ {SCF_OP_RETURN, "return"},
+ {SCF_OP_GOTO, "jmp"},
- {SCF_OP_3AC_TEQ, "teq"},
- {SCF_OP_3AC_CMP, "cmp"},
+ {SCF_OP_3AC_TEQ, "teq"},
+ {SCF_OP_3AC_CMP, "cmp"},
- {SCF_OP_3AC_LEA, "lea"},
+ {SCF_OP_3AC_LEA, "lea"},
{SCF_OP_3AC_SETZ, "setz"},
{SCF_OP_3AC_SETNZ, "setnz"},
{"i32", SCF_OP_BIT_AND, SCF_VAR_I32, SCF_VAR_I32, SCF_VAR_I32, scf_i32_bit_and},
{"i32", SCF_OP_BIT_OR, SCF_VAR_I32, SCF_VAR_I32, SCF_VAR_I32, scf_i32_bit_or},
{"i32", SCF_OP_BIT_NOT, SCF_VAR_I32, SCF_VAR_I32, SCF_VAR_I32, scf_i32_bit_not},
+ {"i32", SCF_OP_BIT_XOR, SCF_VAR_I32, SCF_VAR_I32, SCF_VAR_I32, scf_i32_bit_xor},
{"i32", SCF_OP_LOGIC_AND, SCF_VAR_I32, SCF_VAR_I32, SCF_VAR_I32, scf_i32_logic_and},
{"i32", SCF_OP_LOGIC_OR, SCF_VAR_I32, SCF_VAR_I32, SCF_VAR_I32, scf_i32_logic_or},
{"u32", SCF_OP_BIT_AND, SCF_VAR_U32, SCF_VAR_U32, SCF_VAR_U32, scf_u32_bit_and},
{"u32", SCF_OP_BIT_OR, SCF_VAR_U32, SCF_VAR_U32, SCF_VAR_U32, scf_u32_bit_or},
{"u32", SCF_OP_BIT_NOT, SCF_VAR_U32, SCF_VAR_U32, SCF_VAR_U32, scf_u32_bit_not},
+ {"u32", SCF_OP_BIT_XOR, SCF_VAR_U32, SCF_VAR_U32, SCF_VAR_U32, scf_u32_bit_xor},
{"u32", SCF_OP_LOGIC_AND, SCF_VAR_U32, SCF_VAR_U32, SCF_VAR_U32, scf_u32_logic_and},
{"u32", SCF_OP_LOGIC_OR, SCF_VAR_U32, SCF_VAR_U32, SCF_VAR_U32, scf_u32_logic_or},
{"i64", SCF_OP_BIT_AND, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_bit_and},
{"i64", SCF_OP_BIT_OR, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_bit_or},
{"i64", SCF_OP_BIT_NOT, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_bit_not},
+ {"i64", SCF_OP_BIT_XOR, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_bit_xor},
{"i64", SCF_OP_LOGIC_AND, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_logic_and},
{"i64", SCF_OP_LOGIC_OR, SCF_VAR_I64, SCF_VAR_I64, SCF_VAR_I64, scf_i64_logic_or},
{"u64", SCF_OP_BIT_AND, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_and},
{"u64", SCF_OP_BIT_OR, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_or},
{"u64", SCF_OP_BIT_NOT, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_not},
+ {"u64", SCF_OP_BIT_XOR, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_bit_xor},
{"u64", SCF_OP_LOGIC_AND, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_and},
{"u64", SCF_OP_LOGIC_OR, SCF_VAR_U64, SCF_VAR_U64, SCF_VAR_U64, scf_u64_logic_or},
SCF_I32_BINARY_OP(bit_and, &)
SCF_I32_BINARY_OP(bit_or, |)
+SCF_I32_BINARY_OP(bit_xor, ^)
SCF_I32_UNARY_OP(bit_not, ~)
SCF_I32_BINARY_OP(logic_and, &&)
SCF_I64_BINARY_OP(bit_and, &)
SCF_I64_BINARY_OP(bit_or, |)
+SCF_I64_BINARY_OP(bit_xor, ^)
SCF_I64_UNARY_OP(bit_not, ~)
SCF_I64_BINARY_OP(logic_and, &&)
SCF_U32_BINARY_OP(bit_and, &)
SCF_U32_BINARY_OP(bit_or, |)
+SCF_U32_BINARY_OP(bit_xor, ^)
SCF_U32_UNARY_OP(bit_not, ~)
SCF_U32_BINARY_OP(logic_and, &&)
SCF_U64_BINARY_OP(bit_and, &)
SCF_U64_BINARY_OP(bit_or, |)
+SCF_U64_BINARY_OP(bit_xor, ^)
SCF_U64_UNARY_OP(bit_not, ~)
SCF_U64_BINARY_OP(logic_and, &&)
SCF_OP_SHL_ASSIGN, // <<=
SCF_OP_SHR_ASSIGN, // >>=
SCF_OP_AND_ASSIGN, // &=
+ SCF_OP_XOR_ASSIGN, // ^=
SCF_OP_OR_ASSIGN, // |=
// 30
SCF_LEX_WORD_SHR_ASSIGN, // >>=
SCF_LEX_WORD_BIT_AND_ASSIGN, // &=
SCF_LEX_WORD_BIT_OR_ASSIGN, // |=
+ SCF_LEX_WORD_BIT_XOR_ASSIGN, // ^=
SCF_LEX_WORD_LT, // < less than
SCF_LEX_WORD_GT, // > greater than
scf_vector_t* result_nodes;
scf_node_t* split_parent; // split from the parent
+ int pause_flag; // ++ when followed by a '(' of function call(), sizeof(), etc... only for expr.
+
uint32_t root_flag :1; // set when node is root block
uint32_t file_flag :1; // set when node is a file block
uint32_t enum_flag :1; // set when node is a enum type
uint32_t _3ac_done :1; // set when node's 3ac code is made
uint32_t semi_flag :1; // set when followed by a ';'
- uint32_t pause_flag :1; // set when followed by a '(' of function call(), sizeof(), etc... only for expr.
};
struct scf_label_s {
{"&", "band", SCF_OP_BIT_AND, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{"|", "bor", SCF_OP_BIT_OR, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
+ {"^", "bxor", SCF_OP_BIT_XOR, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{"==", "eq", SCF_OP_EQ, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{"!=", "ne", SCF_OP_NE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT},
{">>=", NULL, SCF_OP_SHR_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{"&=", "and_", SCF_OP_AND_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{"|=", "or_", SCF_OP_OR_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
+ {"^=", "xor_", SCF_OP_XOR_ASSIGN, 11, 2, SCF_OP_ASSOCIATIVITY_RIGHT},
{",", NULL, SCF_OP_COMMA, 12, 2, SCF_OP_ASSOCIATIVITY_LEFT},
SCF_DAG_BINARY(and, BIT_AND)
SCF_DAG_BINARY(or, BIT_OR)
+SCF_DAG_BINARY(xor, BIT_XOR)
SCF_DAG_BINARY(mul, MUL)
SCF_DAG_BINARY(div, DIV)
SCF_DAG_BINARY_ASSIGN(and_assign, AND_ASSIGN)
SCF_DAG_BINARY_ASSIGN(or_assign, OR_ASSIGN)
+SCF_DAG_BINARY_ASSIGN(xor_assign, XOR_ASSIGN)
#define SCF_DAG_ASSIGN_ARRAY_INDEX(name, op) \
static int _scf_dag_op_##name##_array_index(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) \
{SCF_OP_BIT_AND, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_and},
{SCF_OP_BIT_OR, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_or},
+ {SCF_OP_BIT_XOR, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_xor},
{SCF_OP_EQ, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_eq},
{SCF_OP_NE, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_ne},
{SCF_OP_AND_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_and_assign},
{SCF_OP_OR_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_or_assign},
+ {SCF_OP_XOR_ASSIGN, SCF_OP_ASSOCIATIVITY_RIGHT, _scf_dag_op_xor_assign},
{SCF_OP_COMMA, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_comma},
return 0;
}
-static void __scf_loop_entry_clear(scf_list_t* start_prev, scf_3ac_code_t* jmp_end)
+static void __scf_loop_entry_clear(scf_list_t* start_prev, scf_3ac_code_t* jmp_end, scf_branch_ops_t* branch_ops)
{
scf_3ac_code_t* c;
scf_list_t* l;
c = scf_list_data(l, scf_3ac_code_t, list);
l = scf_list_next(l);
+ if (0 == scf_vector_del(branch_ops->_continues, c)
+ || 0 == scf_vector_del(branch_ops->_breaks, c)
+ || 0 == scf_vector_del(branch_ops->_gotos, c)
+ || 0 == scf_vector_del(branch_ops->_labels, c)
+ || 0 == scf_vector_del(branch_ops->_ends, c)) {
+ // delete from 'branch_ops' if 'c' is a jmp operator, which is from source code 'while, if-else, for, ...';
+ }
+
scf_list_del(&c->list);
scf_3ac_code_free(c);
c = NULL;
// delete 'cond check' at 'start of loop'
scf_vector_del(d->branch_ops->_breaks, jmp_end);
- __scf_loop_entry_clear(start_prev, jmp_end);
+ __scf_loop_entry_clear(start_prev, jmp_end, d->branch_ops);
return 0;
}
scf_vector_del(d->branch_ops->_breaks, jmp_end);
- __scf_loop_entry_clear(start_prev, jmp_end);
+ __scf_loop_entry_clear(start_prev, jmp_end, d->branch_ops);
}
return 0;
scf_list_add_tail(d->_3ac_list_head, &end->list);
// re-fill 'break'
-
int i;
for (i = 0; i < local_branch_ops->_breaks->size; i++) {
c = local_branch_ops->_breaks->data[i];
next = scf_list_next(&dst->code->list);
dst->code = scf_list_data(next, scf_3ac_code_t, list);
} else {
- scf_loge("'break' has a bug!\n");
+ scf_loge("c: %p, dst: %p, dst->code: %p, 'jmp branch' has a bug!\n", c, dst, dst->code);
return -1;
}
}
SCF_OP_BINARY(shr, SCF_OP_SHR)
SCF_OP_BINARY(bit_and, SCF_OP_BIT_AND)
SCF_OP_BINARY(bit_or, SCF_OP_BIT_OR)
+SCF_OP_BINARY(bit_xor, SCF_OP_BIT_XOR)
SCF_OP_BINARY(comma, SCF_OP_COMMA)
static int _scf_op_left_value_array_index(scf_ast_t* ast, int type, scf_node_t* left, scf_node_t* right, scf_handler_data_t* d)
SCF_OP_BINARY_ASSIGN(sub, SUB)
SCF_OP_BINARY_ASSIGN(and, AND)
SCF_OP_BINARY_ASSIGN(or, OR)
+SCF_OP_BINARY_ASSIGN(xor, XOR)
SCF_OP_BINARY_ASSIGN(shl, SHL)
SCF_OP_BINARY_ASSIGN(shr, SHR)
assert(2 == nb_nodes);\
scf_handler_data_t* d = data;\
scf_node_t* parent = nodes[0]->parent; \
+ scf_node_t* node0 = nodes[0]; \
+ scf_node_t* node1 = nodes[1]; \
+ \
+ while (SCF_OP_EXPR == node0->type || scf_type_is_assign(node0->type)) \
+ node0 = node0->nodes[0]; \
+ \
+ while (SCF_OP_EXPR == node1->type || scf_type_is_assign(node1->type)) \
+ node1 = node1->nodes[0]; \
\
scf_variable_t* v0 = _scf_operand_get(nodes[0]);\
scf_variable_t* v1 = _scf_operand_get(nodes[1]);\
+ \
if (scf_variable_const(v0)) { \
if (scf_variable_const(v1)) {\
scf_loge("result to compare 2 const var should be calculated before\n"); \
} \
parent->type = op_type2; \
SCF_XCHG(nodes[0], nodes[1]); \
- return _scf_3ac_code_3(d->_3ac_list_head, op_type2, parent, nodes[0], nodes[1]); \
+ return _scf_3ac_code_3(d->_3ac_list_head, op_type2, parent, node1, node0); \
} \
- return _scf_3ac_code_3(d->_3ac_list_head, op_type, parent, nodes[0], nodes[1]); \
+ return _scf_3ac_code_3(d->_3ac_list_head, op_type, parent, node0, node1); \
}
SCF_OP_CMP(eq, SCF_OP_EQ)
if (_scf_op_logic_##name##_jmp(ast, nodes[1], d) < 0) \
return -1; \
\
- jmp->dsts = scf_vector_alloc(); \
- if (!jmp->dsts) \
- return -ENOMEM; \
- scf_3ac_operand_t* dst = scf_3ac_operand_alloc(); \
- if (!dst) \
- return -ENOMEM; \
- if (scf_vector_add(jmp->dsts, dst) < 0) \
- return -ENOMEM; \
+ scf_3ac_operand_t* dst = jmp->dsts->data[0]; \
+ scf_list_t* l = scf_list_tail(d->_3ac_list_head); \
\
- scf_list_t* l = scf_list_tail(d->_3ac_list_head); \
dst->code = scf_list_data(l, scf_3ac_code_t, list); \
\
int ret = scf_vector_add(d->branch_ops->_breaks, jmp); \
[SCF_OP_BIT_AND] = _scf_op_bit_and,
[SCF_OP_BIT_OR ] = _scf_op_bit_or,
+ [SCF_OP_BIT_XOR] = _scf_op_bit_xor,
[SCF_OP_EQ] = _scf_op_eq,
[SCF_OP_NE] = _scf_op_ne,
[SCF_OP_SHR_ASSIGN] = _scf_op_shr_assign,
[SCF_OP_AND_ASSIGN] = _scf_op_and_assign,
[SCF_OP_OR_ASSIGN ] = _scf_op_or_assign,
+ [SCF_OP_XOR_ASSIGN] = _scf_op_xor_assign,
[SCF_OP_COMMA ] = _scf_op_comma,
}
}
-#if 1
+#if 0
for (i = 0; i < functions->size; i++) {
f = functions->data[i];
static int _bb_loop_layers(scf_function_t* f)
{
scf_basic_block_t* entry;
- scf_basic_block_t* exit;
- scf_basic_block_t* bb;
- scf_bb_group_t* loop0;
- scf_bb_group_t* loop1;
-
- int ret;
+ scf_bb_group_t* loop;
int i;
int j;
- ret = __bb_loop_layers(f);
+ int ret = __bb_loop_layers(f);
if (ret < 0)
return ret;
for (i = 0; i < f->bb_loops->size; i++) {
- loop0 = f->bb_loops->data[i];
+ loop = f->bb_loops->data[i];
+
+ for (j = 0; j < loop->entries->size; j++) {
+ entry = loop->entries->data[j];
+
+ scf_logi("loop: %p, j: %d, entry: %p\n", loop, j, entry);
+ }
- assert(1 == loop0->entries->size);
+ assert(1 == loop->entries->size);
- loop0->entry = loop0->entries->data[0];
+ loop->entry = loop->entries->data[0];
}
scf_vector_qsort(f->bb_loops, _loop_index_cmp);
if (scf_list_empty(bb_list_head))
return 0;
+ if (!strcmp(f->node.w->text->data, "__parse_macro_include")) {
+ scf_logi("------- %s() ------\n", f->node.w->text->data);
+ scf_basic_block_print_list(&f->basic_block_list_head);
+ }
+
scf_vector_clear(f->bb_loops, ( void (*)(void*) )scf_bb_group_free);
scf_vector_clear(f->bb_groups, ( void (*)(void*) )scf_bb_group_free);
+++ /dev/null
-#include"scf_optimizer.h"
-
-static int __bb_add_vla_free(scf_basic_block_t* back, scf_function_t* f)
-{
- scf_basic_block_t* jcc = scf_list_data(scf_list_next(&back->list), scf_basic_block_t, list);
- scf_basic_block_t* next = scf_list_data(scf_list_next(&jcc ->list), scf_basic_block_t, list);
- scf_basic_block_t* free;
- scf_basic_block_t* jmp;
- scf_3ac_operand_t* dst;
- scf_3ac_code_t* c;
- scf_3ac_code_t* c2;
- scf_list_t* l;
-
- assert(jcc->jmp_flag);
-
- free = scf_basic_block_alloc();
- if (!free)
- return -ENOMEM;
- scf_list_add_front(&jcc->list, &free->list);
-
- jmp = scf_basic_block_alloc();
- if (!jmp)
- return -ENOMEM;
- scf_list_add_front(&free->list, &jmp->list);
-
- l = scf_list_head(&jcc->code_list_head);
- c = scf_list_data(l, scf_3ac_code_t, list);
-
- c2 = scf_3ac_code_clone(c);
- if (!c2)
- return -ENOMEM;
- scf_list_add_tail(&jmp->code_list_head, &c2->list);
-
- c2->op = scf_3ac_find_operator(SCF_OP_GOTO);
- c2->basic_block = jmp;
-
- int ret = scf_vector_add(f->jmps, c2);
- if (ret < 0)
- return ret;
-
- switch (c->op->type) {
- case SCF_OP_3AC_JZ:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JNZ);
- break;
- case SCF_OP_3AC_JNZ:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JZ);
- break;
-
- case SCF_OP_3AC_JGE:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JLT);
- break;
- case SCF_OP_3AC_JLT:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JGE);
- break;
-
- case SCF_OP_3AC_JGT:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JLE);
- break;
- case SCF_OP_3AC_JLE:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JGT);
- break;
-
- case SCF_OP_3AC_JA:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JBE);
- break;
- case SCF_OP_3AC_JBE:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JA);
- break;
-
- case SCF_OP_3AC_JB:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JAE);
- break;
- case SCF_OP_3AC_JAE:
- c->op = scf_3ac_find_operator(SCF_OP_3AC_JB);
- break;
- default:
- break;
- };
- dst = c->dsts->data[0];
- dst->bb = next;
-
- back->vla_free = free;
- return 0;
-}
-
-static int __loop_add_vla_free(scf_bb_group_t* loop, scf_function_t* f)
-{
- scf_basic_block_t* bb;
- scf_basic_block_t* back;
- scf_basic_block_t* jcc;
- scf_3ac_operand_t* dst;
- scf_3ac_code_t* c;
- scf_3ac_code_t* c2;
- scf_list_t* l;
-
- int i;
- int j;
- int k;
-
- for (i = 0; i < loop->body->size; i++) {
- bb = loop->body->data[i];
-
- if (!bb->vla_flag)
- continue;
-
- for (j = i; j < loop->body->size; j++) {
- back = loop->body->data[j];
-
- if (!back->back_flag)
- continue;
-
- jcc = scf_list_data(scf_list_next(&back->list), scf_basic_block_t, list);
-
- l = scf_list_head(&jcc->code_list_head);
- c = scf_list_data(l, scf_3ac_code_t, list);
- dst = c->dsts->data[0];
-
- for (k = j; k > i; k--) {
- if (dst->bb == loop->body->data[k])
- break;
- }
- if (k > i)
- continue;
-
- if (!back->vla_free) {
- int ret = __bb_add_vla_free(back, f);
- if (ret < 0)
- return ret;
-
- ret = scf_vector_add(loop->body, back->vla_free);
- if (ret < 0)
- return ret;
-
- for (k = loop->body->size - 2; k > j; k--)
- loop->body->data[k + 1] = loop->body->data[k];
- loop->body->data[k + 1] = back->vla_free;
-
- back->vla_free->loop_flag = 1;
- }
-
- for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); l = scf_list_next(l)) {
- c = scf_list_data(l, scf_3ac_code_t, list);
-
- if (SCF_OP_VLA_ALLOC != c->op->type)
- continue;
-
- c2 = scf_3ac_code_clone(c);
- if (!c2)
- return -ENOMEM;
- scf_list_add_front(&back->vla_free->code_list_head, &c2->list);
-
- c2->op = scf_3ac_find_operator(SCF_OP_VLA_FREE);
- c2->basic_block = back->vla_free;
- }
- }
- }
-
- return 0;
-}
-
-static int _optimize_vla(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
-{
- if (!f)
- return -EINVAL;
-
- if (!f->vla_flag || f->bb_loops->size <= 0)
- return 0;
-
- scf_bb_group_t* loop;
- int i;
-
- for (i = 0; i < f->bb_loops->size; i++) {
- loop = f->bb_loops->data[i];
-
- int ret = __loop_add_vla_free(loop, f);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-scf_optimizer_t scf_optimizer_vla =
-{
- .name = "vla",
-
- .optimize = _optimize_vla,
-
- .flags = SCF_OPTIMIZER_LOCAL,
-};
}
} else {
lex->text = text;
- lex->asm_flag = 1;
+ lex->asm_flag = (SCF_ASM == c_version);
}
lex->nb_lines = 1;
return _lex_op2_ll1(lex, pword, c, SCF_LEX_WORD_BIT_OR, chs, types, 2);
}
+ if ('^' == c->c) {
+ char c1 = '=';
+ int t1 = SCF_LEX_WORD_BIT_XOR_ASSIGN;
+
+ return _lex_op2_ll1(lex, pword, c, SCF_LEX_WORD_BIT_XOR, &c1, &t1, 1);
+ }
+
if ('!' == c->c) {
char c1 = '=';
int t1 = SCF_LEX_WORD_NE;
int scf_lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword)
{
- if (!lex || !lex->fp || !pword)
+ if (!lex || !pword)
+ return -EINVAL;
+
+ if (!lex->fp && !lex->text)
return -EINVAL;
scf_lex_word_t* w = NULL;
typedef struct scf_char_s scf_char_t;
typedef struct scf_lex_s scf_lex_t;
-#define SCF_C89 1
-#define SCF_C99 2
+#define SCF_ASM 1
+#define SCF_C89 2
+#define SCF_C99 3
typedef struct {
char* text;
static int __recursive_use_macro(scf_lex_t* lex, scf_lex_word_t** h, scf_stack_t* used_macros)
{
scf_lex_word_t** pp = h;
- scf_lex_word_t* w;
+ scf_lex_word_t* w = NULL;
scf_macro_t* m;
while (*pp) {
typedef struct {
scf_lex_word_t** pp;
- scf_lex_word_t* error;
+// scf_lex_word_t* error;
int n_q_masks;
int n_colons;
(_rela)->inst->rel = (_rela); \
} while (0)
+#define RISC_ASM_ADD_CHECK(_vec, _inst) \
+ do { \
+ if (!(_inst)) { \
+ scf_loge("\n"); \
+ return -ENOMEM; \
+ } \
+ int ret = scf_vector_add((_vec), (_inst)); \
+ if (ret < 0) { \
+ scf_instruction_free(_inst); \
+ return ret; \
+ } \
+ } while (0)
+
#define RISC_RELA_ADD_LABEL(_vec, _rela, _inst, _label) \
do { \
(_rela) = calloc(1, sizeof(scf_rela_t)); \
int x64_bb_load_dn2(intptr_t color, scf_dag_node_t* dn, scf_basic_block_t* bb, scf_function_t* f)
{
- scf_3ac_code_t* c;
- scf_list_t* l;
+ scf_variable_t* v = dn->var;
+ scf_3ac_code_t* c = NULL;
+ scf_list_t* l;
- scf_variable_t* v = dn->var;
if (v->w)
scf_logd("bb: %d, v: %d/%s, bp_offset: -%#x\n", bb->index, v->w->line, v->w->text->data, -v->bp_offset);
- l = scf_list_tail(&bb->code_list_head);
- c = scf_list_data(l, scf_3ac_code_t, list);
+ if (!scf_list_empty(&bb->code_list_head)) {
+
+ l = scf_list_tail(&bb->code_list_head);
+ c = scf_list_data(l, scf_3ac_code_t, list);
+ } else {
+ c = scf_3ac_code_NN(SCF_OP_3AC_NOP, NULL, 0, NULL, 0);
+ if (!c)
+ return -ENOMEM;
+
+ scf_list_add_tail(&bb->code_list_head, &c->list);
+
+ c->basic_block = bb;
+ }
+
+ scf_logd("bb: %p, index: %d, scf_list_empty(&bb->code_list_head): %d\n", bb, bb->index, scf_list_empty(&bb->code_list_head));
return x64_bb_load_dn(color, dn, c, bb, f);
}
scf_dn_status_t* ds2;
scf_dag_node_t* dn;
scf_variable_t* v;
+ scf_register_t* r;
int i;
int j;
ds = bb->dn_colors_entry->data[i];
dn = ds->dag_node;
+ v = dn->var;
intptr_t color = dn->color;
int first = 0;
}
}
- dn->color = -1;
+ if (scf_variable_const_integer(v))
+ dn->color = 0;
+ else
+ dn->color = -1;
+
dn->loaded = 0;
}
if (color != dn->color && color > 0) {
- scf_register_t* r = x64_find_register_color(color);
+
+ r = x64_find_register_color(color);
scf_vector_del(r->dag_nodes, dn);
}
ds = bb->dn_colors_entry->data[i];
dn = ds->dag_node;
+ v = dn->var;
intptr_t color = dn->color;
int first = 0;
}
}
- dn->color = -1;
- dn->loaded = 0;
+ if (scf_variable_const_integer(v))
+ dn->color = 0;
+ else
+ dn->color = -1;
+
+ dn->loaded = 0;
}
if (color != dn->color && color > 0) {
+
r = x64_find_register_color(color);
scf_vector_del(r->dag_nodes, dn);
}
if (dn->color < 0)
- dn->loaded = 0;
+ dn->loaded = 0;
}
for (i = 0; i < bb->dn_colors_entry->size; i++) {
assert(0 == scf_vector_add_unique(r->dag_nodes, dn));
else
scf_vector_del(r->dag_nodes, dn);
- // printf(", %s", r->name);
+// printf(", %s", r->name);
}
- //printf("\n");
+// printf("\n");
}
return 0;
}
X64_INST_OP3(sub, SUB)
X64_INST_OP3(bit_and, AND)
X64_INST_OP3(bit_or, OR)
+X64_INST_OP3(bit_xor, XOR)
static int _x64_inst_comma_handler(scf_native_t* ctx, scf_3ac_code_t* c)
X64_INST_BINARY_ASSIGN(sub_assign, SUB)
X64_INST_BINARY_ASSIGN(and_assign, AND)
X64_INST_BINARY_ASSIGN(or_assign, OR)
+X64_INST_BINARY_ASSIGN(xor_assign, XOR)
static int _x64_inst_assign_pointer_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
[SCF_OP_BIT_AND ] = _x64_inst_bit_and_handler,
[SCF_OP_BIT_OR ] = _x64_inst_bit_or_handler,
+ [SCF_OP_BIT_XOR ] = _x64_inst_bit_xor_handler,
[SCF_OP_3AC_TEQ ] = _x64_inst_teq_handler,
[SCF_OP_3AC_CMP ] = _x64_inst_cmp_handler,
[SCF_OP_AND_ASSIGN ] = _x64_inst_and_assign_handler,
[SCF_OP_OR_ASSIGN ] = _x64_inst_or_assign_handler,
+ [SCF_OP_XOR_ASSIGN ] = _x64_inst_xor_assign_handler,
[SCF_OP_COMMA ] = _x64_inst_comma_handler,
if (SCF_X64_MOV == OpCode_type
|| SCF_X64_MOVSS == OpCode_type
- || SCF_X64_MOVSD == OpCode_type)
+ || SCF_X64_MOVSD == OpCode_type
+ || SCF_X64_LEA == OpCode_type)
X64_SELECT_REG_CHECK(&rd, dst, c, f, 0);
else
X64_SELECT_REG_CHECK(&rd, dst, c, f, 1);
--- /dev/null
+#include"scf_x64.h"
+
+scf_instruction_t* _x64_make_OpCode(scf_x64_OpCode_t* OpCode, int bytes,
+ scf_register_t* r,
+ scf_register_t* b,
+ scf_register_t* x);
+
+int _x64_make_disp(scf_rela_t** prela, scf_instruction_t* inst, uint32_t reg, uint32_t base, int32_t disp);
+
+int x64_make_inst_pic(scf_register_t** r_base, scf_variable_t* v, scf_3ac_code_t* c, scf_function_t* f)
+{
+ assert(!*r_base);
+
+ int ret = x64_select_free_reg(r_base, c, f, 0);
+ if (ret < 0) {
+ scf_loge("PIC: select free reg failed\n");
+ return ret;
+ }
+
+ scf_rela_t* rela = NULL;
+ scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_E2G);
+ scf_instruction_t* inst = _x64_make_OpCode(mov, 8, *r_base, NULL, NULL);
+ if (!inst)
+ return -ENOMEM;
+
+ ret = _x64_make_disp(&rela, inst, (*r_base)->id, -1, 0);
+ if (ret < 0) {
+ free(inst);
+ return ret;
+ }
+
+ X64_INST_ADD_CHECK(c, inst, rela);
+
+ if (SCF_FUNCTION_PTR == v->type && v->const_literal_flag) {
+ assert(v->func_ptr);
+
+ X64_RELA_ADD_CHECK(f->text_relas, rela, c, v, v->func_ptr);
+ } else
+ X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
+
+ rela->type = R_X86_64_GOTPCREL;
+
+ inst->dst.base = *r_base;
+ inst->src.base = NULL;
+ inst->src.disp = 0;
+ inst->src.mem_flag = 1;
+ return 0;
+}
+
+scf_instruction_t* x64_make_inst_M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v, scf_register_t* r_base, scf_3ac_code_t* c, scf_function_t* f)
+{
+ scf_register_t* rbp = x64_find_register("rbp");
+
+ uint32_t base;
+ int32_t offset;
+ uint8_t reg = 0;
+
+ if (OpCode->ModRM_OpCode_used)
+ reg = OpCode->ModRM_OpCode;
+
+ if (!r_base) {
+ if (v->local_flag || v->tmp_flag) {
+
+ base = SCF_X64_REG_RBP;
+ offset = v->bp_offset;
+ r_base = rbp;
+
+ } else if (v->global_flag) {
+ base = -1;
+ offset = 0;
+
+ if (v->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
+ } else {
+ scf_loge("temp var should give a register\n");
+ return NULL;
+ }
+ } else {
+ base = r_base->id;
+
+ if (v->local_flag || v->tmp_flag)
+ offset = v->bp_offset;
+ else
+ offset = v->offset;
+ }
+
+ scf_instruction_t* inst = _x64_make_OpCode(OpCode, v->size, NULL, r_base, NULL);
+ if (!inst)
+ return NULL;
+
+ if (_x64_make_disp(prela, inst, reg, base, offset) < 0) {
+ free(inst);
+ return NULL;
+ }
+
+ if (SCF_X64_INC == OpCode->type || SCF_X64_INC == OpCode->type) {
+
+ inst->src.base = r_base;
+ inst->src.disp = offset;
+ inst->src.mem_flag = 1;
+
+ inst->dst.base = r_base;
+ inst->dst.disp = offset;
+ inst->dst.mem_flag = 1;
+
+ } else if (SCF_X64_MUL == OpCode->type
+ || SCF_X64_DIV == OpCode->type
+ || SCF_X64_IMUL == OpCode->type
+ || SCF_X64_IDIV == OpCode->type
+ || SCF_X64_CALL == OpCode->type) {
+
+ inst->src.base = r_base;
+ inst->src.disp = offset;
+ inst->src.mem_flag = 1;
+ }
+
+ return inst;
+}
+
+scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, uint8_t* imm, int32_t size, scf_3ac_code_t* c, scf_function_t* f)
+{
+ scf_register_t* rbp = x64_find_register("rbp");
+
+ uint32_t base;
+ int32_t offset;
+ uint8_t reg = 0;
+
+ if (OpCode->ModRM_OpCode_used)
+ reg = OpCode->ModRM_OpCode;
+
+ if (!r_base) {
+ if (v_dst->local_flag || v_dst->tmp_flag) {
+
+ base = SCF_X64_REG_RBP;
+ offset = v_dst->bp_offset;
+ r_base = rbp;
+
+ } else if (v_dst->global_flag) {
+ base = -1;
+ offset = 0;
+
+ if (v_dst->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v_dst, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
+ } else {
+ scf_loge("temp var should give a register\n");
+ return NULL;
+ }
+ } else {
+ base = r_base->id;
+
+ if (v_dst->local_flag || v_dst->tmp_flag)
+ offset = v_dst->bp_offset;
+ else
+ offset = v_dst->offset;
+ }
+
+ scf_instruction_t* inst = _x64_make_OpCode(OpCode, v_dst->size, NULL, r_base, NULL);
+ if (!inst)
+ return NULL;
+
+ if (_x64_make_disp(prela, inst, reg, base, offset) < 0) {
+ free(inst);
+ return NULL;
+ }
+
+ size = size > v_dst->size ? v_dst->size : size;
+
+ uint8_t* p = (uint8_t*)&inst->src.imm;
+ int i;
+
+ inst->src.imm = 0;
+
+ for (i = 0; i < size; i++) {
+ inst->code[inst->len++] = imm[i];
+ p[i] = imm[i];
+ }
+
+ inst->dst.base = r_base;
+ inst->dst.disp = offset;
+ inst->dst.mem_flag = 1;
+
+ inst->src.imm_size = size;
+ return inst;
+}
+
+scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, scf_register_t* r_src, scf_3ac_code_t* c, scf_function_t* f)
+{
+ if (OpCode->ModRM_OpCode_used) {
+ scf_loge("ModRM opcode invalid\n");
+ return NULL;
+ }
+
+ scf_register_t* rbp = x64_find_register("rbp");
+ scf_instruction_t* inst = NULL;
+
+ uint32_t base;
+ int32_t offset;
+
+ if (!r_base) {
+ if (v_dst->local_flag || v_dst->tmp_flag) {
+
+ base = SCF_X64_REG_RBP;
+ offset = v_dst->bp_offset;
+
+ r_base = rbp;
+
+ } else if (v_dst->global_flag) {
+ base = -1;
+ offset = 0;
+
+ if (v_dst->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v_dst, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
+ } else {
+ scf_loge("temp var should give a register\n");
+ return NULL;
+ }
+ } else {
+ base = r_base->id;
+
+ if (v_dst->local_flag || v_dst->tmp_flag)
+ offset = v_dst->bp_offset;
+ else
+ offset = v_dst->offset;
+ }
+
+ inst = _x64_make_OpCode(OpCode, x64_variable_size(v_dst), r_src, r_base, NULL);
+ if (!inst)
+ return NULL;
+
+ if (_x64_make_disp(prela, inst, r_src->id, base, offset) < 0) {
+ free(inst);
+ return NULL;
+ }
+
+ inst->src.base = r_src;
+ inst->dst.base = r_base;
+ inst->dst.disp = offset;
+ inst->dst.mem_flag = 1;
+
+ return inst;
+}
+
+scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, scf_variable_t* v_src, scf_3ac_code_t* c, scf_function_t* f)
+{
+ if (OpCode->ModRM_OpCode_used) {
+ scf_loge("ModRM opcode invalid\n");
+ return NULL;
+ }
+
+ scf_register_t* rbp = x64_find_register("rbp");
+ scf_instruction_t* inst = NULL;
+
+ uint32_t base;
+ int32_t offset;
+
+ if (!r_base) {
+ if (v_src->local_flag || v_src->tmp_flag) {
+
+ base = SCF_X64_REG_RBP;
+ offset = v_src->bp_offset;
+ r_base = rbp;
+
+ } else if (v_src->global_flag) {
+ base = -1;
+ offset = 0;
+
+ if (v_src->extern_flag && f->pic_flag) {
+ assert(!r_base);
+
+ int ret = x64_make_inst_pic(&r_base, v_src, c, f);
+ if (ret < 0)
+ return NULL;
+
+ base = r_base->id;
+ }
+ } else {
+ scf_loge("temp var should give a register\n");
+ return NULL;
+ }
+ } else {
+ base = r_base->id;
+
+ if (v_src->local_flag || v_src->tmp_flag)
+ offset = v_src->bp_offset;
+ else
+ offset = v_src->offset;
+ }
+
+ inst = _x64_make_OpCode(OpCode, r_dst->bytes, r_dst, r_base, NULL);
+ if (!inst)
+ return NULL;
+
+ if (_x64_make_disp(prela, inst, r_dst->id, base, offset) < 0) {
+ free(inst);
+ return NULL;
+ }
+
+ inst->dst.base = r_dst;
+ inst->src.base = r_base;
+ inst->src.disp = offset;
+ inst->src.mem_flag = 1;
+
+ return inst;
+}
#include"scf_x64.h"
-static scf_instruction_t* _x64_make_OpCode(scf_x64_OpCode_t* OpCode, int bytes,
+scf_instruction_t* _x64_make_OpCode(scf_x64_OpCode_t* OpCode, int bytes,
scf_register_t* r,
scf_register_t* b,
scf_register_t* x)
return inst;
}
-static int _x64_make_disp(scf_rela_t** prela, scf_instruction_t* inst, uint32_t reg, uint32_t base, int32_t disp)
+int _x64_make_disp(scf_rela_t** prela, scf_instruction_t* inst, uint32_t reg, uint32_t base, int32_t disp)
{
uint8_t ModRM = 0;
scf_ModRM_setReg(&ModRM, reg);
return inst;
}
-int x64_make_inst_pic(scf_register_t** r_base, scf_variable_t* v, scf_3ac_code_t* c, scf_function_t* f)
-{
- assert(!*r_base);
-
- int ret = x64_select_free_reg(r_base, c, f, 0);
- if (ret < 0) {
- scf_loge("PIC: select free reg failed\n");
- return ret;
- }
-
- scf_rela_t* rela = NULL;
- scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_E2G);
- scf_instruction_t* inst = _x64_make_OpCode(mov, 8, *r_base, NULL, NULL);
- if (!inst)
- return -ENOMEM;
-
- ret = _x64_make_disp(&rela, inst, (*r_base)->id, -1, 0);
- if (ret < 0) {
- free(inst);
- return ret;
- }
-
- X64_INST_ADD_CHECK(c, inst, rela);
-
- if (SCF_FUNCTION_PTR == v->type && v->const_literal_flag) {
- assert(v->func_ptr);
-
- X64_RELA_ADD_CHECK(f->text_relas, rela, c, v, v->func_ptr);
- } else
- X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
-
- rela->type = R_X86_64_GOTPCREL;
-
- inst->dst.base = *r_base;
- inst->src.base = NULL;
- inst->src.disp = 0;
- inst->src.mem_flag = 1;
- return 0;
-}
-
scf_instruction_t* x64_make_inst_L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode)
{
uint8_t reg = 0;
return inst;
}
-scf_instruction_t* x64_make_inst_M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v, scf_register_t* r_base, scf_3ac_code_t* c, scf_function_t* f)
-{
- scf_register_t* rbp = x64_find_register("rbp");
-
- uint32_t base;
- int32_t offset;
- uint8_t reg = 0;
-
- if (OpCode->ModRM_OpCode_used)
- reg = OpCode->ModRM_OpCode;
-
- if (!r_base) {
- if (v->local_flag || v->tmp_flag) {
-
- base = SCF_X64_REG_RBP;
- offset = v->bp_offset;
- r_base = rbp;
-
- } else if (v->global_flag) {
- base = -1;
- offset = 0;
-
- if (v->extern_flag && f->pic_flag) {
- assert(!r_base);
-
- int ret = x64_make_inst_pic(&r_base, v, c, f);
- if (ret < 0)
- return NULL;
-
- base = r_base->id;
- }
- } else {
- scf_loge("temp var should give a register\n");
- return NULL;
- }
- } else {
- base = r_base->id;
-
- if (v->local_flag || v->tmp_flag)
- offset = v->bp_offset;
- else
- offset = v->offset;
- }
-
- scf_instruction_t* inst = _x64_make_OpCode(OpCode, v->size, NULL, r_base, NULL);
- if (!inst)
- return NULL;
-
- if (_x64_make_disp(prela, inst, reg, base, offset) < 0) {
- free(inst);
- return NULL;
- }
-
- if (SCF_X64_INC == OpCode->type || SCF_X64_INC == OpCode->type) {
-
- inst->src.base = r_base;
- inst->src.disp = offset;
- inst->src.mem_flag = 1;
-
- inst->dst.base = r_base;
- inst->dst.disp = offset;
- inst->dst.mem_flag = 1;
-
- } else if (SCF_X64_MUL == OpCode->type
- || SCF_X64_DIV == OpCode->type
- || SCF_X64_IMUL == OpCode->type
- || SCF_X64_IDIV == OpCode->type
- || SCF_X64_CALL == OpCode->type) {
-
- inst->src.base = r_base;
- inst->src.disp = offset;
- inst->src.mem_flag = 1;
- }
-
- return inst;
-}
-
scf_instruction_t* x64_make_inst_I2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, uint8_t* imm, int32_t size)
{
uint8_t reg = 0;
return inst;
}
-scf_instruction_t* x64_make_inst_I2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, uint8_t* imm, int32_t size, scf_3ac_code_t* c, scf_function_t* f)
-{
- scf_register_t* rbp = x64_find_register("rbp");
-
- uint32_t base;
- int32_t offset;
- uint8_t reg = 0;
-
- if (OpCode->ModRM_OpCode_used)
- reg = OpCode->ModRM_OpCode;
-
- if (!r_base) {
- if (v_dst->local_flag || v_dst->tmp_flag) {
-
- base = SCF_X64_REG_RBP;
- offset = v_dst->bp_offset;
- r_base = rbp;
-
- } else if (v_dst->global_flag) {
- base = -1;
- offset = 0;
-
- if (v_dst->extern_flag && f->pic_flag) {
- assert(!r_base);
-
- int ret = x64_make_inst_pic(&r_base, v_dst, c, f);
- if (ret < 0)
- return NULL;
-
- base = r_base->id;
- }
- } else {
- scf_loge("temp var should give a register\n");
- return NULL;
- }
- } else {
- base = r_base->id;
-
- if (v_dst->local_flag || v_dst->tmp_flag)
- offset = v_dst->bp_offset;
- else
- offset = v_dst->offset;
- }
-
- scf_instruction_t* inst = _x64_make_OpCode(OpCode, v_dst->size, NULL, r_base, NULL);
- if (!inst)
- return NULL;
-
- if (_x64_make_disp(prela, inst, reg, base, offset) < 0) {
- free(inst);
- return NULL;
- }
-
- size = size > v_dst->size ? v_dst->size : size;
-
- uint8_t* p = (uint8_t*)&inst->src.imm;
- int i;
-
- inst->src.imm = 0;
-
- for (i = 0; i < size; i++) {
- inst->code[inst->len++] = imm[i];
- p[i] = imm[i];
- }
-
- inst->dst.base = r_base;
- inst->dst.disp = offset;
- inst->dst.mem_flag = 1;
-
- inst->src.imm_size = size;
- return inst;
-}
-
scf_instruction_t* x64_make_inst_G2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_src)
{
if (OpCode->ModRM_OpCode_used) {
return inst;
}
-scf_instruction_t* x64_make_inst_G2M(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_variable_t* v_dst, scf_register_t* r_base, scf_register_t* r_src, scf_3ac_code_t* c, scf_function_t* f)
-{
- if (OpCode->ModRM_OpCode_used) {
- scf_loge("ModRM opcode invalid\n");
- return NULL;
- }
-
- scf_register_t* rbp = x64_find_register("rbp");
- scf_instruction_t* inst = NULL;
-
- uint32_t base;
- int32_t offset;
-
- if (!r_base) {
- if (v_dst->local_flag || v_dst->tmp_flag) {
-
- base = SCF_X64_REG_RBP;
- offset = v_dst->bp_offset;
-
- r_base = rbp;
-
- } else if (v_dst->global_flag) {
- base = -1;
- offset = 0;
-
- if (v_dst->extern_flag && f->pic_flag) {
- assert(!r_base);
-
- int ret = x64_make_inst_pic(&r_base, v_dst, c, f);
- if (ret < 0)
- return NULL;
-
- base = r_base->id;
- }
- } else {
- scf_loge("temp var should give a register\n");
- return NULL;
- }
- } else {
- base = r_base->id;
-
- if (v_dst->local_flag || v_dst->tmp_flag)
- offset = v_dst->bp_offset;
- else
- offset = v_dst->offset;
- }
-
- inst = _x64_make_OpCode(OpCode, x64_variable_size(v_dst), r_src, r_base, NULL);
- if (!inst)
- return NULL;
-
- if (_x64_make_disp(prela, inst, r_src->id, base, offset) < 0) {
- free(inst);
- return NULL;
- }
-
- inst->src.base = r_src;
- inst->dst.base = r_base;
- inst->dst.disp = offset;
- inst->dst.mem_flag = 1;
-
- return inst;
-}
-
scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst)
{
if (OpCode->ModRM_OpCode_used) {
return inst;
}
-scf_instruction_t* x64_make_inst_M2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, scf_variable_t* v_src, scf_3ac_code_t* c, scf_function_t* f)
-{
- if (OpCode->ModRM_OpCode_used) {
- scf_loge("ModRM opcode invalid\n");
- return NULL;
- }
-
- scf_register_t* rbp = x64_find_register("rbp");
- scf_instruction_t* inst = NULL;
-
- uint32_t base;
- int32_t offset;
-
- if (!r_base) {
- if (v_src->local_flag || v_src->tmp_flag) {
-
- base = SCF_X64_REG_RBP;
- offset = v_src->bp_offset;
- r_base = rbp;
-
- } else if (v_src->global_flag) {
- base = -1;
- offset = 0;
-
- if (v_src->extern_flag && f->pic_flag) {
- assert(!r_base);
-
- int ret = x64_make_inst_pic(&r_base, v_src, c, f);
- if (ret < 0)
- return NULL;
-
- base = r_base->id;
- }
- } else {
- scf_loge("temp var should give a register\n");
- return NULL;
- }
- } else {
- base = r_base->id;
-
- if (v_src->local_flag || v_src->tmp_flag)
- offset = v_src->bp_offset;
- else
- offset = v_src->offset;
- }
-
- inst = _x64_make_OpCode(OpCode, r_dst->bytes, r_dst, r_base, NULL);
- if (!inst)
- return NULL;
-
- if (_x64_make_disp(prela, inst, r_dst->id, base, offset) < 0) {
- free(inst);
- return NULL;
- }
-
- inst->dst.base = r_dst;
- inst->src.base = r_base;
- inst->src.disp = offset;
- inst->src.mem_flag = 1;
-
- return inst;
-}
-
scf_instruction_t* x64_make_inst_P2G(scf_x64_OpCode_t* OpCode, scf_register_t* r_dst, scf_register_t* r_base, int32_t offset)
{
if (OpCode->ModRM_OpCode_used) {
#include"scf_x64.h"
-scf_x64_OpCode_t x64_OpCodes[] = {
+scf_x64_OpCode_t x64_OpCodes[] =
+{
{SCF_X64_PUSH, "push", 1, {0x50, 0x0, 0x0},1, 8,8, SCF_X64_G, 0,0, 0,{0,0}},
{SCF_X64_POP, "pop", 1, {0x58, 0x0, 0x0},1, 8,8, SCF_X64_G, 0,0, 0,{0,0}},
{SCF_X64_XOR, "xorw", 2, {0x33, 0x0, 0x0},1, 2,2, SCF_X64_E2G, 0,0, 0,{0,0}},
{SCF_X64_XOR, "xorl", 2, {0x33, 0x0, 0x0},1, 4,4, SCF_X64_E2G, 0,0, 0,{0,0}},
{SCF_X64_XOR, "xorq", 2, {0x33, 0x0, 0x0},1, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}},
-#if 0
- {SCF_X64_XOR, "xor", 2, {0x34, 0x0, 0x0},1, 1,1, SCF_X64_I2G, 0,0, 1,{0,0}},
- {SCF_X64_XOR, "xor", 2, {0x35, 0x0, 0x0},1, 2,2, SCF_X64_I2G, 0,0, 1,{0,0}},
- {SCF_X64_XOR, "xor", 2, {0x35, 0x0, 0x0},1, 4,4, SCF_X64_I2G, 0,0, 1,{0,0}},
- {SCF_X64_XOR, "xor", 2, {0x35, 0x0, 0x0},1, 4,8, SCF_X64_I2G, 0,0, 1,{0,0}},
+#if 1
+ {SCF_X64_XOR, "xor", 2, {0x80, 0x0, 0x0},1, 1,1, SCF_X64_I2E, 6,1, 0,{0,0}},
+ {SCF_X64_XOR, "xor", 2, {0x81, 0x0, 0x0},1, 2,2, SCF_X64_I2E, 6,1, 0,{0,0}},
+ {SCF_X64_XOR, "xor", 2, {0x81, 0x0, 0x0},1, 4,4, SCF_X64_I2E, 6,1, 0,{0,0}},
+ {SCF_X64_XOR, "xor", 2, {0x81, 0x0, 0x0},1, 4,8, SCF_X64_I2E, 6,1, 0,{0,0}},
#endif
{SCF_X64_AND, "and", 2, {0x20, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_AND, "and", 2, {0x21, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}},
} \
} while (0)
+#define X64_ASM_ADD_CHECK(_vec, _inst, _rela) \
+ do { \
+ if (!(_inst)) { \
+ scf_loge("\n"); \
+ return -ENOMEM; \
+ } \
+ int ret = scf_vector_add((_vec), (_inst)); \
+ if (ret < 0) { \
+ scf_instruction_free(_inst); \
+ scf_rela_free(_rela); \
+ return ret; \
+ } \
+ } while (0)
+
#define X64_RELA_ADD_LABEL(_vec, _rela, _inst, _label) \
do { \
if (_rela) { \
X64_RCG_BINARY(sub)
X64_RCG_BINARY(bit_and)
X64_RCG_BINARY(bit_or)
+X64_RCG_BINARY(bit_xor)
X64_RCG_BINARY(comma)
static int _x64_rcg_shift(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
return x64_rcg_make(c, g, dst->dag_node, NULL);
}
+static int _x64_rcg_xor_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
+{
+ scf_3ac_operand_t* dst = c->dsts->data[0];
+
+ int ret = x64_rcg_make2(c, dst->dag_node, NULL);
+ if (ret < 0)
+ return ret;
+
+ return x64_rcg_make(c, g, dst->dag_node, NULL);
+}
+
static int _x64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
int i;
X64_RCG_BINARY_ASSIGN(sub)
X64_RCG_BINARY_ASSIGN(and)
X64_RCG_BINARY_ASSIGN(or)
+X64_RCG_BINARY_ASSIGN(xor)
#define X64_RCG_SHIFT_ASSIGN(name) \
static int _x64_rcg_##name##_assign_dereference_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) \
[SCF_OP_BIT_AND ] = _x64_rcg_bit_and_handler,
[SCF_OP_BIT_OR ] = _x64_rcg_bit_or_handler,
+ [SCF_OP_BIT_XOR ] = _x64_rcg_bit_xor_handler,
[SCF_OP_EQ ] = _x64_rcg_eq_handler,
[SCF_OP_NE ] = _x64_rcg_ne_handler,
[SCF_OP_AND_ASSIGN ] = _x64_rcg_and_assign_handler,
[SCF_OP_OR_ASSIGN ] = _x64_rcg_or_assign_handler,
+ [SCF_OP_XOR_ASSIGN ] = _x64_rcg_xor_assign_handler,
[SCF_OP_COMMA ] = _x64_rcg_comma_handler,
CFILES += ../native/x64/scf_x64.c
CFILES += ../native/x64/scf_x64_inst.c
CFILES += ../native/x64/scf_x64_inst_util.c
+CFILES += ../native/x64/scf_x64_inst_pic.c
CFILES += ../native/x64/scf_x64_inst_shift.c
CFILES += ../native/x64/scf_x64_inst_common.c
CFILES += ../native/x64/scf_x64_inst_binary.c
#include"scf_x64.h"
#include"scf_elf_link.h"
-static char* __h_files[] =
+#define __builtin_str "struct __builtin_va_list {" \
+ "uint8_t* iptr;" \
+ "uint8_t* fptr;" \
+ "uint8_t* optr;" \
+ "intptr_t ireg;" \
+ "intptr_t freg;" \
+"};"
+
+static scf_string_t __builtin_h =
{
- "../sysroot/lib/__builtin__.h",
+ .len = sizeof(__builtin_str) - 1,
+ .capacity = -1,
+ .data = __builtin_str,
};
static char* __objs[] =
int ret = 0;
+ scf_parse_t* parse = NULL;
+
scf_vector_t* inc_paths = scf_vector_alloc();
scf_vector_t* lib_paths = scf_vector_alloc();
scf_vector_t* lib_files = scf_vector_alloc();
int pic = 0;
int c_version = SCF_C99;
- int i;
- for (i = 0; i < sizeof(__h_files) / sizeof(__h_files[0]); i++) {
-
- ret = scf_vector_add(srcs, __h_files[i]);
- if (ret < 0)
- goto error;
- }
-
int n_srcs = srcs->size;
+ int i;
for (i = 1; i < argc; i++) {
}
if (srcs->size > n_srcs) {
- scf_parse_t* parse = NULL;
ret = scf_parse_open(&parse, inc_paths, c_version);
if (ret < 0) {
goto error;
}
+ ret = scf_parse_file(parse, "__builtin__.h", &__builtin_h, NULL, NULL);
+ if (ret < 0) {
+ scf_loge("\n");
+ goto error;
+ }
+
for (i = 0; i < srcs->size; i++) {
char* file = srcs->data[i];
m->refs++;
}
- ret = scf_parse_file(parse, file, &_macros, NULL);
+ ret = scf_parse_file(parse, file, NULL, &_macros, NULL);
if (_macros) {
scf_vector_clear(_macros, ( void (*)(void*) )scf_macro_free);
ret = 0;
error:
+ if (parse)
+ scf_parse_close(parse);
+
if (inc_paths)
scf_vector_free(inc_paths);
return SCF_DFA_ERROR;
}
- scf_logd("d->expr: %p, OP: %d\n", d->expr, d->expr->type);
+ scf_logd("d->expr: %p\n", d->expr);
scf_expr_t* grand = scf_stack_top(d->lp_exprs);
if (grand) {
- grand->pause_flag = 1;
+ grand->pause_flag++;
scf_logi("grand: %p, grand->pause_flag: %d\n", grand, grand->pause_flag);
}
scf_expr_t* grand = scf_stack_top(d->lp_exprs);
if (grand) {
- grand->pause_flag = 0;
+ grand->pause_flag--;
scf_logi("grand: %p, grand->pause_flag: %d\n", grand, grand->pause_flag);
}
return SCF_DFA_ERROR;
}
+ scf_logd("d->expr: %p\n", d->expr);
+
return words->size > 0 ? SCF_DFA_CONTINUE : SCF_DFA_NEXT_WORD;
}
static int _expr_action_binary_op(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- scf_logd("\n");
-
scf_parse_t* parse = dfa->priv;
dfa_data_t* d = data;
scf_lex_word_t* w = words->data[words->size - 1];
md->parent_block = NULL;
}
+ scf_logd("d->expr: %p\n", d->expr);
+
return _expr_action_op(dfa, words, data, 2);
}
d->op_comma_flag = 0;
}
- scf_logi("d->op_comma_flag: %d\n", d->op_comma_flag);
+ scf_logi("d->op_comma_flag: %d, d->expr: %p\n", d->op_comma_flag, d->expr);
if (id && id->identity) {
return SCF_DFA_ERROR;
}
+ scf_logi("static_flag: %d, f->static_flag: %d, f: %p\n", id->static_flag, f->static_flag, f);
+
v = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL);
free(id);
id = NULL;
id = NULL;
}
- scf_logi("s->size: %d, function: %s(), line: %d, member_flag: %d\n", s->size, f->node.w->text->data, f->node.w->line, f->member_flag);
-
int ret = _function_add_rets(f, d);
if (ret < 0) {
scf_function_free(f);
return ret;
}
+ scf_logi("s->size: %d, function: %s(), line: %d, static_flag: %d, member_flag: %d\n",
+ s->size, f->node.w->text->data, f->node.w->line, f->static_flag, f->member_flag);
+
if (v_pf) {
v_pf->static_flag = f->static_flag;
v_pf->func_ptr = f;
parse->lex = NULL;
//int64_t tv0 = gettime();
- ret = scf_parse_file(parse, path, &lex->macros, include);
+ ret = scf_parse_file(parse, path, NULL, &lex->macros, include);
//int64_t tv1 = gettime();
//scf_logi("tv1 - tv0: %ld, path: %s\n", tv1 - tv0, path);
if (ret < 0) {
int nb_dots;
} init_module_data_t;
+static int _data_is_index(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return scf_lex_is_const_integer(w) || scf_lex_is_identity(w);
+}
+
static int _do_data_init(scf_dfa_t* dfa, scf_vector_t* words, dfa_data_t* d)
{
scf_parse_t* parse = dfa->priv;
dfa_data_t* d = data;
scf_lex_word_t* w = words->data[words->size - 1];
init_module_data_t* md = d->module_datas[dfa_module_init_data.index];
+ scf_variable_t* v;
if (md->current_dim >= md->current_n) {
scf_loge("init data not right, file: %s, line: %d\n", w->file->data, w->line);
return SCF_DFA_ERROR;
}
- md->current_index[md->current_dim].i = w->data.u64;
+ if (scf_lex_is_identity(w)) {
+ v = NULL;
+
+ if (scf_ast_find_variable(&v, parse->ast, w->text->data) < 0)
+ return SCF_DFA_ERROR;
+
+ if (!v) {
+ scf_loge("%s:%d:%d, const enum '%s' NOT found\n", w->file->data, w->line, w->pos, w->text->data);
+ return SCF_DFA_ERROR;
+ }
+
+ md->current_index[md->current_dim].i = v->data.u64;
+
+ scf_logd("%s:%d:%d, const enum '%s', %ld\n", w->file->data, w->line, w->pos, w->text->data, v->data.u64);
+ } else
+ md->current_index[md->current_dim].i = w->data.u64;
return SCF_DFA_NEXT_WORD;
}
SCF_DFA_MODULE_NODE(dfa, init_data, dot, scf_dfa_is_dot, _data_action_dot);
SCF_DFA_MODULE_NODE(dfa, init_data, member, scf_dfa_is_identity, _data_action_member);
- SCF_DFA_MODULE_NODE(dfa, init_data, index, scf_dfa_is_const_integer, _data_action_index);
+ SCF_DFA_MODULE_NODE(dfa, init_data, index, _data_is_index, _data_action_index);
SCF_DFA_MODULE_NODE(dfa, init_data, assign, scf_dfa_is_assign, scf_dfa_action_next);
SCF_DFA_MODULE_NODE(dfa, init_data, merr, scf_dfa_is_entry, _error_action_member);
scf_dfa_node_add_child(rb, rb);
scf_dfa_node_add_child(rb, comma);
scf_dfa_node_add_child(comma, lb);
+ scf_dfa_node_add_child(comma, rb);
// init expr for member of data
scf_dfa_node_add_child(lb, dot);
scf_expr_t* grand = scf_stack_top(d->lp_exprs);
if (grand) {
- grand->pause_flag = 1;
+ grand->pause_flag++;
scf_logi("grand: %p, grand->pause_flag: %d\n", grand, grand->pause_flag);
}
sd->nb_rps++;
- scf_logd("sd->nb_lps: %d, sd->nb_rps: %d\n", sd->nb_lps, sd->nb_rps);
+ scf_logd("sd->nb_lps: %d, sd->nb_rps: %d, d->expr: %p\n", sd->nb_lps, sd->nb_rps, d->expr);
if (sd->nb_rps < sd->nb_lps) {
scf_expr_t* grand = scf_stack_top(d->lp_exprs);
if (grand) {
- grand->pause_flag = 0;
+ assert(--grand->pause_flag >= 0);
scf_logi("grand: %p, grand->pause_flag: %d\n", grand, grand->pause_flag);
}
return 0;
}
+static int _scf_op_const_xor_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ return 0;
+}
+
static int _scf_op_const_cmp(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
return _scf_op_const_binary(ast, nodes, nb_nodes, data);
return _scf_op_const_binary(ast, nodes, nb_nodes, data);
}
+static int _scf_op_const_bit_xor(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ return _scf_op_const_binary(ast, nodes, nb_nodes, data);
+}
+
static int _scf_op_const_comma(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
[SCF_OP_BIT_AND ] = _scf_op_const_bit_and,
[SCF_OP_BIT_OR ] = _scf_op_const_bit_or,
+ [SCF_OP_BIT_XOR ] = _scf_op_const_bit_xor,
[SCF_OP_EQ ] = _scf_op_const_eq,
[SCF_OP_NE ] = _scf_op_const_ne,
[SCF_OP_SHR_ASSIGN ] = _scf_op_const_shr_assign,
[SCF_OP_AND_ASSIGN ] = _scf_op_const_and_assign,
[SCF_OP_OR_ASSIGN ] = _scf_op_const_or_assign,
+ [SCF_OP_XOR_ASSIGN ] = _scf_op_const_xor_assign,
[SCF_OP_COMMA ] = _scf_op_const_comma,
return _scf_op_semantic_binary_interger(ast, nodes, nb_nodes, data);
}
+static int _scf_op_semantic_bit_xor(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ return _scf_op_semantic_binary_interger(ast, nodes, nb_nodes, data);
+}
+
static int _semantic_multi_rets_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
return _scf_op_semantic_binary_interger_assign(ast, nodes, nb_nodes, data);
}
+static int _scf_op_semantic_xor_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+ return _scf_op_semantic_binary_interger_assign(ast, nodes, nb_nodes, data);
+}
+
static int _scf_op_semantic_cmp(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
{
assert(2 == nb_nodes);
[SCF_OP_BIT_AND ] = _scf_op_semantic_bit_and,
[SCF_OP_BIT_OR ] = _scf_op_semantic_bit_or,
+ [SCF_OP_BIT_XOR ] = _scf_op_semantic_bit_xor,
[SCF_OP_EQ ] = _scf_op_semantic_eq,
[SCF_OP_NE ] = _scf_op_semantic_ne,
[SCF_OP_SHR_ASSIGN ] = _scf_op_semantic_shr_assign,
[SCF_OP_AND_ASSIGN ] = _scf_op_semantic_and_assign,
[SCF_OP_OR_ASSIGN ] = _scf_op_semantic_or_assign,
+ [SCF_OP_XOR_ASSIGN ] = _scf_op_semantic_xor_assign,
[SCF_OP_COMMA ] = _scf_op_semantic_comma,
return 0;
}
-int scf_parse_file(scf_parse_t* parse, const char* path, scf_vector_t** macros, scf_lex_word_t* include)
+int scf_parse_file(scf_parse_t* parse, const char* path, scf_string_t* text, scf_vector_t** macros, scf_lex_word_t* include)
{
if (!parse || !path)
return -EINVAL;
lex = lex->next;
}
- if (scf_lex_open(&parse->lex, path, NULL, parse->c_version, include) < 0)
+ if (scf_lex_open(&parse->lex, path, text, parse->c_version, include) < 0)
return -1;
if (cur == ast->root_block)
parse->lex->next = cur->lex_list;
cur->lex_list = parse->lex;
- parse->lex->macros = *macros;
- *macros = NULL;
+ if (macros) {
+ parse->lex->macros = *macros;
+ *macros = NULL;
+ }
dfa_data_t* d = parse->dfa_data;
scf_lex_word_t* w = NULL;
break;
}
- fclose(parse->lex->fp);
- parse->lex->fp = NULL;
+ if (parse->lex->fp) {
+ fclose(parse->lex->fp);
+ parse->lex->fp = NULL;
+ }
ast->current_block = old;
return ret;
for (i = 0; i < functions->size; i++) {
f = functions->data[i];
- printf("%d, %s(), argv->size: %d, define_flag: %d, inline_flag: %d\n",
- i, f->node.w->text->data, f->argv->size, f->node.define_flag, f->inline_flag);
+ scf_logd("%d, %s(), argv->size: %d, define_flag: %d, inline_flag: %d, static_flag: %d\n",
+ i, f->node.w->text->data, f->argv->size, f->node.define_flag, f->inline_flag, f->static_flag);
if (!f->node.define_flag)
continue;
if (ret < 0)
return ret;
- ret = scf_symtab_add_sym(parse->symtab, f->signature->data, f->code_bytes, offset, SCF_SHNDX_TEXT, ELF64_ST_INFO(STB_GLOBAL, STT_FUNC));
+ uint64_t stb;
+ if (f->static_flag)
+ stb = STB_LOCAL;
+ else
+ stb = STB_GLOBAL;
+
+ ret = scf_symtab_add_sym(parse->symtab, f->signature->data, f->code_bytes, offset, SCF_SHNDX_TEXT, ELF64_ST_INFO(stb, STT_FUNC));
if (ret < 0)
return ret;
int scf_parse_open (scf_parse_t** pparse, const scf_vector_t* inc_paths, int c_version);
int scf_parse_close(scf_parse_t* parse);
-int scf_parse_file (scf_parse_t* parse, const char* path, scf_vector_t** macros, scf_lex_word_t* include);
+int scf_parse_file (scf_parse_t* parse, const char* path, scf_string_t* text, scf_vector_t** macros, scf_lex_word_t* include);
+
int scf_parse_compile(scf_parse_t* parse, const char* arch, int _3ac, int pic_flag);
int scf_parse_to_obj (scf_parse_t* parse, const char* out, const char* arch);