From 495512037313365e9b5d16e39f133ed6bdf1cb01 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Fri, 11 Sep 2026 22:08:31 +0800 Subject: [PATCH] 1, self compile: ../lex/scf_macro_expr.c & ../lex/scf_lex_util.c ok, 2, support xor operator ^, 3, fix: core dump caused by 'empty 3ac code list' of some basic block, in x64_bb_load_dn2(), 4, fix: parse error of complex expr at Line:657 of __macro_if_expr(), 5, fix: array init when index is a const enum, in _data_action_index(), 6, fix: self compile for __use_macro() in ../lex/scf_macro.c, failed source code like below: if ((ret = scf_string_cat(s0, s1)) && (ret = scf_string_cat(s0, s2)) ) { // ... } 7, fix: wild pointer when 'do-while' with a complex condtion expr & followed by a 'if-else', source code like below: int c = '0'; do { } while ('a' <= c && 'z' >= c); int type = 1; if (type < 0) return 1; --- asm/Makefile | 2 + asm/scf_asm.c | 2 +- asm/scf_asm.h | 4 +- asm/scf_dfa_naja.c | 49 ++-- asm/scf_dfa_x64.c | 38 +-- core/scf_3ac.c | 49 ++-- core/scf_calculate.c | 4 + core/scf_calculate_i32.c | 1 + core/scf_calculate_i64.c | 1 + core/scf_calculate_u32.c | 1 + core/scf_calculate_u64.c | 1 + core/scf_core_types.h | 1 + core/scf_lex_word.h | 1 + core/scf_node.h | 3 +- core/scf_operator.c | 2 + core/scf_operator_dag.c | 4 + core/scf_operator_handler_3ac.c | 45 ++-- core/scf_optimizer.c | 2 +- core/scf_optimizer_loop.c | 26 ++- core/scf_optimizer_vla.c | 190 --------------- lex/scf_lex.c | 14 +- lex/scf_lex.h | 5 +- lex/scf_macro.c | 2 +- lex/scf_macro_expr.c | 2 +- native/risc/scf_risc_opcode.h | 13 ++ native/x64/scf_x64_bb_color.c | 50 +++- native/x64/scf_x64_inst.c | 4 + native/x64/scf_x64_inst_common.c | 3 +- native/x64/scf_x64_inst_pic.c | 325 ++++++++++++++++++++++++++ native/x64/scf_x64_inst_util.c | 321 +------------------------ native/x64/scf_x64_opcode.c | 13 +- native/x64/scf_x64_opcode.h | 14 ++ native/x64/scf_x64_rcg.c | 15 ++ parse/Makefile | 1 + parse/main.c | 37 ++- parse/scf_dfa_call.c | 6 +- parse/scf_dfa_expr.c | 8 +- parse/scf_dfa_function.c | 7 +- parse/scf_dfa_include.c | 2 +- parse/scf_dfa_init_data.c | 28 ++- parse/scf_dfa_sizeof.c | 6 +- parse/scf_operator_handler_const.c | 12 + parse/scf_operator_handler_semantic.c | 12 + parse/scf_parse.c | 28 ++- parse/scf_parse.h | 3 +- 45 files changed, 691 insertions(+), 666 deletions(-) delete mode 100644 core/scf_optimizer_vla.c create mode 100644 native/x64/scf_x64_inst_pic.c diff --git a/asm/Makefile b/asm/Makefile index c6849f7..b5538fc 100644 --- a/asm/Makefile +++ b/asm/Makefile @@ -1,6 +1,8 @@ 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 diff --git a/asm/scf_asm.c b/asm/scf_asm.c index 91ff6d5..88391b7 100644 --- a/asm/scf_asm.c +++ b/asm/scf_asm.c @@ -97,7 +97,7 @@ int scf_asm_file(scf_asm_t* _asm, const char* path) 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; diff --git a/asm/scf_asm.h b/asm/scf_asm.h index 39b2132..0966ae7 100644 --- a/asm/scf_asm.h +++ b/asm/scf_asm.h @@ -70,14 +70,14 @@ int scf_asm_fill(scf_instruction_t** __inst, int n, int size, uint64_t imm); 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; } diff --git a/asm/scf_dfa_naja.c b/asm/scf_dfa_naja.c index bab87d9..3b8cb89 100644 --- a/asm/scf_dfa_naja.c +++ b/asm/scf_dfa_naja.c @@ -95,12 +95,12 @@ static int _naja_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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: @@ -113,7 +113,7 @@ static int _naja_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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)) { @@ -160,7 +160,7 @@ static int _naja_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) } 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: @@ -199,7 +199,7 @@ static int _naja_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } @@ -246,7 +246,7 @@ static int _naja_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data) } } - 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; @@ -261,7 +261,7 @@ static int _naja_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data 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); @@ -305,7 +305,7 @@ static int _naja_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data 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)); @@ -401,7 +401,7 @@ static int _naja_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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++; } @@ -481,15 +481,15 @@ static int __asm_naja_ADD(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t 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; } @@ -503,7 +503,7 @@ static int __asm_naja_RET(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t 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; @@ -522,21 +522,24 @@ static int __asm_naja_JMP(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t 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; } @@ -559,7 +562,7 @@ static int __asm_naja_CALL(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_ 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; @@ -567,7 +570,7 @@ static int __asm_naja_CALL(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_ 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)); @@ -601,7 +604,7 @@ static int __asm_naja_ADRP(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_ } 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; @@ -634,7 +637,7 @@ static int __asm_naja_MOV(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t 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; @@ -656,7 +659,7 @@ static int __asm_naja_PUSH(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_ } 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; @@ -678,7 +681,7 @@ static int __asm_naja_POP(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t } 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; @@ -768,7 +771,7 @@ static int _naja_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } @@ -781,10 +784,10 @@ static int _naja_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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; diff --git a/asm/scf_dfa_x64.c b/asm/scf_dfa_x64.c index 5aae34c..ff46213 100644 --- a/asm/scf_dfa_x64.c +++ b/asm/scf_dfa_x64.c @@ -94,12 +94,12 @@ static int _x64_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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: @@ -112,7 +112,7 @@ static int _x64_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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)) { @@ -159,7 +159,7 @@ static int _x64_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) } 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: @@ -198,7 +198,7 @@ static int _x64_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } @@ -245,7 +245,7 @@ static int _x64_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data) } } - 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; @@ -260,7 +260,7 @@ static int _x64_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); @@ -304,7 +304,7 @@ static int _x64_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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)); @@ -400,7 +400,7 @@ static int _x64_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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++; } @@ -489,7 +489,7 @@ static int __x64_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, 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)) { @@ -510,7 +510,7 @@ static int __x64_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, 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)); @@ -563,7 +563,7 @@ static int __x64_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, } } - X64_INST_ADD_CHECK(_asm->current, inst, NULL); + X64_ASM_ADD_CHECK(_asm->current, inst, NULL); } } else if (__inst_data_is_reg(id1)) { @@ -586,7 +586,7 @@ static int __x64_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, 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)); @@ -631,7 +631,7 @@ static int __x64_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, 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; @@ -645,7 +645,7 @@ static int __x64_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, 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)); @@ -663,7 +663,7 @@ static int __x64_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, } 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); } } @@ -697,7 +697,7 @@ static int _x64_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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; @@ -740,7 +740,7 @@ static int _x64_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } @@ -753,10 +753,10 @@ static int _x64_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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; diff --git a/core/scf_3ac.c b/core/scf_3ac.c index eb5a6ae..77f5fcd 100644 --- a/core/scf_3ac.c +++ b/core/scf_3ac.c @@ -3,18 +3,19 @@ #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"}, @@ -22,28 +23,29 @@ static scf_3ac_operator_t _3ac_operators[] = { {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, "+="}, @@ -55,6 +57,7 @@ static scf_3ac_operator_t _3ac_operators[] = { {SCF_OP_SHR_ASSIGN, ">>="}, {SCF_OP_AND_ASSIGN, "&="}, {SCF_OP_OR_ASSIGN, "|="}, + {SCF_OP_XOR_ASSIGN, "^="}, {SCF_OP_COMMA, "comma"}, @@ -63,13 +66,13 @@ static scf_3ac_operator_t _3ac_operators[] = { {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"}, diff --git a/core/scf_calculate.c b/core/scf_calculate.c index 6f068ad..b70d37e 100644 --- a/core/scf_calculate.c +++ b/core/scf_calculate.c @@ -27,6 +27,7 @@ scf_calculate_t base_calculates[] = {"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}, @@ -57,6 +58,7 @@ scf_calculate_t base_calculates[] = {"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}, @@ -87,6 +89,7 @@ scf_calculate_t base_calculates[] = {"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}, @@ -118,6 +121,7 @@ scf_calculate_t base_calculates[] = {"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}, diff --git a/core/scf_calculate_i32.c b/core/scf_calculate_i32.c index c01ad95..1caf5c1 100644 --- a/core/scf_calculate_i32.c +++ b/core/scf_calculate_i32.c @@ -51,6 +51,7 @@ SCF_I32_UNARY_OP(neg, -) 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, &&) diff --git a/core/scf_calculate_i64.c b/core/scf_calculate_i64.c index ed2eee9..b8cd7d5 100644 --- a/core/scf_calculate_i64.c +++ b/core/scf_calculate_i64.c @@ -51,6 +51,7 @@ SCF_I64_UNARY_OP(neg, -) 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, &&) diff --git a/core/scf_calculate_u32.c b/core/scf_calculate_u32.c index fa982d2..aef680d 100644 --- a/core/scf_calculate_u32.c +++ b/core/scf_calculate_u32.c @@ -51,6 +51,7 @@ SCF_U32_UNARY_OP(neg, -) 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, &&) diff --git a/core/scf_calculate_u64.c b/core/scf_calculate_u64.c index 36aaebd..4979a1f 100644 --- a/core/scf_calculate_u64.c +++ b/core/scf_calculate_u64.c @@ -51,6 +51,7 @@ SCF_U64_UNARY_OP(neg, -) 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, &&) diff --git a/core/scf_core_types.h b/core/scf_core_types.h index cd19223..0855551 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -72,6 +72,7 @@ enum scf_core_types SCF_OP_SHL_ASSIGN, // <<= SCF_OP_SHR_ASSIGN, // >>= SCF_OP_AND_ASSIGN, // &= + SCF_OP_XOR_ASSIGN, // ^= SCF_OP_OR_ASSIGN, // |= // 30 diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index 8d00360..f505e64 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -41,6 +41,7 @@ enum scf_lex_words 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 diff --git a/core/scf_node.h b/core/scf_node.h index 3906cdc..58e143b 100644 --- a/core/scf_node.h +++ b/core/scf_node.h @@ -33,6 +33,8 @@ struct scf_node_s { 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 @@ -46,7 +48,6 @@ struct scf_node_s { 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 { diff --git a/core/scf_operator.c b/core/scf_operator.c index eb40d70..213f428 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -45,6 +45,7 @@ static scf_operator_t base_operators[] = {"&", "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}, @@ -69,6 +70,7 @@ static scf_operator_t base_operators[] = {">>=", 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}, diff --git a/core/scf_operator_dag.c b/core/scf_operator_dag.c index 364d5b9..5d49a6f 100644 --- a/core/scf_operator_dag.c +++ b/core/scf_operator_dag.c @@ -318,6 +318,7 @@ SCF_DAG_BINARY(shr, SHR) 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) @@ -370,6 +371,7 @@ SCF_DAG_BINARY_ASSIGN(shr_assign, SHR_ASSIGN) 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) \ @@ -459,6 +461,7 @@ scf_dag_operator_t dag_operators[] = {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}, @@ -491,6 +494,7 @@ scf_dag_operator_t dag_operators[] = {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}, diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index 98f8653..b21f159 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -1073,7 +1073,7 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s 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; @@ -1083,6 +1083,14 @@ static void __scf_loop_entry_clear(scf_list_t* start_prev, scf_3ac_code_t* jmp_e 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; @@ -1137,7 +1145,7 @@ static int _scf_op_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da // 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; } @@ -1190,7 +1198,7 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* 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; @@ -1430,7 +1438,6 @@ static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data) 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]; @@ -1441,7 +1448,7 @@ static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data) 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; } } @@ -1880,6 +1887,7 @@ SCF_OP_BINARY(shl, SCF_OP_SHL) 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) @@ -2070,6 +2078,7 @@ SCF_OP_BINARY_ASSIGN(add, ADD) 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) @@ -2141,9 +2150,18 @@ static int _scf_op_##name(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void 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"); \ @@ -2166,9 +2184,9 @@ static int _scf_op_##name(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void } \ 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) @@ -2422,16 +2440,9 @@ static int _scf_op_logic_##name(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes 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); \ @@ -2483,6 +2494,7 @@ scf_operator_handler_pt __operator_handlers[SCF_N_3AC_OPS] = [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, @@ -2507,6 +2519,7 @@ scf_operator_handler_pt __operator_handlers[SCF_N_3AC_OPS] = [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, diff --git a/core/scf_optimizer.c b/core/scf_optimizer.c index 133a513..5f839d9 100644 --- a/core/scf_optimizer.c +++ b/core/scf_optimizer.c @@ -100,7 +100,7 @@ int scf_optimize(scf_ast_t* ast, scf_vector_t* functions) } } -#if 1 +#if 0 for (i = 0; i < functions->size; i++) { f = functions->data[i]; diff --git a/core/scf_optimizer_loop.c b/core/scf_optimizer_loop.c index e6f6e3e..c72c65b 100644 --- a/core/scf_optimizer_loop.c +++ b/core/scf_optimizer_loop.c @@ -380,16 +380,11 @@ static int __bb_loop_layers(scf_function_t* f) 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; @@ -401,11 +396,17 @@ static int _bb_loop_layers(scf_function_t* f) 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); @@ -733,6 +734,11 @@ static int _optimize_loop(scf_ast_t* ast, scf_function_t* f, scf_vector_t* funct 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); diff --git a/core/scf_optimizer_vla.c b/core/scf_optimizer_vla.c deleted file mode 100644 index 3503d4c..0000000 --- a/core/scf_optimizer_vla.c +++ /dev/null @@ -1,190 +0,0 @@ -#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, -}; diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 4b3c29f..0895840 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -216,7 +216,7 @@ int scf_lex_open(scf_lex_t** plex, const char* path, scf_string_t* text, int c_v } } else { lex->text = text; - lex->asm_flag = 1; + lex->asm_flag = (SCF_ASM == c_version); } lex->nb_lines = 1; @@ -1162,6 +1162,13 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) 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; @@ -1347,7 +1354,10 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) 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; diff --git a/lex/scf_lex.h b/lex/scf_lex.h index bf261f7..72177c9 100644 --- a/lex/scf_lex.h +++ b/lex/scf_lex.h @@ -6,8 +6,9 @@ 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; diff --git a/lex/scf_macro.c b/lex/scf_macro.c index 487a082..7873837 100644 --- a/lex/scf_macro.c +++ b/lex/scf_macro.c @@ -958,7 +958,7 @@ static int _find_used_macro(const void* v0, const void* v1) 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) { diff --git a/lex/scf_macro_expr.c b/lex/scf_macro_expr.c index 98f5e5e..4b22de3 100644 --- a/lex/scf_macro_expr.c +++ b/lex/scf_macro_expr.c @@ -4,7 +4,7 @@ scf_macro_t* __find_macro(scf_lex_t* lex, scf_lex_word_t* w); typedef struct { scf_lex_word_t** pp; - scf_lex_word_t* error; +// scf_lex_word_t* error; int n_q_masks; int n_colons; diff --git a/native/risc/scf_risc_opcode.h b/native/risc/scf_risc_opcode.h index d11bce9..fa62575 100644 --- a/native/risc/scf_risc_opcode.h +++ b/native/risc/scf_risc_opcode.h @@ -67,6 +67,19 @@ scf_instruction_t* risc_make_inst(scf_3ac_code_t* c, uint32_t opcode); (_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)); \ diff --git a/native/x64/scf_x64_bb_color.c b/native/x64/scf_x64_bb_color.c index 2f9eefa..87043fc 100644 --- a/native/x64/scf_x64_bb_color.c +++ b/native/x64/scf_x64_bb_color.c @@ -182,15 +182,28 @@ int x64_bb_save_dn(intptr_t color, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_ba 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); } @@ -233,6 +246,7 @@ int x64_load_bb_colors(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_ scf_dn_status_t* ds2; scf_dag_node_t* dn; scf_variable_t* v; + scf_register_t* r; int i; int j; @@ -247,6 +261,7 @@ int x64_load_bb_colors(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_ ds = bb->dn_colors_entry->data[i]; dn = ds->dag_node; + v = dn->var; intptr_t color = dn->color; int first = 0; @@ -300,12 +315,17 @@ int x64_load_bb_colors(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_ } } - 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); } @@ -421,6 +441,7 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function ds = bb->dn_colors_entry->data[i]; dn = ds->dag_node; + v = dn->var; intptr_t color = dn->color; int first = 0; @@ -475,18 +496,23 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function } } - 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++) { @@ -508,9 +534,9 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function 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; } diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 85135aa..6e74c02 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -1309,6 +1309,7 @@ X64_INST_OP3(add, ADD) 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) @@ -1920,6 +1921,7 @@ X64_INST_BINARY_ASSIGN(add_assign, ADD) 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) { @@ -2391,6 +2393,7 @@ static x64_inst_handler_pt x64_inst_handlers[] = [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, @@ -2423,6 +2426,7 @@ static x64_inst_handler_pt x64_inst_handlers[] = [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, diff --git a/native/x64/scf_x64_inst_common.c b/native/x64/scf_x64_inst_common.c index 4fcb48a..ec7450d 100644 --- a/native/x64/scf_x64_inst_common.c +++ b/native/x64/scf_x64_inst_common.c @@ -233,7 +233,8 @@ int x64_inst_op2(int OpCode_type, scf_dag_node_t* dst, scf_dag_node_t* src, scf_ 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); diff --git a/native/x64/scf_x64_inst_pic.c b/native/x64/scf_x64_inst_pic.c new file mode 100644 index 0000000..6c4d6d0 --- /dev/null +++ b/native/x64/scf_x64_inst_pic.c @@ -0,0 +1,325 @@ +#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; +} diff --git a/native/x64/scf_x64_inst_util.c b/native/x64/scf_x64_inst_util.c index 9d9d760..2f8f300 100644 --- a/native/x64/scf_x64_inst_util.c +++ b/native/x64/scf_x64_inst_util.c @@ -1,6 +1,6 @@ #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) @@ -127,7 +127,7 @@ static scf_instruction_t* _x64_make_OpCode(scf_x64_OpCode_t* OpCode, int bytes, 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); @@ -325,46 +325,6 @@ scf_instruction_t* x64_make_inst_I2E(scf_x64_OpCode_t* OpCode, scf_register_t* r 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; @@ -405,83 +365,6 @@ scf_instruction_t* x64_make_inst_L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode) 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; @@ -518,79 +401,6 @@ scf_instruction_t* x64_make_inst_I2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCod 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) { @@ -615,70 +425,6 @@ scf_instruction_t* x64_make_inst_G2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCod 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) { @@ -703,69 +449,6 @@ scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCod 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) { diff --git a/native/x64/scf_x64_opcode.c b/native/x64/scf_x64_opcode.c index d373969..251a285 100644 --- a/native/x64/scf_x64_opcode.c +++ b/native/x64/scf_x64_opcode.c @@ -1,6 +1,7 @@ #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}}, @@ -32,11 +33,11 @@ scf_x64_OpCode_t x64_OpCodes[] = { {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}}, diff --git a/native/x64/scf_x64_opcode.h b/native/x64/scf_x64_opcode.h index 1abe401..af1f0d8 100644 --- a/native/x64/scf_x64_opcode.h +++ b/native/x64/scf_x64_opcode.h @@ -96,6 +96,20 @@ scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCo } \ } 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) { \ diff --git a/native/x64/scf_x64_rcg.c b/native/x64/scf_x64_rcg.c index 79ed787..7092443 100644 --- a/native/x64/scf_x64_rcg.c +++ b/native/x64/scf_x64_rcg.c @@ -638,6 +638,7 @@ X64_RCG_BINARY(add) 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) @@ -860,6 +861,17 @@ static int _x64_rcg_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_ 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; @@ -1038,6 +1050,7 @@ X64_RCG_BINARY_ASSIGN(add) 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) \ @@ -1227,6 +1240,7 @@ static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] = [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, @@ -1248,6 +1262,7 @@ static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] = [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, diff --git a/parse/Makefile b/parse/Makefile index 8cba095..60f5581 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -18,6 +18,7 @@ CFILES += ../native/scf_instruction.c 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 diff --git a/parse/main.c b/parse/main.c index 4c87a25..1f04712 100644 --- a/parse/main.c +++ b/parse/main.c @@ -3,9 +3,19 @@ #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[] = @@ -294,6 +304,8 @@ int main(int argc, char* argv[]) 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(); @@ -326,15 +338,8 @@ int main(int argc, char* argv[]) 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++) { @@ -544,7 +549,6 @@ int main(int argc, char* argv[]) } if (srcs->size > n_srcs) { - scf_parse_t* parse = NULL; ret = scf_parse_open(&parse, inc_paths, c_version); if (ret < 0) { @@ -552,6 +556,12 @@ int main(int argc, char* argv[]) 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]; @@ -572,7 +582,7 @@ int main(int argc, char* argv[]) 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); @@ -652,6 +662,9 @@ int main(int argc, char* argv[]) ret = 0; error: + if (parse) + scf_parse_close(parse); + if (inc_paths) scf_vector_free(inc_paths); diff --git a/parse/scf_dfa_call.c b/parse/scf_dfa_call.c index b4334ae..57000c0 100644 --- a/parse/scf_dfa_call.c +++ b/parse/scf_dfa_call.c @@ -119,11 +119,11 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } @@ -220,7 +220,7 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 46bbc38..fac9cca 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -191,6 +191,8 @@ static int _expr_action_expr(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } + scf_logd("d->expr: %p\n", d->expr); + return words->size > 0 ? SCF_DFA_CONTINUE : SCF_DFA_NEXT_WORD; } @@ -336,8 +338,6 @@ static int _expr_action_unary_op(scf_dfa_t* dfa, scf_vector_t* words, void* data 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]; @@ -382,6 +382,8 @@ static int _expr_action_binary_op(scf_dfa_t* dfa, scf_vector_t* words, void* dat md->parent_block = NULL; } + scf_logd("d->expr: %p\n", d->expr); + return _expr_action_op(dfa, words, data, 2); } @@ -543,7 +545,7 @@ static int _expr_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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) { diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 7610942..23195df 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -53,6 +53,8 @@ int _function_add_rets(scf_function_t* f, dfa_data_t* d) 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; @@ -235,14 +237,15 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d, scf_lex_word_t* lp) 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; diff --git a/parse/scf_dfa_include.c b/parse/scf_dfa_include.c index 365bf56..86a842d 100644 --- a/parse/scf_dfa_include.c +++ b/parse/scf_dfa_include.c @@ -67,7 +67,7 @@ static int _include_action_path(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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) { diff --git a/parse/scf_dfa_init_data.c b/parse/scf_dfa_init_data.c index db77857..36f88cc 100644 --- a/parse/scf_dfa_init_data.c +++ b/parse/scf_dfa_init_data.c @@ -26,6 +26,13 @@ typedef struct { 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; @@ -323,13 +330,29 @@ static int _data_action_index(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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; } @@ -386,7 +409,7 @@ static int _dfa_init_module_init_data(scf_dfa_t* dfa) 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); @@ -436,6 +459,7 @@ static int _dfa_init_syntax_init_data(scf_dfa_t* dfa) 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); diff --git a/parse/scf_dfa_sizeof.c b/parse/scf_dfa_sizeof.c index 839eb43..5d90f9f 100644 --- a/parse/scf_dfa_sizeof.c +++ b/parse/scf_dfa_sizeof.c @@ -57,7 +57,7 @@ static int _sizeof_action_sizeof(scf_dfa_t* dfa, scf_vector_t* words, void* data 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); } @@ -99,7 +99,7 @@ static int _sizeof_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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) { @@ -190,7 +190,7 @@ static int _sizeof_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) 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); } diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index dd29f5f..a630b82 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -892,6 +892,11 @@ static int _scf_op_const_or_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no 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); @@ -947,6 +952,11 @@ static int _scf_op_const_bit_or(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes 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); @@ -1079,6 +1089,7 @@ scf_operator_handler_pt const_operator_handlers[SCF_N_OPS] = [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, @@ -1103,6 +1114,7 @@ scf_operator_handler_pt const_operator_handlers[SCF_N_OPS] = [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, diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index dcc43b9..137847b 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -2486,6 +2486,11 @@ static int _scf_op_semantic_bit_or(scf_ast_t* ast, scf_node_t** nodes, int nb_no 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); @@ -2844,6 +2849,11 @@ static int _scf_op_semantic_or_assign(scf_ast_t* ast, scf_node_t** nodes, int nb 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); @@ -3112,6 +3122,7 @@ scf_operator_handler_pt semantic_operator_handlers[SCF_N_OPS] = [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, @@ -3136,6 +3147,7 @@ scf_operator_handler_pt semantic_operator_handlers[SCF_N_OPS] = [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, diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 0bf0edc..e78e4b1 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -109,7 +109,7 @@ int scf_parse_close(scf_parse_t* parse) 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; @@ -141,7 +141,7 @@ int scf_parse_file(scf_parse_t* parse, const char* path, scf_vector_t** macros, 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) @@ -150,8 +150,10 @@ int scf_parse_file(scf_parse_t* parse, const char* path, scf_vector_t** macros, 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; @@ -191,8 +193,10 @@ int scf_parse_file(scf_parse_t* parse, const char* path, scf_vector_t** macros, 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; @@ -1777,8 +1781,8 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions) 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; @@ -2142,7 +2146,13 @@ int64_t scf_parse_fill_code2(scf_parse_t* parse, scf_vector_t* functions, scf_ve 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; diff --git a/parse/scf_parse.h b/parse/scf_parse.h index 92b5897..15da040 100644 --- a/parse/scf_parse.h +++ b/parse/scf_parse.h @@ -134,7 +134,8 @@ int scf_parse_dfa_init(scf_parse_t* parse); 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); -- 2.25.1