main:
push %rbp
- leaq hello, %rdi
+ movq pointer, %rdi
xorq %rax, %rax
call printf
pop %rbp
ret
.data
+pointer: .quad hello
hello: .asciz "hello world\n"
#include"scf_asm.h"
#include"scf_symtab.h"
+void _x64_set_offset_for_jmps(scf_vector_t* text);
+
int scf_asm_open(scf_asm_t** pasm)
{
if (!pasm)
if (!text)
return -ENOMEM;
+ _x64_set_offset_for_jmps(_asm->text);
+
for (i = 0; i < _asm->text->size; i++) {
inst = _asm->text->data[i];
if (relas->size > 0) {
scf_elf_section_t s = {0};
- s.name = ".rela.text";
+ s.name = ".rela.data";
s.sh_type = SHT_RELA;
s.sh_flags = SHF_INFO_LINK;
s.sh_addralign = 8;
s.data = NULL;
s.data_len = 0;
s.sh_link = 0;
- s.sh_info = ASM_SHNDX_TEXT;
+ s.sh_info = ASM_SHNDX_DATA;
ret = scf_elf_add_rela_section(elf, &s, relas);
}
if (ret < 0)
goto error;
- scf_elf_sym_t* sym;
- int i;
-
- for (i = 0; i < _asm->symtab->size; i++) {
- sym = _asm->symtab->data[i];
-
- ret = scf_elf_add_sym(elf, sym, ".symtab");
- if (ret < 0)
- goto error;
- }
+ ret = scf_elf_add_syms(elf, _asm->symtab, ".symtab");
+ if (ret < 0)
+ goto error;
ret = scf_elf_write_rel(elf);
error:
scf_lex_word_t* label;
scf_lex_word_t* global;
+ scf_lex_word_t* fill;
scf_OpCode_t* opcode;
scf_inst_data_t operands[4];
return SCF_LEX_WORD_ASM_GLOBAL == w->type;
}
-static int _inst_is_asciz(scf_dfa_t* dfa, void* word)
+static int _inst_is_fill(scf_dfa_t* dfa, void* word)
{
scf_lex_word_t* w = word;
- return SCF_LEX_WORD_ASM_ASCIZ == w->type;
+ return SCF_LEX_WORD_ASM_FILL == w->type;
+}
+
+static int _inst_is_type(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_ASM_BYTE <= w->type && SCF_LEX_WORD_ASM_ASCIZ >= w->type;
+}
+
+static int _inst_is_number(scf_dfa_t* dfa, void* word)
+{
+ scf_lex_word_t* w = word;
+
+ return SCF_LEX_WORD_CONST_CHAR <= w->type && SCF_LEX_WORD_CONST_DOUBLE >= w->type;
}
static int _inst_is_str(scf_dfa_t* dfa, void* word)
return SCF_DFA_NEXT_WORD;
}
-static int _inst_action_asciz(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _inst_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_asm_t* _asm = dfa->priv;
+ dfa_asm_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+
+ d->fill = w;
+
+ return SCF_DFA_NEXT_WORD;
+}
+
+static int _inst_action_type(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_asm_t* _asm = dfa->priv;
dfa_asm_t* d = data;
return SCF_DFA_NEXT_WORD;
}
+static int _inst_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_asm_t* _asm = dfa->priv;
+ dfa_asm_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+ scf_lex_word_t* w2;
+ scf_instruction_t* inst;
+
+ w2 = dfa->ops->pop_word(dfa);
+ dfa->ops->push_word(dfa, w2);
+
+ if (d->opcode) {
+ switch (w2->type) {
+ case SCF_LEX_WORD_LP:
+ d->operands[d->i].disp = w->data.u64;
+ d->operands[d->i].flag = 1;
+ break;
+
+ case SCF_LEX_WORD_RP:
+ d->operands[d->i].scale = w->data.i;
+ d->operands[d->i].flag = 1;
+ break;
+
+ case SCF_LEX_WORD_ID:
+ case SCF_LEX_WORD_COMMA:
+ case SCF_LEX_WORD_LF:
+ if (d->n_lp != d->n_rp) {
+ scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ d->operands[d->i].imm = w->data.u64;
+ d->operands[d->i].imm_size = 8;
+ d->operands[d->i].flag = 0;
+
+ if (SCF_LEX_WORD_ID == w2->type) {
+ if (SCF_X64_JZ > d->opcode->type || SCF_X64_JMP < d->opcode->type) {
+ scf_loge("opcode '%s' MUST be jcc/jmp, in file: %s, line: %d\n", w->text->data, w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ switch (w2->text->data[0]) {
+ case 'b':
+ d->operands[d->i].imm <<= 8;
+ d->operands[d->i].imm |= 0x1;
+ break;
+ case 'f':
+ d->operands[d->i].imm <<= 8;
+ d->operands[d->i].imm |= 0x2;
+ break;
+ default:
+ scf_loge("the char followed a number label MUST be 'b' or 'f', but real '%c' in file: %s, line: %d\n",
+ w2->text->data[0], w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ break;
+ };
+
+ w2 = dfa->ops->pop_word(dfa);
+ dfa->ops->free_word(w2);
+ w2 = NULL;
+ }
+
+ d->i++;
+ break;
+ default:
+ scf_loge("number '%s', w2: %s, file: %s, line: %d\n", w->text->data, w2->text->data, w->file->data, w->line);
+ return -1;
+ break;
+ };
+
+ } else if (d->fill) {
+ switch (w2->type) {
+ case SCF_LEX_WORD_COMMA:
+ case SCF_LEX_WORD_LF:
+ if (d->n_lp != d->n_rp) {
+ scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ d->operands[d->i].imm = w->data.u64;
+ d->operands[d->i].flag = 0;
+ d->i++;
+ break;
+ default:
+ scf_loge("number '%s', w2: %s, file: %s, line: %d\n", w->text->data, w2->text->data, w->file->data, w->line);
+ return -1;
+ break;
+ };
+
+ } else if (SCF_LEX_WORD_LF == w2->type || SCF_LEX_WORD_COMMA == w2->type) {
+ int n;
+ switch (d->type) {
+ case SCF_LEX_WORD_ASM_BYTE:
+ n = 1;
+ break;
+ case SCF_LEX_WORD_ASM_WORD:
+ n = 2;
+ break;
+
+ case SCF_LEX_WORD_ASM_LONG:
+ n = 4;
+ break;
+ case SCF_LEX_WORD_ASM_QUAD:
+ n = 8;
+ break;
+ default:
+ scf_loge("const number '%s' MUST be '.byte', '.word', '.long' or '.quad' type, file: %s, line: %d\n",
+ w->text->data, w->file->data, w->line);
+ return -1;
+ break;
+ };
+
+ inst = calloc(1, sizeof(scf_instruction_t));
+ if (!inst)
+ return -ENOMEM;
+
+ memcpy(inst->code, (uint8_t*)&w->data, n);
+ inst->len = n;
+
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ if (d->label) {
+ inst->label = d->label;
+ d ->label = NULL;
+ }
+ }
+
+ return SCF_DFA_NEXT_WORD;
+}
+
static int _inst_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_asm_t* _asm = dfa->priv;
}
}
- X64_INST_ADD_CHECK(_asm->current, inst);
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
if (d->label) {
inst->label = d->label;
d ->label = NULL;
scf_lex_word_free(w2);
return ret;
}
+
+ } else {
+ w2 = dfa->ops->pop_word(dfa);
+ dfa->ops->push_word(dfa, w2);
+
+ if (SCF_LEX_WORD_LF == w2->type || SCF_LEX_WORD_COMMA == w2->type) {
+
+ if (SCF_LEX_WORD_ASM_QUAD != d->type) {
+ scf_loge("the type of label '%s' MUST be .quad, file: %s, line: %d\n",
+ w->text->data, w->file->data, w->line);
+ return -1;
+ }
+
+ scf_instruction_t* inst = calloc(1, sizeof(scf_instruction_t));
+ if (!inst)
+ return -ENOMEM;
+ inst->len = 8;
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+
+ if (d->label) {
+ inst->label = d->label;
+ d ->label = NULL;
+ }
+
+ scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
+ if (!rela)
+ return -ENOMEM;
+
+ rela->name = scf_string_clone(w->text);
+ if (!rela->name) {
+ scf_rela_free(rela);
+ return -ENOMEM;
+ }
+
+ rela->inst = inst;
+ rela->type = R_X86_64_64;
+
+ int ret;
+ if (_asm->current == _asm->text)
+ ret = scf_vector_add(_asm->text_relas, rela);
+ else
+ ret = scf_vector_add(_asm->data_relas, rela);
+
+ if (ret < 0) {
+ scf_rela_free(rela);
+ return ret;
+ }
+ }
}
return SCF_DFA_NEXT_WORD;
return SCF_DFA_NEXT_WORD;
}
+static int _inst_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ dfa_asm_t* d = data;
+
+ d->n_lp++;
+ return SCF_DFA_NEXT_WORD;
+}
+
+static int _inst_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->i++;
+ }
+
+ return SCF_DFA_NEXT_WORD;
+}
+
static int _inst_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_asm_t* _asm = dfa->priv;
}
}
+ scf_logi("w->text->data: %s, w->data.u32: %d, w->type: %d\n", w->text->data, w->data.u32, w->type);
d->label = scf_lex_word_clone(w);
if (!d->label)
return -ENOMEM;
return SCF_DFA_NEXT_WORD;
}
-static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int __inst_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
{
- scf_asm_t* _asm = dfa->priv;
- dfa_asm_t* d = data;
- scf_lex_word_t* w = words->data[words->size - 1];
+ scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode;
+ scf_instruction_t* inst = NULL;
+ scf_inst_data_t* id0 = &d->operands[0];
+ scf_inst_data_t* id1 = &d->operands[1];
- if (d->opcode) {
- scf_instruction_t* inst;
- scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode;
- scf_inst_data_t* id0;
- scf_inst_data_t* id1;
+ int OpBytes = opcode->OpBytes;
+ int RegBytes = opcode->RegBytes;
+ int EG = opcode->EG;
- int OpBytes = opcode->OpBytes;
- int RegBytes = opcode->RegBytes;
- int EG = opcode->EG;
+ if (__inst_data_is_reg(id0)) {
+ OpBytes = id0->base->bytes;
- if (2 == d->i) {
- id0 = &d->operands[0];
- id1 = &d->operands[1];
+ if (__inst_data_is_reg(id1)) {
+ RegBytes = id1->base->bytes;
- if (__inst_data_is_reg(id0)) {
- OpBytes = id0->base->bytes;
+ opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G);
+ if (!opcode) {
+ opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G2E);
- if (__inst_data_is_reg(id1)) {
- RegBytes = id1->base->bytes;
+ if (!opcode) {
+ scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
- opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G);
- if (!opcode) {
- scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
- return SCF_DFA_ERROR;
- }
+ inst = x64_make_inst_G2E(opcode, id1->base, id0->base);
+ } else
+ inst = x64_make_inst_E2G(opcode, id1->base, id0->base);
- inst = x64_make_inst_E2G(opcode, id1->base, id0->base);
- X64_INST_ADD_CHECK(_asm->current, inst);
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ }
+ } else if (__inst_data_is_const(id0)) {
+ uint64_t imm = id0->imm;
+
+ if (imm >> 32)
+ OpBytes = 8;
+ else if (imm >> 16)
+ OpBytes = 4;
+ else if (imm >> 8)
+ OpBytes = 2;
+ else
+ OpBytes = 1;
+
+ if (__inst_data_is_reg(id1)) {
+ RegBytes = id1->base->bytes;
+
+ int i;
+ for (i = OpBytes; i <= RegBytes; i <<= 1) {
+ opcode = x64_find_OpCode(d->opcode->type, i, RegBytes, SCF_X64_I2E);
+ if (opcode) {
+ inst = x64_make_inst_I2E(opcode, id1->base, (uint8_t*)&imm, i);
+ break;
}
+ }
- } else if (__inst_data_is_reg(id1)) {
- RegBytes = id1->base->bytes;
+ if (i > RegBytes) {
+ for (i = OpBytes; i <= RegBytes; i <<= 1) {
+ opcode = x64_find_OpCode(d->opcode->type, i, RegBytes, SCF_X64_I2G);
+ if (opcode) {
+ inst = x64_make_inst_I2G(opcode, id1->base, (uint8_t*)&imm, i);
+ break;
+ }
+ }
- opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G);
- if (!opcode) {
- scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+ if (i > RegBytes) {
+ scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
return SCF_DFA_ERROR;
}
+ }
- scf_rela_t* rela = NULL;
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ }
+
+ } else if (__inst_data_is_reg(id1)) {
+ RegBytes = id1->base->bytes;
+ OpBytes = RegBytes;
+
+ scf_logi("OpBytes: %d, RegBytes: %d\n", OpBytes, RegBytes);
+
+ opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E2G);
+ if (!opcode) {
+ scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ int32_t disp = id0->disp;
+ if (id0->label)
+ disp = 0x1000; // make disp to 4bytes, only for disp from a label
- inst = x64_make_inst_L2G(&rela, opcode, id1->base);
- X64_INST_ADD_CHECK(_asm->current, inst);
- X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text);
+ if (id1->index)
+ 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);
+
+ if (id0->label) {
+ scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
+ if (!rela)
+ return -ENOMEM;
+
+ *(uint32_t*)(inst->code + inst->len - 4) = 0;
+
+ rela->inst_offset = inst->len - 4;
+ X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text);
+ }
+ } else {
+ scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ *__inst = inst;
+ return 0;
+}
+
+static int __inst_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+ scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode;
+ scf_instruction_t* inst = NULL;
+ scf_inst_data_t* id = &d->operands[0];
+
+ int OpBytes = opcode->OpBytes;
+ int RegBytes = opcode->RegBytes;
+ int EG = opcode->EG;
+
+ if (__inst_data_is_reg(id)) {
+ OpBytes = id->base->bytes;
+
+ opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G);
+ if (!opcode) {
+ opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E);
+ if (!opcode) {
+ scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+ return SCF_DFA_ERROR;
}
- } else if (1 == d->i) {
- id0 = &d->operands[0];
+ 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);
- if (__inst_data_is_reg(id0)) {
- OpBytes = id0->base->bytes;
+ } else {
+ scf_rela_t* rela = NULL;
- opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G);
- if (!opcode) {
- opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E);
- if (!opcode) {
- scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
- return SCF_DFA_ERROR;
- }
+ if (SCF_X64_CALL == d->opcode->type
+ || (SCF_X64_JZ <= d->opcode->type && SCF_X64_JMP >= d->opcode->type)) {
+ uint32_t disp = 0;
- inst = x64_make_inst_E(opcode, id0->base);
- } else
- inst = x64_make_inst_G(opcode, id0->base);
- X64_INST_ADD_CHECK(_asm->current, inst);
+ if (!id->label)
+ disp = id->imm;
- } else {
- scf_rela_t* rela = NULL;
- uint32_t disp = 0;
-
- if (SCF_X64_CALL == d->opcode->type) {
- 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);
-
- rela = calloc(1, sizeof(scf_rela_t));
- if (!rela)
- return -ENOMEM;
-
- rela->inst_offset = 1;
- X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text);
- } else {
- opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E);
- if (!opcode) {
- scf_loge("valid opcode '%s' NOT found, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
- return SCF_DFA_ERROR;
- }
+ 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);
- inst = x64_make_inst_L(&rela, opcode);
- X64_INST_ADD_CHECK(_asm->current, inst);
- X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text);
- }
+ if (id->label) {
+ rela = calloc(1, sizeof(scf_rela_t));
+ if (!rela)
+ return -ENOMEM;
+
+ rela->inst_offset = inst->len - 4;
+ scf_logw("rela->inst_offset: %d, inst->len: %d\n", rela->inst_offset, inst->len);
+ X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
}
} else {
- inst = x64_make_inst(opcode, 8);
- X64_INST_ADD_CHECK(_asm->current, inst);
+ opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_E);
+ if (!opcode) {
+ scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+ return SCF_DFA_ERROR;
+ }
+
+ inst = x64_make_inst_L(&rela, opcode);
+ X64_INST_ADD_CHECK(_asm->current, inst, rela);
+ X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
}
+ }
+
+ *__inst = inst;
+ return 0;
+}
+
+static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_asm_t* _asm = dfa->priv;
+ dfa_asm_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+ scf_instruction_t* inst = NULL;
+
+ if (d->opcode) {
+ scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)d->opcode;
+ scf_inst_data_t* id0;
+
+ int OpBytes = opcode->OpBytes;
+ int RegBytes = opcode->RegBytes;
+ int EG = opcode->EG;
+
+ int ret = 0;
+ switch (d->i) {
+ case 2:
+ ret = __inst_op2(&inst, _asm, d, w);
+ break;
+ case 1:
+ ret = __inst_op1(&inst, _asm, d, w);
+ break;
+ case 0:
+ inst = x64_make_inst(opcode, 8);
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ break;
+ default:
+ break;
+ };
+
+ if (ret < 0)
+ return ret;
if (d->label) {
inst->label = d->label;
scf_instruction_print(inst);
d->opcode = NULL;
+
+ } else if (d->fill) {
+ if (d->i < 3) {
+ scf_loge(".fill needs 3 operands, file: %s, line: %d\n", d->fill->file->data, d->fill->line);
+ return SCF_DFA_ERROR;
+ }
+
+ int64_t n = d->operands[0].imm;
+ int64_t size = d->operands[1].imm;
+ uint64_t imm = d->operands[2].imm;
+ int64_t i;
+
+ inst = calloc(1, sizeof(scf_instruction_t));
+ if (!inst)
+ return -ENOMEM;
+
+ if (n * size <= sizeof(inst->code)) {
+ for (i = 0; i < n; i++)
+ memcpy(inst->code + i * size, (uint8_t*)&imm, size);
+
+ inst->len = n * size;
+ } else {
+ inst->bin = scf_string_alloc();
+ if (inst->bin) {
+ scf_instruction_free(inst);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < n; i++) {
+ int ret = scf_string_cat_cstr_len(inst->bin, (uint8_t*)&imm, size);
+ if (ret < 0) {
+ scf_instruction_free(inst);
+ return -ENOMEM;
+ }
+ }
+ }
+
+ X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+ d->fill = NULL;
}
for (int i = 0; i < 4; i++) {
return SCF_DFA_OK;
}
+static int _inst_action_hash(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+ scf_asm_t* _asm = dfa->priv;
+ dfa_asm_t* d = data;
+ scf_lex_word_t* w = words->data[words->size - 1];
+
+ while (w = dfa->ops->pop_word(dfa))
+ {
+ if (SCF_LEX_WORD_LF == w->type) {
+ dfa->ops->push_word(dfa, w);
+ break;
+ }
+
+ dfa->ops->free_word(w);
+ }
+
+ return SCF_DFA_NEXT_WORD;
+}
+
+int _x64_set_offset_for_jmps(scf_vector_t* text)
+{
+ scf_instruction_t* inst;
+ scf_instruction_t* dst;
+ int i;
+ int j;
+
+ for (i = 0; i < text->size; i++) {
+ inst = text->data[i];
+
+ if (!inst->OpCode)
+ continue;
+
+ if (inst->OpCode->type != SCF_X64_CALL
+ && (inst->OpCode->type < SCF_X64_JZ || inst->OpCode->type > SCF_X64_JMP))
+ continue;
+
+ int32_t bytes = 0;
+ uint32_t label = *(uint32_t*)(inst->code + inst->len - 4);
+ uint32_t flag = label & 0xff;
+ label >>= 8;
+
+ switch (flag) {
+ case 1:
+ for (j = i; j >= 0; j--) {
+ dst = text->data[j];
+
+ if (dst->label
+ && scf_lex_is_const_integer(dst->label)
+ && dst->label->data.u32 == label) {
+ inst->next = dst;
+ break;
+ }
+ }
+
+ if (j < 0) {
+ scf_loge("number label %d NOT found\n", label);
+ return -1;
+ }
+ break;
+
+ case 2:
+ for (j = i + 1; j < text->size; j++) {
+ dst = text->data[j];
+
+ if (dst->label
+ && scf_lex_is_const_integer(dst->label)
+ && dst->label->data.u32 == label) {
+ inst->next = dst;
+ break;
+ }
+ }
+
+ if (j >= text->size) {
+ scf_loge("number label %d NOT found\n", label);
+ return -1;
+ }
+ break;
+ default:
+ break;
+ };
+ }
+
+ while (1) {
+ int drop_bytes = 0;
+
+ for (i = 0; i < text->size; i++) {
+ inst = text->data[i];
+
+ if (!inst->OpCode || !inst->next)
+ continue;
+
+ if (inst->OpCode->type != SCF_X64_CALL
+ && (inst->OpCode->type < SCF_X64_JZ || inst->OpCode->type > SCF_X64_JMP))
+ continue;
+
+ int32_t bytes = 0;
+ uint32_t label = *(uint32_t*)(inst->code + inst->len - 4);
+ uint32_t front = label & 0xff;
+ label >>= 8;
+
+ if (front) {
+ for (j = i + 1; j < text->size; j++) {
+ dst = text->data[j];
+
+ if (dst == inst->next)
+ break;
+
+ if (dst->len > 0)
+ bytes += dst->len;
+ else if (dst->bin)
+ bytes += dst->bin->len;
+ }
+ } else {
+ for (j = i; j >= 0; j--) {
+ dst = text->data[j];
+
+ if (dst->len > 0)
+ bytes -= dst->len;
+ else if (dst->bin)
+ bytes -= dst->bin->len;
+
+ if (dst == inst->next)
+ break;
+ }
+ }
+
+ scf_x64_OpCode_t* opcode = (scf_x64_OpCode_t*)inst->OpCode;
+ int n_bytes = 4;
+
+ if (SCF_X64_CALL != opcode->type) {
+ if (-128 <= bytes && bytes <= 127)
+ n_bytes = 1;
+
+ opcode = x64_find_OpCode(opcode->type, n_bytes, n_bytes, SCF_X64_I);
+ }
+
+ int old_len = inst->len;
+ x64_make_inst_I2(inst, opcode, (uint8_t*)&bytes, n_bytes);
+
+ int diff = old_len - inst->len;
+ assert(diff >= 0);
+
+ drop_bytes += diff;
+ }
+
+ if (0 == drop_bytes)
+ break;
+ }
+}
+
static int _dfa_init_module_inst(scf_dfa_t* dfa)
{
SCF_DFA_MODULE_NODE(dfa, inst, text, _inst_is_text, _inst_action_text);
SCF_DFA_MODULE_NODE(dfa, inst, data, _inst_is_data, _inst_action_data);
SCF_DFA_MODULE_NODE(dfa, inst, global, _inst_is_global, _inst_action_global);
+ SCF_DFA_MODULE_NODE(dfa, inst, fill, _inst_is_fill, _inst_action_fill);
- SCF_DFA_MODULE_NODE(dfa, inst, asciz, _inst_is_asciz, _inst_action_asciz);
+ SCF_DFA_MODULE_NODE(dfa, inst, type, _inst_is_type, _inst_action_type);
SCF_DFA_MODULE_NODE(dfa, inst, str, _inst_is_str, _inst_action_str);
+ SCF_DFA_MODULE_NODE(dfa, inst, number, _inst_is_number, _inst_action_number);
SCF_DFA_MODULE_NODE(dfa, inst, identity, scf_dfa_is_identity, _inst_action_identity);
SCF_DFA_MODULE_NODE(dfa, inst, colon, scf_dfa_is_colon, _inst_action_colon);
SCF_DFA_MODULE_NODE(dfa, inst, reg, _inst_is_reg, _inst_action_reg);
SCF_DFA_MODULE_NODE(dfa, inst, percent, _inst_is_percent, scf_dfa_action_next);
+ SCF_DFA_MODULE_NODE(dfa, inst, lp, scf_dfa_is_lp, _inst_action_lp);
+ SCF_DFA_MODULE_NODE(dfa, inst, rp, scf_dfa_is_rp, _inst_action_rp);
+
SCF_DFA_MODULE_NODE(dfa, inst, comma, scf_dfa_is_comma, _inst_action_comma);
SCF_DFA_MODULE_NODE(dfa, inst, LF, scf_dfa_is_LF, _inst_action_LF);
+ SCF_DFA_MODULE_NODE(dfa, inst, HASH, scf_dfa_is_hash, _inst_action_hash);
scf_asm_t* _asm = dfa->priv;
dfa_asm_t* d = _asm->dfa_data;
SCF_DFA_GET_MODULE_NODE(dfa, inst, text, text);
SCF_DFA_GET_MODULE_NODE(dfa, inst, data, data);
SCF_DFA_GET_MODULE_NODE(dfa, inst, global, global);
+ SCF_DFA_GET_MODULE_NODE(dfa, inst, fill, fill);
SCF_DFA_GET_MODULE_NODE(dfa, inst, identity, identity);
SCF_DFA_GET_MODULE_NODE(dfa, inst, colon, colon);
- SCF_DFA_GET_MODULE_NODE(dfa, inst, asciz, asciz);
+ SCF_DFA_GET_MODULE_NODE(dfa, inst, type, type);
SCF_DFA_GET_MODULE_NODE(dfa, inst, str, str);
+ SCF_DFA_GET_MODULE_NODE(dfa, inst, number, number);
SCF_DFA_GET_MODULE_NODE(dfa, inst, opcode, opcode);
SCF_DFA_GET_MODULE_NODE(dfa, inst, reg, reg);
SCF_DFA_GET_MODULE_NODE(dfa, inst, percent, percent);
+ SCF_DFA_GET_MODULE_NODE(dfa, inst, lp, lp);
+ SCF_DFA_GET_MODULE_NODE(dfa, inst, rp, rp);
SCF_DFA_GET_MODULE_NODE(dfa, inst, comma, comma);
SCF_DFA_GET_MODULE_NODE(dfa, inst, LF, LF);
+ SCF_DFA_GET_MODULE_NODE(dfa, inst, HASH, HASH);
// asm syntax
scf_vector_add(dfa->syntaxes, text);
scf_vector_add(dfa->syntaxes, data);
scf_vector_add(dfa->syntaxes, global);
+ scf_vector_add(dfa->syntaxes, fill);
scf_vector_add(dfa->syntaxes, opcode);
scf_vector_add(dfa->syntaxes, identity);
+ scf_vector_add(dfa->syntaxes, number);
- scf_vector_add(dfa->syntaxes, asciz);
+ scf_vector_add(dfa->syntaxes, type);
+ scf_vector_add(dfa->syntaxes, HASH);
scf_vector_add(dfa->syntaxes, LF);
// .text .data
// label:
scf_dfa_node_add_child(identity, colon);
+ scf_dfa_node_add_child(number, colon);
scf_dfa_node_add_child(colon, LF);
// .asciz
- scf_dfa_node_add_child(asciz, str);
+ scf_dfa_node_add_child(type, str);
+ scf_dfa_node_add_child(type, number);
+ scf_dfa_node_add_child(type, identity);
+
scf_dfa_node_add_child(str, LF);
+ scf_dfa_node_add_child(number, LF);
+ scf_dfa_node_add_child(identity, LF);
// asm instruction
scf_dfa_node_add_child(opcode, identity);
-
+ scf_dfa_node_add_child(opcode, number);
scf_dfa_node_add_child(opcode, reg);
+
+ scf_dfa_node_add_child(identity, comma);
+ scf_dfa_node_add_child(number, comma);
scf_dfa_node_add_child(reg, comma);
+
+ scf_dfa_node_add_child(comma, identity);
+ scf_dfa_node_add_child(comma, number);
scf_dfa_node_add_child(comma, reg);
+
+ scf_dfa_node_add_child(identity, LF);
+ scf_dfa_node_add_child(number, LF);
scf_dfa_node_add_child(reg, LF);
// %reg of 'AT & T'
scf_dfa_node_add_child(opcode, percent);
scf_dfa_node_add_child(comma, percent);
+ // memory addr such as: (rax), 8(rax), disp(rax, rcx, 8),
+ scf_dfa_node_add_child(opcode, lp);
+ scf_dfa_node_add_child(identity, lp);
+ scf_dfa_node_add_child(number, lp);
+
+ scf_dfa_node_add_child(lp, percent);
+ scf_dfa_node_add_child(lp, reg);
+ scf_dfa_node_add_child(lp, comma); // ( , rcx, 8), empty base == 0
+
+ scf_dfa_node_add_child(reg, rp);
+ scf_dfa_node_add_child(number, rp);
+ scf_dfa_node_add_child(rp, comma);
+ scf_dfa_node_add_child(rp, LF);
+
+ // .fill
+ scf_dfa_node_add_child(fill, number);
+
return SCF_DFA_OK;
}
SCF_LEX_WORD_LF, // '\n', line feed, LF
SCF_LEX_WORD_HASH, // # hash
SCF_LEX_WORD_HASH2, // ## hash2
+ SCF_LEX_WORD_DOLLAR, // $ dollar
SCF_LEX_WORD_COMMA, // , comma
SCF_LEX_WORD_SEMICOLON, // ;
return -1;
}
+int scf_elf_add_syms(scf_elf_context_t* elf, const scf_vector_t* syms, const char* sh_name)
+{
+ scf_elf_sym_t* sym;
+ int i;
+
+ for (i = 0; i < syms->size; i++) {
+ sym = syms->data[i];
+
+ int ret = scf_elf_add_sym(elf, sym, sh_name);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
int scf_elf_add_section(scf_elf_context_t* elf, const scf_elf_section_t* section)
{
if (elf && section) {
int scf_elf_open2(scf_elf_context_t* elf, const char* machine);
int scf_elf_close(scf_elf_context_t* elf);
-int scf_elf_add_sym (scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh_name);
-int scf_elf_add_section(scf_elf_context_t* elf, const scf_elf_section_t* section);
+int scf_elf_add_sym (scf_elf_context_t* elf, const scf_elf_sym_t* sym, const char* sh_name);
+int scf_elf_add_syms(scf_elf_context_t* elf, const scf_vector_t* syms, const char* sh_name);
+int scf_elf_add_section (scf_elf_context_t* elf, const scf_elf_section_t* section);
int scf_elf_add_rela_section(scf_elf_context_t* elf, const scf_elf_section_t* section, scf_vector_t* relas);
int scf_elf_add_dyn_need(scf_elf_context_t* elf, const char* soname);
int scf_elf_add_dyn_rela(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
|| '\r' == c->c || '\t' == c->c
|| ' ' == c->c || '\\' == c->c) {
- if ('\n' == c->c) {
- lex->nb_lines++;
- lex->pos = 0;
-
+ if ('\n' == c->c)
+ {
if (SCF_UTF8_LF == c->flag || lex->asm_flag)
{
w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_LF);
free(c);
c = NULL;
+
+ lex->nb_lines++;
+ lex->pos = 0;
return 0;
}
+
+ lex->nb_lines++;
+ lex->pos = 0;
} else
lex->pos++;
return _lex_macro(lex);
}
+ if ('$' == c->c && lex->asm_flag)
+ {
+ free(c);
+ c = _lex_pop_char(lex);
+ if (!c)
+ return -1;
+
+ if ('0' <= c->c && '9' >= c->c)
+ return _lex_number(lex, pword, c);
+
+ if ('_' == c->c
+ || ('a' <= c->c && 'z' >= c->c)
+ || ('A' <= c->c && 'Z' >= c->c)
+ || (0x4e00 <= c->c && 0x9fa5 >= c->c)) { // support China chars
+
+ _lex_push_char(lex, c);
+
+ w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_DOLLAR);
+ if (!w)
+ return -ENOMEM;
+
+ w->text = scf_string_cstr("$");
+ if (!w->text) {
+ scf_lex_word_free(w);
+ return -ENOMEM;
+ }
+
+ *pword = w;
+ return 0;
+ }
+ }
+
scf_loge("unknown char: %c, utf: %#x, in file: %s, line: %d\n", c->c, c->c, lex->file->data, lex->nb_lines);
+
+ free(c);
return -1;
}
case SCF_LEX_WORD_KEY_DEFINE:
ret = __parse_macro_define(lex);
break;
+
default:
+ if (lex->asm_flag) {
+ scf_lex_push_word(lex, w1);
+ *pword = w;
+ return 0;
+ }
+
scf_loge("unknown macro '%s', file: %s, line: %d\n", w1->text->data, w1->file->data, w1->line);
ret = -1;
break;
#define X64_SAVE_RABI(offset, rabi) \
do { \
inst = x64_make_inst_G2P(mov, rbp, offset, rabi); \
- X64_INST_ADD_CHECK(f->init_code->instructions, inst); \
+ X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL); \
f->init_code_bytes += inst->len; \
} while (0)
if (f->bp_used_flag || f->vla_flag || f->call_flag) {
inst = x64_make_inst_G2E(mov, rsp, rbp);
- X64_INST_ADD_CHECK(end->instructions, inst);
+ X64_INST_ADD_CHECK(end->instructions, inst, NULL);
end->inst_bytes += inst->len;
bb ->code_bytes += inst->len;
inst = x64_make_inst_G(pop, rbp);
- X64_INST_ADD_CHECK(end->instructions, inst);
+ X64_INST_ADD_CHECK(end->instructions, inst, NULL);
end->inst_bytes += inst->len;
bb ->code_bytes += inst->len;
}
if (f->bp_used_flag || f->vla_flag || f->call_flag) {
inst = x64_make_inst_G(push, rbp);
- X64_INST_ADD_CHECK(f->init_code->instructions, inst);
+ X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL);
f->init_code_bytes += inst->len;
inst = x64_make_inst_G2E(mov, rbp, rsp);
- X64_INST_ADD_CHECK(f->init_code->instructions, inst);
+ X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL);
f->init_code_bytes += inst->len;
if (f->callee_saved_size & 0xf) {
local, f->local_vars_size, f->callee_saved_size);
inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&local, 4);
- X64_INST_ADD_CHECK(f->init_code->instructions, inst);
+ X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL);
f->init_code_bytes += inst->len;
int err = _x64_save_rabi(f);
}
inst = x64_make_inst(ret, 8);
- X64_INST_ADD_CHECK(end->instructions, inst);
+ X64_INST_ADD_CHECK(end->instructions, inst, NULL);
end->inst_bytes += inst->len;
bb ->code_bytes += inst->len;
static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
{
scf_register_t* rsp = x64_find_register("rsp");
-
scf_x64_OpCode_t* lea;
scf_x64_OpCode_t* mov;
scf_x64_OpCode_t* movx;
if (!rd) {
if (movx) {
inst = x64_make_inst_E2G(movx, rs, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
inst = x64_make_inst_G2P(mov, rsp, v->sp_offset, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
continue;
}
if (!X64_COLOR_CONFLICT(rd->color, rs->color)) {
if (movx) {
inst = x64_make_inst_E2G(movx, rs, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
rd = x64_find_register_color_bytes(rd->color, rs->bytes);
inst = x64_make_inst_G2E(mov, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else if (movx) {
inst = x64_make_inst_E2G(movx, rs, rs);
}
for (i = 0; i < nb_movx; i++) {
- X64_INST_ADD_CHECK(c->instructions, inst_movx[i]);
+ X64_INST_ADD_CHECK(c->instructions, inst_movx[i], NULL);
}
return nb_floats;
scf_3ac_operand_t* dst;
scf_dag_node_t* dn;
scf_variable_t* v;
-
scf_register_t* rd;
scf_register_t* rs;
scf_x64_OpCode_t* mov;
int valid = _x64_dst_reg_valid(rd, updated_regs, nb_updated, idx_int, nb_int);
if (valid) {
inst = x64_make_inst_G2E(mov, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
assert(nb_updated < max_updated);
dn->color = rs->color;
dn->loaded = 1;
} else {
- scf_rela_t* rela = NULL;
-
if (0 == v->bp_offset && !v->global_flag && !v->local_flag) {
int size = f->local_vars_size + dst_size;
scf_logd("v->bp_offset: %d, local_flag: %d, tmp_flag: %d, rs->name: %s\n", v->bp_offset, v->local_flag, v->tmp_flag, rs->name);
}
+ scf_rela_t* rela = NULL;
+
inst = x64_make_inst_G2M(&rela, mov, dn->var, NULL, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL);
}
}
scf_x64_context_t* x64 = ctx->priv;
scf_function_t* f = x64->f;
-
scf_3ac_operand_t* src0 = c->srcs->data[0];
scf_variable_t* var_pf = src0->dag_node->var;
scf_function_t* pf = var_pf->func_ptr;
int32_t stack_size = _x64_inst_call_stack_size(c);
if (stack_size > 0) {
- sub = x64_find_OpCode(SCF_X64_SUB, 4,4, SCF_X64_I2E);
+ sub = x64_find_OpCode(SCF_X64_SUB, 4,4, SCF_X64_I2E);
inst_rsp = x64_make_inst_I2E(sub, rsp, (uint8_t*)&stack_size, 4);
- X64_INST_ADD_CHECK(c->instructions, inst_rsp);
+ X64_INST_ADD_CHECK(c->instructions, inst_rsp, NULL);
}
ret = _x64_inst_call_argv(c, f);
mov = x64_find_OpCode(SCF_X64_MOV, 4,4, SCF_X64_I2G);
inst = x64_make_inst_I2G(mov, eax, (uint8_t*)&imm, sizeof(imm));
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
scf_register_t* saved_regs[X64_ABI_CALLER_SAVES_NB];
int32_t offset = 0;
call = x64_find_OpCode(SCF_X64_CALL, 4,4, SCF_X64_I);
inst = x64_make_inst_I(call, (uint8_t*)&offset, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst->OpCode = (scf_OpCode_t*)call;
}
inst = x64_make_inst_E(call, r_pf);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst->OpCode = (scf_OpCode_t*)call;
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M(&rela, call, var_pf, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, pf);
inst->OpCode = (scf_OpCode_t*)call;
if (stack_size > 0) {
add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E);
inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&stack_size, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
int nb_updated = 0;
scf_instruction_t* inst = NULL;
scf_register_t* rd = NULL;
scf_variable_t* var = dst->dag_node->var;
-
scf_x64_OpCode_t* OpCode = x64_find_OpCode(OpCode_type, var->size, var->size, SCF_X64_E);
+
if (!OpCode) {
scf_loge("\n");
return -1;
if (dst->dag_node->color > 0) {
X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0);
inst = x64_make_inst_E(OpCode, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M(&rela, OpCode, var, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL);
}
scf_instruction_t* inst = NULL;
scf_register_t* rs = NULL;
scf_variable_t* var = src->dag_node->var;
-
scf_x64_OpCode_t* OpCode = x64_find_OpCode(OpCode_type, var->size, var->size, SCF_X64_E);
+
if (!OpCode) {
scf_loge("\n");
return -1;
if (src->dag_node->color > 0) {
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_E(OpCode, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else if (0 == src->dag_node->color) {
scf_loge("\n");
scf_rela_t* rela = NULL;
inst = x64_make_inst_M(&rela, OpCode, var, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, var, NULL);
}
X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0);
inst = x64_make_inst_E2G(pxor, rd, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
if (src->dag_node->color > 0) {
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_E2G(sub, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
- scf_rela_t* rela = NULL;
-
v = src->dag_node->var;
if (0 == src->dag_node->color) {
v->tmp_flag = 0;
}
+ scf_rela_t* rela = NULL;
+
inst = x64_make_inst_M2G(&rela, sub, rd, NULL, v);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, v1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v1, NULL);
return 0;
}
if (src->dag_node->color > 0) {
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_I2E(OpCode, rs, (uint8_t*)&v->data_size, imm_size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_I2M(&rela, OpCode, v, NULL, (uint8_t*)&v->data_size, imm_size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
if (src->dag_node->color > 0) {
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_E(OpCode, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M(&rela, OpCode, v, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
}
else
inst = x64_make_inst_I2P(OpCode, sib.base, sib.disp, (uint8_t*)&vs->data, size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
if (sib.index) {
inst = x64_make_inst_G2SIB(OpCode, sib.base, sib.index, sib.scale, sib.disp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_G2P(OpCode, sib.base, sib.disp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
}
if (sib.index) {
inst = x64_make_inst_SIB2G(OpCode, rd, sib.base, sib.index, sib.scale, sib.disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_P2G(OpCode, rd, sib.base, sib.disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
}
lea = x64_find_OpCode(SCF_X64_LEA, 8,8, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->dag_node->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->dag_node->var, NULL);
return 0;
}
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_G2E(mov, rsi, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
scf_rela_t* rela = NULL;
inst = x64_make_inst_M2G(&rela, lea, rdi, NULL, msg->dag_node->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, msg->dag_node->var, NULL);
inst = x64_make_inst_G2E(xor, rax, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
// call printf() to show msg
uint32_t imm = 0;
inst = x64_make_inst_I(call, (uint8_t*)&imm, sizeof(imm));
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
rela = calloc(1, sizeof(scf_rela_t));
if (!rela)
X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, logf->dag_node->var->func_ptr);
inst = x64_make_inst_G2E(xor, rax, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rax, 0, rax);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
uint32_t imm = 0xf;
inst = x64_make_inst_I2E(add, rs, (uint8_t*)&imm, sizeof(imm));
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
imm = ~0xf;
inst = x64_make_inst_I2E(and, rs, (uint8_t*)&imm, sizeof(imm));
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_E2G(sub, rsp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
int ret = x64_save_var(src->dag_node, c, f);
if (ret < 0)
X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0);
inst = x64_make_inst_G2E(mov, rd, rsp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
inst = x64_make_inst_E2G(add, rsp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2E(xor, rs, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return x64_save_var(src->dag_node, c, f);
}
if (rd->bytes > size) {
inst = x64_make_inst_E2G(mov, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else {
X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (!X64_COLOR_CONFLICT(rd->color, rs->color) || rd->bytes > size) {
inst = x64_make_inst_E2G(mov, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
}
} else if (0 == src->dag_node->color) {
mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_I2G);
inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&v->data, rd->bytes);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_M2G(&rela, mov, rd, NULL, v);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
}
}
if (0 == dn->color) { \
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G); \
inst = x64_make_inst_I2G(mov, r, (uint8_t*)&dn->var->data, size); \
- X64_INST_ADD_CHECK(c->instructions, inst); \
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL); \
\
} else { \
if (dn->color < 0) \
if (!X64_COLOR_CONFLICT(rd->color, r->color)) { \
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_G2E); \
inst = x64_make_inst_G2E(mov, r, rd); \
- X64_INST_ADD_CHECK(c->instructions, inst); \
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL); \
} \
} \
} while (0)
stos = x64_find_OpCode(SCF_X64_STOS, 1, 8, SCF_X64_G);
inst = x64_make_inst(stos, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8);
inst = x64_make_inst_G(push, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
if (n & 0x1) {
r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[n - 1], 8);
inst = x64_make_inst_G(push, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
}
if (n & 0x1) {
r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[n - 1], 8);
inst = x64_make_inst_G(pop, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
for (i = n - 1; i >= 0; i--) {
r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8);
inst = x64_make_inst_G(pop, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
X64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0);
inst = x64_make_inst_P2G(lea, rptr, rbp, offset_int);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 0, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_P2G(lea, rptr, rbp, offset_float);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 8, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_P2G(lea, rptr, rbp, offset_others);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 16, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
mov = x64_find_OpCode(SCF_X64_MOV, 4, 8, SCF_X64_I2E);
-
inst = x64_make_inst_I2P(mov, rap, 24, (uint8_t*)&f->args_int, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_I2P(mov, rap, 32, (uint8_t*)&f->args_float, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
X64_SELECT_REG_CHECK(&rptr, ptr->dag_node, c, f, 0);
inst = x64_make_inst_G2E(xor, rptr, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 0, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 8, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 16, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 24, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(mov, rap, 32, rptr);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
ptr->dag_node->var->tmp_flag = 0;
ptr->dag_node->color = 0;
}
inst = x64_make_inst_I2P(cmp, rap, idx_offset, (uint8_t*)&nints, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst_jge = x64_make_inst_I(jge, (uint8_t*)&offset, sizeof(offset));
- X64_INST_ADD_CHECK(c->instructions, inst_jge);
+ X64_INST_ADD_CHECK(c->instructions, inst_jge, NULL);
inst = x64_make_inst_P2G(mov, rptr, rap, ptr_offset);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
offset += inst->len;
inst = x64_make_inst_I2P(sub, rap, ptr_offset, (uint8_t*)&incptr, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
offset += inst->len;
inst_jmp = x64_make_inst_I(jmp, (uint8_t*)&offset, sizeof(offset));
- X64_INST_ADD_CHECK(c->instructions, inst_jmp);
+ X64_INST_ADD_CHECK(c->instructions, inst_jmp, NULL);
offset += inst_jmp->len;
uint8_t* p = (uint8_t*)&offset;
offset = 0;
inst = x64_make_inst_P2G(mov, rptr, rap, 16);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
offset += inst->len;
inst = x64_make_inst_I2P(add, rap, 16, (uint8_t*)&incptr, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
offset += inst->len;
for (i = 0; i < 4; i++)
inst_jmp->code[jmp->nb_OpCodes + i] = p[i];
inst = x64_make_inst_P(inc, rap, idx_offset, 8);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
if (is_float) {
if (4 == size)
mov2 = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
inst = x64_make_inst_P2G(mov2, rd, rptr, 0);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
return ret;
}
- mov = x64_find_OpCode(mov_type, v->size, v->size, SCF_X64_E2G);
+ mov = x64_find_OpCode(mov_type, v->size, v->size, SCF_X64_E2G);
if (ri)
inst = x64_make_inst_SIB2G(mov, rs, rb, ri, scale, disp);
else
inst = x64_make_inst_P2G(mov, rs, rb, disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
OpCode = x64_find_OpCode(OpCode_type, v->size, v->size, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, OpCode, rs, NULL, src->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
+ X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
end:
mov = x64_find_OpCode(mov_type, v->size, v->size, SCF_X64_G2E);
inst = x64_make_inst_G2SIB(mov, rb, ri, scale, disp, rs);
else
inst = x64_make_inst_G2P(mov, rb, disp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
static int _binary_assign_sib_int(x64_sib_t* sib, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f, int OpCode_type)
{
- scf_variable_t* v = src->var;
- scf_register_t* rs = NULL;
-
- scf_register_t* rb = sib->base;
- scf_register_t* ri = sib->index;
- int32_t scale = sib->scale;
- int32_t disp = sib->disp;
+ scf_variable_t* v = src->var;
+ scf_register_t* rs = NULL;
+ scf_register_t* rb = sib->base;
+ scf_register_t* ri = sib->index;
+ int32_t scale = sib->scale;
+ int32_t disp = sib->disp;
scf_x64_OpCode_t* OpCode;
scf_instruction_t* inst;
inst = x64_make_inst_I2SIB(OpCode, rb, ri, scale, disp, (uint8_t*)&v->data, dsize);
else
inst = x64_make_inst_I2P(OpCode, rb, disp, (uint8_t*)&v->data, dsize);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
inst = x64_make_inst_G2SIB(OpCode, rb, ri, scale, disp, rs);
else
inst = x64_make_inst_G2P(OpCode, rb, disp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
scf_x64_context_t* x64 = ctx->priv;
scf_function_t* f = x64->f;
-
scf_3ac_operand_t* dst = c->dsts->data[0];
scf_3ac_operand_t* base = c->srcs->data[0];
scf_3ac_operand_t* index = c->srcs->data[c->srcs->size - 1];
scf_variable_t* vd = dst ->dag_node->var;
scf_variable_t* vb = base ->dag_node->var;
scf_variable_t* vi = index->dag_node->var;
-
scf_register_t* rd = NULL;
x64_sib_t sib = {0};
int is_float = scf_variable_float(vd);
if (is_float) {
if (SCF_VAR_FLOAT == vd->type)
- mov = x64_find_OpCode(SCF_X64_MOVSS, rd->bytes, rd->bytes, SCF_X64_E2G);
+ mov = x64_find_OpCode(SCF_X64_MOVSS, rd->bytes, rd->bytes, SCF_X64_E2G);
else if (SCF_VAR_DOUBLE == vd->type)
- mov = x64_find_OpCode(SCF_X64_MOVSD, rd->bytes, rd->bytes, SCF_X64_E2G);
+ mov = x64_find_OpCode(SCF_X64_MOVSD, rd->bytes, rd->bytes, SCF_X64_E2G);
} else
- mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_E2G);
+ mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_E2G);
if (sib.index) {
inst = x64_make_inst_SIB2G(mov, rd, sib.base, sib.index, sib.scale, sib.disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_P2G(mov, rd, sib.base, sib.disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
}
if (!src || !src->dag_node)
return -EINVAL;
- scf_variable_t* b = base->dag_node->var;
- assert(b->nb_pointers > 0 || b->nb_dimentions > 0 || b->type >= SCF_STRUCT);
-
if (!c->instructions) {
c->instructions = scf_vector_alloc();
if (!c->instructions)
return -ENOMEM;
}
+ scf_variable_t* b = base->dag_node->var;
scf_variable_t* v = src->dag_node->var;
x64_sib_t sib = {0};
+ assert(b->nb_pointers > 0 || b->nb_dimentions > 0 || b->type >= SCF_STRUCT);
+
int ret = x64_dereference_reg(&sib, base->dag_node, NULL, c, f);
if (ret < 0)
return ret;
r = x64_find_register_color_bytes(rs->color, 8);
inst = x64_make_inst_G(push, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_I2G(mov, rs, (uint8_t*)&mask, dsize);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
if (sib.index)
inst = x64_make_inst_G2SIB(and, sib.base, sib.index, sib.scale, sib.disp, rs);
else
inst = x64_make_inst_G2P(and, sib.base, sib.disp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G(pop, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
int imm = (rs->bytes << 3) - vm->bit_size;
assert(imm > 0);
shr = x64_find_OpCode(SCF_X64_SHR, 1, rs->bytes, SCF_X64_I2E);
inst = x64_make_inst_I2E(shl, rs, (uint8_t*)&imm, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
imm -= vm->bit_offset;
assert(imm >= 0);
if (imm > 0) {
inst = x64_make_inst_I2E(shr, rs, (uint8_t*)&imm, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
mov = x64_find_OpCode(SCF_X64_OR, dsize, dsize, SCF_X64_G2E);
inst = x64_make_inst_G2SIB(mov, sib.base, sib.index, sib.scale, sib.disp, rs);
else
inst = x64_make_inst_G2P(mov, sib.base, sib.disp, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
scf_x64_context_t* x64 = ctx->priv;
scf_function_t* f = x64->f;
-
scf_3ac_operand_t* dst = c->dsts->data[0];
scf_3ac_operand_t* base = c->srcs->data[0];
scf_3ac_operand_t* member = c->srcs->data[1];
scf_variable_t* vd = dst->dag_node->var;
scf_variable_t* vb = base ->dag_node->var;
scf_variable_t* vm = member->dag_node->var;
-
scf_register_t* rd = NULL;
x64_sib_t sib = {0};
if (sib.index) {
inst = x64_make_inst_SIB2G(mov, rd, sib.base, sib.index, sib.scale, sib.disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_P2G(mov, rd, sib.base, sib.disp);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
if (vm->bit_size > 0) {
if (imm > 0) {
inst = x64_make_inst_I2E(shl, rd, (uint8_t*)&imm, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
imm += vm->bit_offset;
inst = x64_make_inst_I2E(shr, rd, (uint8_t*)&imm, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
scf_x64_OpCode_t* cmp;
scf_instruction_t* inst;
- scf_register_t* rs1;
- scf_register_t* rs0 = NULL;
+ scf_register_t* rs1;
+ scf_register_t* rs0 = NULL;
scf_rela_t* rela = NULL;
X64_SELECT_REG_CHECK(&rs0, src0, c, f, 1);
X64_SELECT_REG_CHECK(&rs1, src1, c, f, 1);
inst = x64_make_inst_E2G(cmp, rs0, rs1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
} else {
if (cmp) {
inst = x64_make_inst_I2E(cmp, rs0, (uint8_t*)&src1->var->data, src1_size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
cmp = x64_find_OpCode(SCF_X64_CMP, rs0->bytes, src1_size, SCF_X64_G2E);
inst = x64_make_inst_G2E(cmp, rs0, rs1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
src1->loaded = 0;
src1->color = 0;
if (src1->color > 0) {
X64_SELECT_REG_CHECK(&rs1, src1, c, f, 1);
inst = x64_make_inst_E2G(cmp, rs0, rs1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_M2G(&rela, cmp, rs0, NULL, src1->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src1->var, NULL);
}
mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_I2G);
inst = x64_make_inst_I2G(mov, rd, (uint8_t*)&imm, rd->bytes);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
rd = x64_find_register_color_bytes(rd->color, 1);
}
inst = x64_make_inst_E(setcc, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
test = x64_find_OpCode(SCF_X64_TEST, v->size, v->size, SCF_X64_G2E);
inst = x64_make_inst_G2E(test, rs, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
{
scf_x64_OpCode_t* OpCode;
scf_instruction_t* inst;
- scf_register_t* rd = NULL;
- scf_register_t* rs = NULL;
+ scf_register_t* rd = NULL;
+ scf_register_t* rs = NULL;
scf_rela_t* rela = NULL;
assert( scf_variable_const(src->var));
}
if (dst->color > 0) {
-
if (SCF_X64_MOV == OpCode_type)
X64_SELECT_REG_CHECK(&rd, dst, c, f, 0);
else
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2G);
if (OpCode) {
inst = x64_make_inst_I2G(OpCode, rd, (uint8_t*)&src->var->data, src_size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E);
if (OpCode) {
inst = x64_make_inst_I2E(OpCode, rd, (uint8_t*)&src->var->data, src_size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
inst = x64_make_inst_G2E(OpCode, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
src->color = 0;
src->loaded = 0;
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_I2E);
if (OpCode) {
inst = x64_make_inst_I2M(&rela, OpCode, dst->var, NULL, (uint8_t*)&src->var->data, src_size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
return 0;
}
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
inst = x64_make_inst_G2M(&rela, OpCode, dst->var, NULL, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
src->color = 0;
return -EINVAL;
}
- scf_register_t* rd = NULL;
+ scf_register_t* rd = NULL;
scf_instruction_t* inst = NULL;
scf_x64_OpCode_t* lea = x64_find_OpCode(SCF_X64_LEA, 8, 8, SCF_X64_E2G);
scf_rela_t* rela = NULL;
src->var->tmp_flag = 0;
inst = x64_make_inst_M2G(&rela, lea, rd, NULL, src->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
return 0;
}
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_G2E);
if (OpCode) {
inst = x64_make_inst_G2E(OpCode, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_E2G);
if (!OpCode) {
}
inst = x64_make_inst_E2G(OpCode, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else {
OpCode = x64_find_OpCode(OpCode_type, src_size, dst_size, SCF_X64_E2G);
}
inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
scf_x64_OpCode_t* xor;
scf_instruction_t* inst;
- scf_register_t* rs;
- scf_register_t* rd = NULL;
+ scf_register_t* rs;
+ scf_register_t* rd = NULL;
X64_SELECT_REG_CHECK(&rd, dst, c, f, 0);
assert(4 == src->var->size);
xor = x64_find_OpCode(SCF_X64_XOR, 8, 8, SCF_X64_G2E);
inst = x64_make_inst_G2E(xor, rd, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
movx = x64_find_OpCode(SCF_X64_MOV, 4, 4, SCF_X64_E2G);
}
if (src->color > 0) {
X64_SELECT_REG_CHECK(&rs, src, c, f, 0);
inst = x64_make_inst_E2G(movx, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else if (0 == src->color) {
// get the rd's low bits register
mov = x64_find_OpCode(SCF_X64_MOV, src->var->size, src->var->size, SCF_X64_I2G);
inst = x64_make_inst_I2G(mov, rs, (uint8_t*)&src->var->data, src->var->size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_E2G(movx, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M2G(&rela, movx, rd, NULL, src->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
int x64_inst_float_cast(scf_dag_node_t* dst, scf_dag_node_t* src, scf_3ac_code_t* c, scf_function_t* f)
{
scf_x64_OpCode_t* OpCode;
-
scf_instruction_t* inst;
scf_register_t* rs = NULL;
scf_register_t* rd = NULL;
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
- inst = x64_make_inst_E2G(OpCode, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ inst = x64_make_inst_E2G(OpCode, rd, rs);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else if (src->color > 0) {
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
inst = x64_make_inst_E2G(OpCode, rd, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M2G(&rela, OpCode, rd, NULL, src->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
scf_instruction_t* inst = x64_make_inst_I(jcc, (uint8_t*)&offset, sizeof(offset));
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
-
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_G2E);
inst = x64_make_inst_G2E(mov, rl, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
if (rd->id != rh->id) {
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, mov, rl, NULL, dst->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
div = x64_find_OpCode(SCF_X64_IDIV, size, size, SCF_X64_E);
cdq = x64_find_OpCode_by_type(SCF_X64_CDQ);
inst = x64_make_inst(cdq, size << 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
div = x64_find_OpCode(SCF_X64_DIV, size, size, SCF_X64_E);
xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
inst = x64_make_inst_G2E(xor, rh, rh);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
if (src->color > 0) {
X64_SELECT_REG_CHECK(&rs, src, c, f, 1);
inst = x64_make_inst_E(div, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
-
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M(&rela, div, src->var, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
if (rd->id != result->id) {
mov = x64_find_OpCode(SCF_X64_MOV, rd->bytes, rd->bytes, SCF_X64_G2E);
inst = x64_make_inst_G2E(mov, rd, result);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else {
scf_rela_t* rela = NULL;
mov = x64_find_OpCode(SCF_X64_MOV, dst->var->size, dst->var->size, SCF_X64_G2E);
inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, result);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G);
inst = x64_make_inst_I2G(mov, rh, (uint8_t*)&src->var->data, size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_E(mul, rh);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
scf_rela_t* rela = NULL;
inst = x64_make_inst_M(&rela, mul, src->var, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, src->var, NULL);
}
if (rd->id == rl->id) {
inst = x64_make_inst_E(mul, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else if (rs->id == rl->id) {
inst = x64_make_inst_E(mul, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
inst = x64_make_inst_G2E(mov, rl, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_E(mul, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else {
if (rd->id != rl->id) {
inst = x64_make_inst_G2E(mov, rl, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
int ret = _int_mul_src(mul, rh, src, c, f);
if (rs->id != rl->id) {
inst = x64_make_inst_G2E(mov, rl, rs);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
inst = x64_make_inst_M(&rela, mul, dst->var, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
} else {
mov2 = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, mov2, rl, NULL, dst->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
int ret = _int_mul_src(mul, rh, src, c, f);
if (rd) {
if (rd->id != rl->id) {
inst = x64_make_inst_G2E(mov, rd, rl);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else {
inst = x64_make_inst_G2M(&rela, mov, dst->var, NULL, rl);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
mov = x64_find_OpCode(SCF_X64_MOV, 1, 1, SCF_X64_G2E);
inst = x64_make_inst_G2E(mov, cl, rc);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else if (count->color < 0) {
- scf_rela_t* rela = NULL;
-
ret = x64_overflow_reg(cl, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
}
+ scf_rela_t* rela = NULL;
+
mov = x64_find_OpCode(SCF_X64_MOV, 1, 1, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, mov, cl, NULL, count->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, count->var, NULL);
}
return -ENOMEM;
}
- scf_register_t* rd = NULL;
-
+ scf_register_t* rd = NULL;
scf_instruction_t* inst;
scf_x64_OpCode_t* mov;
scf_x64_OpCode_t* shift;
if (0 != count->color) {
shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_G2E);
inst = x64_make_inst_E(shift, rd);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_I2E);
- inst = x64_make_inst_I2E(shift, rd, (uint8_t*)&count->var->data, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ inst = x64_make_inst_I2E(shift, rd, (uint8_t*)&count->var->data, 1);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else {
scf_rela_t* rela = NULL;
if (0 != count->color) {
shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_G2E);
inst = x64_make_inst_M(&rela, shift, dst->var, NULL);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
} else {
shift = x64_find_OpCode(OpCode_type, 1, dst->var->size, SCF_X64_I2E);
inst = x64_make_inst_I2M(&rela, shift, dst->var, NULL, (uint8_t*)&count->var->data, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dst->var, NULL);
}
}
inst = x64_make_inst_SIB(OpCode, sib->base, sib->index, sib->scale, sib->disp, size);
else
inst = x64_make_inst_P(OpCode, sib->base, sib->disp, size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
return 0;
}
case SCF_X64_POP:
case SCF_X64_RET:
case SCF_X64_CALL:
+ case SCF_X64_SYSCALL:
case SCF_X64_CVTSS2SD:
break;
scf_ModRM_setRM(&ModRM, base);
- if (SCF_X64_RM_EBP != base
- && SCF_X64_RM_ESP != base
- && SCF_X64_RM_R12 != base
- && SCF_X64_RM_R13 != base
- && 0 == disp) {
- scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE);
- inst->code[inst->len++] = ModRM;
- return 0;
+ if (0 == disp) {
+ if (SCF_X64_RM_ESP == base || SCF_X64_RM_R12 == base) {
+ scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE);
+ inst->code[inst->len++] = ModRM;
+
+ uint8_t SIB = 0;
+ scf_SIB_setBase(&SIB, base);
+ scf_SIB_setIndex(&SIB, base);
+ scf_SIB_setScale(&SIB, SCF_X64_SIB_SCALE1);
+ inst->code[inst->len++] = SIB;
+ return 0;
+
+ } else if (SCF_X64_RM_EBP != base && SCF_X64_RM_R13 != base) {
+ scf_ModRM_setMod(&ModRM, SCF_X64_MOD_BASE);
+ inst->code[inst->len++] = ModRM;
+ return 0;
+ }
}
if (disp <= 127 && disp >= -128) {
{SCF_X64_LEA, "lea", 1, {0x8d, 0x0, 0x0},1, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}},
{SCF_X64_LEA, "leaq", 1, {0x8d, 0x0, 0x0},1, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}},
+ {SCF_X64_MOV, "movb", 2, {0x88, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}},
+ {SCF_X64_MOV, "movw", 2, {0x89, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}},
+ {SCF_X64_MOV, "movl", 2, {0x89, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}},
+ {SCF_X64_MOV, "movq", 2, {0x89, 0x0, 0x0},1, 8,8, SCF_X64_G2E, 0,0, 0,{0,0}},
+
{SCF_X64_MOV, "mov", 2, {0x88, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_MOV, "mov", 2, {0x89, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_MOV, "mov", 2, {0x89, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_CMP, "cmp", 2, {0x83, 0x0, 0x0},1, 1,4, SCF_X64_I2E, 7,1, 0,{0,0}},
{SCF_X64_CMP, "cmp", 2, {0x83, 0x0, 0x0},1, 1,8, SCF_X64_I2E, 7,1, 0,{0,0}},
+ {SCF_X64_TEST, "testb", 2, {0x84, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}},
+ {SCF_X64_TEST, "testw", 2, {0x85, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}},
+ {SCF_X64_TEST, "testl", 2, {0x85, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}},
+ {SCF_X64_TEST, "testq", 2, {0x85, 0x0, 0x0},1, 8,8, SCF_X64_G2E, 0,0, 0,{0,0}},
+
{SCF_X64_TEST, "test", 2, {0x84, 0x0, 0x0},1, 1,1, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_TEST, "test", 2, {0x85, 0x0, 0x0},1, 2,2, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_TEST, "test", 2, {0x85, 0x0, 0x0},1, 4,4, SCF_X64_G2E, 0,0, 0,{0,0}},
{SCF_X64_CVTTSD2SI, "cvttsd2si", 8, {0xf2, 0x0f, 0x2c},3, 8,4, SCF_X64_E2G, 0,0, 0,{0,0}},
{SCF_X64_CVTTSD2SI, "cvttsd2si", 8, {0xf2, 0x0f, 0x2c},3, 8,8, SCF_X64_E2G, 0,0, 0,{0,0}},
- {SCF_X64_JZ, "jz", 2, {0x74, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
+ {SCF_X64_JZ, "jz", 2, {0x74, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
{SCF_X64_JZ, "jz", 6, {0x0f, 0x84, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}},
+ {SCF_X64_JZ, "je", 2, {0x74, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
+ {SCF_X64_JZ, "je", 6, {0x0f, 0x84, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}},
- {SCF_X64_JNZ, "jnz", 2, {0x75, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
+ {SCF_X64_JNZ, "jnz", 2, {0x75, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
{SCF_X64_JNZ, "jnz", 6, {0x0f, 0x85, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}},
+ {SCF_X64_JNZ, "jne", 2, {0x75, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
+ {SCF_X64_JNZ, "jne", 6, {0x0f, 0x85, 0x0},2, 4,4, SCF_X64_I, 0,0, 0,{0,0}},
{SCF_X64_JG, "jg", 2, {0x7f, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
{SCF_X64_JG, "jg", 6, {0x0f, 0x8f,0x0},1, 4,4, SCF_X64_I, 0,0, 0,{0,0}},
{SCF_X64_JMP, "jmp", 2, {0xeb, 0x0, 0x0},1, 1,1, SCF_X64_I, 0,0, 0,{0,0}},
{SCF_X64_JMP, "jmp", 5, {0xe9, 0x0, 0x0},1, 4,4, SCF_X64_I, 0,0, 0,{0,0}},
- {SCF_X64_JMP, "jmp", 2, {0xff, 0x0, 0x0},1, 8,8, SCF_X64_E, 4,1, 0,{0,0}},
+
+ {SCF_X64_SYSCALL, "syscall", 2, {0xf, 0x5, 0x0},2, 8,8, SCF_X64_G, 0,0, 0,{0,0}},
};
scf_x64_OpCode_t* x64_find_OpCode_by_type(const int type)
scf_instruction_t* x64_make_inst_G2L(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_src);
scf_instruction_t* x64_make_inst_L2G(scf_rela_t** prela, scf_x64_OpCode_t* OpCode, scf_register_t* r_dst);
-#define X64_INST_ADD_CHECK(vec, inst) \
+#define X64_INST_ADD_CHECK(vec, inst, rela) \
do { \
if (!(inst)) { \
scf_loge("\n"); \
int ret = scf_vector_add((vec), (inst)); \
if (ret < 0) { \
scf_loge("\n"); \
- free(inst); \
+ scf_instruction_free(inst); \
+ scf_rela_free(rela); \
return ret; \
} \
} while (0)
int ret = scf_vector_add((vec), (rela)); \
if (ret < 0) { \
scf_loge("\n"); \
- free(rela); \
+ scf_rela_free(rela); \
return ret; \
} \
} \
inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2);
else {
inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(movsd, rsp, 0, r2);
}
else
inst = x64_make_inst_G(push, r2);
}
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
saved_regs[n++] = r2;
size += 8;
inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2);
else {
inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2P(movsd, rsp, 0, r2);
}
else
inst = x64_make_inst_G(push, r2);
}
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
saved_regs[n++] = r2;
size += 8;
if (i == nb_updated) {
if (X64_COLOR_TYPE(r2->color)) {
inst = x64_make_inst_P2G(movsd, r2, rsp, 0);
- X64_INST_ADD_CHECK(instructions, inst);
+ X64_INST_ADD_CHECK(instructions, inst, NULL);
inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4);
} else
inst = x64_make_inst_G(pop, r2);
- X64_INST_ADD_CHECK(instructions, inst);
+ X64_INST_ADD_CHECK(instructions, inst, NULL);
} else {
inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4);
- X64_INST_ADD_CHECK(instructions, inst);
+ X64_INST_ADD_CHECK(instructions, inst, NULL);
}
}
return 0;
}
inst = x64_make_inst_G2M(&rela, mov, v, NULL, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
end:
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, v->func_ptr);
} else {
xor = x64_find_OpCode(SCF_X64_XOR, size, size, SCF_X64_G2E);
inst = x64_make_inst_G2E(xor, r, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
} else if (scf_variable_const_string(v)) {
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
} else if (v->nb_dimentions > 0) {
lea = x64_find_OpCode(SCF_X64_LEA, size, size, SCF_X64_E2G);
inst = x64_make_inst_M2G(&rela, lea, r, NULL, v);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
} else {
mov = x64_find_OpCode(SCF_X64_MOV, size, size, SCF_X64_I2G);
inst = x64_make_inst_I2G(mov, r, (uint8_t*)&v->data, size);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
return 0;
}
inst = x64_make_inst_M2G(&rela, mov, r, NULL, dn->var);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, rela);
X64_RELA_ADD_CHECK(f->data_relas, rela, c, dn->var, NULL);
dn->loaded = 1;
if (scf_variable_signed(index->var)) {
mov = x64_find_OpCode(SCF_X64_MOVSX, ri->bytes, ri2->bytes, SCF_X64_E2G);
inst = x64_make_inst_E2G(mov, ri2, ri);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else if (ri->bytes <= 2) {
mov = x64_find_OpCode(SCF_X64_MOVZX, ri->bytes, ri2->bytes, SCF_X64_E2G);
inst = x64_make_inst_E2G(mov, ri2, ri);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
} else {
assert(4 == ri->bytes);
mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E);
inst = x64_make_inst_G2E(mov, rs, ri2);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
shl = x64_find_OpCode(SCF_X64_SHL, 1, 8, SCF_X64_I2E);
add = x64_find_OpCode(SCF_X64_ADD, 8, 8, SCF_X64_G2E);
count -= i;
inst = x64_make_inst_I2E(shl, rs, (uint8_t*)&count, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
inst = x64_make_inst_G2E(add, rs, ri2);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
count = i;
}
if (count > 0) {
inst = x64_make_inst_I2E(shl, rs, (uint8_t*)&count, 1);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
}
ri = rs;
if (j < N) {
inst = x64_make_inst_G(push, r);
- X64_INST_ADD_CHECK(f->init_code->instructions, inst);
+ X64_INST_ADD_CHECK(f->init_code->instructions, inst, NULL);
f->init_code_bytes += inst->len;
}
if (j < N) {
inst = x64_make_inst_G(pop, r);
- X64_INST_ADD_CHECK(c->instructions, inst);
+ X64_INST_ADD_CHECK(c->instructions, inst, NULL);
bb->code_bytes += inst->len;
f->callee_saved_size += 8;
SCF_X64_JMP,
+ SCF_X64_SYSCALL,
+
SCF_X64_NB
};
goto error;
}
- scf_elf_sym_t* sym;
- int i;
-
- for (i = 0; i < parse->symtab->size; i++) {
- sym = parse->symtab->data[i];
-
- ret = scf_elf_add_sym(elf, sym, ".symtab");
- if (ret < 0)
- goto error;
- }
+ ret = scf_elf_add_syms(elf, parse->symtab, ".symtab");
+ if (ret < 0)
+ goto error;
ret = scf_elf_write_rel(elf);
error:
scf_string_t* scf_string_alloc();
+scf_string_t* scf_string_alloc_len(size_t len);
scf_string_t* scf_string_clone(scf_string_t* s);