Compare commits
11 Commits
original
...
loader_sep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50950028e0 | ||
|
|
1c5e1c2fce | ||
|
|
5c7799b778 | ||
|
|
0209b7ceb2 | ||
|
|
f6118dc0c4 | ||
|
|
d5e1fc733f | ||
|
|
c1eb8df114 | ||
|
|
ca129c5177 | ||
|
|
c19231a1bd | ||
|
|
5087a051b5 | ||
|
|
ba110a64cb |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,3 +5,5 @@ tests/outputs/*
|
|||||||
tests/errors
|
tests/errors
|
||||||
*.autosave
|
*.autosave
|
||||||
bld*
|
bld*
|
||||||
|
*.user
|
||||||
|
*.idb
|
||||||
|
|||||||
124
3rd_party/libdisasm/ia32_implicit.cpp
vendored
124
3rd_party/libdisasm/ia32_implicit.cpp
vendored
@@ -20,81 +20,81 @@ typedef struct {
|
|||||||
static op_implicit_list_t list_aaa[] =
|
static op_implicit_list_t list_aaa[] =
|
||||||
/* 37 : AAA : rw AL */
|
/* 37 : AAA : rw AL */
|
||||||
/* 3F : AAS : rw AL */
|
/* 3F : AAS : rw AL */
|
||||||
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* aaa */
|
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* aaa */
|
||||||
|
|
||||||
static op_implicit_list_t list_aad[] =
|
static op_implicit_list_t list_aad[] =
|
||||||
/* D5 0A, D5 (ib) : AAD : rw AX */
|
/* D5 0A, D5 (ib) : AAD : rw AX */
|
||||||
/* D4 0A, D4 (ib) : AAM : rw AX */
|
/* D4 0A, D4 (ib) : AAM : rw AX */
|
||||||
{{ OP_R | OP_W, REG_WORD_OFFSET }, {0}}; /* aad */
|
{{ OP_R | OP_W, REG_WORD_OFFSET }, {0,0}}; /* aad */
|
||||||
|
|
||||||
static op_implicit_list_t list_call[] =
|
static op_implicit_list_t list_call[] =
|
||||||
/* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */
|
/* E8, FF, 9A, FF : CALL : rw ESP, rw EIP */
|
||||||
/* C2, C3, CA, CB : RET : rw ESP, rw EIP */
|
/* C2, C3, CA, CB : RET : rw ESP, rw EIP */
|
||||||
{{ OP_R | OP_W, REG_EIP_INDEX },
|
{{ OP_R | OP_W, REG_EIP_INDEX },
|
||||||
{ OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* call, ret */
|
{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* call, ret */
|
||||||
|
|
||||||
static op_implicit_list_t list_cbw[] =
|
static op_implicit_list_t list_cbw[] =
|
||||||
/* 98 : CBW : r AL, rw AX */
|
/* 98 : CBW : r AL, rw AX */
|
||||||
{{ OP_R | OP_W, REG_WORD_OFFSET },
|
{{ OP_R | OP_W, REG_WORD_OFFSET },
|
||||||
{ OP_R, REG_BYTE_OFFSET}, {0}}; /* cbw */
|
{ OP_R, REG_BYTE_OFFSET}, {0,0}}; /* cbw */
|
||||||
|
|
||||||
static op_implicit_list_t list_cwde[] =
|
static op_implicit_list_t list_cwde[] =
|
||||||
/* 98 : CWDE : r AX, rw EAX */
|
/* 98 : CWDE : r AX, rw EAX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
||||||
{ OP_R, REG_WORD_OFFSET }, {0}}; /* cwde */
|
{ OP_R, REG_WORD_OFFSET }, {0,0}}; /* cwde */
|
||||||
|
|
||||||
static op_implicit_list_t list_clts[] =
|
static op_implicit_list_t list_clts[] =
|
||||||
/* 0F 06 : CLTS : rw CR0 */
|
/* 0F 06 : CLTS : rw CR0 */
|
||||||
{{ OP_R | OP_W, REG_CTRL_OFFSET}, {0}}; /* clts */
|
{{ OP_R | OP_W, REG_CTRL_OFFSET}, {0,0}}; /* clts */
|
||||||
|
|
||||||
static op_implicit_list_t list_cmpxchg[] =
|
static op_implicit_list_t list_cmpxchg[] =
|
||||||
/* 0F B0 : CMPXCHG : rw AL */
|
/* 0F B0 : CMPXCHG : rw AL */
|
||||||
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* cmpxchg */
|
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* cmpxchg */
|
||||||
|
|
||||||
static op_implicit_list_t list_cmpxchgb[] =
|
static op_implicit_list_t list_cmpxchgb[] =
|
||||||
/* 0F B1 : CMPXCHG : rw EAX */
|
/* 0F B1 : CMPXCHG : rw EAX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* cmpxchg */
|
{{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* cmpxchg */
|
||||||
|
|
||||||
static op_implicit_list_t list_cmpxchg8b[] =
|
static op_implicit_list_t list_cmpxchg8b[] =
|
||||||
/* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */
|
/* 0F C7 : CMPXCHG8B : rw EDX, rw EAX, r ECX, r EBX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
||||||
{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
|
{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_R, REG_DWORD_OFFSET + 1 },
|
{ OP_R, REG_DWORD_OFFSET + 1 },
|
||||||
{ OP_R, REG_DWORD_OFFSET + 3 }, {0}}; /* cmpxchg8b */
|
{ OP_R, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cmpxchg8b */
|
||||||
|
|
||||||
static op_implicit_list_t list_cpuid[] =
|
static op_implicit_list_t list_cpuid[] =
|
||||||
/* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */
|
/* 0F A2 : CPUID : rw EAX, w EBX, w ECX, w EDX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 1 },
|
{ OP_W, REG_DWORD_OFFSET + 1 },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 2 },
|
{ OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 3 }, {0}}; /* cpuid */
|
{ OP_W, REG_DWORD_OFFSET + 3 }, {0,0}}; /* cpuid */
|
||||||
|
|
||||||
static op_implicit_list_t list_cwd[] =
|
static op_implicit_list_t list_cwd[] =
|
||||||
/* 99 : CWD/CWQ : rw EAX, w EDX */
|
/* 99 : CWD/CWQ : rw EAX, w EDX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* cwd */
|
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* cwd */
|
||||||
|
|
||||||
static op_implicit_list_t list_daa[] =
|
static op_implicit_list_t list_daa[] =
|
||||||
/* 27 : DAA : rw AL */
|
/* 27 : DAA : rw AL */
|
||||||
/* 2F : DAS : rw AL */
|
/* 2F : DAS : rw AL */
|
||||||
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0}}; /* daa */
|
{{ OP_R | OP_W, REG_BYTE_OFFSET }, {0,0}}; /* daa */
|
||||||
|
|
||||||
static op_implicit_list_t list_idiv[] =
|
static op_implicit_list_t list_idiv[] =
|
||||||
/* F6 : DIV, IDIV : r AX, w AL, w AH */
|
/* F6 : DIV, IDIV : r AX, w AL, w AH */
|
||||||
/* FIXED: first op was EAX, not Aw. TODO: verify! */
|
/* FIXED: first op was EAX, not Aw. TODO: verify! */
|
||||||
{{ OP_R, REG_WORD_OFFSET },
|
{{ OP_R, REG_WORD_OFFSET },
|
||||||
{ OP_W, REG_BYTE_OFFSET },
|
{ OP_W, REG_BYTE_OFFSET },
|
||||||
{ OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* div */
|
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* div */
|
||||||
|
|
||||||
static op_implicit_list_t list_div[] =
|
static op_implicit_list_t list_div[] =
|
||||||
/* F7 : DIV, IDIV : rw EDX, rw EAX */
|
/* F7 : DIV, IDIV : rw EDX, rw EAX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* div */
|
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* div */
|
||||||
|
|
||||||
static op_implicit_list_t list_enter[] =
|
static op_implicit_list_t list_enter[] =
|
||||||
/* C8 : ENTER : rw ESP w EBP */
|
/* C8 : ENTER : rw ESP w EBP */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET + 4 },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET + 4 },
|
||||||
{ OP_R, REG_DWORD_OFFSET + 5 }, {0}}; /* enter */
|
{ OP_R, REG_DWORD_OFFSET + 5 }, {0,0}}; /* enter */
|
||||||
|
|
||||||
static op_implicit_list_t list_f2xm1[] =
|
static op_implicit_list_t list_f2xm1[] =
|
||||||
/* D9 F0 : F2XM1 : rw ST(0) */
|
/* D9 F0 : F2XM1 : rw ST(0) */
|
||||||
@@ -109,7 +109,7 @@ static op_implicit_list_t list_f2xm1[] =
|
|||||||
/* D9 FE : FSIN : rw ST(0) */
|
/* D9 FE : FSIN : rw ST(0) */
|
||||||
/* D9 FA : FSQRT : rw ST(0) */
|
/* D9 FA : FSQRT : rw ST(0) */
|
||||||
/* D9 F4 : FXTRACT : rw ST(0) */
|
/* D9 F4 : FXTRACT : rw ST(0) */
|
||||||
{{ OP_R | OP_W, REG_FPU_OFFSET }, {0}}; /* f2xm1 */
|
{{ OP_R | OP_W, REG_FPU_OFFSET }, {0,0}}; /* f2xm1 */
|
||||||
|
|
||||||
static op_implicit_list_t list_fcom[] =
|
static op_implicit_list_t list_fcom[] =
|
||||||
/* D8, DC, DE D9 : FCOM : r ST(0) */
|
/* D8, DC, DE D9 : FCOM : r ST(0) */
|
||||||
@@ -117,17 +117,17 @@ static op_implicit_list_t list_fcom[] =
|
|||||||
/* DF, D8 : FIST : r ST(0) */
|
/* DF, D8 : FIST : r ST(0) */
|
||||||
/* D9 E4 : FTST : r ST(0) */
|
/* D9 E4 : FTST : r ST(0) */
|
||||||
/* D9 E5 : FXAM : r ST(0) */
|
/* D9 E5 : FXAM : r ST(0) */
|
||||||
{{ OP_R, REG_FPU_OFFSET }, {0}}; /* fcom */
|
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fcom */
|
||||||
|
|
||||||
static op_implicit_list_t list_fpatan[] =
|
static op_implicit_list_t list_fpatan[] =
|
||||||
/* D9 F3 : FPATAN : r ST(0), rw ST(1) */
|
/* D9 F3 : FPATAN : r ST(0), rw ST(1) */
|
||||||
{{ OP_R, REG_FPU_OFFSET }, {0}}; /* fpatan */
|
{{ OP_R, REG_FPU_OFFSET }, {0,0}}; /* fpatan */
|
||||||
|
|
||||||
static op_implicit_list_t list_fprem[] =
|
static op_implicit_list_t list_fprem[] =
|
||||||
/* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */
|
/* D9 F8, D9 F5 : FPREM : rw ST(0) r ST(1) */
|
||||||
/* D9 FD : FSCALE : rw ST(0), r ST(1) */
|
/* D9 FD : FSCALE : rw ST(0), r ST(1) */
|
||||||
{{ OP_R | OP_W, REG_FPU_OFFSET },
|
{{ OP_R | OP_W, REG_FPU_OFFSET },
|
||||||
{ OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fprem */
|
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fprem */
|
||||||
|
|
||||||
static op_implicit_list_t list_faddp[] =
|
static op_implicit_list_t list_faddp[] =
|
||||||
/* DE C1 : FADDP : r ST(0), rw ST(1) */
|
/* DE C1 : FADDP : r ST(0), rw ST(1) */
|
||||||
@@ -135,67 +135,67 @@ static op_implicit_list_t list_faddp[] =
|
|||||||
/* D9 F1 : FYL2X : r ST(0), rw ST(1) */
|
/* D9 F1 : FYL2X : r ST(0), rw ST(1) */
|
||||||
/* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */
|
/* D9 F9 : FYL2XP1 : r ST(0), rw ST(1) */
|
||||||
{{ OP_R, REG_FPU_OFFSET },
|
{{ OP_R, REG_FPU_OFFSET },
|
||||||
{ OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0}}; /* faddp */
|
{ OP_R | OP_W, REG_FPU_OFFSET + 1 }, {0,0}}; /* faddp */
|
||||||
|
|
||||||
static op_implicit_list_t list_fucompp[] =
|
static op_implicit_list_t list_fucompp[] =
|
||||||
/* DA E9 : FUCOMPP : r ST(0), r ST(1) */
|
/* DA E9 : FUCOMPP : r ST(0), r ST(1) */
|
||||||
{{ OP_R, REG_FPU_OFFSET },
|
{{ OP_R, REG_FPU_OFFSET },
|
||||||
{ OP_R, REG_FPU_OFFSET + 1 }, {0}}; /* fucompp */
|
{ OP_R, REG_FPU_OFFSET + 1 }, {0,0}}; /* fucompp */
|
||||||
|
|
||||||
static op_implicit_list_t list_imul[] =
|
static op_implicit_list_t list_imul[] =
|
||||||
/* F6 : IMUL : r AL, w AX */
|
/* F6 : IMUL : r AL, w AX */
|
||||||
/* F6 : MUL : r AL, w AX */
|
/* F6 : MUL : r AL, w AX */
|
||||||
{{ OP_R, REG_BYTE_OFFSET },
|
{{ OP_R, REG_BYTE_OFFSET },
|
||||||
{ OP_W, REG_WORD_OFFSET }, {0}}; /* imul */
|
{ OP_W, REG_WORD_OFFSET }, {0,0}}; /* imul */
|
||||||
|
|
||||||
static op_implicit_list_t list_mul[] =
|
static op_implicit_list_t list_mul[] =
|
||||||
/* F7 : IMUL : rw EAX, w EDX */
|
/* F7 : IMUL : rw EAX, w EDX */
|
||||||
/* F7 : MUL : rw EAX, w EDX */
|
/* F7 : MUL : rw EAX, w EDX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 2 }, {0}}; /* imul */
|
{ OP_W, REG_DWORD_OFFSET + 2 }, {0,0}}; /* imul */
|
||||||
|
|
||||||
static op_implicit_list_t list_lahf[] =
|
static op_implicit_list_t list_lahf[] =
|
||||||
/* 9F : LAHF : r EFLAGS, w AH */
|
/* 9F : LAHF : r EFLAGS, w AH */
|
||||||
{{ OP_R, REG_FLAGS_INDEX },
|
{{ OP_R, REG_FLAGS_INDEX },
|
||||||
{ OP_W, REG_BYTE_OFFSET + 4 }, {0}}; /* lahf */
|
{ OP_W, REG_BYTE_OFFSET + 4 }, {0,0}}; /* lahf */
|
||||||
|
|
||||||
static op_implicit_list_t list_ldmxcsr[] =
|
static op_implicit_list_t list_ldmxcsr[] =
|
||||||
/* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */
|
/* 0F AE : LDMXCSR : w MXCSR SSE Control Status Reg */
|
||||||
{{ OP_W, REG_MXCSG_INDEX }, {0}}; /* ldmxcsr */
|
{{ OP_W, REG_MXCSG_INDEX }, {0,0}}; /* ldmxcsr */
|
||||||
|
|
||||||
static op_implicit_list_t list_leave[] =
|
static op_implicit_list_t list_leave[] =
|
||||||
/* C9 : LEAVE : rw ESP, w EBP */
|
/* C9 : LEAVE : rw ESP, w EBP */
|
||||||
{{ OP_R | OP_W, REG_ESP_INDEX },
|
{{ OP_R | OP_W, REG_ESP_INDEX },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 5 }, {0}}; /* leave */
|
{ OP_W, REG_DWORD_OFFSET + 5 }, {0,0}}; /* leave */
|
||||||
|
|
||||||
static op_implicit_list_t list_lgdt[] =
|
static op_implicit_list_t list_lgdt[] =
|
||||||
/* 0F 01 : LGDT : w GDTR */
|
/* 0F 01 : LGDT : w GDTR */
|
||||||
{{ OP_W, REG_GDTR_INDEX }, {0}}; /* lgdt */
|
{{ OP_W, REG_GDTR_INDEX }, {0,0}}; /* lgdt */
|
||||||
|
|
||||||
static op_implicit_list_t list_lidt[] =
|
static op_implicit_list_t list_lidt[] =
|
||||||
/* 0F 01 : LIDT : w IDTR */
|
/* 0F 01 : LIDT : w IDTR */
|
||||||
{{ OP_W, REG_IDTR_INDEX }, {0}}; /* lidt */
|
{{ OP_W, REG_IDTR_INDEX }, {0,0}}; /* lidt */
|
||||||
|
|
||||||
static op_implicit_list_t list_lldt[] =
|
static op_implicit_list_t list_lldt[] =
|
||||||
/* 0F 00 : LLDT : w LDTR */
|
/* 0F 00 : LLDT : w LDTR */
|
||||||
{{ OP_W, REG_LDTR_INDEX }, {0}}; /* lldt */
|
{{ OP_W, REG_LDTR_INDEX }, {0,0}}; /* lldt */
|
||||||
|
|
||||||
static op_implicit_list_t list_lmsw[] =
|
static op_implicit_list_t list_lmsw[] =
|
||||||
/* 0F 01 : LMSW : w CR0 */
|
/* 0F 01 : LMSW : w CR0 */
|
||||||
{{ OP_W, REG_CTRL_OFFSET }, {0}}; /* lmsw */
|
{{ OP_W, REG_CTRL_OFFSET }, {0,0}}; /* lmsw */
|
||||||
|
|
||||||
static op_implicit_list_t list_loop[] =
|
static op_implicit_list_t list_loop[] =
|
||||||
/* E0, E1, E2 : LOOP : rw ECX */
|
/* E0, E1, E2 : LOOP : rw ECX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* loop */
|
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* loop */
|
||||||
|
|
||||||
static op_implicit_list_t list_ltr[] =
|
static op_implicit_list_t list_ltr[] =
|
||||||
/* 0F 00 : LTR : w Task Register */
|
/* 0F 00 : LTR : w Task Register */
|
||||||
{{ OP_W, REG_TR_INDEX }, {0}}; /* ltr */
|
{{ OP_W, REG_TR_INDEX }, {0,0}}; /* ltr */
|
||||||
|
|
||||||
static op_implicit_list_t list_pop[] =
|
static op_implicit_list_t list_pop[] =
|
||||||
/* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */
|
/* 8F, 58, 1F, 07, 17, 0F A1, 0F A9 : POP : rw ESP */
|
||||||
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
|
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
|
||||||
{{ OP_R | OP_W, REG_ESP_INDEX }, {0}}; /* pop, push */
|
{{ OP_R | OP_W, REG_ESP_INDEX }, {0,0}}; /* pop, push */
|
||||||
|
|
||||||
static op_implicit_list_t list_popad[] =
|
static op_implicit_list_t list_popad[] =
|
||||||
/* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */
|
/* 61 : POPAD : rw esp, w edi esi ebp ebx edx ecx eax */
|
||||||
@@ -206,12 +206,12 @@ static op_implicit_list_t list_popad[] =
|
|||||||
{ OP_W, REG_DWORD_OFFSET + 3 },
|
{ OP_W, REG_DWORD_OFFSET + 3 },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 2 },
|
{ OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 1 },
|
{ OP_W, REG_DWORD_OFFSET + 1 },
|
||||||
{ OP_W, REG_DWORD_OFFSET }, {0}}; /* popad */
|
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* popad */
|
||||||
|
|
||||||
static op_implicit_list_t list_popfd[] =
|
static op_implicit_list_t list_popfd[] =
|
||||||
/* 9D : POPFD : rw esp, w eflags */
|
/* 9D : POPFD : rw esp, w eflags */
|
||||||
{{ OP_R | OP_W, REG_ESP_INDEX },
|
{{ OP_R | OP_W, REG_ESP_INDEX },
|
||||||
{ OP_W, REG_FLAGS_INDEX }, {0}}; /* popfd */
|
{ OP_W, REG_FLAGS_INDEX }, {0,0}}; /* popfd */
|
||||||
|
|
||||||
static op_implicit_list_t list_pushad[] =
|
static op_implicit_list_t list_pushad[] =
|
||||||
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
|
/* FF, 50, 6A, 68, 0E, 16, 1E, 06, 0F A0, 0F A8 : PUSH : rw ESP */
|
||||||
@@ -223,102 +223,102 @@ static op_implicit_list_t list_pushad[] =
|
|||||||
{ OP_R, REG_DWORD_OFFSET + 3 },
|
{ OP_R, REG_DWORD_OFFSET + 3 },
|
||||||
{ OP_R, REG_DWORD_OFFSET + 5 },
|
{ OP_R, REG_DWORD_OFFSET + 5 },
|
||||||
{ OP_R, REG_DWORD_OFFSET + 6 },
|
{ OP_R, REG_DWORD_OFFSET + 6 },
|
||||||
{ OP_R, REG_DWORD_OFFSET + 7 }, {0}}; /* pushad */
|
{ OP_R, REG_DWORD_OFFSET + 7 }, {0,0}}; /* pushad */
|
||||||
|
|
||||||
static op_implicit_list_t list_pushfd[] =
|
static op_implicit_list_t list_pushfd[] =
|
||||||
/* 9C : PUSHFD : rw esp, r eflags */
|
/* 9C : PUSHFD : rw esp, r eflags */
|
||||||
{{ OP_R | OP_W, REG_ESP_INDEX },
|
{{ OP_R | OP_W, REG_ESP_INDEX },
|
||||||
{ OP_R, REG_FLAGS_INDEX }, {0}}; /* pushfd */
|
{ OP_R, REG_FLAGS_INDEX }, {0,0}}; /* pushfd */
|
||||||
|
|
||||||
static op_implicit_list_t list_rdmsr[] =
|
static op_implicit_list_t list_rdmsr[] =
|
||||||
/* 0F 32 : RDMSR : r ECX, w EDX, w EAX */
|
/* 0F 32 : RDMSR : r ECX, w EDX, w EAX */
|
||||||
{{ OP_R, REG_DWORD_OFFSET + 1 },
|
{{ OP_R, REG_DWORD_OFFSET + 1 },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 2 },
|
{ OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_W, REG_DWORD_OFFSET }, {0}}; /* rdmsr */
|
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdmsr */
|
||||||
|
|
||||||
static op_implicit_list_t list_rdpmc[] =
|
static op_implicit_list_t list_rdpmc[] =
|
||||||
/* 0F 33 : RDPMC : r ECX, w EDX, w EAX */
|
/* 0F 33 : RDPMC : r ECX, w EDX, w EAX */
|
||||||
{{ OP_R, REG_DWORD_OFFSET + 1 },
|
{{ OP_R, REG_DWORD_OFFSET + 1 },
|
||||||
{ OP_W, REG_DWORD_OFFSET + 2 },
|
{ OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_W, REG_DWORD_OFFSET }, {0}}; /* rdpmc */
|
{ OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdpmc */
|
||||||
|
|
||||||
static op_implicit_list_t list_rdtsc[] =
|
static op_implicit_list_t list_rdtsc[] =
|
||||||
/* 0F 31 : RDTSC : rw EDX, rw EAX */
|
/* 0F 31 : RDTSC : rw EDX, rw EAX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
|
{{ OP_R | OP_W, REG_DWORD_OFFSET + 2 },
|
||||||
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0}}; /* rdtsc */
|
{ OP_R | OP_W, REG_DWORD_OFFSET }, {0,0}}; /* rdtsc */
|
||||||
|
|
||||||
static op_implicit_list_t list_rep[] =
|
static op_implicit_list_t list_rep[] =
|
||||||
/* F3, F2 ... : REP : rw ECX */
|
/* F3, F2 ... : REP : rw ECX */
|
||||||
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0}};/* rep */
|
{{ OP_R | OP_W, REG_DWORD_OFFSET + 1 }, {0,0}};/* rep */
|
||||||
|
|
||||||
static op_implicit_list_t list_rsm[] =
|
static op_implicit_list_t list_rsm[] =
|
||||||
/* 0F AA : RSM : r CR4, r CR0 */
|
/* 0F AA : RSM : r CR4, r CR0 */
|
||||||
{{ OP_R, REG_CTRL_OFFSET + 4 },
|
{{ OP_R, REG_CTRL_OFFSET + 4 },
|
||||||
{ OP_R, REG_CTRL_OFFSET }, {0}}; /* rsm */
|
{ OP_R, REG_CTRL_OFFSET }, {0,0}}; /* rsm */
|
||||||
|
|
||||||
static op_implicit_list_t list_sahf[] =
|
static op_implicit_list_t list_sahf[] =
|
||||||
/* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */
|
/* 9E : SAHF : r ah, rw eflags (set SF ZF AF PF CF) */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sahf */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sahf */
|
||||||
|
|
||||||
static op_implicit_list_t list_sgdt[] =
|
static op_implicit_list_t list_sgdt[] =
|
||||||
/* 0F : SGDT : r gdtr */
|
/* 0F : SGDT : r gdtr */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sgdt */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sgdt */
|
||||||
|
|
||||||
static op_implicit_list_t list_sidt[] =
|
static op_implicit_list_t list_sidt[] =
|
||||||
/* 0F : SIDT : r idtr */
|
/* 0F : SIDT : r idtr */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sidt */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sidt */
|
||||||
|
|
||||||
static op_implicit_list_t list_sldt[] =
|
static op_implicit_list_t list_sldt[] =
|
||||||
/* 0F : SLDT : r ldtr */
|
/* 0F : SLDT : r ldtr */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sldt */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sldt */
|
||||||
|
|
||||||
static op_implicit_list_t list_smsw[] =
|
static op_implicit_list_t list_smsw[] =
|
||||||
/* 0F : SMSW : r CR0 */
|
/* 0F : SMSW : r CR0 */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* smsw */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* smsw */
|
||||||
|
|
||||||
static op_implicit_list_t list_stmxcsr[] =
|
static op_implicit_list_t list_stmxcsr[] =
|
||||||
/* 0F AE : STMXCSR : r MXCSR */
|
/* 0F AE : STMXCSR : r MXCSR */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* stmxcsr */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* stmxcsr */
|
||||||
|
|
||||||
static op_implicit_list_t list_str[] =
|
static op_implicit_list_t list_str[] =
|
||||||
/* 0F 00 : STR : r TR (task register) */
|
/* 0F 00 : STR : r TR (task register) */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* str */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* str */
|
||||||
|
|
||||||
static op_implicit_list_t list_sysenter[] =
|
static op_implicit_list_t list_sysenter[] =
|
||||||
/* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags
|
/* 0F 34 : SYSENTER : w cs, w eip, w ss, w esp, r CR0, w eflags
|
||||||
* r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */
|
* r sysenter_cs_msr, sysenter_esp_msr, sysenter_eip_msr */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysenter */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysenter */
|
||||||
|
|
||||||
static op_implicit_list_t list_sysexit[] =
|
static op_implicit_list_t list_sysexit[] =
|
||||||
/* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp
|
/* 0F 35 : SYSEXIT : r edx, r ecx, w cs, w eip, w ss, w esp
|
||||||
* r sysenter_cs_msr */
|
* r sysenter_cs_msr */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* sysexit */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* sysexit */
|
||||||
|
|
||||||
static op_implicit_list_t list_wrmsr[] =
|
static op_implicit_list_t list_wrmsr[] =
|
||||||
/* 0F 30 : WRMST : r edx, r eax, r ecx */
|
/* 0F 30 : WRMST : r edx, r eax, r ecx */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* wrmsr */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* wrmsr */
|
||||||
|
|
||||||
static op_implicit_list_t list_xlat[] =
|
static op_implicit_list_t list_xlat[] =
|
||||||
/* D7 : XLAT : rw al r ebx (ptr) */
|
/* D7 : XLAT : rw al r ebx (ptr) */
|
||||||
/* TODO: finish this! */
|
/* TODO: finish this! */
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* xlat */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* xlat */
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R
|
* monitor 0f 01 c8 eax OP_R ecx OP_R edx OP_R
|
||||||
* mwait 0f 01 c9 eax OP_R ecx OP_R
|
* mwait 0f 01 c9 eax OP_R ecx OP_R
|
||||||
*/
|
*/
|
||||||
static op_implicit_list_t list_monitor[] =
|
static op_implicit_list_t list_monitor[] =
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* monitor */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* monitor */
|
||||||
static op_implicit_list_t list_mwait[] =
|
static op_implicit_list_t list_mwait[] =
|
||||||
{{ OP_R, REG_DWORD_OFFSET }, {0}}; /* mwait */
|
{{ OP_R, REG_DWORD_OFFSET }, {0,0}}; /* mwait */
|
||||||
|
|
||||||
op_implicit_list_t *op_implicit_list[] = {
|
op_implicit_list_t *op_implicit_list[] = {
|
||||||
/* This is a list of implicit operands which are read/written by
|
/* This is a list of implicit operands which are read/written by
|
||||||
@@ -407,6 +407,20 @@ unsigned int Ia32_Decoder::ia32_insn_implicit_ops( unsigned int impl_idx ) {
|
|||||||
if (!op) {
|
if (!op) {
|
||||||
op = m_decoded->x86_operand_new();
|
op = m_decoded->x86_operand_new();
|
||||||
/* all implicit operands are registers */
|
/* all implicit operands are registers */
|
||||||
|
if(m_decoded->addr_size==2)
|
||||||
|
{
|
||||||
|
if(list->operand==REG_EIP_INDEX)
|
||||||
|
handle_impl_reg( op, REG_IP_INDEX );
|
||||||
|
else if(list->operand<REG_WORD_OFFSET)
|
||||||
|
{
|
||||||
|
handle_impl_reg( op, (list->operand-REG_DWORD_OFFSET)+REG_WORD_OFFSET);
|
||||||
|
assert((list->operand-REG_DWORD_OFFSET)<REG_WORD_OFFSET-REG_DWORD_OFFSET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handle_impl_reg( op, list->operand);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
handle_impl_reg( op, list->operand );
|
handle_impl_reg( op, list->operand );
|
||||||
/* decrement the 'explicit count' incremented by default in
|
/* decrement the 'explicit count' incremented by default in
|
||||||
* x86_operand_new */
|
* x86_operand_new */
|
||||||
|
|||||||
7
3rd_party/libdisasm/ia32_insn.cpp
vendored
7
3rd_party/libdisasm/ia32_insn.cpp
vendored
@@ -240,7 +240,7 @@ void Ia32_Decoder::ia32_handle_prefix( unsigned int prefixes ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void reg_32_to_16( x86_op_t *op, x86_insn_t *insn, void *arg ) {
|
static void reg_32_to_16( x86_op_t *op, x86_insn_t */*insn*/, void */*arg*/ ) {
|
||||||
|
|
||||||
/* if this is a 32-bit register and it is a general register ... */
|
/* if this is a 32-bit register and it is a general register ... */
|
||||||
if ( op->type == op_register && op->data.reg.size == 4 &&
|
if ( op->type == op_register && op->data.reg.size == 4 &&
|
||||||
@@ -539,12 +539,11 @@ size_t ia32_table_lookup( unsigned char *buf, size_t buf_len,
|
|||||||
|
|
||||||
size_t Ia32_Decoder::handle_insn_suffix( unsigned char *buf, size_t buf_len,
|
size_t Ia32_Decoder::handle_insn_suffix( unsigned char *buf, size_t buf_len,
|
||||||
ia32_insn_t *raw_insn ) {
|
ia32_insn_t *raw_insn ) {
|
||||||
ia32_table_desc_t *table_desc;
|
// ia32_table_desc_t *table_desc;
|
||||||
ia32_insn_t *sfx_insn;
|
ia32_insn_t *sfx_insn;
|
||||||
size_t size;
|
size_t size;
|
||||||
unsigned int prefixes = 0;
|
unsigned int prefixes = 0;
|
||||||
|
//table_desc = &ia32_tables[raw_insn->table];
|
||||||
table_desc = &ia32_tables[raw_insn->table];
|
|
||||||
size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn,
|
size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn,
|
||||||
&prefixes );
|
&prefixes );
|
||||||
if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) {
|
if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) {
|
||||||
|
|||||||
9
3rd_party/libdisasm/ia32_invariant.cpp
vendored
9
3rd_party/libdisasm/ia32_invariant.cpp
vendored
@@ -137,7 +137,7 @@ static int ia32_invariant_modrm( unsigned char *in, unsigned char *out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ia32_decode_invariant( unsigned char *buf, size_t buf_len,
|
static int ia32_decode_invariant( unsigned char *buf, size_t /*buf_len*/,
|
||||||
ia32_insn_t *t, unsigned char *out,
|
ia32_insn_t *t, unsigned char *out,
|
||||||
unsigned int prefixes, x86_invariant_t *inv) {
|
unsigned int prefixes, x86_invariant_t *inv) {
|
||||||
|
|
||||||
@@ -251,13 +251,13 @@ static int ia32_decode_invariant( unsigned char *buf, size_t buf_len,
|
|||||||
case ADDRMETH_X:
|
case ADDRMETH_X:
|
||||||
inv->operands[x].flags.op_signed=true;
|
inv->operands[x].flags.op_signed=true;
|
||||||
inv->operands[x].flags.op_pointer=true;
|
inv->operands[x].flags.op_pointer=true;
|
||||||
inv->operands[x].flags.op_seg=x86_op_flags::op_ds_seg;
|
inv->operands[x].flags.op_seg=(x86_op_flags::op_ds_seg)>>8;
|
||||||
inv->operands[x].flags.op_string=true;
|
inv->operands[x].flags.op_string=true;
|
||||||
break;
|
break;
|
||||||
case ADDRMETH_Y:
|
case ADDRMETH_Y:
|
||||||
inv->operands[x].flags.op_signed=true;
|
inv->operands[x].flags.op_signed=true;
|
||||||
inv->operands[x].flags.op_pointer=true;
|
inv->operands[x].flags.op_pointer=true;
|
||||||
inv->operands[x].flags.op_seg=x86_op_flags::op_es_seg;
|
inv->operands[x].flags.op_seg=x86_op_flags::op_es_seg>>8;
|
||||||
inv->operands[x].flags.op_string=true;
|
inv->operands[x].flags.op_string=true;
|
||||||
break;
|
break;
|
||||||
case ADDRMETH_RR:
|
case ADDRMETH_RR:
|
||||||
@@ -307,6 +307,7 @@ size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ) {
|
size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ) {
|
||||||
x86_invariant_t inv = { {0} };
|
x86_invariant_t inv;
|
||||||
|
memset(&inv,0,sizeof(x86_invariant_t));
|
||||||
return( ia32_disasm_invariant( buf, buf_len, &inv ) );
|
return( ia32_disasm_invariant( buf, buf_len, &inv ) );
|
||||||
}
|
}
|
||||||
|
|||||||
6
3rd_party/libdisasm/ia32_modrm.cpp
vendored
6
3rd_party/libdisasm/ia32_modrm.cpp
vendored
@@ -155,12 +155,12 @@ static size_t modrm_decode16( unsigned char *buf, unsigned int buf_len,
|
|||||||
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3);
|
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 3);
|
||||||
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7);
|
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7);
|
||||||
case MOD16_RM_BPSI:
|
case MOD16_RM_BPSI:
|
||||||
op->flags.op_seg = x86_op_flags::op_ss_seg;
|
op->flags.op_seg = x86_op_flags::op_ss_seg>>8;
|
||||||
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5);
|
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5);
|
||||||
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6);
|
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 6);
|
||||||
break;
|
break;
|
||||||
case MOD16_RM_BPDI:
|
case MOD16_RM_BPDI:
|
||||||
op->flags.op_seg = x86_op_flags::op_ss_seg;
|
op->flags.op_seg = x86_op_flags::op_ss_seg>>8;
|
||||||
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5);
|
ia32_handle_register(&ea->base, REG_WORD_OFFSET + 5);
|
||||||
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7);
|
ia32_handle_register(&ea->index, REG_WORD_OFFSET + 7);
|
||||||
break;
|
break;
|
||||||
@@ -172,7 +172,7 @@ static size_t modrm_decode16( unsigned char *buf, unsigned int buf_len,
|
|||||||
break;
|
break;
|
||||||
case MOD16_RM_BP:
|
case MOD16_RM_BP:
|
||||||
if ( modrm->mod != MOD16_MOD_NODISP ) {
|
if ( modrm->mod != MOD16_MOD_NODISP ) {
|
||||||
op->flags.op_seg = x86_op_flags::op_ss_seg;
|
op->flags.op_seg = x86_op_flags::op_ss_seg>>8;
|
||||||
ia32_handle_register(&ea->base,
|
ia32_handle_register(&ea->base,
|
||||||
REG_WORD_OFFSET + 5);
|
REG_WORD_OFFSET + 5);
|
||||||
}
|
}
|
||||||
|
|||||||
57
3rd_party/libdisasm/ia32_operand.cpp
vendored
57
3rd_party/libdisasm/ia32_operand.cpp
vendored
@@ -20,17 +20,17 @@ static void apply_seg( x86_op_t *op, unsigned int prefixes ) {
|
|||||||
switch ( prefixes & PREFIX_REG_MASK ) {
|
switch ( prefixes & PREFIX_REG_MASK ) {
|
||||||
/* NOTE: that op->flags for segment override are not a bitfield */
|
/* NOTE: that op->flags for segment override are not a bitfield */
|
||||||
case PREFIX_CS:
|
case PREFIX_CS:
|
||||||
op->flags.op_seg = x86_op_flags::op_cs_seg; break;
|
op->flags.op_seg = x86_op_flags::op_cs_seg>>8; break;
|
||||||
case PREFIX_SS:
|
case PREFIX_SS:
|
||||||
op->flags.op_seg = x86_op_flags::op_ss_seg; break;
|
op->flags.op_seg = x86_op_flags::op_ss_seg>>8; break;
|
||||||
case PREFIX_DS:
|
case PREFIX_DS:
|
||||||
op->flags.op_seg = x86_op_flags::op_ds_seg; break;
|
op->flags.op_seg = x86_op_flags::op_ds_seg>>8; break;
|
||||||
case PREFIX_ES:
|
case PREFIX_ES:
|
||||||
op->flags.op_seg = x86_op_flags::op_es_seg; break;
|
op->flags.op_seg = x86_op_flags::op_es_seg>>8; break;
|
||||||
case PREFIX_FS:
|
case PREFIX_FS:
|
||||||
op->flags.op_seg = x86_op_flags::op_fs_seg; break;
|
op->flags.op_seg = x86_op_flags::op_fs_seg>>8; break;
|
||||||
case PREFIX_GS:
|
case PREFIX_GS:
|
||||||
op->flags.op_seg = x86_op_flags::op_gs_seg; break;
|
op->flags.op_seg = x86_op_flags::op_gs_seg>>8; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -107,19 +107,17 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
|
|||||||
/* No MODRM : note these set operand type explicitly */
|
/* No MODRM : note these set operand type explicitly */
|
||||||
case ADDRMETH_A: /* No modR/M -- direct addr */
|
case ADDRMETH_A: /* No modR/M -- direct addr */
|
||||||
op->type = op_absolute;
|
op->type = op_absolute;
|
||||||
|
//according to Intel Manuals, offset goes first
|
||||||
/* segment:offset address used in far calls */
|
/* segment:offset address used in far calls */
|
||||||
x86_imm_sized( buf, buf_len,
|
|
||||||
&op->data.absolute.segment, 2 );
|
|
||||||
if ( m_decoded->addr_size == 4 ) {
|
if ( m_decoded->addr_size == 4 ) {
|
||||||
x86_imm_sized( buf, buf_len,
|
x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 );
|
||||||
&op->data.absolute.offset.off32, 4 );
|
|
||||||
size = 6;
|
|
||||||
} else {
|
|
||||||
x86_imm_sized( buf, buf_len,
|
|
||||||
&op->data.absolute.offset.off16, 2 );
|
|
||||||
size = 4;
|
size = 4;
|
||||||
|
} else {
|
||||||
|
x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off16, 2 );
|
||||||
|
size = 2;
|
||||||
}
|
}
|
||||||
|
x86_imm_sized( buf+size, buf_len-size, &op->data.absolute.segment, 2 );
|
||||||
|
size+=2;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ADDRMETH_I: /* Immediate val */
|
case ADDRMETH_I: /* Immediate val */
|
||||||
@@ -140,17 +138,24 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
|
|||||||
op->data.far_offset depending on the size of
|
op->data.far_offset depending on the size of
|
||||||
the operand */
|
the operand */
|
||||||
op->flags.op_signed = true;
|
op->flags.op_signed = true;
|
||||||
if ( op_size == 1 ) {
|
switch(op_size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
/* one-byte near offset */
|
/* one-byte near offset */
|
||||||
op->type = op_relative_near;
|
op->type = op_relative_near;
|
||||||
x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
|
size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
|
||||||
} else {
|
break;
|
||||||
|
case 2:
|
||||||
/* far offset...is this truly signed? */
|
/* far offset...is this truly signed? */
|
||||||
op->type = op_relative_far;
|
op->type = op_relative_far;
|
||||||
x86_imm_signsized(buf, buf_len,
|
int16_t offset_val; // easier upcast to int32_t
|
||||||
&op->data.relative_far, op_size );
|
size = x86_imm_signsized(buf, buf_len, &offset_val, 2 );
|
||||||
|
op->data.relative_far=offset_val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
size=0;
|
||||||
}
|
}
|
||||||
size = op_size;
|
|
||||||
break;
|
break;
|
||||||
case ADDRMETH_O: /* No ModR/M; op is word/dword offset */
|
case ADDRMETH_O: /* No ModR/M; op is word/dword offset */
|
||||||
/* NOTE: these are actually RVAs not offsets to seg!! */
|
/* NOTE: these are actually RVAs not offsets to seg!! */
|
||||||
@@ -172,20 +177,20 @@ size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
|
|||||||
case ADDRMETH_X: /* Memory addressed by DS:SI [string] */
|
case ADDRMETH_X: /* Memory addressed by DS:SI [string] */
|
||||||
op->type = op_expression;
|
op->type = op_expression;
|
||||||
op->flags.op_hardcode = true;
|
op->flags.op_hardcode = true;
|
||||||
op->flags.op_seg = x86_op_flags::op_ds_seg;
|
op->flags.op_seg = x86_op_flags::op_ds_seg>>8;
|
||||||
op->flags.op_pointer = true;
|
op->flags.op_pointer = true;
|
||||||
op->flags.op_string = true;
|
op->flags.op_string = true;
|
||||||
ia32_handle_register( &op->data.expression.base,
|
ia32_handle_register( &op->data.expression.base,
|
||||||
REG_DWORD_OFFSET + 6 );
|
gen_regs + 6 );
|
||||||
break;
|
break;
|
||||||
case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */
|
case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */
|
||||||
op->type = op_expression;
|
op->type = op_expression;
|
||||||
op->flags.op_hardcode = true;
|
op->flags.op_hardcode = true;
|
||||||
op->flags.op_seg = x86_op_flags::op_es_seg;
|
op->flags.op_seg = x86_op_flags::op_es_seg>>8;
|
||||||
op->flags.op_pointer = true;
|
op->flags.op_pointer = true;
|
||||||
op->flags.op_string = true;
|
op->flags.op_string = true;
|
||||||
ia32_handle_register( &op->data.expression.base,
|
ia32_handle_register( &op->data.expression.base,
|
||||||
REG_DWORD_OFFSET + 7 );
|
gen_regs + 7 );
|
||||||
break;
|
break;
|
||||||
case ADDRMETH_RR: /* Gen Register hard-coded in opcode */
|
case ADDRMETH_RR: /* Gen Register hard-coded in opcode */
|
||||||
op->type = op_register;
|
op->type = op_register;
|
||||||
@@ -258,7 +263,7 @@ size_t Ia32_Decoder::decode_operand_size( unsigned int op_type, x86_op_t *op ) {
|
|||||||
* value s a 16:16 pointer or a 16:32 pointer, where
|
* value s a 16:16 pointer or a 16:32 pointer, where
|
||||||
* the first '16' is a segment */
|
* the first '16' is a segment */
|
||||||
size = (m_decoded->addr_size == 4) ? 6 : 4;
|
size = (m_decoded->addr_size == 4) ? 6 : 4;
|
||||||
op->datatype = (size == 4) ? op_descr32 : op_descr16;
|
op->datatype = (size == 6) ? op_descr32 : op_descr16;
|
||||||
break;
|
break;
|
||||||
case OPTYPE_b: /* byte, ignore op-size */
|
case OPTYPE_b: /* byte, ignore op-size */
|
||||||
size = 1;
|
size = 1;
|
||||||
|
|||||||
4
3rd_party/libdisasm/ia32_reg.cpp
vendored
4
3rd_party/libdisasm/ia32_reg.cpp
vendored
@@ -60,7 +60,7 @@ static struct {
|
|||||||
{ REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */
|
{ REG_FPU_OFFSET + 5, 0 }, /* mm5 : 23 */
|
||||||
{ REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */
|
{ REG_FPU_OFFSET + 6, 0 }, /* mm6 : 24 */
|
||||||
{ REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */
|
{ REG_FPU_OFFSET + 7, 0 } /* mm7 : 25 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* REGISTER TABLE: size, type, and name of every register in the
|
/* REGISTER TABLE: size, type, and name of every register in the
|
||||||
* CPU. Does not include MSRs since the are, after all,
|
* CPU. Does not include MSRs since the are, after all,
|
||||||
@@ -189,7 +189,7 @@ static struct {
|
|||||||
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
|
{ REG_DWORD_SIZE, reg_sys, 0, "esp_msr" },
|
||||||
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
|
/* REG_EIPMSR_INDEX : SYSENTER_EIP_MSR : 92 */
|
||||||
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
|
{ REG_DWORD_SIZE, reg_sys, 0, "eip_msr" },
|
||||||
{ 0 }
|
{ 0,reg_undef,0,"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
72
3rd_party/libdisasm/libdis.h
vendored
72
3rd_party/libdisasm/libdis.h
vendored
@@ -6,6 +6,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* 'NEW" types
|
/* 'NEW" types
|
||||||
@@ -89,7 +90,7 @@ enum x86_options { /* these can be ORed together */
|
|||||||
opt_none= 0,
|
opt_none= 0,
|
||||||
opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */
|
opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */
|
||||||
opt_16_bit=2, /* 16-bit/DOS disassembly */
|
opt_16_bit=2, /* 16-bit/DOS disassembly */
|
||||||
opt_att_mnemonics=4, /* use AT&T syntax names for alternate opcode mnemonics */
|
opt_att_mnemonics=4 /* use AT&T syntax names for alternate opcode mnemonics */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ========================================= Instruction Representation */
|
/* ========================================= Instruction Representation */
|
||||||
@@ -275,32 +276,59 @@ struct x86_op_t{
|
|||||||
unsigned char fpuenv[28];
|
unsigned char fpuenv[28];
|
||||||
/* offset from segment */
|
/* offset from segment */
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
x86_reg_t reg; /* ID of CPU register */
|
/* ID of CPU register */
|
||||||
char relative_near; /* offsets from current insn */
|
x86_reg_t reg;
|
||||||
|
/* offsets from current insn */
|
||||||
|
char relative_near;
|
||||||
int32_t relative_far;
|
int32_t relative_far;
|
||||||
x86_absolute_t absolute; /* segment:offset */
|
/* segment:offset */
|
||||||
x86_ea_t expression; /* effective address [expression] */
|
x86_absolute_t absolute;
|
||||||
|
/* effective address [expression] */
|
||||||
|
x86_ea_t expression;
|
||||||
} data;
|
} data;
|
||||||
/* this is needed to make formatting operands more sane */
|
/* this is needed to make formatting operands more sane */
|
||||||
void * insn; /* pointer to x86_insn_t owning operand */
|
void * insn; /* pointer to x86_insn_t owning operand */
|
||||||
size_t size()
|
size_t size() const
|
||||||
{
|
{
|
||||||
return operand_size();
|
return operand_size();
|
||||||
}
|
}
|
||||||
/* get size of operand data in bytes */
|
/* get size of operand data in bytes */
|
||||||
size_t operand_size();
|
size_t operand_size() const;
|
||||||
/* format (sprintf) an operand into 'buf' using specified syntax */
|
/* format (sprintf) an operand into 'buf' using specified syntax */
|
||||||
int x86_format_operand(char *buf, int len, enum x86_asm_format format );
|
int x86_format_operand(char *buf, int len, enum x86_asm_format format );
|
||||||
bool is_address( ) {
|
bool is_address( ) const {
|
||||||
return ( type == op_absolute || type == op_offset );
|
return ( type == op_absolute || type == op_offset );
|
||||||
}
|
}
|
||||||
bool is_relative( ) {
|
bool is_relative( ) const {
|
||||||
return ( type == op_relative_near || type == op_relative_far );
|
return ( type == op_relative_near || type == op_relative_far );
|
||||||
}
|
}
|
||||||
|
bool is_immediate( ) const { return ( type == op_immediate ); }
|
||||||
|
int32_t getAddress()
|
||||||
|
{
|
||||||
|
assert(is_address()||is_relative());
|
||||||
|
switch ( type ) {
|
||||||
|
case op_relative_near:
|
||||||
|
return (int32_t) data.relative_near;
|
||||||
|
case op_absolute:
|
||||||
|
if(datatype==op_descr16)
|
||||||
|
return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off16;
|
||||||
|
else
|
||||||
|
return int32_t((data.absolute.segment)<<4) + data.absolute.offset.off32;
|
||||||
|
case op_offset:
|
||||||
|
return data.offset;
|
||||||
|
case op_relative_far:
|
||||||
|
return (int32_t) data.relative_far;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ~0;
|
||||||
|
}
|
||||||
char * format( enum x86_asm_format format );
|
char * format( enum x86_asm_format format );
|
||||||
x86_op_t * copy()
|
x86_op_t * copy()
|
||||||
{
|
{
|
||||||
x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 );
|
x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 );
|
||||||
|
|
||||||
if ( op ) {
|
if ( op ) {
|
||||||
memcpy( op, this, sizeof(x86_op_t) );
|
memcpy( op, this, sizeof(x86_op_t) );
|
||||||
}
|
}
|
||||||
@@ -439,7 +467,7 @@ enum x86_insn_note {
|
|||||||
insn_note_smm = 2, /* "" in System Management Mode */
|
insn_note_smm = 2, /* "" in System Management Mode */
|
||||||
insn_note_serial = 4, /* Serializing instruction */
|
insn_note_serial = 4, /* Serializing instruction */
|
||||||
insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */
|
insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */
|
||||||
insn_note_nosuffix = 16, /* Does not have size suffix in att-style formatting */
|
insn_note_nosuffix = 16 /* Does not have size suffix in att-style formatting */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This specifies what effects the instruction has on the %eflags register */
|
/* This specifies what effects the instruction has on the %eflags register */
|
||||||
@@ -520,7 +548,6 @@ enum x86_insn_prefix {
|
|||||||
|
|
||||||
|
|
||||||
/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */
|
/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */
|
||||||
|
|
||||||
/* FOREACH types: these are used to limit the foreach results to
|
/* FOREACH types: these are used to limit the foreach results to
|
||||||
* operands which match a certain "type" (implicit or explicit)
|
* operands which match a certain "type" (implicit or explicit)
|
||||||
* or which are accessed in certain ways (e.g. read or write). Note
|
* or which are accessed in certain ways (e.g. read or write). Note
|
||||||
@@ -604,29 +631,36 @@ public:
|
|||||||
void *block; /* code block containing this insn */
|
void *block; /* code block containing this insn */
|
||||||
void *function; /* function containing this insn */
|
void *function; /* function containing this insn */
|
||||||
int tag; /* tag the insn as seen/processed */
|
int tag; /* tag the insn as seen/processed */
|
||||||
x86_op_t * x86_operand_new();
|
x86_op_t *x86_operand_new();
|
||||||
|
/* convenience routine: returns count of operands matching 'type' */
|
||||||
size_t x86_operand_count( enum x86_op_foreach_type type );
|
size_t x86_operand_count( enum x86_op_foreach_type type );
|
||||||
/* accessor functions for the operands */
|
/* accessor functions for the operands */
|
||||||
x86_op_t * x86_operand_1st( );
|
x86_op_t * operand_1st( );
|
||||||
x86_op_t * x86_operand_2nd( );
|
x86_op_t * operand_2nd( );
|
||||||
x86_op_t * x86_operand_3rd( );
|
x86_op_t * operand_3rd( );
|
||||||
x86_op_t * get_dest();
|
const x86_op_t * get_dest() const;
|
||||||
int32_t x86_get_rel_offset( );
|
int32_t x86_get_rel_offset( );
|
||||||
x86_op_t * x86_get_branch_target( );
|
x86_op_t * x86_get_branch_target( );
|
||||||
x86_op_t * x86_get_imm( );
|
x86_op_t * x86_get_imm( );
|
||||||
uint8_t * x86_get_raw_imm( );
|
|
||||||
/* More accessor fuctions, this time for user-defined info... */
|
/* More accessor fuctions, this time for user-defined info... */
|
||||||
|
uint8_t * x86_get_raw_imm( );
|
||||||
|
/* set the address (usually RVA) of the insn */
|
||||||
void x86_set_insn_addr( uint32_t addr );
|
void x86_set_insn_addr( uint32_t addr );
|
||||||
|
/* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
|
||||||
int x86_format_mnemonic( char *buf, int len, enum x86_asm_format format);
|
int x86_format_mnemonic( char *buf, int len, enum x86_asm_format format);
|
||||||
int x86_format_insn( char *buf, int len, enum x86_asm_format);
|
int x86_format_insn( char *buf, int len, enum x86_asm_format);
|
||||||
void x86_oplist_free( );
|
void x86_oplist_free( );
|
||||||
|
/* returns 0 if an instruction is invalid, 1 if valid */
|
||||||
bool is_valid( );
|
bool is_valid( );
|
||||||
uint32_t x86_get_address( );
|
uint32_t x86_get_address( );
|
||||||
void make_invalid(unsigned char *buf);
|
void make_invalid(unsigned char *buf);
|
||||||
/* instruction tagging: these routines allow the programmer to mark
|
/* instruction tagging: these routines allow the programmer to mark
|
||||||
* instructions as "seen" in a DFS, for example. libdisasm does not use
|
* instructions as "seen" in a DFS, for example. libdisasm does not use
|
||||||
* the tag field.*/
|
* the tag field.*/
|
||||||
|
/* set insn->tag to 1 */
|
||||||
void x86_tag_insn( );
|
void x86_tag_insn( );
|
||||||
|
|
||||||
|
/* return insn->tag */
|
||||||
int x86_insn_is_tagged();
|
int x86_insn_is_tagged();
|
||||||
/* set insn->tag to 0 */
|
/* set insn->tag to 0 */
|
||||||
void x86_untag_insn();
|
void x86_untag_insn();
|
||||||
@@ -722,7 +756,7 @@ public:
|
|||||||
* offset : Offset in buffer to disassemble
|
* offset : Offset in buffer to disassemble
|
||||||
* insn : Structure to fill with disassembled instruction
|
* insn : Structure to fill with disassembled instruction
|
||||||
*/
|
*/
|
||||||
unsigned int x86_disasm( unsigned char *buf, unsigned int buf_len,
|
unsigned int x86_disasm(const unsigned char *buf, unsigned int buf_len,
|
||||||
uint32_t buf_rva, unsigned int offset,
|
uint32_t buf_rva, unsigned int offset,
|
||||||
x86_insn_t * insn );
|
x86_insn_t * insn );
|
||||||
/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
|
/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
|
||||||
@@ -803,7 +837,7 @@ public:
|
|||||||
* void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
|
* void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
|
||||||
* where 'alias_reg' is a reg operand and 'output_reg' is filled with the
|
* where 'alias_reg' is a reg operand and 'output_reg' is filled with the
|
||||||
* register that the operand is an alias for */
|
* register that the operand is an alias for */
|
||||||
//#define x86_get_aliased_reg( alias_reg, output_reg ) \
|
//#define x86_get_aliased_reg( alias_reg, output_reg )
|
||||||
// x86_reg_from_id( alias_reg->alias, output_reg )
|
// x86_reg_from_id( alias_reg->alias, output_reg )
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
3rd_party/libdisasm/x86_disasm.cpp
vendored
13
3rd_party/libdisasm/x86_disasm.cpp
vendored
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
#endif
|
#endif
|
||||||
void x86_insn_t::make_invalid(unsigned char *buf)
|
void x86_insn_t::make_invalid(unsigned char *buf)
|
||||||
{
|
{
|
||||||
@@ -21,7 +21,7 @@ void x86_insn_t::make_invalid(unsigned char *buf)
|
|||||||
type = insn_invalid;
|
type = insn_invalid;
|
||||||
memcpy( bytes, buf, 1 );
|
memcpy( bytes, buf, 1 );
|
||||||
}
|
}
|
||||||
unsigned int X86_Disasm::x86_disasm( unsigned char *buf, unsigned int buf_len,
|
unsigned int X86_Disasm::x86_disasm( const unsigned char *buf, unsigned int buf_len,
|
||||||
uint32_t buf_rva, unsigned int offset,
|
uint32_t buf_rva, unsigned int offset,
|
||||||
x86_insn_t *insn ){
|
x86_insn_t *insn ){
|
||||||
int len, size;
|
int len, size;
|
||||||
@@ -141,7 +141,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
|
|||||||
x86_insn_t insn;
|
x86_insn_t insn;
|
||||||
x86_op_t *op;
|
x86_op_t *op;
|
||||||
int32_t next_addr;
|
int32_t next_addr;
|
||||||
uint32_t next_offset;
|
int32_t next_offset;
|
||||||
unsigned int size, count = 0, bytes = 0, cont = 1;
|
unsigned int size, count = 0, bytes = 0, cont = 1;
|
||||||
|
|
||||||
while ( cont && bytes < buf_len ) {
|
while ( cont && bytes < buf_len ) {
|
||||||
@@ -161,7 +161,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( follow_insn_dest(&insn) ) {
|
if ( follow_insn_dest(&insn) ) {
|
||||||
op = insn.x86_operand_1st();//x86_get_dest_operand
|
op = insn.operand_1st();//x86_get_dest_operand
|
||||||
next_addr = -1;
|
next_addr = -1;
|
||||||
|
|
||||||
/* if caller supplied a resolver, use it to determine
|
/* if caller supplied a resolver, use it to determine
|
||||||
@@ -175,8 +175,7 @@ unsigned int X86_Disasm::x86_disasm_forward( unsigned char *buf, unsigned int bu
|
|||||||
if (next_addr != -1 ) {
|
if (next_addr != -1 ) {
|
||||||
next_offset = next_addr - buf_rva;
|
next_offset = next_addr - buf_rva;
|
||||||
/* if offset is in this buffer... */
|
/* if offset is in this buffer... */
|
||||||
if ( next_offset >= 0 &&
|
if ( next_offset >= 0 && next_offset < buf_len ) {
|
||||||
next_offset < buf_len ) {
|
|
||||||
/* go ahead and disassemble */
|
/* go ahead and disassemble */
|
||||||
count += x86_disasm_forward( buf,
|
count += x86_disasm_forward( buf,
|
||||||
buf_len,
|
buf_len,
|
||||||
|
|||||||
98
3rd_party/libdisasm/x86_format.cpp
vendored
98
3rd_party/libdisasm/x86_format.cpp
vendored
@@ -46,7 +46,7 @@
|
|||||||
} \
|
} \
|
||||||
} while( 0 )
|
} while( 0 )
|
||||||
|
|
||||||
static char *prefix_strings[] = {
|
static const char *prefix_strings[] = {
|
||||||
"", /* no prefix */
|
"", /* no prefix */
|
||||||
"repz ", /* the trailing spaces make it easy to prepend to mnemonic */
|
"repz ", /* the trailing spaces make it easy to prepend to mnemonic */
|
||||||
"repnz ",
|
"repnz ",
|
||||||
@@ -115,7 +115,7 @@ static void get_operand_data_str( x86_op_t *op, char *str, int len ){
|
|||||||
static void get_operand_regtype_str( int regtype, char *str, int len )
|
static void get_operand_regtype_str( int regtype, char *str, int len )
|
||||||
{
|
{
|
||||||
static struct {
|
static struct {
|
||||||
char *name;
|
const char *name;
|
||||||
int value;
|
int value;
|
||||||
} operand_regtypes[] = {
|
} operand_regtypes[] = {
|
||||||
{"reg_gen" , 0x00001},
|
{"reg_gen" , 0x00001},
|
||||||
@@ -284,7 +284,7 @@ static int format_expr( x86_ea_t *ea, char *buf, int len,
|
|||||||
static int format_seg( x86_op_t *op, char *buf, int len,
|
static int format_seg( x86_op_t *op, char *buf, int len,
|
||||||
enum x86_asm_format format ) {
|
enum x86_asm_format format ) {
|
||||||
int len_orig = len;
|
int len_orig = len;
|
||||||
char *reg = "";
|
const char *reg = "";
|
||||||
|
|
||||||
if (! op || ! buf || ! len || ! op->flags.whole) {
|
if (! op || ! buf || ! len || ! op->flags.whole) {
|
||||||
return(0);
|
return(0);
|
||||||
@@ -295,8 +295,9 @@ static int format_seg( x86_op_t *op, char *buf, int len,
|
|||||||
if (! (int) op->flags.op_seg) {
|
if (! (int) op->flags.op_seg) {
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
uint16_t seg_ov=uint16_t(op->flags.op_seg)<<8;
|
||||||
switch (op->flags.op_seg) {
|
switch (seg_ov)
|
||||||
|
{
|
||||||
case x86_op_flags::op_es_seg: reg = "es"; break;
|
case x86_op_flags::op_es_seg: reg = "es"; break;
|
||||||
case x86_op_flags::op_cs_seg: reg = "cs"; break;
|
case x86_op_flags::op_cs_seg: reg = "cs"; break;
|
||||||
case x86_op_flags::op_ss_seg: reg = "ss"; break;
|
case x86_op_flags::op_ss_seg: reg = "ss"; break;
|
||||||
@@ -328,9 +329,9 @@ static int format_seg( x86_op_t *op, char *buf, int len,
|
|||||||
return( len_orig - len ); /* return length of appended string */
|
return( len_orig - len ); /* return length of appended string */
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_operand_datatype_str( x86_op_t *op ){
|
static const char *get_operand_datatype_str( x86_op_t *op ){
|
||||||
|
|
||||||
static char *types[] = {
|
static const char *types[] = {
|
||||||
"sbyte", /* 0 */
|
"sbyte", /* 0 */
|
||||||
"sword",
|
"sword",
|
||||||
"sqword",
|
"sqword",
|
||||||
@@ -405,7 +406,7 @@ static int format_insn_eflags_str( enum x86_flag_status flags, char *buf,
|
|||||||
int len) {
|
int len) {
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *name;
|
const char *name;
|
||||||
int value;
|
int value;
|
||||||
} insn_flags[] = {
|
} insn_flags[] = {
|
||||||
{ "carry_set ", 0x0001 },
|
{ "carry_set ", 0x0001 },
|
||||||
@@ -440,9 +441,9 @@ static int format_insn_eflags_str( enum x86_flag_status flags, char *buf,
|
|||||||
return( len_orig - len );
|
return( len_orig - len );
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_insn_group_str( enum x86_insn_t::x86_insn_group gp ) {
|
static const char *get_insn_group_str( enum x86_insn_t::x86_insn_group gp ) {
|
||||||
|
|
||||||
static char *types[] = {
|
static const char *types[] = {
|
||||||
"", // 0
|
"", // 0
|
||||||
"controlflow",// 1
|
"controlflow",// 1
|
||||||
"arithmetic", // 2
|
"arithmetic", // 2
|
||||||
@@ -467,10 +468,10 @@ static char *get_insn_group_str( enum x86_insn_t::x86_insn_group gp ) {
|
|||||||
return types[gp];
|
return types[gp];
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_insn_type_str( enum x86_insn_type type ) {
|
static const char *get_insn_type_str( enum x86_insn_type type ) {
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *name;
|
const char *name;
|
||||||
int value;
|
int value;
|
||||||
} types[] = {
|
} types[] = {
|
||||||
/* insn_controlflow */
|
/* insn_controlflow */
|
||||||
@@ -592,8 +593,8 @@ static char *get_insn_type_str( enum x86_insn_type type ) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_insn_cpu_str( enum x86_insn_cpu cpu ) {
|
static const char *get_insn_cpu_str( enum x86_insn_cpu cpu ) {
|
||||||
static char *intel[] = {
|
static const char *intel[] = {
|
||||||
"", // 0
|
"", // 0
|
||||||
"8086", // 1
|
"8086", // 1
|
||||||
"80286", // 2
|
"80286", // 2
|
||||||
@@ -620,8 +621,8 @@ static char *get_insn_cpu_str( enum x86_insn_cpu cpu ) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_insn_isa_str( enum x86_insn_isa isa ) {
|
static const char *get_insn_isa_str( enum x86_insn_isa isa ) {
|
||||||
static char *subset[] = {
|
static const char *subset[] = {
|
||||||
NULL, // 0
|
NULL, // 0
|
||||||
"General Purpose", // 1
|
"General Purpose", // 1
|
||||||
"Floating Point", // 2
|
"Floating Point", // 2
|
||||||
@@ -880,11 +881,11 @@ static int format_operand_xml( x86_op_t *op, x86_insn_t *insn, char *buf,
|
|||||||
return( strlen( buf ) );
|
return( strlen( buf ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int format_operand_raw( x86_op_t *op, x86_insn_t *insn, char *buf,
|
static int format_operand_raw( x86_op_t *op, x86_insn_t */*insn*/, char *buf,
|
||||||
int len){
|
int len){
|
||||||
|
|
||||||
char str[MAX_OP_RAW_STRING];
|
char str[MAX_OP_RAW_STRING];
|
||||||
char *datatype = get_operand_datatype_str(op);
|
const char *datatype = get_operand_datatype_str(op);
|
||||||
|
|
||||||
switch (op->type) {
|
switch (op->type) {
|
||||||
case op_register:
|
case op_register:
|
||||||
@@ -1042,7 +1043,7 @@ char * x86_op_t::format( enum x86_asm_format format ) {
|
|||||||
|
|
||||||
static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
|
static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
char *suffix;
|
const char *suffix;
|
||||||
|
|
||||||
if (! insn || ! buf || ! len )
|
if (! insn || ! buf || ! len )
|
||||||
return(0);
|
return(0);
|
||||||
@@ -1051,8 +1052,8 @@ static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
|
|||||||
|
|
||||||
/* do long jump/call prefix */
|
/* do long jump/call prefix */
|
||||||
if ( insn->type == insn_jmp || insn->type == insn_call ) {
|
if ( insn->type == insn_jmp || insn->type == insn_call ) {
|
||||||
if (! is_imm_jmp( insn->x86_operand_1st() ) ||
|
if (! is_imm_jmp( insn->operand_1st() ) ||
|
||||||
(insn->x86_operand_1st())->datatype != op_byte ) {
|
(insn->operand_1st())->datatype != op_byte ) {
|
||||||
/* far jump/call, use "l" prefix */
|
/* far jump/call, use "l" prefix */
|
||||||
STRNCAT( buf, "l", len );
|
STRNCAT( buf, "l", len );
|
||||||
}
|
}
|
||||||
@@ -1076,11 +1077,11 @@ static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
|
|||||||
insn->type == insn_out
|
insn->type == insn_out
|
||||||
)) {
|
)) {
|
||||||
if ( insn->x86_operand_count( op_explicit ) > 0 &&
|
if ( insn->x86_operand_count( op_explicit ) > 0 &&
|
||||||
is_memory_op( insn->x86_operand_1st() ) ){
|
is_memory_op( insn->operand_1st() ) ){
|
||||||
size = insn->x86_operand_1st()->operand_size();
|
size = insn->operand_1st()->operand_size();
|
||||||
} else if ( insn->x86_operand_count( op_explicit ) > 1 &&
|
} else if ( insn->x86_operand_count( op_explicit ) > 1 &&
|
||||||
is_memory_op( insn->x86_operand_2nd() ) ){
|
is_memory_op( insn->operand_2nd() ) ){
|
||||||
size = insn->x86_operand_2nd()->operand_size();
|
size = insn->operand_2nd()->operand_size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1094,7 +1095,6 @@ static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) {
|
|||||||
return ( strlen( buf ) );
|
return ( strlen( buf ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
|
|
||||||
int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
|
int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
|
||||||
enum x86_asm_format format){
|
enum x86_asm_format format){
|
||||||
char str[MAX_OP_STRING];
|
char str[MAX_OP_STRING];
|
||||||
@@ -1137,7 +1137,7 @@ static int format_insn_note(x86_insn_t *insn, char *buf, int len){
|
|||||||
return( len_orig - len );
|
return( len_orig - len );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int format_raw_insn( x86_insn_t *insn, char *buf, int len ){
|
static int format_raw_insn( x86_insn_t *insn, char *buf, size_t len ){
|
||||||
struct op_string opstr = { buf, len };
|
struct op_string opstr = { buf, len };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -1223,24 +1223,24 @@ static int format_xml_insn( x86_insn_t *insn, char *buf, int len ) {
|
|||||||
len -= format_insn_eflags_str( insn->flags_tested, buf, len );
|
len -= format_insn_eflags_str( insn->flags_tested, buf, len );
|
||||||
STRNCAT( buf, "\"/>\n\t</flags>\n", len );
|
STRNCAT( buf, "\"/>\n\t</flags>\n", len );
|
||||||
|
|
||||||
if ( insn->x86_operand_1st() ) {
|
if ( insn->operand_1st() ) {
|
||||||
insn->x86_operand_1st()->x86_format_operand(str,
|
insn->operand_1st()->x86_format_operand(str,
|
||||||
sizeof str, xml_syntax);
|
sizeof str, xml_syntax);
|
||||||
STRNCAT( buf, "\t<operand name=dest>\n", len );
|
STRNCAT( buf, "\t<operand name=dest>\n", len );
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
STRNCAT( buf, "\t</operand>\n", len );
|
STRNCAT( buf, "\t</operand>\n", len );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( insn->x86_operand_2nd() ) {
|
if ( insn->operand_2nd() ) {
|
||||||
insn->x86_operand_2nd()->x86_format_operand(str,sizeof str,
|
insn->operand_2nd()->x86_format_operand(str,sizeof str,
|
||||||
xml_syntax);
|
xml_syntax);
|
||||||
STRNCAT( buf, "\t<operand name=src>\n", len );
|
STRNCAT( buf, "\t<operand name=src>\n", len );
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
STRNCAT( buf, "\t</operand>\n", len );
|
STRNCAT( buf, "\t</operand>\n", len );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( insn->x86_operand_3rd() ) {
|
if ( insn->operand_3rd() ) {
|
||||||
insn->x86_operand_3rd()->x86_format_operand(str,sizeof str,
|
insn->operand_3rd()->x86_format_operand(str,sizeof str,
|
||||||
xml_syntax);
|
xml_syntax);
|
||||||
STRNCAT( buf, "\t<operand name=imm>\n", len );
|
STRNCAT( buf, "\t<operand name=imm>\n", len );
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
@@ -1342,13 +1342,13 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
|
|||||||
STRNCAT( buf, "\t", len );
|
STRNCAT( buf, "\t", len );
|
||||||
|
|
||||||
/* dest */
|
/* dest */
|
||||||
if ( (dst = x86_operand_1st()) && !(dst->flags.op_implied) ) {
|
if ( (dst = operand_1st()) && !(dst->flags.op_implied) ) {
|
||||||
dst->x86_format_operand(str, MAX_OP_STRING, format);
|
dst->x86_format_operand(str, MAX_OP_STRING, format);
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* src */
|
/* src */
|
||||||
if ( (src = x86_operand_2nd()) ) {
|
if ( (src = operand_2nd()) ) {
|
||||||
if ( !(dst->flags.op_implied) ) {
|
if ( !(dst->flags.op_implied) ) {
|
||||||
STRNCAT( buf, ", ", len );
|
STRNCAT( buf, ", ", len );
|
||||||
}
|
}
|
||||||
@@ -1357,9 +1357,9 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* imm */
|
/* imm */
|
||||||
if ( x86_operand_3rd()) {
|
if ( operand_3rd()) {
|
||||||
STRNCAT( buf, ", ", len );
|
STRNCAT( buf, ", ", len );
|
||||||
x86_operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
|
operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1373,8 +1373,8 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
|
|||||||
/* not sure which is correct? sometimes GNU as requires
|
/* not sure which is correct? sometimes GNU as requires
|
||||||
* an imm as the first operand, sometimes as the third... */
|
* an imm as the first operand, sometimes as the third... */
|
||||||
/* imm */
|
/* imm */
|
||||||
if ( x86_operand_3rd() ) {
|
if ( operand_3rd() ) {
|
||||||
x86_operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
|
operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
/* there is always 'dest' operand if there is 'src' */
|
/* there is always 'dest' operand if there is 'src' */
|
||||||
STRNCAT( buf, ", ", len );
|
STRNCAT( buf, ", ", len );
|
||||||
@@ -1382,13 +1382,13 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
|
|||||||
|
|
||||||
if ( (note & insn_note_nonswap ) == 0 ) {
|
if ( (note & insn_note_nonswap ) == 0 ) {
|
||||||
/* regular AT&T style swap */
|
/* regular AT&T style swap */
|
||||||
src = x86_operand_2nd();
|
src = operand_2nd();
|
||||||
dst = x86_operand_1st();
|
dst = operand_1st();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* special-case instructions */
|
/* special-case instructions */
|
||||||
src = x86_operand_1st();
|
src = operand_1st();
|
||||||
dst = x86_operand_2nd();
|
dst = operand_2nd();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* src */
|
/* src */
|
||||||
@@ -1431,20 +1431,20 @@ int x86_insn_t::x86_format_insn( char *buf, int len,
|
|||||||
|
|
||||||
/* print operands */
|
/* print operands */
|
||||||
/* dest */
|
/* dest */
|
||||||
if ( x86_operand_1st() ) {
|
if ( operand_1st() ) {
|
||||||
x86_operand_1st()->x86_format_operand(str, MAX_OP_STRING,format);
|
operand_1st()->x86_format_operand(str, MAX_OP_STRING,format);
|
||||||
STRNCATF( buf, "%s\t", str, len );
|
STRNCATF( buf, "%s\t", str, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* src */
|
/* src */
|
||||||
if ( x86_operand_2nd() ) {
|
if ( operand_2nd() ) {
|
||||||
x86_operand_2nd()->x86_format_operand(str, MAX_OP_STRING,format);
|
operand_2nd()->x86_format_operand(str, MAX_OP_STRING,format);
|
||||||
STRNCATF( buf, "%s\t", str, len );
|
STRNCATF( buf, "%s\t", str, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* imm */
|
/* imm */
|
||||||
if ( x86_operand_3rd()) {
|
if ( operand_3rd()) {
|
||||||
x86_operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
|
operand_3rd()->x86_format_operand(str, MAX_OP_STRING,format);
|
||||||
STRNCAT( buf, str, len );
|
STRNCAT( buf, str, len );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
3rd_party/libdisasm/x86_insn.cpp
vendored
13
3rd_party/libdisasm/x86_insn.cpp
vendored
@@ -17,7 +17,6 @@ int x86_insn_is_valid( x86_insn_t *insn ) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns false if an instruction is invalid, true if valid */
|
|
||||||
bool x86_insn_t::is_valid( )
|
bool x86_insn_t::is_valid( )
|
||||||
{
|
{
|
||||||
if ( this && this->type != insn_invalid && this->size > 0 )
|
if ( this && this->type != insn_invalid && this->size > 0 )
|
||||||
@@ -94,13 +93,12 @@ x86_op_t * x86_insn_t::x86_get_branch_target() {
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
x86_op_t * x86_insn_t::get_dest() {
|
const x86_op_t * x86_insn_t::get_dest() const {
|
||||||
x86_oplist_t *op_lst;
|
x86_oplist_t *op_lst;
|
||||||
assert(this);
|
assert(this);
|
||||||
if ( ! operands ) {
|
if ( ! operands ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
assert(this->x86_operand_count(op_dest)==1);
|
|
||||||
for (op_lst = operands; op_lst; op_lst = op_lst->next ) {
|
for (op_lst = operands; op_lst; op_lst = op_lst->next ) {
|
||||||
if ( op_lst->op.access & op_write)
|
if ( op_lst->op.access & op_write)
|
||||||
return &(op_lst->op);
|
return &(op_lst->op);
|
||||||
@@ -171,7 +169,7 @@ uint8_t *x86_insn_t::x86_get_raw_imm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t x86_op_t::operand_size() {
|
size_t x86_op_t::operand_size() const {
|
||||||
switch (datatype ) {
|
switch (datatype ) {
|
||||||
case op_byte: return 1;
|
case op_byte: return 1;
|
||||||
case op_word: return 2;
|
case op_word: return 2;
|
||||||
@@ -203,13 +201,12 @@ size_t x86_op_t::operand_size() {
|
|||||||
return(4); /* default size */
|
return(4); /* default size */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** set the address (usually RVA) of the insn */
|
|
||||||
void x86_insn_t::x86_set_insn_addr( uint32_t _addr ) {
|
void x86_insn_t::x86_set_insn_addr( uint32_t _addr ) {
|
||||||
addr = _addr;
|
addr = _addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void x86_insn_t::x86_set_insn_offset( unsigned int offset ){
|
void x86_insn_t::x86_set_insn_offset( unsigned int _offset ){
|
||||||
offset = offset;
|
offset = _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void x86_insn_t::x86_set_insn_function( void * func ){
|
void x86_insn_t::x86_set_insn_function( void * func ){
|
||||||
@@ -220,7 +217,6 @@ void x86_insn_t::x86_set_insn_block( void * _block ){
|
|||||||
block = _block;
|
block = _block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** set insn->tag to 1 */
|
|
||||||
void x86_insn_t::x86_tag_insn(){
|
void x86_insn_t::x86_tag_insn(){
|
||||||
tag = 1;
|
tag = 1;
|
||||||
}
|
}
|
||||||
@@ -229,7 +225,6 @@ void x86_insn_t::x86_untag_insn(){
|
|||||||
tag = 0;
|
tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \return insn->tag */
|
|
||||||
int x86_insn_t::x86_insn_is_tagged(){
|
int x86_insn_t::x86_insn_is_tagged(){
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|||||||
9
3rd_party/libdisasm/x86_operand_list.cpp
vendored
9
3rd_party/libdisasm/x86_operand_list.cpp
vendored
@@ -164,12 +164,11 @@ int x86_insn_t::x86_operand_foreach( x86_operand_fn func, void *arg, enum x86_op
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void count_operand( x86_op_t *op, x86_insn_t *insn, void *arg ) {
|
static void count_operand( x86_op_t */*op*/, x86_insn_t */*insn*/, void *arg ) {
|
||||||
size_t * count = (size_t *) arg;
|
size_t * count = (size_t *) arg;
|
||||||
*count = *count + 1;
|
*count = *count + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** convenience routine: returns count of operands matching 'type' */
|
|
||||||
size_t x86_insn_t::x86_operand_count( enum x86_op_foreach_type type ) {
|
size_t x86_insn_t::x86_operand_count( enum x86_op_foreach_type type ) {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
@@ -185,7 +184,7 @@ size_t x86_insn_t::x86_operand_count( enum x86_op_foreach_type type ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* accessor functions */
|
/* accessor functions */
|
||||||
x86_op_t * x86_insn_t::x86_operand_1st() {
|
x86_op_t * x86_insn_t::operand_1st() {
|
||||||
if (! explicit_count ) {
|
if (! explicit_count ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -193,7 +192,7 @@ x86_op_t * x86_insn_t::x86_operand_1st() {
|
|||||||
return &(operands->op);
|
return &(operands->op);
|
||||||
}
|
}
|
||||||
|
|
||||||
x86_op_t * x86_insn_t::x86_operand_2nd( ) {
|
x86_op_t * x86_insn_t::operand_2nd( ) {
|
||||||
if ( explicit_count < 2 ) {
|
if ( explicit_count < 2 ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -201,7 +200,7 @@ x86_op_t * x86_insn_t::x86_operand_2nd( ) {
|
|||||||
return &(operands->next->op);
|
return &(operands->next->op);
|
||||||
}
|
}
|
||||||
|
|
||||||
x86_op_t * x86_insn_t::x86_operand_3rd( ) {
|
x86_op_t * x86_insn_t::operand_3rd( ) {
|
||||||
if ( explicit_count < 3 ) {
|
if ( explicit_count < 3 ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,27 +2,30 @@ PROJECT(dcc_original)
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
||||||
|
#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS)
|
||||||
IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
ADD_DEFINITIONS(/W4)
|
ADD_DEFINITIONS(/W4)
|
||||||
ELSE()
|
ELSE()
|
||||||
|
#-D_GLIBCXX_DEBUG
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG " ) #--coverage
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} " ) #--coverage
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
|
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
|
||||||
|
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
|
||||||
|
include(cotire)
|
||||||
FIND_PACKAGE(LLVM)
|
FIND_PACKAGE(LLVM)
|
||||||
FIND_PACKAGE(Boost)
|
FIND_PACKAGE(Boost)
|
||||||
IF(dcc_build_tests)
|
IF(dcc_build_tests)
|
||||||
|
enable_testing()
|
||||||
FIND_PACKAGE(GMock)
|
FIND_PACKAGE(GMock)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(3rd_party)
|
ADD_SUBDIRECTORY(3rd_party)
|
||||||
|
|
||||||
llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support)
|
llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native mc support tablegen)
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
3rd_party/libdisasm
|
3rd_party/libdisasm
|
||||||
include
|
include
|
||||||
@@ -30,9 +33,7 @@ INCLUDE_DIRECTORIES(
|
|||||||
${Boost_INCLUDE_DIRS}
|
${Boost_INCLUDE_DIRS}
|
||||||
${LLVM_INCLUDE_DIRS}
|
${LLVM_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
set(dcc_LIB_SOURCES
|
||||||
set(dcc_SOURCES
|
|
||||||
src/dcc.cpp
|
|
||||||
src/ast.cpp
|
src/ast.cpp
|
||||||
src/backend.cpp
|
src/backend.cpp
|
||||||
src/bundle.cpp
|
src/bundle.cpp
|
||||||
@@ -46,8 +47,10 @@ set(dcc_SOURCES
|
|||||||
src/frontend.cpp
|
src/frontend.cpp
|
||||||
src/graph.cpp
|
src/graph.cpp
|
||||||
src/hlicode.cpp
|
src/hlicode.cpp
|
||||||
|
src/hltype.cpp
|
||||||
src/machine_x86.cpp
|
src/machine_x86.cpp
|
||||||
src/icode.cpp
|
src/icode.cpp
|
||||||
|
src/RegisterNode
|
||||||
src/idioms.cpp
|
src/idioms.cpp
|
||||||
src/idioms/idiom1.cpp
|
src/idioms/idiom1.cpp
|
||||||
src/idioms/arith_idioms.cpp
|
src/idioms/arith_idioms.cpp
|
||||||
@@ -58,6 +61,7 @@ set(dcc_SOURCES
|
|||||||
src/idioms/shift_idioms.cpp
|
src/idioms/shift_idioms.cpp
|
||||||
src/idioms/xor_idioms.cpp
|
src/idioms/xor_idioms.cpp
|
||||||
src/locident.cpp
|
src/locident.cpp
|
||||||
|
src/liveness_set.cpp
|
||||||
src/parser.cpp
|
src/parser.cpp
|
||||||
src/perfhlib.cpp
|
src/perfhlib.cpp
|
||||||
src/procs.cpp
|
src/procs.cpp
|
||||||
@@ -69,6 +73,10 @@ set(dcc_SOURCES
|
|||||||
src/symtab.cpp
|
src/symtab.cpp
|
||||||
src/udm.cpp
|
src/udm.cpp
|
||||||
src/BasicBlock.cpp
|
src/BasicBlock.cpp
|
||||||
|
src/CallConvention.cpp
|
||||||
|
)
|
||||||
|
set(dcc_SOURCES
|
||||||
|
src/dcc.cpp
|
||||||
)
|
)
|
||||||
set(dcc_HEADERS
|
set(dcc_HEADERS
|
||||||
include/ast.h
|
include/ast.h
|
||||||
@@ -101,12 +109,18 @@ set(dcc_HEADERS
|
|||||||
include/Procedure.h
|
include/Procedure.h
|
||||||
include/StackFrame.h
|
include/StackFrame.h
|
||||||
include/BasicBlock.h
|
include/BasicBlock.h
|
||||||
|
include/CallConvention.h
|
||||||
|
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
||||||
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
||||||
|
|
||||||
|
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
||||||
|
#cotire(dcc_lib)
|
||||||
|
|
||||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
||||||
TARGET_LINK_LIBRARIES(dcc_original disasm_s ${REQ_LLVM_LIBRARIES})
|
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
||||||
|
TARGET_LINK_LIBRARIES(dcc_original LLVMSupport dcc_lib disasm_s ${REQ_LLVM_LIBRARIES} LLVMSupport)
|
||||||
if(dcc_build_tests)
|
if(dcc_build_tests)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
2762
CMakeScripts/cotire.cmake
Normal file
2762
CMakeScripts/cotire.cmake
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd bld
|
#cd bld
|
||||||
make -j5
|
#make -j5
|
||||||
cd ..
|
#cd ..
|
||||||
./test_use_base.sh
|
./test_use_base.sh
|
||||||
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
./test_use_all.sh
|
./test_use_all.sh
|
||||||
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff -wB tests/prev/ tests/outputs/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
#include <llvm/ADT/ilist_node.h>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
@@ -16,24 +16,28 @@ class CIcodeRec;
|
|||||||
struct BB;
|
struct BB;
|
||||||
struct LOCAL_ID;
|
struct LOCAL_ID;
|
||||||
struct interval;
|
struct interval;
|
||||||
|
//TODO: consider default address value -> INVALID
|
||||||
struct TYPEADR_TYPE
|
struct TYPEADR_TYPE
|
||||||
{
|
{
|
||||||
uint32_t ip; /* Out edge icode address */
|
uint32_t ip; /* Out edge icode address */
|
||||||
BB * BBptr; /* Out edge pointer to next BB */
|
BB * BBptr; /* Out edge pointer to next BB */
|
||||||
interval *intPtr; /* Out edge ptr to next interval*/
|
interval *intPtr; /* Out edge ptr to next interval*/
|
||||||
|
TYPEADR_TYPE(uint32_t addr=0) : ip(addr),BBptr(nullptr),intPtr(nullptr)
|
||||||
|
{}
|
||||||
|
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BB : public llvm::ilist_node<BB>
|
struct BB : public llvm::ilist_node<BB>
|
||||||
{
|
{
|
||||||
|
friend struct Function;
|
||||||
private:
|
private:
|
||||||
BB(const BB&);
|
BB(const BB&);
|
||||||
BB() : nodeType(0),traversed(DFS_NONE),
|
BB() : nodeType(0),traversed(DFS_NONE),
|
||||||
numHlIcodes(0),flg(0),
|
numHlIcodes(0),flg(0),
|
||||||
inEdges(0),
|
inEdges(0),
|
||||||
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
||||||
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0),
|
inInterval(0),correspInt(0),
|
||||||
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
|
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(NO_TYPE),latchNode(0),
|
||||||
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
|
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -41,6 +45,7 @@ private:
|
|||||||
//friend class SymbolTableListTraits<BB, Function>;
|
//friend class SymbolTableListTraits<BB, Function>;
|
||||||
typedef boost::iterator_range<iICODE> rCODE;
|
typedef boost::iterator_range<iICODE> rCODE;
|
||||||
rCODE instructions;
|
rCODE instructions;
|
||||||
|
rCODE &my_range() {return instructions;}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct ValidFunctor
|
struct ValidFunctor
|
||||||
@@ -72,36 +77,31 @@ public:
|
|||||||
interval *inInterval; /* Node's interval */
|
interval *inInterval; /* Node's interval */
|
||||||
|
|
||||||
/* For derived sequence construction */
|
/* For derived sequence construction */
|
||||||
interval *correspInt; /* Corresponding interval in
|
interval *correspInt; //!< Corresponding interval in derived graph Gi-1
|
||||||
* derived graph Gi-1 */
|
// For live register analysis
|
||||||
|
// LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))
|
||||||
/* For live register analysis
|
LivenessSet liveUse; /* LiveUse(b) */
|
||||||
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */
|
LivenessSet def; /* Def(b) */
|
||||||
std::bitset<32> liveUse; /* LiveUse(b) */
|
LivenessSet liveIn; /* LiveIn(b) */
|
||||||
std::bitset<32> def; /* Def(b) */
|
LivenessSet liveOut; /* LiveOut(b) */
|
||||||
std::bitset<32> liveIn; /* LiveIn(b) */
|
|
||||||
std::bitset<32> liveOut; /* LiveOut(b) */
|
|
||||||
|
|
||||||
/* For structuring analysis */
|
/* For structuring analysis */
|
||||||
int dfsFirstNum; /* DFS #: first visit of node */
|
int dfsFirstNum; /* DFS #: first visit of node */
|
||||||
int dfsLastNum; /* DFS #: last visit of node */
|
int dfsLastNum; /* DFS #: last visit of node */
|
||||||
int immedDom; /* Immediate dominator (dfsLast
|
int immedDom; /* Immediate dominator (dfsLast index) */
|
||||||
* index) */
|
|
||||||
int ifFollow; /* node that ends the if */
|
int ifFollow; /* node that ends the if */
|
||||||
int loopType; /* Type of loop (if any) */
|
eNodeHeaderType loopType; /* Type of loop (if any) */
|
||||||
int latchNode; /* latching node of the loop */
|
int latchNode; /* latching node of the loop */
|
||||||
int numBackEdges; /* # of back edges */
|
size_t numBackEdges; /* # of back edges */
|
||||||
int loopHead; /* most nested loop head to which
|
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
|
||||||
* thcis node belongs (dfsLast) */
|
|
||||||
int loopFollow; /* node that follows the loop */
|
int loopFollow; /* node that follows the loop */
|
||||||
int caseHead; /* most nested case to which this
|
int caseHead; /* most nested case to which this node belongs (dfsLast) */
|
||||||
node belongs (dfsLast) */
|
|
||||||
int caseTail; /* tail node for the case */
|
int caseTail; /* tail node for the case */
|
||||||
|
|
||||||
int index; /* Index, used in several ways */
|
int index; /* Index, used in several ways */
|
||||||
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
||||||
static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent);
|
static BB * CreateIntervalBB(Function *parent);
|
||||||
static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent);
|
static BB * Create(const rCODE &r, eBBKind _nodeType, Function *parent);
|
||||||
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
|
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
|
||||||
void mergeFallThrough(CIcodeRec &Icode);
|
void mergeFallThrough(CIcodeRec &Icode);
|
||||||
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
|
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
|
||||||
@@ -114,18 +114,23 @@ public:
|
|||||||
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
|
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
|
||||||
BB * rmJMP(int marker, BB *pBB);
|
BB * rmJMP(int marker, BB *pBB);
|
||||||
void genDU1();
|
void genDU1();
|
||||||
int findBBExps(LOCAL_ID &locals, Function *f);
|
void findBBExps(LOCAL_ID &locals, Function *f);
|
||||||
bool valid() {return 0==(flg & INVALID_BB); }
|
bool valid() {return 0==(flg & INVALID_BB); }
|
||||||
bool wasTraversedAtLevel(int l) const {return traversed==l;}
|
bool wasTraversedAtLevel(int l) const {return traversed==l;}
|
||||||
ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond);
|
ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, bool &repCond);
|
||||||
void addOutEdge(uint32_t ip) // TODO: fix this
|
void addOutEdge(uint32_t ip) // TODO: fix this
|
||||||
{
|
{
|
||||||
edges[0].ip = ip;
|
edges.push_back(TYPEADR_TYPE(ip));
|
||||||
}
|
}
|
||||||
|
void addOutEdgeInterval(interval *i) // TODO: fix this
|
||||||
|
{
|
||||||
|
edges.push_back(TYPEADR_TYPE(i));
|
||||||
|
}
|
||||||
|
|
||||||
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
|
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
|
||||||
private:
|
private:
|
||||||
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
|
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
|
||||||
void ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode);
|
void ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode);
|
||||||
bool isEndOfPath(int latch_node_idx) const;
|
bool isEndOfPath(int latch_node_idx) const;
|
||||||
Function *Parent;
|
Function *Parent;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ struct PROG /* Loaded program image parameters */
|
|||||||
uint16_t segMain; /* The segment of the main() proc */
|
uint16_t segMain; /* The segment of the main() proc */
|
||||||
bool bSigs; /* True if signatures loaded */
|
bool bSigs; /* True if signatures loaded */
|
||||||
int cbImage; /* Length of image in bytes */
|
int cbImage; /* Length of image in bytes */
|
||||||
uint8_t * Image; /* Allocated by loader to hold entire program image */
|
const uint8_t *image() const {return Imagez;}
|
||||||
|
uint8_t * Imagez; /* Allocated by loader to hold entire program image */
|
||||||
|
int addressingMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
31
include/CallConvention.h
Normal file
31
include/CallConvention.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ast.h"
|
||||||
|
|
||||||
|
struct CConv {
|
||||||
|
enum Type {
|
||||||
|
UNKNOWN=0,
|
||||||
|
C,
|
||||||
|
PASCAL
|
||||||
|
};
|
||||||
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode)=0;
|
||||||
|
virtual void writeComments(std::ostream &)=0;
|
||||||
|
static CConv * create(Type v);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct C_CallingConvention : public CConv {
|
||||||
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
|
virtual void writeComments(std::ostream &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int processCArg(Function *callee, Function *pProc, ICODE *picode, size_t numArgs);
|
||||||
|
};
|
||||||
|
struct Pascal_CallingConvention : public CConv {
|
||||||
|
virtual void processHLI(Function *func, Expr *_exp, iICODE picode);
|
||||||
|
virtual void writeComments(std::ostream &);
|
||||||
|
};
|
||||||
|
struct Unknown_CallingConvention : public CConv {
|
||||||
|
void processHLI(Function *func, Expr *_exp, iICODE picode) {}
|
||||||
|
virtual void writeComments(std::ostream &);
|
||||||
|
};
|
||||||
@@ -8,6 +8,7 @@ enum regType
|
|||||||
};
|
};
|
||||||
enum condId
|
enum condId
|
||||||
{
|
{
|
||||||
|
UNDEF=0,
|
||||||
GLOB_VAR, /* global variable */
|
GLOB_VAR, /* global variable */
|
||||||
REGISTER, /* register */
|
REGISTER, /* register */
|
||||||
LOCAL_VAR, /* negative disp */
|
LOCAL_VAR, /* negative disp */
|
||||||
@@ -57,33 +58,33 @@ enum opLoc
|
|||||||
enum eLLFlags
|
enum eLLFlags
|
||||||
{
|
{
|
||||||
|
|
||||||
B =0x0000001, /* uint8_t operands (value implicitly used) */
|
B = 0x0000001, /* uint8_t operands (value implicitly used) */
|
||||||
I =0x0000002, /* Immed. source */
|
I = 0x0000002, /* Immed. source */
|
||||||
NOT_HLL =0x0000004, /* Not HLL inst. */
|
NOT_HLL = 0x0000004, /* Not HLL inst. */
|
||||||
FLOAT_OP =0x0000008, /* ESC or WAIT */
|
FLOAT_OP = 0x0000008, /* ESC or WAIT */
|
||||||
SEG_IMMED =0x0000010, /* Number is relocated segment value */
|
SEG_IMMED = 0x0000010, /* Number is relocated segment value */
|
||||||
IMPURE =0x0000020, /* Instruction modifies code */
|
IMPURE = 0x0000020, /* Instruction modifies code */
|
||||||
WORD_OFF =0x0000040, /* Inst has uint16_t offset ie.could be address */
|
WORD_OFF = 0x0000040, /* Inst has uint16_t offset ie.could be address */
|
||||||
TERMINATES =0x0000080, /* Instruction terminates program */
|
TERMINATES = 0x0000080, /* Instruction terminates program */
|
||||||
CASE =0x0000100, /* Label as case part of switch */
|
CASE = 0x0000100, /* Label as case part of switch */
|
||||||
SWITCH =0x0000200, /* Treat indirect JMP as switch stmt */
|
SWITCH = 0x0000200, /* Treat indirect JMP as switch stmt */
|
||||||
TARGET =0x0000400, /* Jump target */
|
TARGET = 0x0000400, /* Jump target */
|
||||||
SYNTHETIC =0x0000800, /* Synthetic jump instruction */
|
SYNTHETIC = 0x0000800, /* Synthetic jump instruction */
|
||||||
NO_LABEL =0x0001000, /* Immed. jump cannot be linked to a label */
|
NO_LABEL = 0x0001000, /* Immed. jump cannot be linked to a label */
|
||||||
NO_CODE =0x0002000, /* Hole in Icode array */
|
NO_CODE = 0x0002000, /* Hole in Icode array */
|
||||||
SYM_USE =0x0004000, /* Instruction uses a symbol */
|
SYM_USE = 0x0004000, /* Instruction uses a symbol */
|
||||||
SYM_DEF =0x0008000, /* Instruction defines a symbol */
|
SYM_DEF = 0x0008000, /* Instruction defines a symbol */
|
||||||
NO_SRC =0x0010000, /* Opcode takes no source */
|
NO_SRC = 0x0010000, /* Opcode takes no source */
|
||||||
NO_OPS =0x0020000, /* Opcode takes no operands */
|
NO_OPS = 0x0020000, /* Opcode takes no operands */
|
||||||
IM_OPS =0x0040000, /* Opcode takes implicit operands */
|
IM_OPS = 0x0040000, /* Opcode takes implicit operands */
|
||||||
SRC_B =0x0080000, /* Source operand is uint8_t (dest is uint16_t) */
|
SRC_B = 0x0080000, /* Source operand is uint8_t (dest is uint16_t) */
|
||||||
HLL_LABEL =0x0100000, /* Icode has a high level language label */
|
HLL_LABEL = 0x0100000, /* Icode has a high level language label */
|
||||||
IM_DST =0x0200000, /* Implicit DST for opcode (SIGNEX) */
|
IM_DST = 0x0200000, /* Implicit DST for opcode (SIGNEX) */
|
||||||
IM_SRC =0x0400000, /* Implicit SRC for opcode (dx:ax) */
|
IM_SRC = 0x0400000, /* Implicit SRC for opcode (dx:ax) */
|
||||||
IM_TMP_DST =0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */
|
IM_TMP_DST = 0x0800000, /* Implicit rTMP DST for opcode (DIV/IDIV) */
|
||||||
JMP_ICODE =0x1000000, /* Jmp dest immed.op converted to icode index */
|
JMP_ICODE = 0x1000000, /* Jmp dest immed.op converted to icode index */
|
||||||
JX_LOOP =0x2000000, /* Cond jump is part of loop conditional exp */
|
JX_LOOP = 0x2000000, /* Cond jump is part of loop conditional exp */
|
||||||
REST_STK =0x4000000 /* Stack needs to be restored after CALL */
|
REST_STK = 0x4000000 /* Stack needs to be restored after CALL */
|
||||||
#define ICODEMASK 0x0FF00FF /* Masks off parser flags */
|
#define ICODEMASK 0x0FF00FF /* Masks off parser flags */
|
||||||
};
|
};
|
||||||
/* Types of icodes */
|
/* Types of icodes */
|
||||||
@@ -176,7 +177,7 @@ enum llIcode
|
|||||||
iPOP,
|
iPOP,
|
||||||
iPOPA,
|
iPOPA,
|
||||||
iPOPF,
|
iPOPF,
|
||||||
iPUSH,
|
iPUSH, // 77
|
||||||
iPUSHA,
|
iPUSHA,
|
||||||
iPUSHF,
|
iPUSHF,
|
||||||
iRCL, /* 80 */
|
iRCL, /* 80 */
|
||||||
@@ -216,6 +217,7 @@ enum condNodeType
|
|||||||
{
|
{
|
||||||
UNKNOWN_OP=0,
|
UNKNOWN_OP=0,
|
||||||
BOOLEAN_OP, /* condOps */
|
BOOLEAN_OP, /* condOps */
|
||||||
|
|
||||||
NEGATION, /* not (2's complement) */
|
NEGATION, /* not (2's complement) */
|
||||||
ADDRESSOF, /* addressOf (&) */
|
ADDRESSOF, /* addressOf (&) */
|
||||||
DEREFERENCE, /* contents of (*) */
|
DEREFERENCE, /* contents of (*) */
|
||||||
@@ -237,7 +239,7 @@ enum hlFirst
|
|||||||
/* HIGH_LEVEL icodes opcodes */
|
/* HIGH_LEVEL icodes opcodes */
|
||||||
enum hlIcode
|
enum hlIcode
|
||||||
{
|
{
|
||||||
HLI_INVALID,
|
HLI_INVALID=0,
|
||||||
HLI_ASSIGN, /* := */
|
HLI_ASSIGN, /* := */
|
||||||
HLI_CALL, /* Call procedure */
|
HLI_CALL, /* Call procedure */
|
||||||
HLI_JCOND, /* Conditional jump */
|
HLI_JCOND, /* Conditional jump */
|
||||||
|
|||||||
@@ -2,32 +2,29 @@
|
|||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "machine_x86.h"
|
#include "machine_x86.h"
|
||||||
|
struct GlobalVariable;
|
||||||
|
struct AstIdent;
|
||||||
struct IDENTTYPE
|
struct IDENTTYPE
|
||||||
{
|
{
|
||||||
|
friend struct GlobalVariable;
|
||||||
|
friend struct Constant;
|
||||||
|
friend struct AstIdent;
|
||||||
|
protected:
|
||||||
condId idType;
|
condId idType;
|
||||||
regType regiType; /* for REGISTER only */
|
public:
|
||||||
|
condId type() {return idType;}
|
||||||
|
void type(condId t) {idType=t;}
|
||||||
union _idNode {
|
union _idNode {
|
||||||
int regiIdx; /* index into localId, REGISTER */
|
|
||||||
int globIdx; /* index into symtab for GLOB_VAR */
|
|
||||||
int localIdx; /* idx into localId, LOCAL_VAR */
|
int localIdx; /* idx into localId, LOCAL_VAR */
|
||||||
int paramIdx; /* idx into args symtab, PARAMS */
|
int paramIdx; /* idx into args symtab, PARAMS */
|
||||||
int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
|
|
||||||
struct _kte
|
|
||||||
{ /* for CONSTANT only */
|
|
||||||
uint32_t kte; /* value of the constant */
|
|
||||||
uint8_t size; /* #bytes size constant */
|
|
||||||
} kte;
|
|
||||||
uint32_t strIdx; /* idx into image, for STRING */
|
uint32_t strIdx; /* idx into image, for STRING */
|
||||||
int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/
|
int longIdx; /* idx into LOCAL_ID table, LONG_VAR*/
|
||||||
struct _call { /* for FUNCTION only */
|
|
||||||
Function *proc;
|
|
||||||
STKFRAME *args;
|
|
||||||
} call;
|
|
||||||
struct { /* for OTHER; tmp struct */
|
struct { /* for OTHER; tmp struct */
|
||||||
eReg seg; /* segment */
|
eReg seg; /* segment */
|
||||||
eReg regi; /* index mode */
|
eReg regi; /* index mode */
|
||||||
int16_t off; /* offset */
|
int16_t off; /* offset */
|
||||||
} other;
|
} other;
|
||||||
} idNode;
|
} idNode;
|
||||||
|
IDENTTYPE() : idType(UNDEF)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
//#include <llvm/ADT/ilist_node.h>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <map>
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
#include "locident.h"
|
#include "locident.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "StackFrame.h"
|
#include "StackFrame.h"
|
||||||
|
#include "CallConvention.h"
|
||||||
/* PROCEDURE NODE */
|
/* PROCEDURE NODE */
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
struct COND_EXPR;
|
struct Expr;
|
||||||
struct Disassembler;
|
struct Disassembler;
|
||||||
struct Function;
|
struct Function;
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
|
struct PROG;
|
||||||
|
|
||||||
typedef llvm::iplist<Function> FunctionListType;
|
struct Function;
|
||||||
typedef FunctionListType lFunction;
|
|
||||||
typedef lFunction::iterator ilFunction;
|
|
||||||
|
|
||||||
namespace llvm
|
namespace llvm
|
||||||
{
|
{
|
||||||
@@ -48,9 +49,9 @@ enum PROC_FLAGS
|
|||||||
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
|
PROC_IJMP =0x00000200,/* Proc incomplete due to indirect jmp */
|
||||||
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
|
PROC_ICALL =0x00000400, /* Proc incomplete due to indirect call */
|
||||||
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
|
PROC_HLL =0x00001000, /* Proc is likely to be from a HLL */
|
||||||
CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
|
// CALL_PASCAL =0x00002000, /* Proc uses Pascal calling convention */
|
||||||
CALL_C =0x00004000, /* Proc uses C calling convention */
|
// CALL_C =0x00004000, /* Proc uses C calling convention */
|
||||||
CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
|
// CALL_UNKNOWN=0x00008000, /* Proc uses unknown calling convention */
|
||||||
PROC_NEAR =0x00010000, /* Proc exits with near return */
|
PROC_NEAR =0x00010000, /* Proc exits with near return */
|
||||||
PROC_FAR =0x00020000, /* Proc exits with far return */
|
PROC_FAR =0x00020000, /* Proc exits with far return */
|
||||||
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
|
GRAPH_IRRED =0x00100000, /* Proc generates an irreducible graph */
|
||||||
@@ -58,24 +59,24 @@ enum PROC_FLAGS
|
|||||||
DI_REGVAR =0x00400000, /* DI is used as a stack variable */
|
DI_REGVAR =0x00400000, /* DI is used as a stack variable */
|
||||||
PROC_IS_FUNC=0x00800000, /* Proc is a function */
|
PROC_IS_FUNC=0x00800000, /* Proc is a function */
|
||||||
REG_ARGS =0x01000000, /* Proc has registers as arguments */
|
REG_ARGS =0x01000000, /* Proc has registers as arguments */
|
||||||
PROC_VARARG =0x02000000, /* Proc has variable arguments */
|
// PROC_VARARG =0x02000000, /* Proc has variable arguments */
|
||||||
PROC_OUTPUT =0x04000000, /* C for this proc has been output */
|
PROC_OUTPUT =0x04000000, /* C for this proc has been output */
|
||||||
PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */
|
PROC_RUNTIME=0x08000000, /* Proc is part of the runtime support */
|
||||||
PROC_ISLIB =0x10000000, /* Proc is a library function */
|
PROC_ISLIB =0x10000000, /* Proc is a library function */
|
||||||
PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */
|
PROC_ASM =0x20000000, /* Proc is an intrinsic assembler routine */
|
||||||
PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */
|
PROC_IS_HLL =0x40000000 /* Proc has HLL prolog code */
|
||||||
#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
|
//#define CALL_MASK 0xFFFF9FFF /* Masks off CALL_C and CALL_PASCAL */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionType
|
struct FunctionType
|
||||||
{
|
{
|
||||||
bool m_vararg;
|
bool m_vararg=false;
|
||||||
bool isVarArg() const {return m_vararg;}
|
bool isVarArg() const {return m_vararg;}
|
||||||
};
|
};
|
||||||
struct Assignment
|
struct Assignment
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs;
|
Expr *lhs;
|
||||||
COND_EXPR *rhs;
|
Expr *rhs;
|
||||||
};
|
};
|
||||||
struct JumpTable
|
struct JumpTable
|
||||||
{
|
{
|
||||||
@@ -86,17 +87,44 @@ struct JumpTable
|
|||||||
size_t entrySize() { return 2;}
|
size_t entrySize() { return 2;}
|
||||||
void pruneEntries(uint16_t cs);
|
void pruneEntries(uint16_t cs);
|
||||||
};
|
};
|
||||||
|
class FunctionCfg
|
||||||
|
{
|
||||||
|
std::list<BB*> m_listBB; /* Ptr. to BB list/CFG */
|
||||||
|
public:
|
||||||
|
typedef std::list<BB*>::iterator iterator;
|
||||||
|
iterator begin() {
|
||||||
|
return m_listBB.begin();
|
||||||
|
}
|
||||||
|
iterator end() {
|
||||||
|
return m_listBB.end();
|
||||||
|
}
|
||||||
|
BB * &front() { return m_listBB.front();}
|
||||||
|
void nodeSplitting()
|
||||||
|
{
|
||||||
|
/* Converts the irreducible graph G into an equivalent reducible one, by
|
||||||
|
* means of node splitting. */
|
||||||
|
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
|
||||||
|
}
|
||||||
|
void push_back(BB *v) { m_listBB.push_back(v);}
|
||||||
|
};
|
||||||
struct Function : public llvm::ilist_node<Function>
|
struct Function : public llvm::ilist_node<Function>
|
||||||
{
|
{
|
||||||
typedef llvm::iplist<BB> BasicBlockListType;
|
typedef llvm::iplist<BB> BasicBlockListType;
|
||||||
// BasicBlock iterators...
|
// BasicBlock iterators...
|
||||||
typedef BasicBlockListType::iterator iterator;
|
typedef BasicBlockListType::iterator iterator;
|
||||||
typedef BasicBlockListType::const_iterator const_iterator;
|
typedef BasicBlockListType::const_iterator const_iterator;
|
||||||
private:
|
protected:
|
||||||
BasicBlockListType BasicBlocks; ///< The basic blocks
|
BasicBlockListType BasicBlocks; ///< The basic blocks
|
||||||
|
Function(FunctionType */*ty*/) : procEntry(0),depth(0),flg(0),cbParam(0),m_dfsLast(0),numBBs(0),
|
||||||
|
hasCase(false),liveAnal(0)
|
||||||
|
{
|
||||||
|
type = new FunctionType;
|
||||||
|
callingConv(CConv::UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
FunctionType * type;
|
||||||
|
CConv * m_call_conv;
|
||||||
uint32_t procEntry; /* label number */
|
uint32_t procEntry; /* label number */
|
||||||
std::string name; /* Meaningful name for this proc */
|
std::string name; /* Meaningful name for this proc */
|
||||||
STATE state; /* Entry state */
|
STATE state; /* Entry state */
|
||||||
@@ -109,38 +137,42 @@ public:
|
|||||||
|
|
||||||
/* Icodes and control flow graph */
|
/* Icodes and control flow graph */
|
||||||
CIcodeRec Icode; /* Object with ICODE records */
|
CIcodeRec Icode; /* Object with ICODE records */
|
||||||
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */
|
FunctionCfg m_actual_cfg;
|
||||||
std::vector<BB*> m_dfsLast;
|
std::vector<BB*> m_dfsLast;
|
||||||
std::list<BB*> heldBBs;
|
std::map<int,BB*> m_ip_to_bb;
|
||||||
//BB * *dfsLast; /* Array of pointers to BBs in dfsLast
|
|
||||||
// * (reverse postorder) order */
|
// * (reverse postorder) order */
|
||||||
size_t numBBs; /* Number of BBs in the graph cfg */
|
size_t numBBs; /* Number of BBs in the graph cfg */
|
||||||
bool hasCase; /* Procedure has a case node */
|
bool hasCase; /* Procedure has a case node */
|
||||||
|
|
||||||
/* For interprocedural live analysis */
|
/* For interprocedural live analysis */
|
||||||
std::bitset<32> liveIn; /* Registers used before defined */
|
LivenessSet liveIn; /* Registers used before defined */
|
||||||
std::bitset<32> liveOut; /* Registers that may be used in successors */
|
LivenessSet liveOut; /* Registers that may be used in successors */
|
||||||
bool liveAnal; /* Procedure has been analysed already */
|
bool liveAnal; /* Procedure has been analysed already */
|
||||||
|
|
||||||
Function(void *ty=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
|
virtual ~Function() {
|
||||||
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
|
delete type;
|
||||||
{
|
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static Function *Create(void *ty=0,int Linkage=0,const std::string &nm="",void *module=0)
|
static Function *Create(FunctionType *ty=0,int /*Linkage*/=0,const std::string &nm="",void */*module*/=0)
|
||||||
{
|
{
|
||||||
Function *r=new Function(ty);
|
Function *r=new Function(ty);
|
||||||
r->name = nm;
|
r->name = nm;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
|
FunctionType *getFunctionType() const {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
CConv *callingConv() const { return m_call_conv;}
|
||||||
|
void callingConv(CConv::Type v);
|
||||||
|
|
||||||
|
// bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
|
||||||
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
|
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
|
||||||
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
|
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
|
||||||
void compoundCond();
|
void compoundCond();
|
||||||
void writeProcComments();
|
void writeProcComments();
|
||||||
void lowLevelAnalysis();
|
void lowLevelAnalysis();
|
||||||
void bindIcodeOff();
|
void bindIcodeOff();
|
||||||
void dataFlow(std::bitset<32> &liveOut);
|
void dataFlow(LivenessSet &liveOut);
|
||||||
void compressCFG();
|
void compressCFG();
|
||||||
void highLevelGen();
|
void highLevelGen();
|
||||||
void structure(derSeq *derivedG);
|
void structure(derSeq *derivedG);
|
||||||
@@ -151,7 +183,7 @@ public:
|
|||||||
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
|
void FollowCtrl(CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void process_operands(ICODE &pIcode, STATE *pstate);
|
void process_operands(ICODE &pIcode, STATE *pstate);
|
||||||
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
bool process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void freeCFG();
|
void freeCFG();
|
||||||
void codeGen(std::ostream &fs);
|
void codeGen(std::ostream &fs);
|
||||||
void mergeFallThrough(BB *pBB);
|
void mergeFallThrough(BB *pBB);
|
||||||
@@ -164,9 +196,14 @@ public:
|
|||||||
|
|
||||||
void displayCFG();
|
void displayCFG();
|
||||||
void displayStats();
|
void displayStats();
|
||||||
void processHliCall(COND_EXPR *exp, iICODE picode);
|
void processHliCall(Expr *exp, iICODE picode);
|
||||||
|
|
||||||
void preprocessReturnDU(std::bitset<32> &_liveOut);
|
void preprocessReturnDU(LivenessSet &_liveOut);
|
||||||
|
Expr * adjustActArgType(Expr *_exp, hlType forType);
|
||||||
|
std::string writeCall(Function *tproc, STKFRAME &args, int *numLoc);
|
||||||
|
void processDosInt(STATE *pstate, PROG &prog, bool done);
|
||||||
|
ICODE *translate_DIV(LLInst *ll, ICODE &_Icode);
|
||||||
|
ICODE *translate_XCHG(LLInst *ll, ICODE &_Icode);
|
||||||
protected:
|
protected:
|
||||||
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
||||||
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
@@ -190,10 +227,32 @@ protected:
|
|||||||
void findExps();
|
void findExps();
|
||||||
void genDU1();
|
void genDU1();
|
||||||
void elimCondCodes();
|
void elimCondCodes();
|
||||||
void liveRegAnalysis(std::bitset<32> &in_liveOut);
|
void liveRegAnalysis(LivenessSet &in_liveOut);
|
||||||
void findIdioms();
|
void findIdioms();
|
||||||
void propLong();
|
void propLong();
|
||||||
void genLiveKtes();
|
void genLiveKtes();
|
||||||
uint8_t findDerivedSeq (derSeq &derivedGi);
|
bool findDerivedSeq(derSeq &derivedGi);
|
||||||
bool nextOrderGraph(derSeq &derivedGi);
|
bool nextOrderGraph(derSeq &derivedGi);
|
||||||
};
|
};
|
||||||
|
namespace llvm {
|
||||||
|
template<> struct ilist_traits<typename ::Function>
|
||||||
|
: public ilist_default_traits<typename ::Function> {
|
||||||
|
|
||||||
|
// createSentinel is used to get hold of the node that marks the end of the
|
||||||
|
// list... (same trick used here as in ilist_traits<Instruction>)
|
||||||
|
typename ::Function *createSentinel() const {
|
||||||
|
return static_cast<typename ::Function*>(&Sentinel);
|
||||||
|
}
|
||||||
|
static void destroySentinel(typename ::Function*) {}
|
||||||
|
|
||||||
|
typename ::Function *provideInitialHead() const { return createSentinel(); }
|
||||||
|
typename ::Function *ensureHead(::Function*) const { return createSentinel(); }
|
||||||
|
static void noteHead(typename ::Function*, typename ::Function*) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable ilist_node<typename ::Function> Sentinel;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
typedef llvm::iplist<Function> FunctionListType;
|
||||||
|
typedef FunctionListType lFunction;
|
||||||
|
typedef lFunction::iterator ilFunction;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ struct STKFRAME : public SymbolTableCommon<STKSYM>
|
|||||||
int16_t maxOff; /* Maximum offset in stack frame*/
|
int16_t maxOff; /* Maximum offset in stack frame*/
|
||||||
int cb; /* Number of bytes in arguments */
|
int cb; /* Number of bytes in arguments */
|
||||||
int numArgs; /* No. of arguments in the table*/
|
int numArgs; /* No. of arguments in the table*/
|
||||||
void adjustForArgType(int numArg_, hlType actType_);
|
void adjustForArgType(size_t numArg_, hlType actType_);
|
||||||
STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
|
STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
358
include/ast.h
358
include/ast.h
@@ -5,10 +5,11 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include <boost/range.hpp>
|
|
||||||
static const int operandSize=20;
|
static const int operandSize=20;
|
||||||
/* The following definitions and types define the Conditional Expression
|
/* The following definitions and types define the Conditional Expression
|
||||||
* attributed syntax tree, as defined by the following EBNF:
|
* attributed syntax tree, as defined by the following EBNF:
|
||||||
@@ -22,129 +23,160 @@ static const int operandSize=20;
|
|||||||
static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER,
|
static const condOp condOpJCond[12] = {LESS, LESS_EQUAL, GREATER_EQUAL, GREATER,
|
||||||
EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL,
|
EQUAL, NOT_EQUAL, LESS, GREATER_EQUAL,
|
||||||
LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
|
LESS_EQUAL, GREATER, GREATER_EQUAL, LESS};
|
||||||
|
struct AstIdent;
|
||||||
struct Function;
|
struct Function;
|
||||||
struct STKFRAME;
|
struct STKFRAME;
|
||||||
struct LOCAL_ID;
|
struct LOCAL_ID;
|
||||||
struct ICODE;
|
struct ICODE;
|
||||||
struct LLInst;
|
struct LLInst;
|
||||||
|
struct LLOperand;
|
||||||
struct ID;
|
struct ID;
|
||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
typedef boost::iterator_range<iICODE> rICODE;
|
typedef boost::iterator_range<iICODE> rICODE;
|
||||||
#include "IdentType.h"
|
#include "IdentType.h"
|
||||||
|
|
||||||
/* Expression data type */
|
/* Expression data type */
|
||||||
struct COND_EXPR
|
struct Expr
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
struct /* for BOOLEAN_OP */
|
|
||||||
{
|
|
||||||
condOp op;
|
|
||||||
COND_EXPR *lhs;
|
|
||||||
COND_EXPR *rhs;
|
|
||||||
} boolExpr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
condNodeType m_type; /* Conditional Expression Node Type */
|
condNodeType m_type; /* Conditional Expression Node Type */
|
||||||
union _exprNode { /* Different cond expr nodes */
|
|
||||||
COND_EXPR *unaryExp; /* for NEGATION,ADDRESSOF,DEREFERENCE*/
|
|
||||||
IDENTTYPE ident; /* for IDENTIFIER */
|
|
||||||
} expr;
|
|
||||||
COND_EXPR *lhs()
|
|
||||||
{
|
|
||||||
assert(m_type==BOOLEAN_OP);
|
|
||||||
return boolExpr.lhs;
|
|
||||||
}
|
|
||||||
const COND_EXPR *lhs() const
|
|
||||||
{
|
|
||||||
assert(m_type==BOOLEAN_OP);
|
|
||||||
return boolExpr.lhs;
|
|
||||||
}
|
|
||||||
COND_EXPR *rhs()
|
|
||||||
{
|
|
||||||
assert(m_type==BOOLEAN_OP);
|
|
||||||
return boolExpr.rhs;
|
|
||||||
}
|
|
||||||
const COND_EXPR *rhs() const
|
|
||||||
{
|
|
||||||
assert(m_type==BOOLEAN_OP);
|
|
||||||
return boolExpr.rhs;
|
|
||||||
}
|
|
||||||
condOp op() const { return boolExpr.op;}
|
|
||||||
public:
|
public:
|
||||||
static COND_EXPR *idRegIdx(int idx, regType reg_type);
|
static bool insertSubTreeLongReg(Expr *exp, Expr *&tree, int longIdx);
|
||||||
static COND_EXPR *idKte(uint32_t kte, uint8_t size);
|
static bool insertSubTreeReg(Expr *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
static COND_EXPR *idLoc(int off, LOCAL_ID *localId);
|
static bool insertSubTreeReg(AstIdent *&tree, Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
static COND_EXPR *idReg(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
|
|
||||||
static COND_EXPR *idLongIdx(int idx);
|
|
||||||
static COND_EXPR *idOther(eReg seg, eReg regi, int16_t off);
|
|
||||||
static COND_EXPR *idParam(int off, const STKFRAME *argSymtab);
|
|
||||||
static COND_EXPR *unary(condNodeType t, COND_EXPR *sub_expr);
|
|
||||||
static COND_EXPR *idLong(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
|
||||||
static COND_EXPR *idFunc(Function *pproc, STKFRAME *args);
|
|
||||||
static COND_EXPR *idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
|
|
||||||
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
|
|
||||||
static COND_EXPR *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
|
|
||||||
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
|
|
||||||
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
|
|
||||||
public:
|
public:
|
||||||
virtual COND_EXPR *clone() const;
|
|
||||||
void release();
|
virtual Expr *clone() const=0; //!< Makes a deep copy of the given expression
|
||||||
void changeBoolOp(condOp newOp);
|
Expr(condNodeType t=UNKNOWN_OP) : m_type(t)
|
||||||
COND_EXPR(const COND_EXPR &other)
|
|
||||||
{
|
{
|
||||||
m_type=other.m_type;
|
|
||||||
expr=other.expr;
|
|
||||||
boolExpr=other.boolExpr;
|
|
||||||
}
|
|
||||||
COND_EXPR(condNodeType t=UNKNOWN_OP) : m_type(t)
|
|
||||||
{
|
|
||||||
memset(&expr,0,sizeof(_exprNode));
|
|
||||||
memset(&boolExpr,0,sizeof(boolExpr));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual ~COND_EXPR() {}
|
/** Recursively deallocates the abstract syntax tree rooted at *exp */
|
||||||
|
virtual ~Expr() {}
|
||||||
public:
|
public:
|
||||||
virtual COND_EXPR *inverse() const; // return new COND_EXPR that is invarse of this
|
virtual std::string walkCondExpr (Function * pProc, int* numLoc) const=0;
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
virtual Expr *inverse() const=0; // return new COND_EXPR that is invarse of this
|
||||||
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)=0;
|
||||||
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)=0;
|
||||||
virtual hlType expType(Function *pproc) const;
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx)=0;
|
||||||
|
virtual hlType expType(Function *pproc) const=0;
|
||||||
|
virtual int hlTypeSize(Function *pproc) const=0;
|
||||||
|
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId) { return this; }
|
||||||
};
|
};
|
||||||
struct BinaryOperator : public COND_EXPR
|
struct UnaryOperator : public Expr
|
||||||
|
{
|
||||||
|
UnaryOperator(condNodeType t=UNKNOWN_OP) : Expr(t),unaryExp(nullptr) {}
|
||||||
|
Expr *unaryExp;
|
||||||
|
virtual Expr *inverse() const
|
||||||
|
{
|
||||||
|
if (m_type == NEGATION) //TODO: memleak here
|
||||||
|
{
|
||||||
|
return unaryExp->clone();
|
||||||
|
}
|
||||||
|
return this->clone();
|
||||||
|
}
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
UnaryOperator *newExp = new UnaryOperator(*this);
|
||||||
|
newExp->unaryExp = unaryExp->clone();
|
||||||
|
return newExp;
|
||||||
|
}
|
||||||
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
|
||||||
|
static UnaryOperator *Create(condNodeType t, Expr *sub_expr)
|
||||||
|
{
|
||||||
|
UnaryOperator *newExp = new UnaryOperator();
|
||||||
|
newExp->m_type = t;
|
||||||
|
newExp->unaryExp = sub_expr;
|
||||||
|
return (newExp);
|
||||||
|
}
|
||||||
|
~UnaryOperator()
|
||||||
|
{
|
||||||
|
delete unaryExp;
|
||||||
|
unaryExp=nullptr;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
int hlTypeSize(Function *pproc) const;
|
||||||
|
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
|
virtual hlType expType(Function *pproc) const;
|
||||||
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryOperator : public Expr
|
||||||
{
|
{
|
||||||
condOp m_op;
|
condOp m_op;
|
||||||
COND_EXPR *m_lhs;
|
Expr *m_lhs;
|
||||||
COND_EXPR *m_rhs;
|
Expr *m_rhs;
|
||||||
BinaryOperator(condOp o)
|
BinaryOperator(condOp o) : Expr(BOOLEAN_OP)
|
||||||
{
|
{
|
||||||
m_op = o;
|
m_op = o;
|
||||||
m_lhs=m_rhs=nullptr;
|
m_lhs=m_rhs=nullptr;
|
||||||
}
|
}
|
||||||
static BinaryOperator *Create(condOp o,COND_EXPR *l,COND_EXPR *r);
|
BinaryOperator(condOp o,Expr *l,Expr *r) : Expr(BOOLEAN_OP)
|
||||||
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
|
{
|
||||||
virtual COND_EXPR *inverse();
|
m_op = o;
|
||||||
virtual COND_EXPR *clone();
|
m_lhs=l;
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
|
m_rhs=r;
|
||||||
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
|
}
|
||||||
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
|
~BinaryOperator()
|
||||||
|
{
|
||||||
|
assert(m_lhs!=m_rhs || m_lhs==nullptr);
|
||||||
|
delete m_lhs;
|
||||||
|
delete m_rhs;
|
||||||
|
m_lhs=m_rhs=nullptr;
|
||||||
|
}
|
||||||
|
static BinaryOperator *Create(condOp o,Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
BinaryOperator *res = new BinaryOperator(o);
|
||||||
|
res->m_lhs = l;
|
||||||
|
res->m_rhs = r;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
static BinaryOperator *LogicAnd(Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
return Create(DBL_AND,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *createSHL(Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
return Create(SHL,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *And(Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
return Create(AND,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *Or(Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
return Create(OR,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *LogicOr(Expr *l,Expr *r)
|
||||||
|
{
|
||||||
|
return Create(DBL_OR,l,r);
|
||||||
|
}
|
||||||
|
static BinaryOperator *CreateAdd(Expr *l,Expr *r) {
|
||||||
|
return Create(ADD,l,r);
|
||||||
|
|
||||||
COND_EXPR *lhs()
|
}
|
||||||
|
void changeBoolOp(condOp newOp);
|
||||||
|
virtual Expr *inverse() const;
|
||||||
|
virtual Expr *clone() const;
|
||||||
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
|
||||||
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
|
const Expr *lhs() const
|
||||||
|
{
|
||||||
|
return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->lhs());
|
||||||
|
}
|
||||||
|
const Expr *rhs() const
|
||||||
|
{
|
||||||
|
return const_cast<const Expr *>(const_cast<BinaryOperator *>(this)->rhs());
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr *lhs()
|
||||||
{
|
{
|
||||||
assert(m_type==BOOLEAN_OP);
|
assert(m_type==BOOLEAN_OP);
|
||||||
return m_lhs;
|
return m_lhs;
|
||||||
}
|
}
|
||||||
const COND_EXPR *lhs() const
|
Expr *rhs()
|
||||||
{
|
|
||||||
assert(m_type==BOOLEAN_OP);
|
|
||||||
return m_lhs;
|
|
||||||
}
|
|
||||||
COND_EXPR *rhs()
|
|
||||||
{
|
|
||||||
assert(m_type==BOOLEAN_OP);
|
|
||||||
return m_rhs;
|
|
||||||
}
|
|
||||||
const COND_EXPR *rhs() const
|
|
||||||
{
|
{
|
||||||
assert(m_type==BOOLEAN_OP);
|
assert(m_type==BOOLEAN_OP);
|
||||||
return m_rhs;
|
return m_rhs;
|
||||||
@@ -152,26 +184,134 @@ struct BinaryOperator : public COND_EXPR
|
|||||||
condOp op() const { return m_op;}
|
condOp op() const { return m_op;}
|
||||||
/* Changes the boolean conditional operator at the root of this expression */
|
/* Changes the boolean conditional operator at the root of this expression */
|
||||||
void op(condOp o) { m_op=o;}
|
void op(condOp o) { m_op=o;}
|
||||||
|
std::string walkCondExpr (Function * pProc, int* numLoc) const;
|
||||||
|
public:
|
||||||
|
hlType expType(Function *pproc) const;
|
||||||
|
int hlTypeSize(Function *pproc) const;
|
||||||
};
|
};
|
||||||
struct UnaryOperator : public COND_EXPR
|
struct AstIdent : public UnaryOperator
|
||||||
{
|
{
|
||||||
condOp op;
|
AstIdent() : UnaryOperator(IDENTIFIER)
|
||||||
COND_EXPR *unaryExp;
|
|
||||||
virtual COND_EXPR *inverse();
|
|
||||||
virtual COND_EXPR *clone();
|
|
||||||
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs);
|
|
||||||
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
|
|
||||||
{
|
{
|
||||||
UnaryOperator *newExp = new UnaryOperator();
|
|
||||||
newExp->m_type=t;
|
|
||||||
newExp->unaryExp = sub_expr;
|
|
||||||
return (newExp);
|
|
||||||
}
|
}
|
||||||
};
|
IDENTTYPE ident; /* for IDENTIFIER */
|
||||||
|
static AstIdent * Loc(int off, LOCAL_ID *localId);
|
||||||
|
static AstIdent * LongIdx(int idx);
|
||||||
|
static AstIdent * String(uint32_t idx);
|
||||||
|
static AstIdent * Other(eReg seg, eReg regi, int16_t off);
|
||||||
|
static AstIdent * Param(int off, const STKFRAME *argSymtab);
|
||||||
|
static AstIdent * Long(LOCAL_ID *localId, opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
||||||
|
static AstIdent * idID(const ID *retVal, LOCAL_ID *locsym, iICODE ix_);
|
||||||
|
static Expr * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
|
||||||
|
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
return new AstIdent(*this);
|
||||||
|
}
|
||||||
|
virtual int hlTypeSize(Function *pproc) const;
|
||||||
|
virtual hlType expType(Function *pproc) const;
|
||||||
|
virtual Expr * performLongRemoval(eReg regi, LOCAL_ID *locId);
|
||||||
|
virtual std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
|
virtual Expr *insertSubTreeLongReg(Expr *_expr, int longIdx);
|
||||||
|
virtual bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
|
protected:
|
||||||
|
eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl);
|
||||||
|
|
||||||
struct GlobalVariable : public COND_EXPR
|
|
||||||
{
|
|
||||||
static COND_EXPR *Create(int16_t segValue, int16_t off);
|
|
||||||
};
|
};
|
||||||
struct Constant : public COND_EXPR
|
struct GlobalVariable : public AstIdent
|
||||||
{};
|
{
|
||||||
|
bool valid;
|
||||||
|
int globIdx;
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
return new GlobalVariable(*this);
|
||||||
|
}
|
||||||
|
GlobalVariable(int16_t segValue, int16_t off);
|
||||||
|
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
int hlTypeSize(Function *pproc) const;
|
||||||
|
hlType expType(Function *pproc) const;
|
||||||
|
};
|
||||||
|
struct GlobalVariableIdx : public AstIdent
|
||||||
|
{
|
||||||
|
bool valid;
|
||||||
|
int idxGlbIdx; /* idx into localId, GLOB_VAR_IDX */
|
||||||
|
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
return new GlobalVariableIdx(*this);
|
||||||
|
}
|
||||||
|
GlobalVariableIdx(int16_t segValue, int16_t off, uint8_t regi, const LOCAL_ID *locSym);
|
||||||
|
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
int hlTypeSize(Function *pproc) const;
|
||||||
|
hlType expType(Function *pproc) const;
|
||||||
|
};
|
||||||
|
struct Constant : public AstIdent
|
||||||
|
{
|
||||||
|
struct _kte
|
||||||
|
{ /* for CONSTANT only */
|
||||||
|
uint32_t kte; /* value of the constant */
|
||||||
|
uint8_t size; /* #bytes size constant */
|
||||||
|
} kte;
|
||||||
|
|
||||||
|
Constant(uint32_t _kte, uint8_t size)
|
||||||
|
{
|
||||||
|
ident.idType = CONSTANT;
|
||||||
|
kte.kte = _kte;
|
||||||
|
kte.size = size;
|
||||||
|
}
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
return new Constant(*this);
|
||||||
|
}
|
||||||
|
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
int hlTypeSize(Function *pproc) const;
|
||||||
|
hlType expType(Function *pproc) const;
|
||||||
|
};
|
||||||
|
struct FuncNode : public AstIdent
|
||||||
|
{
|
||||||
|
struct _call { /* for FUNCTION only */
|
||||||
|
Function *proc;
|
||||||
|
STKFRAME *args;
|
||||||
|
} call;
|
||||||
|
|
||||||
|
FuncNode(Function *pproc, STKFRAME *args)
|
||||||
|
{
|
||||||
|
call.proc = pproc;
|
||||||
|
call.args = args;
|
||||||
|
}
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
return new FuncNode(*this);
|
||||||
|
}
|
||||||
|
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
int hlTypeSize(Function *pproc) const;
|
||||||
|
hlType expType(Function *pproc) const;
|
||||||
|
};
|
||||||
|
struct RegisterNode : public AstIdent
|
||||||
|
{
|
||||||
|
const LOCAL_ID *m_syms;
|
||||||
|
regType regiType; /* for REGISTER only */
|
||||||
|
int regiIdx; /* index into localId, REGISTER */
|
||||||
|
|
||||||
|
virtual Expr *insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
|
|
||||||
|
RegisterNode(int idx, regType reg_type,const LOCAL_ID *syms)
|
||||||
|
{
|
||||||
|
m_syms= syms;
|
||||||
|
ident.type(REGISTER);
|
||||||
|
regiType = reg_type;
|
||||||
|
regiIdx = idx;
|
||||||
|
}
|
||||||
|
RegisterNode(const LLOperand &, LOCAL_ID *locsym);
|
||||||
|
|
||||||
|
//RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym);
|
||||||
|
virtual Expr *clone() const
|
||||||
|
{
|
||||||
|
return new RegisterNode(*this);
|
||||||
|
}
|
||||||
|
std::string walkCondExpr(Function *pProc, int *numLoc) const;
|
||||||
|
int hlTypeSize(Function *) const;
|
||||||
|
hlType expType(Function *pproc) const;
|
||||||
|
bool xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
|
};
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
int current_indent;
|
int current_indent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern bundle cCode;
|
||||||
#define lineSize 360 /* 3 lines in the mean time */
|
#define lineSize 360 /* 3 lines in the mean time */
|
||||||
|
|
||||||
//void newBundle (bundle *procCode);
|
//void newBundle (bundle *procCode);
|
||||||
|
|||||||
@@ -20,27 +20,8 @@
|
|||||||
#include "bundle.h"
|
#include "bundle.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
struct Project;
|
class Project;
|
||||||
/* CALL GRAPH NODE */
|
/* CALL GRAPH NODE */
|
||||||
struct CALL_GRAPH
|
|
||||||
{
|
|
||||||
ilFunction proc; /* Pointer to procedure in pProcList */
|
|
||||||
std::vector<CALL_GRAPH *> outEdges; /* array of out edges */
|
|
||||||
public:
|
|
||||||
void write();
|
|
||||||
CALL_GRAPH() : outEdges(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
void writeNodeCallGraph(int indIdx);
|
|
||||||
bool insertCallGraph(ilFunction caller, ilFunction callee);
|
|
||||||
bool insertCallGraph(Function *caller, ilFunction callee);
|
|
||||||
void insertArc(ilFunction newProc);
|
|
||||||
};
|
|
||||||
//#define NUM_PROCS_DELTA 5 /* delta # procs a proc invokes */
|
|
||||||
//extern std::list<Function> pProcList;
|
|
||||||
//extern FunctionListType pProcList;
|
|
||||||
//extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
|
||||||
extern bundle cCode; /* Output C procedure's declaration and code */
|
extern bundle cCode; /* Output C procedure's declaration and code */
|
||||||
|
|
||||||
/**** Global variables ****/
|
/**** Global variables ****/
|
||||||
@@ -62,12 +43,8 @@ typedef struct { /* Command line option flags */
|
|||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
#include "BinaryImage.h"
|
#include "BinaryImage.h"
|
||||||
extern std::bitset<32> duReg[30]; /* def/use bits for registers */
|
|
||||||
|
|
||||||
//extern uint32_t duReg[30]; /* def/use bits for registers */
|
|
||||||
extern std::bitset<32> maskDuReg[30]; /* masks off du bits for regs */
|
|
||||||
|
|
||||||
/* Registers used by icode instructions */
|
|
||||||
|
|
||||||
/* Memory map states */
|
/* Memory map states */
|
||||||
enum eAreaType
|
enum eAreaType
|
||||||
@@ -110,13 +87,13 @@ void udm(void); /* udm.c */
|
|||||||
void freeCFG(BB * cfg); /* graph.c */
|
void freeCFG(BB * cfg); /* graph.c */
|
||||||
BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */
|
BB * newBB(BB *, int, int, uint8_t, int, Function *); /* graph.c */
|
||||||
void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */
|
void BackEnd(char *filename, CALL_GRAPH *); /* backend.c */
|
||||||
char *cChar(uint8_t c); /* backend.c */
|
extern char *cChar(uint8_t c); /* backend.c */
|
||||||
eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */
|
eErrorId scan(uint32_t ip, ICODE &p); /* scanner.c */
|
||||||
void parse (CALL_GRAPH * *); /* parser.c */
|
void parse (CALL_GRAPH * *); /* parser.c */
|
||||||
|
|
||||||
int strSize (uint8_t *, char); /* parser.c */
|
extern int strSize (const uint8_t *, char); /* parser.c */
|
||||||
//void disassem(int pass, Function * pProc); /* disassem.c */
|
//void disassem(int pass, Function * pProc); /* disassem.c */
|
||||||
void interactDis(Function * initProc, int initIC); /* disassem.c */
|
void interactDis(Function *, int initIC); /* disassem.c */
|
||||||
bool JmpInst(llIcode opcode); /* idioms.c */
|
bool JmpInst(llIcode opcode); /* idioms.c */
|
||||||
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */
|
queue::iterator appendQueue(queue &Q, BB *node); /* reducible.c */
|
||||||
|
|
||||||
@@ -124,25 +101,15 @@ void SetupLibCheck(void); /* chklib.c */
|
|||||||
void CleanupLibCheck(void); /* chklib.c */
|
void CleanupLibCheck(void); /* chklib.c */
|
||||||
bool LibCheck(Function &p); /* chklib.c */
|
bool LibCheck(Function &p); /* chklib.c */
|
||||||
|
|
||||||
/* Exported functions from procs.c */
|
|
||||||
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
|
|
||||||
void adjustActArgType (COND_EXPR *, hlType, Function *);
|
|
||||||
|
|
||||||
/* Exported functions from ast.c */
|
|
||||||
std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, int *);
|
|
||||||
int hlTypeSize (const COND_EXPR *, Function *);
|
|
||||||
//hlType expType (const COND_EXPR *, Function *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Exported functions from hlicode.c */
|
/* Exported functions from hlicode.c */
|
||||||
std::string writeCall (Function *, STKFRAME &, Function *, int *);
|
const char *writeJcond(const HLTYPE &, Function *, int *);
|
||||||
char *writeJcond (const HLTYPE &, Function *, int *);
|
const char *writeJcondInv (HLTYPE, Function *, int *);
|
||||||
char *writeJcondInv (HLTYPE, Function *, int *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Exported funcions from locident.c */
|
/* Exported funcions from locident.c */
|
||||||
boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
|
bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
|
||||||
boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
|
bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
|
||||||
eReg otherLongRegi(eReg, int, LOCAL_ID *);
|
eReg otherLongRegi(eReg, int, LOCAL_ID *);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
/****************************************************************************
|
/*
|
||||||
* dcc project disassembler header
|
***************************************************************************
|
||||||
* (C) Mike van Emmerik
|
dcc project disassembler header
|
||||||
****************************************************************************/
|
(C) Mike van Emmerik
|
||||||
|
***************************************************************************
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "bundle.h"
|
#include "bundle.h"
|
||||||
@@ -32,24 +33,6 @@ public:
|
|||||||
|
|
||||||
#define EXT 0x100 /* "Extended" flag */
|
#define EXT 0x100 /* "Extended" flag */
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
|
||||||
#define KEY_DOWN EXT+'P'
|
|
||||||
#define KEY_LEFT EXT+'K'
|
|
||||||
#define KEY_UP EXT+'H'
|
|
||||||
#define KEY_RIGHT EXT+'M'
|
|
||||||
#define KEY_NPAGE EXT+'Q'
|
|
||||||
#define KEY_PPAGE EXT+'I'
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _CONSOLE
|
|
||||||
#define KEY_DOWN 0x50 /* Same as keypad scancodes */
|
|
||||||
#define KEY_LEFT 0x4B
|
|
||||||
#define KEY_UP 0x48
|
|
||||||
#define KEY_RIGHT 0x4D
|
|
||||||
#define KEY_NPAGE 0x51
|
|
||||||
#define KEY_PPAGE 0x49
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __UNIX__
|
#ifdef __UNIX__
|
||||||
#define KEY_DOWN EXT+'B'
|
#define KEY_DOWN EXT+'B'
|
||||||
#define KEY_LEFT EXT+'D'
|
#define KEY_LEFT EXT+'D'
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
/***************************************************************************
|
/*
|
||||||
|
|
||||||
|
=**************************************************************************
|
||||||
* File : dosdcc.h
|
* File : dosdcc.h
|
||||||
* Purpose : include file for files decompiled by dcc.
|
* Purpose : include file for files decompiled by dcc.
|
||||||
* Copyright (c) Cristina Cifuentes - QUT - 1992
|
* Copyright (c) Cristina Cifuentes - QUT - 1992
|
||||||
**************************************************************************/
|
*************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
/* Type definitions for intel 80x86 architecture */
|
/* Type definitions for intel 80x86 architecture */
|
||||||
typedef unsigned int uint16_t; /* 16 bits */
|
typedef unsigned int uint16_t; /* 16 bits */
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
/*****************************************************************************
|
/*
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
* Error codes
|
* Error codes
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
***************************************************************************
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/* These definitions refer to errorMessage in error.c */
|
/* These definitions refer to errorMessage in error.c */
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
/*****************************************************************************
|
/*
|
||||||
|
****************************************************************************
|
||||||
* CFG, BB and interval related definitions
|
* CFG, BB and interval related definitions
|
||||||
* (C) Cristina Cifuentes
|
* ( C ) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
|
||||||
struct Function;
|
struct Function;
|
||||||
/* Types of basic block nodes */
|
/* Types of basic block nodes */
|
||||||
/* Real basic blocks: type defined according to their out-edges */
|
/* Real basic blocks: type defined according to their out-edges */
|
||||||
@@ -55,6 +58,7 @@ enum eNodeHeaderType
|
|||||||
#define ELSE 1 /* else edge */
|
#define ELSE 1 /* else edge */
|
||||||
|
|
||||||
/* Basic Block (BB) flags */
|
/* Basic Block (BB) flags */
|
||||||
|
|
||||||
#define INVALID_BB 0x0001 /* BB is not valid any more */
|
#define INVALID_BB 0x0001 /* BB is not valid any more */
|
||||||
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
|
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
|
||||||
|
|
||||||
@@ -64,30 +68,24 @@ typedef std::list<BB *> queue;
|
|||||||
|
|
||||||
struct interval
|
struct interval
|
||||||
{
|
{
|
||||||
uint8_t numInt; /* # of the interval */
|
uint8_t numInt=0; /* # of the interval */
|
||||||
uint8_t numOutEdges; /* Number of out edges */
|
uint8_t numOutEdges=0; /* Number of out edges */
|
||||||
queue nodes; /* Nodes of the interval*/
|
queue nodes; /* Nodes of the interval*/
|
||||||
queue::iterator currNode; /* Current node */
|
queue::iterator currNode; /* Current node */
|
||||||
interval *next; /* Next interval */
|
interval * next=0; /* Next interval */
|
||||||
BB *firstOfInt();
|
BB * firstOfInt();
|
||||||
interval()
|
interval() : currNode(nodes.end()){
|
||||||
{
|
|
||||||
numInt=numOutEdges=0;
|
|
||||||
currNode=nodes.end();
|
|
||||||
next=0;
|
|
||||||
}
|
}
|
||||||
|
void appendNodeInt(queue &pqH, BB *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Derived Sequence structure */
|
/* Derived Sequence structure */
|
||||||
struct derSeq_Entry
|
struct derSeq_Entry
|
||||||
{
|
{
|
||||||
BB * Gi; /* Graph pointer */
|
BB * Gi=nullptr; /* Graph pointer */
|
||||||
interval * Ii; /* Interval list of Gi */
|
std::list<interval *> m_intervals;
|
||||||
derSeq_Entry() : Gi(0),Ii(0)
|
interval * Ii=nullptr; /* Interval list of Gi */
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
~derSeq_Entry();
|
~derSeq_Entry();
|
||||||
public:
|
public:
|
||||||
void findIntervals(Function *c);
|
void findIntervals(Function *c);
|
||||||
|
|||||||
341
include/icode.h
341
include/icode.h
@@ -7,17 +7,18 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <initializer_list>
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
#include <llvm/ADT/ilist_node.h>
|
||||||
#include <llvm/CodeGen/MachineInstr.h>
|
|
||||||
#include <llvm/MC/MCInst.h>
|
#include <llvm/MC/MCInst.h>
|
||||||
#include <llvm/MC/MCAsmInfo.h>
|
#include <llvm/IR/Instruction.h>
|
||||||
#include <llvm/Value.h>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include <llvm/Instruction.h>
|
|
||||||
#include <boost/range.hpp>
|
|
||||||
#include "libdis.h"
|
#include "libdis.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
||||||
|
#include "CallConvention.h"
|
||||||
|
|
||||||
//enum condId;
|
//enum condId;
|
||||||
|
|
||||||
@@ -25,13 +26,102 @@ struct LOCAL_ID;
|
|||||||
struct BB;
|
struct BB;
|
||||||
struct Function;
|
struct Function;
|
||||||
struct STKFRAME;
|
struct STKFRAME;
|
||||||
struct CIcodeRec;
|
class CIcodeRec;
|
||||||
struct ICODE;
|
struct ICODE;
|
||||||
struct bundle;
|
struct bundle;
|
||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
typedef std::list<ICODE>::reverse_iterator riICODE;
|
typedef std::list<ICODE>::reverse_iterator riICODE;
|
||||||
typedef boost::iterator_range<iICODE> rCODE;
|
typedef boost::iterator_range<iICODE> rCODE;
|
||||||
extern std::bitset<32> duReg[30];
|
|
||||||
|
struct LivenessSet
|
||||||
|
{
|
||||||
|
std::set<eReg> registers;
|
||||||
|
public:
|
||||||
|
LivenessSet(const std::initializer_list<eReg> &init) : registers(init) {}
|
||||||
|
LivenessSet() {}
|
||||||
|
LivenessSet(const LivenessSet &other) : registers(other.registers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
registers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// LivenessSet(LivenessSet &&other) : LivenessSet()
|
||||||
|
// {
|
||||||
|
// swap(*this,other);
|
||||||
|
// }
|
||||||
|
LivenessSet &operator=(LivenessSet other)
|
||||||
|
{
|
||||||
|
swap(*this,other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
friend void swap(LivenessSet& first, LivenessSet& second) // nothrow
|
||||||
|
{
|
||||||
|
// enable ADL (not necessary in our case, but good practice)
|
||||||
|
using std::swap;
|
||||||
|
|
||||||
|
// by swapping the members of two classes,
|
||||||
|
// the two classes are effectively swapped
|
||||||
|
swap(first.registers, second.registers);
|
||||||
|
}
|
||||||
|
LivenessSet &operator|=(const LivenessSet &other)
|
||||||
|
{
|
||||||
|
registers.insert(other.registers.begin(),other.registers.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
LivenessSet &operator&=(const LivenessSet &other)
|
||||||
|
{
|
||||||
|
std::set<eReg> res;
|
||||||
|
std::set_intersection(registers.begin(),registers.end(),
|
||||||
|
other.registers.begin(),other.registers.end(),
|
||||||
|
std::inserter(res, res.end()));
|
||||||
|
registers = res;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
LivenessSet &operator-=(const LivenessSet &other)
|
||||||
|
{
|
||||||
|
std::set<eReg> res;
|
||||||
|
std::set_difference(registers.begin(),registers.end(),
|
||||||
|
other.registers.begin(),other.registers.end(),
|
||||||
|
std::inserter(res, res.end()));
|
||||||
|
registers = res;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
LivenessSet operator-(const LivenessSet &other) const
|
||||||
|
{
|
||||||
|
return LivenessSet(*this) -= other;
|
||||||
|
}
|
||||||
|
LivenessSet operator+(const LivenessSet &other) const
|
||||||
|
{
|
||||||
|
return LivenessSet(*this) |= other;
|
||||||
|
}
|
||||||
|
LivenessSet operator &(const LivenessSet &other) const
|
||||||
|
{
|
||||||
|
return LivenessSet(*this) &= other;
|
||||||
|
}
|
||||||
|
bool any() const
|
||||||
|
{
|
||||||
|
return not registers.empty();
|
||||||
|
}
|
||||||
|
bool operator==(const LivenessSet &other) const
|
||||||
|
{
|
||||||
|
return registers==other.registers;
|
||||||
|
}
|
||||||
|
bool operator!=(const LivenessSet &other) const { return not(*this==other);}
|
||||||
|
|
||||||
|
LivenessSet &setReg(int r);
|
||||||
|
LivenessSet &addReg(int r);
|
||||||
|
bool testReg(int r) const
|
||||||
|
{
|
||||||
|
return registers.find(eReg(r))!=registers.end();
|
||||||
|
}
|
||||||
|
bool testRegAndSubregs(int r) const;
|
||||||
|
LivenessSet &clrReg(int r);
|
||||||
|
private:
|
||||||
|
void postProcessCompositeRegs();
|
||||||
|
};
|
||||||
|
|
||||||
/* uint8_t and uint16_t registers */
|
/* uint8_t and uint16_t registers */
|
||||||
|
|
||||||
/* Def/use of flags - low 4 bits represent flags */
|
/* Def/use of flags - low 4 bits represent flags */
|
||||||
@@ -45,14 +135,16 @@ struct DU
|
|||||||
#define MAX_REGS_DEF 4 /* 2 regs def'd for long-reg vars */
|
#define MAX_REGS_DEF 4 /* 2 regs def'd for long-reg vars */
|
||||||
|
|
||||||
|
|
||||||
struct COND_EXPR;
|
struct Expr;
|
||||||
|
struct AstIdent;
|
||||||
|
struct UnaryOperator;
|
||||||
struct HlTypeSupport
|
struct HlTypeSupport
|
||||||
{
|
{
|
||||||
//hlIcode opcode; /* hlIcode opcode */
|
//hlIcode opcode; /* hlIcode opcode */
|
||||||
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
|
virtual bool removeRegFromLong(eReg regi, LOCAL_ID *locId)=0;
|
||||||
virtual std::string writeOut(Function *pProc, int *numLoc)=0;
|
virtual std::string writeOut(Function *pProc, int *numLoc) const=0;
|
||||||
protected:
|
protected:
|
||||||
void performLongRemoval (eReg regi, LOCAL_ID *locId, COND_EXPR *tree);
|
Expr * performLongRemoval (eReg regi, LOCAL_ID *locId, Expr *tree);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CallType : public HlTypeSupport
|
struct CallType : public HlTypeSupport
|
||||||
@@ -61,41 +153,41 @@ struct CallType : public HlTypeSupport
|
|||||||
Function * proc;
|
Function * proc;
|
||||||
STKFRAME * args; // actual arguments
|
STKFRAME * args; // actual arguments
|
||||||
void allocStkArgs (int num);
|
void allocStkArgs (int num);
|
||||||
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc);
|
bool newStkArg(Expr *exp, llIcode opcode, Function *pproc);
|
||||||
void placeStkArg(COND_EXPR *exp, int pos);
|
void placeStkArg(Expr *exp, int pos);
|
||||||
virtual COND_EXPR * toId();
|
virtual Expr * toAst();
|
||||||
public:
|
public:
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
bool removeRegFromLong(eReg /*regi*/, LOCAL_ID */*locId*/)
|
||||||
{
|
{
|
||||||
printf("CallType : removeRegFromLong not supproted");
|
printf("CallType : removeRegFromLong not supproted");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string writeOut(Function *pProc, int *numLoc);
|
std::string writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
struct AssignType : public HlTypeSupport
|
struct AssignType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
/* for HLI_ASSIGN */
|
/* for HLI_ASSIGN */
|
||||||
COND_EXPR *lhs;
|
protected:
|
||||||
COND_EXPR *rhs;
|
public:
|
||||||
AssignType() : lhs(0),rhs(0) {}
|
Expr *m_lhs;
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
Expr *rhs;
|
||||||
{
|
AssignType() {}
|
||||||
performLongRemoval(regi,locId,lhs);
|
Expr *lhs() const {return m_lhs;}
|
||||||
return true;
|
void lhs(Expr *l);
|
||||||
}
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId);
|
||||||
std::string writeOut(Function *pProc, int *numLoc);
|
std::string writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
struct ExpType : public HlTypeSupport
|
struct ExpType : public HlTypeSupport
|
||||||
{
|
{
|
||||||
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
|
/* for HLI_JCOND, HLI_RET, HLI_PUSH, HLI_POP*/
|
||||||
COND_EXPR *v;
|
Expr *v;
|
||||||
ExpType() : v(0) {}
|
ExpType() : v(0) {}
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
||||||
{
|
{
|
||||||
performLongRemoval(regi,locId,v);
|
v=performLongRemoval(regi,locId,v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string writeOut(Function *pProc, int *numLoc);
|
std::string writeOut(Function *pProc, int *numLoc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HLTYPE
|
struct HLTYPE
|
||||||
@@ -106,35 +198,27 @@ public:
|
|||||||
hlIcode opcode; /* hlIcode opcode */
|
hlIcode opcode; /* hlIcode opcode */
|
||||||
AssignType asgn;
|
AssignType asgn;
|
||||||
CallType call;
|
CallType call;
|
||||||
HlTypeSupport *get()
|
HlTypeSupport *get();
|
||||||
|
const HlTypeSupport *get() const
|
||||||
{
|
{
|
||||||
switch(opcode)
|
return const_cast<const HlTypeSupport *>(const_cast<HLTYPE*>(this)->get());
|
||||||
{
|
|
||||||
case HLI_ASSIGN: return &asgn;
|
|
||||||
case HLI_RET:
|
|
||||||
case HLI_POP:
|
|
||||||
case HLI_JCOND:
|
|
||||||
case HLI_PUSH: return &exp;
|
|
||||||
case HLI_CALL: return &call;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void expr(COND_EXPR *e)
|
void expr(Expr *e)
|
||||||
{
|
{
|
||||||
assert(e);
|
assert(e);
|
||||||
exp.v=e;
|
exp.v=e;
|
||||||
}
|
}
|
||||||
void replaceExpr(COND_EXPR *e)
|
Expr *getMyExpr()
|
||||||
{
|
{
|
||||||
assert(e);
|
if(opcode==HLI_CALL)
|
||||||
delete exp.v;
|
return call.toAst();
|
||||||
exp.v=e;
|
return expr();
|
||||||
}
|
}
|
||||||
COND_EXPR * expr() { return exp.v;}
|
void replaceExpr(Expr *e);
|
||||||
const COND_EXPR * const expr() const { return exp.v;}
|
Expr * expr() { return exp.v;}
|
||||||
void set(hlIcode i,COND_EXPR *e)
|
const Expr * expr() const { return exp.v;}
|
||||||
|
void set(hlIcode i,Expr *e)
|
||||||
{
|
{
|
||||||
if(i!=HLI_RET)
|
if(i!=HLI_RET)
|
||||||
assert(e);
|
assert(e);
|
||||||
@@ -142,73 +226,93 @@ public:
|
|||||||
opcode=i;
|
opcode=i;
|
||||||
exp.v=e;
|
exp.v=e;
|
||||||
}
|
}
|
||||||
void set(COND_EXPR *l,COND_EXPR *r)
|
void set(Expr *l,Expr *r);
|
||||||
{
|
void setCall(Function *proc);
|
||||||
assert(l);
|
|
||||||
assert(r);
|
|
||||||
opcode = HLI_ASSIGN;
|
|
||||||
assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
|
|
||||||
asgn.lhs=l;
|
|
||||||
asgn.rhs=r;
|
|
||||||
}
|
|
||||||
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
|
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
|
||||||
{}
|
{}
|
||||||
|
// HLTYPE() // help valgrind find uninitialized HLTYPES
|
||||||
|
// {}
|
||||||
HLTYPE & operator=(const HLTYPE &l)
|
HLTYPE & operator=(const HLTYPE &l)
|
||||||
{
|
{
|
||||||
exp=l.exp;
|
exp = l.exp;
|
||||||
opcode=l.opcode;
|
opcode = l.opcode;
|
||||||
asgn=l.asgn;
|
asgn = l.asgn;
|
||||||
call=l.call;
|
call = l.call;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
std::string write1HlIcode(Function *pProc, int *numLoc);
|
std::string write1HlIcode(Function *pProc, int *numLoc) const;
|
||||||
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs);
|
void setAsgn(Expr *lhs, Expr *rhs);
|
||||||
} ;
|
} ;
|
||||||
/* LOW_LEVEL icode operand record */
|
/* LOW_LEVEL icode operand record */
|
||||||
struct LLOperand
|
struct LLOperand
|
||||||
{
|
{
|
||||||
llvm::MCOperand llvm_op;
|
|
||||||
eReg seg; /* CS, DS, ES, SS */
|
eReg seg; /* CS, DS, ES, SS */
|
||||||
eReg segOver; /* CS, DS, ES, SS if segment override */
|
eReg segOver; /* CS, DS, ES, SS if segment override */
|
||||||
int16_t segValue; /* Value of segment seg during analysis */
|
int16_t segValue; /* Value of segment seg during analysis */
|
||||||
eReg regi; /* 0 < regs < INDEXBASE <= index modes */
|
eReg regi; /* 0 < regs < INDEXBASE <= index modes */
|
||||||
int16_t off; /* memory address offset */
|
int16_t off; /* memory address offset */
|
||||||
uint32_t opz; /* idx of immed src op */
|
uint32_t opz; /* idx of immed src op */
|
||||||
|
bool immed;
|
||||||
|
bool is_offset; // set by jumps
|
||||||
|
bool is_compound;
|
||||||
|
size_t width;
|
||||||
//union {/* Source operand if (flg & I) */
|
//union {/* Source operand if (flg & I) */
|
||||||
struct { /* Call & # actual arg bytes */
|
struct { /* Call & # actual arg bytes */
|
||||||
Function *proc; /* pointer to target proc (for CALL(F))*/
|
Function *proc; /* pointer to target proc (for CALL(F))*/
|
||||||
int cb; /* # actual arg bytes */
|
int cb; /* # actual arg bytes */
|
||||||
} proc;
|
} proc;
|
||||||
LLOperand() : seg(rUNDEF),segValue(0),segOver(rUNDEF),regi(rUNDEF),off(0),opz(0)
|
LLOperand() : seg(rUNDEF),segOver(rUNDEF),segValue(0),regi(rUNDEF),off(0),
|
||||||
|
opz(0),immed(0),is_offset(false),is_compound(0),width(0)
|
||||||
{
|
{
|
||||||
proc.proc=0;
|
proc.proc=0;
|
||||||
proc.cb=0;
|
proc.cb=0;
|
||||||
}
|
}
|
||||||
|
LLOperand(eReg r,size_t w) : LLOperand()
|
||||||
|
{
|
||||||
|
regi=r;
|
||||||
|
width=w;
|
||||||
|
}
|
||||||
|
bool operator==(const LLOperand &with) const
|
||||||
|
{
|
||||||
|
return (seg==with.seg) &&
|
||||||
|
(segOver==with.segOver) &&
|
||||||
|
(segValue==with.segValue) &&
|
||||||
|
(regi == with.regi) &&
|
||||||
|
(off == with.off) &&
|
||||||
|
(opz==with.opz) &&
|
||||||
|
(proc.proc==with.proc.proc);
|
||||||
|
}
|
||||||
int64_t getImm2() const {return opz;}
|
int64_t getImm2() const {return opz;}
|
||||||
void SetImmediateOp(uint32_t dw)
|
void SetImmediateOp(uint32_t dw)
|
||||||
{
|
{
|
||||||
opz=dw;
|
opz=dw;
|
||||||
}
|
}
|
||||||
eReg getReg2() {return regi;}
|
eReg getReg2() const {return regi;}
|
||||||
bool isReg() const;
|
bool isReg() const;
|
||||||
static LLOperand CreateImm2(int64_t Val)
|
static LLOperand CreateImm2(int64_t Val,uint8_t wdth=2)
|
||||||
{
|
{
|
||||||
LLOperand Op;
|
LLOperand Op;
|
||||||
//Op.Kind = kImmediate;
|
Op.immed=true;
|
||||||
//Op.ImmVal = Val;
|
|
||||||
Op.opz = Val;
|
Op.opz = Val;
|
||||||
|
Op.width = wdth;
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
static LLOperand CreateReg2(unsigned Val)
|
static LLOperand CreateReg2(unsigned Val)
|
||||||
{
|
{
|
||||||
LLOperand Op;
|
LLOperand Op;
|
||||||
// Op.Kind = kRegister;
|
|
||||||
// Op.RegVal = Reg;
|
|
||||||
Op.regi = (eReg)Val;
|
Op.regi = (eReg)Val;
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
void addProcInformation(int param_count,uint32_t call_conv);
|
bool isSet()
|
||||||
|
{
|
||||||
|
return not (*this == LLOperand());
|
||||||
|
}
|
||||||
|
void addProcInformation(int param_count, CConv::Type call_conv);
|
||||||
|
bool isImmediate() const { return immed;}
|
||||||
|
void setImmediate(bool x) { immed=x;}
|
||||||
|
bool compound() const {return is_compound;} // dx:ax pair
|
||||||
|
size_t byteWidth() const { assert(width<=4); return width;}
|
||||||
};
|
};
|
||||||
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
|
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
|
||||||
{
|
{
|
||||||
@@ -219,7 +323,7 @@ public:
|
|||||||
int codeIdx; /* Index into cCode.code */
|
int codeIdx; /* Index into cCode.code */
|
||||||
uint8_t numBytes; /* Number of bytes this instr */
|
uint8_t numBytes; /* Number of bytes this instr */
|
||||||
uint32_t label; /* offset in image (20-bit adr) */
|
uint32_t label; /* offset in image (20-bit adr) */
|
||||||
LLOperand dst; /* destination operand */
|
LLOperand m_dst; /* destination operand */
|
||||||
DU flagDU; /* def/use of flags */
|
DU flagDU; /* def/use of flags */
|
||||||
int caseEntry;
|
int caseEntry;
|
||||||
std::vector<uint32_t> caseTbl2;
|
std::vector<uint32_t> caseTbl2;
|
||||||
@@ -239,8 +343,6 @@ public:
|
|||||||
flg &= ~flag;
|
flg &= ~flag;
|
||||||
}
|
}
|
||||||
uint32_t getFlag() const {return flg;}
|
uint32_t getFlag() const {return flg;}
|
||||||
//llIcode getOpcode() const { return opcode; }
|
|
||||||
|
|
||||||
uint32_t GetLlLabel() const { return label;}
|
uint32_t GetLlLabel() const { return label;}
|
||||||
|
|
||||||
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
|
void SetImmediateOp(uint32_t dw) {m_src.SetImmediateOp(dw);}
|
||||||
@@ -250,25 +352,29 @@ public:
|
|||||||
{
|
{
|
||||||
return (getOpcode()==op);
|
return (getOpcode()==op);
|
||||||
}
|
}
|
||||||
|
bool matchWithRegDst(llIcode op)
|
||||||
|
{
|
||||||
|
return (getOpcode()==op) and m_dst.isReg();
|
||||||
|
}
|
||||||
bool match(llIcode op,eReg dest)
|
bool match(llIcode op,eReg dest)
|
||||||
{
|
{
|
||||||
return (getOpcode()==op)&&dst.regi==dest;
|
return (getOpcode()==op)&&m_dst.regi==dest;
|
||||||
}
|
}
|
||||||
bool match(llIcode op,eReg dest,uint32_t flgs)
|
bool match(llIcode op,eReg dest,uint32_t flgs)
|
||||||
{
|
{
|
||||||
return (getOpcode()==op) and (dst.regi==dest) and testFlags(flgs);
|
return (getOpcode()==op) and (m_dst.regi==dest) and testFlags(flgs);
|
||||||
}
|
}
|
||||||
bool match(llIcode op,eReg dest,eReg src_reg)
|
bool match(llIcode op,eReg dest,eReg src_reg)
|
||||||
{
|
{
|
||||||
return (getOpcode()==op)&&(dst.regi==dest)&&(m_src.regi==src_reg);
|
return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg);
|
||||||
}
|
}
|
||||||
bool match(eReg dest,eReg src_reg)
|
bool match(eReg dest,eReg src_reg)
|
||||||
{
|
{
|
||||||
return (dst.regi==dest)&&(m_src.regi==src_reg);
|
return (m_dst.regi==dest)&&(m_src.regi==src_reg);
|
||||||
}
|
}
|
||||||
bool match(eReg dest)
|
bool match(eReg dest)
|
||||||
{
|
{
|
||||||
return (dst.regi==dest);
|
return (m_dst.regi==dest);
|
||||||
}
|
}
|
||||||
bool match(llIcode op,uint32_t flgs)
|
bool match(llIcode op,uint32_t flgs)
|
||||||
{
|
{
|
||||||
@@ -279,6 +385,19 @@ public:
|
|||||||
setOpcode(op);
|
setOpcode(op);
|
||||||
flg =flags;
|
flg =flags;
|
||||||
}
|
}
|
||||||
|
void set(llIcode op,uint32_t flags,eReg dst_reg)
|
||||||
|
{
|
||||||
|
setOpcode(op);
|
||||||
|
m_dst = LLOperand::CreateReg2(dst_reg);
|
||||||
|
flg =flags;
|
||||||
|
}
|
||||||
|
void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op)
|
||||||
|
{
|
||||||
|
setOpcode(op);
|
||||||
|
m_dst = LLOperand::CreateReg2(dst_reg);
|
||||||
|
m_src = src_op;
|
||||||
|
flg =flags;
|
||||||
|
}
|
||||||
void emitGotoLabel(int indLevel);
|
void emitGotoLabel(int indLevel);
|
||||||
void findJumpTargets(CIcodeRec &_pc);
|
void findJumpTargets(CIcodeRec &_pc);
|
||||||
void writeIntComment(std::ostringstream &s);
|
void writeIntComment(std::ostringstream &s);
|
||||||
@@ -287,7 +406,6 @@ public:
|
|||||||
|
|
||||||
void flops(std::ostringstream &out);
|
void flops(std::ostringstream &out);
|
||||||
bool isJmpInst();
|
bool isJmpInst();
|
||||||
HLTYPE toHighLevel(COND_EXPR *lhs, COND_EXPR *rhs, Function *func);
|
|
||||||
HLTYPE createCall();
|
HLTYPE createCall();
|
||||||
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
LLInst(ICODE *container) : flg(0),codeIdx(0),numBytes(0),m_link(container)
|
||||||
{
|
{
|
||||||
@@ -309,16 +427,16 @@ public:
|
|||||||
}
|
}
|
||||||
void replaceDst(const LLOperand &with)
|
void replaceDst(const LLOperand &with)
|
||||||
{
|
{
|
||||||
dst = with;
|
m_dst = with;
|
||||||
}
|
|
||||||
void replaceDst(eReg r)
|
|
||||||
{
|
|
||||||
dst = LLOperand::CreateReg2(r);
|
|
||||||
}
|
}
|
||||||
|
// void replaceDst(eReg r)
|
||||||
|
// {
|
||||||
|
// dst = LLOperand::CreateReg2(r);
|
||||||
|
// }
|
||||||
ICODE *m_link;
|
ICODE *m_link;
|
||||||
condId idType(opLoc sd) const;
|
condId idType(opLoc sd) const;
|
||||||
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
|
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
|
||||||
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
|
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
|
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
|
||||||
@@ -362,18 +480,21 @@ public:
|
|||||||
use.reset();
|
use.reset();
|
||||||
lastDefRegi.reset();
|
lastDefRegi.reset();
|
||||||
}
|
}
|
||||||
std::bitset<32> def; // For Registers: position in bitset is reg index
|
LivenessSet def; // For Registers: position in bitset is reg index
|
||||||
std::bitset<32> use; // For Registers: position in uint32_t is reg index
|
LivenessSet use; // For Registers: position in uint32_t is reg index
|
||||||
std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
|
LivenessSet lastDefRegi;// Bit set if last def of this register in BB
|
||||||
void addDefinedAndUsed(eReg r)
|
void addDefinedAndUsed(eReg r)
|
||||||
{
|
{
|
||||||
def |= duReg[r];
|
def.addReg(r);
|
||||||
use |= duReg[r];
|
use.addReg(r);
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct DU1
|
struct DU1
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
int numRegsDef; /* # registers defined by this inst */
|
||||||
|
|
||||||
|
public:
|
||||||
struct Use
|
struct Use
|
||||||
{
|
{
|
||||||
int Reg; // used register
|
int Reg; // used register
|
||||||
@@ -389,7 +510,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
int numRegsDef; /* # registers defined by this inst */
|
|
||||||
uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */
|
uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */
|
||||||
Use idx[MAX_REGS_DEF+1];
|
Use idx[MAX_REGS_DEF+1];
|
||||||
//int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
//int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
||||||
@@ -414,6 +534,11 @@ public:
|
|||||||
Use &u(idx[regIdx]);
|
Use &u(idx[regIdx]);
|
||||||
u.removeUser(ic);
|
u.removeUser(ic);
|
||||||
}
|
}
|
||||||
|
int getNumRegsDef() const {return numRegsDef;}
|
||||||
|
void clearAllDefs() {numRegsDef=0;}
|
||||||
|
DU1 &addDef(eReg r) {numRegsDef++; return *this;}
|
||||||
|
DU1 &setDef(eReg r) {numRegsDef=1; return *this;}
|
||||||
|
void removeDef(eReg r) {numRegsDef--;}
|
||||||
DU1() : numRegsDef(0)
|
DU1() : numRegsDef(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -426,8 +551,16 @@ public:
|
|||||||
LLInst * ll() { return &m_ll;}
|
LLInst * ll() { return &m_ll;}
|
||||||
const LLInst * ll() const { return &m_ll;}
|
const LLInst * ll() const { return &m_ll;}
|
||||||
|
|
||||||
HLTYPE * hl() { return &m_hl;}
|
HLTYPE * hlU() {
|
||||||
const HLTYPE * hl() const { return &m_hl;}
|
// assert(type==HIGH_LEVEL);
|
||||||
|
// assert(m_hl.opcode!=HLI_INVALID);
|
||||||
|
return &m_hl;
|
||||||
|
}
|
||||||
|
const HLTYPE * hl() const {
|
||||||
|
// assert(type==HIGH_LEVEL);
|
||||||
|
// assert(m_hl.opcode!=HLI_INVALID);
|
||||||
|
return &m_hl;
|
||||||
|
}
|
||||||
void hl(const HLTYPE &v) { m_hl=v;}
|
void hl(const HLTYPE &v) { m_hl=v;}
|
||||||
|
|
||||||
void setRegDU(eReg regi, operDu du_in);
|
void setRegDU(eReg regi, operDu du_in);
|
||||||
@@ -437,13 +570,13 @@ public:
|
|||||||
condId idType(opLoc sd);
|
condId idType(opLoc sd);
|
||||||
// HLL setting functions
|
// HLL setting functions
|
||||||
// set this icode to be an assign
|
// set this icode to be an assign
|
||||||
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
|
void setAsgn(Expr *lhs, Expr *rhs)
|
||||||
{
|
{
|
||||||
type=HIGH_LEVEL;
|
type=HIGH_LEVEL;
|
||||||
hl()->setAsgn(lhs,rhs);
|
hlU()->setAsgn(lhs,rhs);
|
||||||
}
|
}
|
||||||
void setUnary(hlIcode op, COND_EXPR *_exp);
|
void setUnary(hlIcode op, Expr *_exp);
|
||||||
void setJCond(COND_EXPR *cexp);
|
void setJCond(Expr *cexp);
|
||||||
|
|
||||||
void emitGotoLabel(int indLevel);
|
void emitGotoLabel(int indLevel);
|
||||||
void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
|
void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
|
||||||
@@ -452,11 +585,11 @@ public:
|
|||||||
public:
|
public:
|
||||||
bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId);
|
bool removeDefRegi(eReg regi, int thisDefIdx, LOCAL_ID *locId);
|
||||||
void checkHlCall();
|
void checkHlCall();
|
||||||
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc)
|
bool newStkArg(Expr *exp, llIcode opcode, Function *pproc)
|
||||||
{
|
{
|
||||||
return hl()->call.newStkArg(exp,opcode,pproc);
|
return hlU()->call.newStkArg(exp,opcode,pproc);
|
||||||
}
|
}
|
||||||
ICODE() : m_ll(this),type(NOT_SCANNED),Parent(0),loc_ip(0),invalid(false)
|
ICODE() : m_ll(this),Parent(0),invalid(false),type(NOT_SCANNED),loc_ip(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@@ -485,6 +618,6 @@ public:
|
|||||||
void SetInBB(rCODE &rang, BB* pnewBB);
|
void SetInBB(rCODE &rang, BB* pnewBB);
|
||||||
bool labelSrch(uint32_t target, uint32_t &pIndex);
|
bool labelSrch(uint32_t target, uint32_t &pIndex);
|
||||||
iterator labelSrch(uint32_t target);
|
iterator labelSrch(uint32_t target);
|
||||||
ICODE * GetIcode(int ip);
|
ICODE * GetIcode(size_t ip);
|
||||||
bool alreadyDecoded(uint32_t target);
|
bool alreadyDecoded(uint32_t target);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ struct Idiom18 : public Idiom
|
|||||||
protected:
|
protected:
|
||||||
iICODE m_icodes[4];
|
iICODE m_icodes[4];
|
||||||
bool m_is_dec;
|
bool m_is_dec;
|
||||||
|
/* type of variable: 1 = reg-var, 2 = local */
|
||||||
|
int m_idiom_type;
|
||||||
public:
|
public:
|
||||||
Idiom18(Function *f) : Idiom(f)
|
Idiom18(Function *f) : Idiom(f)
|
||||||
{
|
{
|
||||||
@@ -64,7 +66,7 @@ struct Idiom20 : public Idiom
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
iICODE m_icodes[4];
|
iICODE m_icodes[4];
|
||||||
bool m_is_dec;
|
condNodeType m_is_dec;
|
||||||
public:
|
public:
|
||||||
Idiom20(Function *f) : Idiom(f)
|
Idiom20(Function *f) : Idiom(f)
|
||||||
{
|
{
|
||||||
|
|||||||
11
include/loader.h
Normal file
11
include/loader.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class ILoader
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class LoaderManger
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
@@ -18,7 +18,8 @@
|
|||||||
/* Type definition */
|
/* Type definition */
|
||||||
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
|
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
|
||||||
// TODO: why ?
|
// TODO: why ?
|
||||||
struct COND_EXPR;
|
struct Expr;
|
||||||
|
struct AstIdent;
|
||||||
struct ICODE;
|
struct ICODE;
|
||||||
struct LLInst;
|
struct LLInst;
|
||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
@@ -30,37 +31,67 @@ struct IDX_ARRAY : public std::vector<iICODE>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
enum frameType
|
||||||
{
|
{
|
||||||
STK_FRAME, /* For stack vars */
|
STK_FRAME, /* For stack vars */
|
||||||
REG_FRAME, /* For register variables */
|
REG_FRAME, /* For register variables */
|
||||||
GLB_FRAME /* For globals */
|
GLB_FRAME /* For globals */
|
||||||
} frameType;
|
};
|
||||||
|
|
||||||
typedef struct
|
struct BWGLB_TYPE
|
||||||
{
|
{
|
||||||
int16_t seg; /* segment value */
|
int16_t seg; /* segment value */
|
||||||
int16_t off; /* offset */
|
int16_t off; /* offset */
|
||||||
eReg regi; /* optional indexed register */
|
eReg regi; /* optional indexed register */
|
||||||
} BWGLB_TYPE;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
/* For TYPE_LONG_(UN)SIGN on the stack */
|
||||||
{ /* For TYPE_LONG_(UN)SIGN on the stack */
|
struct LONG_STKID_TYPE
|
||||||
|
{
|
||||||
int offH; /* high offset from BP */
|
int offH; /* high offset from BP */
|
||||||
int offL; /* low offset from BP */
|
int offL; /* low offset from BP */
|
||||||
} LONG_STKID_TYPE;
|
LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
|
||||||
|
};
|
||||||
|
/* For TYPE_LONG_(UN)SIGN registers */
|
||||||
struct LONGID_TYPE
|
struct LONGID_TYPE
|
||||||
{ /* For TYPE_LONG_(UN)SIGN registers */
|
{
|
||||||
eReg h; /* high register */
|
protected:
|
||||||
eReg l; /* low register */
|
eReg m_h; /* high register */
|
||||||
|
eReg m_l; /* low register */
|
||||||
|
public:
|
||||||
|
void set(eReg highpart,eReg lowpart)
|
||||||
|
{
|
||||||
|
m_h = highpart;
|
||||||
|
m_l = lowpart;
|
||||||
|
}
|
||||||
|
eReg l() const { return m_l; }
|
||||||
|
eReg h() const { return m_h; }
|
||||||
bool srcDstRegMatch(iICODE a,iICODE b) const;
|
bool srcDstRegMatch(iICODE a,iICODE b) const;
|
||||||
|
LONGID_TYPE() {} // uninitializing constructor to help valgrind catch uninit accesses
|
||||||
|
LONGID_TYPE(eReg h,eReg l) : m_h(h),m_l(l) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LONGGLB_TYPE /* For TYPE_LONG_(UN)SIGN globals */
|
||||||
|
{
|
||||||
|
int16_t seg; /* segment value */
|
||||||
|
int16_t offH; /* offset high */
|
||||||
|
int16_t offL; /* offset low */
|
||||||
|
uint8_t regi; /* optional indexed register */
|
||||||
|
LONGGLB_TYPE(int16_t _seg,int16_t _H,int16_t _L,int8_t _reg=0)
|
||||||
|
{
|
||||||
|
seg=_seg;
|
||||||
|
offH=_H;
|
||||||
|
offL=_L;
|
||||||
|
regi=_reg;
|
||||||
|
}
|
||||||
|
};
|
||||||
/* ID, LOCAL_ID */
|
/* ID, LOCAL_ID */
|
||||||
struct ID
|
struct ID
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
|
||||||
|
public:
|
||||||
hlType type; /* Probable type */
|
hlType type; /* Probable type */
|
||||||
bool illegal; /* Boolean: not a valid field any more */
|
bool illegal; /* Boolean: not a valid field any more */
|
||||||
//std::vector<iICODE> idx;
|
//std::vector<iICODE> idx;
|
||||||
@@ -69,37 +100,43 @@ struct ID
|
|||||||
bool hasMacro; /* Identifier requires a macro */
|
bool hasMacro; /* Identifier requires a macro */
|
||||||
char macro[10]; /* Macro for this identifier */
|
char macro[10]; /* Macro for this identifier */
|
||||||
std::string name; /* Identifier's name */
|
std::string name; /* Identifier's name */
|
||||||
union { /* Different types of identifiers */
|
union ID_UNION { /* Different types of identifiers */
|
||||||
|
friend struct ID;
|
||||||
|
protected:
|
||||||
|
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
|
||||||
|
public:
|
||||||
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
|
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
|
||||||
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
|
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
|
||||||
uint8_t regOff; /* register offset (if any) */
|
uint8_t regOff; /* register offset (if any) */
|
||||||
int off; /* offset from BP */
|
int off; /* offset from BP */
|
||||||
} bwId;
|
} bwId;
|
||||||
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
|
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
|
||||||
LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers */
|
LONGGLB_TYPE longGlb;
|
||||||
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
|
|
||||||
struct { /* For TYPE_LONG_(UN)SIGN globals */
|
|
||||||
int16_t seg; /* segment value */
|
|
||||||
int16_t offH; /* offset high */
|
|
||||||
int16_t offL; /* offset low */
|
|
||||||
uint8_t regi; /* optional indexed register */
|
|
||||||
} longGlb;
|
|
||||||
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
struct { /* For TYPE_LONG_(UN)SIGN constants */
|
||||||
uint32_t h; /* high uint16_t */
|
uint32_t h; /* high uint16_t */
|
||||||
uint32_t l; /* low uint16_t */
|
uint32_t l; /* low uint16_t */
|
||||||
} longKte;
|
} longKte;
|
||||||
|
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
|
||||||
} id;
|
} id;
|
||||||
|
LONGID_TYPE & longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
||||||
|
const LONGID_TYPE & longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
|
||||||
|
LONG_STKID_TYPE & longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
||||||
|
const LONG_STKID_TYPE & longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
|
||||||
ID();
|
ID();
|
||||||
ID(hlType t, frameType f);
|
ID(hlType t, frameType f);
|
||||||
|
ID(hlType t, const LONGID_TYPE &s);
|
||||||
|
ID(hlType t, const LONG_STKID_TYPE &s);
|
||||||
|
ID(hlType t, const LONGGLB_TYPE &s);
|
||||||
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
|
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
|
||||||
uint16_t typeBitsize() const
|
uint16_t typeBitsize() const
|
||||||
{
|
{
|
||||||
return TypeContainer::typeSize(type)*8;
|
return TypeContainer::typeSize(type)*8;
|
||||||
}
|
}
|
||||||
|
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
|
||||||
void setLocalName(int i)
|
void setLocalName(int i)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
sprintf (buf, "loc%ld", i);
|
sprintf (buf, "loc%d", i);
|
||||||
name=buf;
|
name=buf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -121,8 +158,8 @@ public:
|
|||||||
std::vector<ID>::iterator end() {return id_arr.end();}
|
std::vector<ID>::iterator end() {return id_arr.end();}
|
||||||
int newByteWordReg(hlType t, eReg regi);
|
int newByteWordReg(hlType t, eReg regi);
|
||||||
int newByteWordStk(hlType t, int off, uint8_t regOff);
|
int newByteWordStk(hlType t, int off, uint8_t regOff);
|
||||||
int newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t);
|
int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t);
|
||||||
int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_);
|
int newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_);
|
||||||
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
|
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
|
||||||
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
|
||||||
void newIdent(hlType t, frameType f);
|
void newIdent(hlType t, frameType f);
|
||||||
@@ -131,8 +168,8 @@ public:
|
|||||||
size_t csym() const {return id_arr.size();}
|
size_t csym() const {return id_arr.size();}
|
||||||
void newRegArg(iICODE picode, iICODE ticode) const;
|
void newRegArg(iICODE picode, iICODE ticode) const;
|
||||||
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
||||||
void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
|
void forwardSubs(Expr *lhs, Expr *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
|
||||||
COND_EXPR *createId(const ID *retVal, iICODE ix_);
|
AstIdent *createId(const ID *retVal, iICODE ix_);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
struct LivenessSet;
|
||||||
/* Machine registers */
|
/* Machine registers */
|
||||||
enum eReg
|
enum eReg
|
||||||
{
|
{
|
||||||
@@ -32,8 +33,9 @@ enum eReg
|
|||||||
rBH = 20,
|
rBH = 20,
|
||||||
|
|
||||||
rTMP= 21, /* temp register for DIV/IDIV/MOD */
|
rTMP= 21, /* temp register for DIV/IDIV/MOD */
|
||||||
|
rTMP2= 22, /* temp register for DIV/IDIV/MOD */
|
||||||
/* Indexed modes go from INDEXBASE to INDEXBASE+7 */
|
/* Indexed modes go from INDEXBASE to INDEXBASE+7 */
|
||||||
INDEX_BX_SI = 22, // "bx+si"
|
INDEX_BX_SI = 23, // "bx+si"
|
||||||
INDEX_BX_DI, // "bx+di"
|
INDEX_BX_DI, // "bx+di"
|
||||||
INDEX_BP_SI, // "bp+si"
|
INDEX_BP_SI, // "bp+si"
|
||||||
INDEX_BP_DI, // "bp+di"
|
INDEX_BP_DI, // "bp+di"
|
||||||
@@ -64,19 +66,14 @@ public:
|
|||||||
bool physicalReg(eReg r);
|
bool physicalReg(eReg r);
|
||||||
/* Writes the registers that are set in the bitvector */
|
/* Writes the registers that are set in the bitvector */
|
||||||
//TODO: move this into Machine_X86 ?
|
//TODO: move this into Machine_X86 ?
|
||||||
static void writeRegVector (std::ostream &ostr,const std::bitset<32> ®i)
|
static void writeRegVector (std::ostream &ostr,const LivenessSet ®i);
|
||||||
{
|
static eReg subRegH(eReg reg);
|
||||||
int j;
|
|
||||||
for (j = rAX; j < INDEX_BX_SI; j++)
|
|
||||||
{
|
|
||||||
if (regi.test(j-1))
|
|
||||||
ostr << regName(eReg(j))<<" ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static eReg subRegH(eReg reg); //TODO: move these into machine_x86
|
|
||||||
static eReg subRegL(eReg reg);
|
static eReg subRegL(eReg reg);
|
||||||
|
|
||||||
static bool isMemOff(eReg r);
|
static bool isMemOff(eReg r);
|
||||||
static bool isSubRegisterOf(eReg reg, eReg parent);
|
static bool isSubRegisterOf(eReg reg, eReg parent);
|
||||||
|
static bool hasSubregisters(eReg reg);
|
||||||
|
|
||||||
|
static bool isPartOfComposite(eReg reg);
|
||||||
|
static eReg compositeParent(eReg reg);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,10 +3,7 @@
|
|||||||
hashing functions
|
hashing functions
|
||||||
* (C) Mike van Emmerik
|
* (C) Mike van Emmerik
|
||||||
*/
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
//#define bool unsigned char
|
|
||||||
#define uint8_t unsigned char
|
|
||||||
#define uint16_t unsigned short
|
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
void hashCleanup(void); /* Frees memory allocated by hashParams() */
|
void hashCleanup(void); /* Frees memory allocated by hashParams() */
|
||||||
|
|||||||
@@ -4,60 +4,49 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
|
#include <boost/icl/interval.hpp>
|
||||||
|
#include <boost/icl/interval_map.hpp>
|
||||||
|
#include <boost/icl/split_interval_map.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "BinaryImage.h"
|
#include "BinaryImage.h"
|
||||||
struct Function;
|
#include "Procedure.h"
|
||||||
struct SourceMachine;
|
class SourceMachine;
|
||||||
struct CALL_GRAPH;
|
struct CALL_GRAPH;
|
||||||
|
class IProject
|
||||||
|
{
|
||||||
|
virtual PROG *binary()=0;
|
||||||
|
virtual const std::string & project_name() const =0;
|
||||||
|
virtual const std::string & binary_path() const =0;
|
||||||
|
};
|
||||||
|
class Project : public IProject
|
||||||
|
{
|
||||||
|
static Project *s_instance;
|
||||||
|
std::string m_fname;
|
||||||
|
std::string m_project_name;
|
||||||
|
public:
|
||||||
|
|
||||||
typedef llvm::iplist<Function> FunctionListType;
|
typedef llvm::iplist<Function> FunctionListType;
|
||||||
typedef FunctionListType lFunction;
|
typedef FunctionListType lFunction;
|
||||||
typedef lFunction::iterator ilFunction;
|
typedef FunctionListType::iterator ilFunction;
|
||||||
|
|
||||||
|
|
||||||
struct Project
|
|
||||||
{
|
|
||||||
SYMTAB symtab; /* Global symbol table */
|
SYMTAB symtab; /* Global symbol table */
|
||||||
|
|
||||||
std::string m_fname;
|
|
||||||
FunctionListType pProcList;
|
FunctionListType pProcList;
|
||||||
CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
||||||
PROG prog; /* Loaded program image parameters */
|
PROG prog; /* Loaded program image parameters */
|
||||||
Project() {}
|
|
||||||
// no copies
|
// no copies
|
||||||
Project(const Project&) = delete;
|
Project(const Project&) = delete;
|
||||||
const Project &operator=(const Project & l) =delete;
|
const Project &operator=(const Project & l) =delete;
|
||||||
// only moves
|
// only moves
|
||||||
Project(Project && l)
|
Project(); // default constructor,
|
||||||
{
|
|
||||||
m_fname =l.m_fname;
|
|
||||||
size_t before=l.pProcList.size();
|
|
||||||
pProcList.splice(pProcList.end(),l.pProcList);
|
|
||||||
callGraph=l.callGraph;
|
|
||||||
l.m_fname.clear();
|
|
||||||
l.pProcList.clear();
|
|
||||||
l.callGraph=0;
|
|
||||||
assert(before==pProcList.size());
|
|
||||||
}
|
|
||||||
Project &operator=(Project && l)
|
|
||||||
{
|
|
||||||
if(this == &l)
|
|
||||||
return *this;
|
|
||||||
m_fname =l.m_fname;
|
|
||||||
size_t before=l.pProcList.size();
|
|
||||||
pProcList.splice(pProcList.end(),l.pProcList);
|
|
||||||
callGraph=l.callGraph;
|
|
||||||
l.m_fname.clear();
|
|
||||||
l.pProcList.clear();
|
|
||||||
l.callGraph=0;
|
|
||||||
assert(before==pProcList.size());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void create(const std::string & a);
|
||||||
|
const std::string &project_name() const {return m_project_name;}
|
||||||
|
const std::string &binary_path() const {return m_fname;}
|
||||||
ilFunction funcIter(Function *to_find);
|
ilFunction funcIter(Function *to_find);
|
||||||
ilFunction findByEntry(uint32_t entry);
|
ilFunction findByEntry(uint32_t entry);
|
||||||
ilFunction createFunction();
|
ilFunction createFunction(FunctionType *f,const std::string &name);
|
||||||
bool valid(ilFunction iter);
|
bool valid(ilFunction iter);
|
||||||
|
|
||||||
int getSymIdxByAdd(uint32_t adr);
|
int getSymIdxByAdd(uint32_t adr);
|
||||||
@@ -72,6 +61,7 @@ public:
|
|||||||
SourceMachine *machine();
|
SourceMachine *machine();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void initialize();
|
||||||
void writeGlobSymTable();
|
void writeGlobSymTable();
|
||||||
};
|
};
|
||||||
//extern Project g_proj;
|
//extern Project g_proj;
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
/* Extracts reg bits from middle of mod-reg-rm uint8_t */
|
|
||||||
#define REG(x) ((uint8_t)(x & 0x38) >> 3)
|
#define REG(x) ((uint8_t)(x & 0x38) >> 3)
|
||||||
|
//#define LH(p) ((int)((uint8_t *)(p))[0] + ((int)((uint8_t *)(p))[1] << 8))
|
||||||
struct ICODE;
|
struct ICODE;
|
||||||
|
/* Extracts reg bits from middle of mod-reg-rm uint8_t */
|
||||||
extern eErrorId scan(uint32_t ip, ICODE &p);
|
extern eErrorId scan(uint32_t ip, ICODE &p);
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ struct STATE
|
|||||||
memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86
|
memset(r,0,sizeof(int16_t)*INDEX_BX_SI); //TODO: move this to machine_x86
|
||||||
memset(f,0,sizeof(uint8_t)*INDEX_BX_SI);
|
memset(f,0,sizeof(uint8_t)*INDEX_BX_SI);
|
||||||
}
|
}
|
||||||
|
void setMemoryByte(uint32_t addr,uint8_t val)
|
||||||
|
{
|
||||||
|
//TODO: make this into a full scale value tracking class !
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
struct COND_EXPR;
|
struct Expr;
|
||||||
|
struct AstIdent;
|
||||||
struct TypeContainer;
|
struct TypeContainer;
|
||||||
/* * * * * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * * * */
|
||||||
/* Symbol table structs and protos */
|
/* Symbol table structs and protos */
|
||||||
@@ -23,26 +24,29 @@ struct SymbolCommon
|
|||||||
};
|
};
|
||||||
struct SYM : public SymbolCommon
|
struct SYM : public SymbolCommon
|
||||||
{
|
{
|
||||||
|
typedef uint32_t tLabel;
|
||||||
SYM() : label(0),flg(0)
|
SYM() : label(0),flg(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
int32_t label; /* physical address (20 bit) */
|
uint32_t label; /* physical address (20 bit) */
|
||||||
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
|
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
|
||||||
};
|
};
|
||||||
/* STACK FRAME */
|
/* STACK FRAME */
|
||||||
struct STKSYM : public SymbolCommon
|
struct STKSYM : public SymbolCommon
|
||||||
{
|
{
|
||||||
COND_EXPR *actual; /* Expression tree of actual parameter */
|
typedef int16_t tLabel;
|
||||||
COND_EXPR *regs; /* For register arguments only */
|
Expr *actual; /* Expression tree of actual parameter */
|
||||||
int16_t label; /* Immediate off from BP (+:args, -:params) */
|
AstIdent *regs; /* For register arguments only */
|
||||||
|
tLabel label; /* Immediate off from BP (+:args, -:params) */
|
||||||
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
|
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
|
||||||
bool hasMacro; /* This type needs a macro */
|
bool hasMacro; /* This type needs a macro */
|
||||||
std::string macro; /* Macro name */
|
std::string macro; /* Macro name */
|
||||||
bool invalid; /* Boolean: invalid entry in formal arg list*/
|
bool invalid; /* Boolean: invalid entry in formal arg list*/
|
||||||
STKSYM()
|
STKSYM()
|
||||||
{
|
{
|
||||||
actual=regs=0;
|
actual=0;
|
||||||
|
regs=0;
|
||||||
label=0;
|
label=0;
|
||||||
regOff=0;
|
regOff=0;
|
||||||
invalid=hasMacro = false;
|
invalid=hasMacro = false;
|
||||||
@@ -60,13 +64,13 @@ class SymbolTableCommon : public std::vector<T>
|
|||||||
public:
|
public:
|
||||||
typedef typename std::vector<T>::iterator iterator;
|
typedef typename std::vector<T>::iterator iterator;
|
||||||
typedef typename std::vector<T>::const_iterator const_iterator;
|
typedef typename std::vector<T>::const_iterator const_iterator;
|
||||||
iterator findByLabel(int lab)
|
iterator findByLabel(typename T::tLabel lab)
|
||||||
{
|
{
|
||||||
auto iter = std::find_if(this->begin(),this->end(),
|
auto iter = std::find_if(this->begin(),this->end(),
|
||||||
[lab](T &s)->bool {return s.label==lab;});
|
[lab](T &s)->bool {return s.label==lab;});
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
const_iterator findByLabel(int lab) const
|
const_iterator findByLabel(typename T::tLabel lab) const
|
||||||
{
|
{
|
||||||
auto iter = std::find_if(this->begin(),this->end(),
|
auto iter = std::find_if(this->begin(),this->end(),
|
||||||
[lab](const T &s)->bool {return s.label==lab;});
|
[lab](const T &s)->bool {return s.label==lab;});
|
||||||
@@ -102,12 +106,12 @@ struct SYMTABLE
|
|||||||
enum tableType /* The table types */
|
enum tableType /* The table types */
|
||||||
{
|
{
|
||||||
Label=0, /* The label table */
|
Label=0, /* The label table */
|
||||||
Comment, /* The comment table */
|
Comment /* The comment table */
|
||||||
NUM_TABLE_TYPES /* Number of entries: must be last */
|
|
||||||
};
|
};
|
||||||
|
constexpr int NUM_TABLE_TYPES = int(Comment)+1; /* Number of entries: must be last */
|
||||||
|
|
||||||
void createSymTables(void);
|
void createSymTables(void);
|
||||||
void destroySymTables(void);
|
void destroySymTables(void);
|
||||||
boolT readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
|
bool readVal (std::ostringstream &symName, uint32_t symOff, Function *symProc);
|
||||||
void selectTable(tableType); /* Select a particular table */
|
void selectTable(tableType); /* Select a particular table */
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
/****************************************************************************
|
/*
|
||||||
|
***************************************************************************
|
||||||
* dcc project general header
|
* dcc project general header
|
||||||
* (C) Cristina Cifuentes, Mike van Emmerik
|
* (C) Cristina Cifuentes, Mike van Emmerik
|
||||||
****************************************************************************/
|
***************************************************************************
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -10,10 +12,6 @@
|
|||||||
#define MAX 0x7FFFFFFF
|
#define MAX 0x7FFFFFFF
|
||||||
|
|
||||||
/* Type definitions used in the program */
|
/* Type definitions used in the program */
|
||||||
typedef unsigned char byte; /* 8 bits */
|
|
||||||
typedef unsigned short word;/* 16 bits */
|
|
||||||
typedef short int16; /* 16 bits */
|
|
||||||
typedef unsigned char boolT; /* 8 bits */
|
|
||||||
|
|
||||||
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
|
#define SYNTHESIZED_MIN 0x100000 /* Synthesized labs use bits 21..32 */
|
||||||
|
|
||||||
@@ -22,17 +20,17 @@ typedef unsigned char boolT; /* 8 bits */
|
|||||||
#define PATLEN 23 /* Length of proc patterns */
|
#define PATLEN 23 /* Length of proc patterns */
|
||||||
#define WILD 0xF4 /* The wild byte */
|
#define WILD 0xF4 /* The wild byte */
|
||||||
|
|
||||||
/****** MACROS *******/
|
/* MACROS */
|
||||||
|
|
||||||
/* Macro reads a LH word from the image regardless of host convention */
|
// Macro reads a LH word from the image regardless of host convention
|
||||||
/* Returns a 16 bit quantity, e.g. C000 is read into an Int as C000 */
|
// Returns a 16 bit quantity, e.g. C000 is read into an Int as C000
|
||||||
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
|
//#define LH(p) ((int16)((byte *)(p))[0] + ((int16)((byte *)(p))[1] << 8))
|
||||||
#define LH(p) ((word)((byte *)(p))[0] + ((word)((byte *)(p))[1] << 8))
|
#define LH(p) ((uint16_t)((uint8_t *)(p))[0] + ((uint16_t)((uint8_t *)(p))[1] << 8))
|
||||||
|
|
||||||
|
|
||||||
/* Macro reads a LH word from the image regardless of host convention */
|
/* Macro reads a LH word from the image regardless of host convention */
|
||||||
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
|
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
|
||||||
#define LH_SIGNED(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
|
#define LH_SIGNED(p) (((uint8_t *)(p))[0] + (((char *)(p))[1] << 8))
|
||||||
|
|
||||||
/* Macro tests bit b for type t in prog.map */
|
/* Macro tests bit b for type t in prog.map */
|
||||||
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
||||||
@@ -53,19 +51,20 @@ struct eDuVal
|
|||||||
USE=2,
|
USE=2,
|
||||||
VAL=4
|
VAL=4
|
||||||
};
|
};
|
||||||
int def :1; /* Variable was first defined than used */
|
uint8_t def :1; //!< Variable was first defined than used
|
||||||
int use :1; /* Variable was first used than defined */
|
uint8_t use :1; //!< Variable was first used than defined
|
||||||
int val :1; /* Variable has an initial value. 2 cases:
|
uint8_t val :1; /* Variable has an initial value. 2 cases:
|
||||||
* 1. When variable is used first (ie. global)
|
1. When variable is used first (ie. global)
|
||||||
* 2. When a value is moved into the variable
|
2. When a value is moved into the variable
|
||||||
* for the first time. */
|
for the first time.
|
||||||
|
*/
|
||||||
void setFlags(uint16_t x)
|
void setFlags(uint16_t x)
|
||||||
{
|
{
|
||||||
def = x&DEF;
|
def = x&DEF;
|
||||||
use = x&USE;
|
use = x&USE;
|
||||||
val = x&VAL;
|
val = x&VAL;
|
||||||
}
|
}
|
||||||
bool isUSE_VAL() {return use&&val;} /* Use and Val */
|
bool isUSE_VAL() {return use&&val;} //Use and Val
|
||||||
};
|
};
|
||||||
static constexpr const char * hlTypes[13] = {
|
static constexpr const char * hlTypes[13] = {
|
||||||
"", "char", "unsigned char", "int", "unsigned int",
|
"", "char", "unsigned char", "int", "unsigned int",
|
||||||
@@ -88,6 +87,12 @@ struct TypeContainer
|
|||||||
return 2;
|
return 2;
|
||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
return 1;
|
return 1;
|
||||||
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
|
return 4;
|
||||||
|
case TYPE_FLOAT:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return ~0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ def perform_test(exepath,filepath,outname,args)
|
|||||||
filepath=path_local(filepath)
|
filepath=path_local(filepath)
|
||||||
joined_args = args.join(' ')
|
joined_args = args.join(' ')
|
||||||
printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
|
printf("calling:" + "#{exepath} -a1 #{joined_args} -o#{output_path}.a1 #{filepath}\n")
|
||||||
|
STDERR << "Errors for : #{filepath}"
|
||||||
result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
|
result = `#{exepath} -a1 -o#{output_path}.a1 #{filepath}`
|
||||||
result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
|
result = `#{exepath} -a2 #{joined_args} -o#{output_path}.a2 #{filepath}`
|
||||||
|
result = `#{exepath} #{joined_args} -o#{output_path} #{filepath}`
|
||||||
puts result
|
puts result
|
||||||
p $?
|
p $?
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
|
BB *BB::Create(void */*ctx*/, const string &/*s*/, Function *parent, BB */*insertBefore*/)
|
||||||
{
|
{
|
||||||
BB *pnewBB = new BB;
|
BB *pnewBB = new BB;
|
||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
@@ -19,7 +19,7 @@ BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
|
|||||||
* @arg start - basic block starts here, might be parent->Icode.end()
|
* @arg start - basic block starts here, might be parent->Icode.end()
|
||||||
* @arg fin - last of basic block's instructions
|
* @arg fin - last of basic block's instructions
|
||||||
*/
|
*/
|
||||||
BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent)
|
BB *BB::Create(const rCODE &r,eBBKind _nodeType, Function *parent)
|
||||||
{
|
{
|
||||||
BB* pnewBB;
|
BB* pnewBB;
|
||||||
pnewBB = new BB;
|
pnewBB = new BB;
|
||||||
@@ -27,47 +27,30 @@ BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Fun
|
|||||||
pnewBB->immedDom = NO_DOM;
|
pnewBB->immedDom = NO_DOM;
|
||||||
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
||||||
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
||||||
pnewBB->instructions = make_iterator_range(start,fin);
|
pnewBB->instructions = r;
|
||||||
if(start==parent->Icode.end())
|
int addr = pnewBB->begin()->loc_ip;
|
||||||
{
|
|
||||||
pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive
|
|
||||||
}
|
|
||||||
if (numOutEdges)
|
|
||||||
pnewBB->edges.resize(numOutEdges);
|
|
||||||
|
|
||||||
/* Mark the basic block to which the icodes belong to, but only for
|
/* Mark the basic block to which the icodes belong to, but only for
|
||||||
* real code basic blocks (ie. not interval bbs) */
|
* real code basic blocks (ie. not interval bbs) */
|
||||||
if(parent)
|
if(parent)
|
||||||
{
|
{
|
||||||
if (start != parent->Icode.end())
|
//setInBB should automatically handle if our range is empty
|
||||||
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
||||||
parent->heldBBs.push_back(pnewBB);
|
|
||||||
parent->m_cfg.push_back(pnewBB);
|
assert(parent->m_ip_to_bb.find(addr)==parent->m_ip_to_bb.end());
|
||||||
|
parent->m_ip_to_bb[addr] = pnewBB;
|
||||||
|
parent->m_actual_cfg.push_back(pnewBB);
|
||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
}
|
}
|
||||||
if ( start != parent->Icode.end() ) /* Only for code BB's */
|
|
||||||
|
if ( r.begin() != parent->Icode.end() ) /* Only for code BB's */
|
||||||
stats.numBBbef++;
|
stats.numBBbef++;
|
||||||
return pnewBB;
|
return pnewBB;
|
||||||
|
|
||||||
}
|
}
|
||||||
BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent)
|
BB *BB::CreateIntervalBB(Function *parent)
|
||||||
{
|
{
|
||||||
iICODE st(parent->Icode.begin());
|
iICODE endOfParent = parent->Icode.end();
|
||||||
iICODE fin(parent->Icode.begin());
|
return Create(make_iterator_range(endOfParent,endOfParent),INTERVAL_NODE,nullptr);
|
||||||
if(start==-1)
|
|
||||||
{
|
|
||||||
st = parent->Icode.end();
|
|
||||||
fin = parent->Icode.end();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
advance(st,start);
|
|
||||||
advance(fin,ip);
|
|
||||||
}
|
|
||||||
return Create(st,fin,_nodeType,numOutEdges,parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
||||||
@@ -81,14 +64,14 @@ static const char *const s_loopType[] = {"noLoop", "while", "repeat", "loop", "f
|
|||||||
void BB::display()
|
void BB::display()
|
||||||
{
|
{
|
||||||
printf("\nnode type = %s, ", s_nodeType[nodeType]);
|
printf("\nnode type = %s, ", s_nodeType[nodeType]);
|
||||||
printf("start = %ld, length = %ld, #out edges = %ld\n", begin()->loc_ip, size(), edges.size());
|
printf("start = %d, length = %zd, #out edges = %zd\n", begin()->loc_ip, size(), edges.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < edges.size(); i++)
|
for (size_t i = 0; i < edges.size(); i++)
|
||||||
{
|
{
|
||||||
if(edges[i].BBptr==0)
|
if(edges[i].BBptr==nullptr)
|
||||||
printf(" outEdge[%2d] = Unlinked out edge to %d\n",i, edges[i].ip);
|
printf(" outEdge[%2zd] = Unlinked out edge to %d\n",i, edges[i].ip);
|
||||||
else
|
else
|
||||||
printf(" outEdge[%2d] = %d\n",i, edges[i].BBptr->begin()->loc_ip);
|
printf(" outEdge[%2zd] = %d\n",i, edges[i].BBptr->begin()->loc_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@@ -101,29 +84,29 @@ void BB::displayDfs()
|
|||||||
traversed = DFS_DISP;
|
traversed = DFS_DISP;
|
||||||
|
|
||||||
printf("node type = %s, ", s_nodeType[nodeType]);
|
printf("node type = %s, ", s_nodeType[nodeType]);
|
||||||
printf("start = %ld, length = %ld, #in-edges = %ld, #out-edges = %ld\n",
|
printf("start = %d, length = %zd, #in-edges = %zd, #out-edges = %zd\n",
|
||||||
begin()->loc_ip, size(), inEdges.size(), edges.size());
|
begin()->loc_ip, size(), inEdges.size(), edges.size());
|
||||||
printf("dfsFirst = %ld, dfsLast = %ld, immed dom = %ld\n",
|
printf("dfsFirst = %d, dfsLast = %d, immed dom = %d\n",
|
||||||
dfsFirstNum, dfsLastNum,
|
dfsFirstNum, dfsLastNum,
|
||||||
immedDom == MAX ? -1 : immedDom);
|
immedDom == MAX ? -1 : immedDom);
|
||||||
printf("loopType = %s, loopHead = %ld, latchNode = %ld, follow = %ld\n",
|
printf("loopType = %s, loopHead = %d, latchNode = %d, follow = %d\n",
|
||||||
s_loopType[loopType],
|
s_loopType[loopType],
|
||||||
loopHead == MAX ? -1 : loopHead,
|
loopHead == MAX ? -1 : loopHead,
|
||||||
latchNode == MAX ? -1 : latchNode,
|
latchNode == MAX ? -1 : latchNode,
|
||||||
loopFollow == MAX ? -1 : loopFollow);
|
loopFollow == MAX ? -1 : loopFollow);
|
||||||
printf ("ifFollow = %ld, caseHead = %ld, caseTail = %ld\n",
|
printf ("ifFollow = %d, caseHead = %d, caseTail = %d\n",
|
||||||
ifFollow == MAX ? -1 : ifFollow,
|
ifFollow == MAX ? -1 : ifFollow,
|
||||||
caseHead == MAX ? -1 : caseHead,
|
caseHead == MAX ? -1 : caseHead,
|
||||||
caseTail == MAX ? -1 : caseTail);
|
caseTail == MAX ? -1 : caseTail);
|
||||||
|
|
||||||
if (nodeType == INTERVAL_NODE)
|
if (nodeType == INTERVAL_NODE)
|
||||||
printf("corresponding interval = %ld\n", correspInt->numInt);
|
printf("corresponding interval = %d\n", correspInt->numInt);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int edge_idx=0;
|
int edge_idx=0;
|
||||||
for(BB *node : inEdges)
|
for(BB *node : inEdges)
|
||||||
{
|
{
|
||||||
printf (" inEdge[%ld] = %ld\n", edge_idx, node->begin()->loc_ip);
|
printf (" inEdge[%d] = %d\n", edge_idx, node->begin()->loc_ip);
|
||||||
edge_idx++;
|
edge_idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,9 +115,9 @@ void BB::displayDfs()
|
|||||||
for(TYPEADR_TYPE &edg : edges)
|
for(TYPEADR_TYPE &edg : edges)
|
||||||
{
|
{
|
||||||
if (nodeType == INTERVAL_NODE)
|
if (nodeType == INTERVAL_NODE)
|
||||||
printf(" outEdge[%ld] = %ld\n", i, edg.BBptr->correspInt->numInt);
|
printf(" outEdge[%d] = %d\n", i, edg.BBptr->correspInt->numInt);
|
||||||
else
|
else
|
||||||
printf(" outEdge[%d] = %ld\n", i, edg.BBptr->begin()->loc_ip);
|
printf(" outEdge[%d] = %d\n", i, edg.BBptr->begin()->loc_ip);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
printf("----\n");
|
printf("----\n");
|
||||||
@@ -146,14 +129,12 @@ void BB::displayDfs()
|
|||||||
pb.BBptr->displayDfs();
|
pb.BBptr->displayDfs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Recursive procedure that writes the code for the given procedure, pointed
|
/** Recursive procedure that writes the code for the given procedure, pointed
|
||||||
* to by pBB.
|
to by pBB.
|
||||||
* Parameters: pBB: pointer to the cfg.
|
\param indLevel indentation level - used for formatting.
|
||||||
* Icode: pointer to the Icode array for the cfg graph of the
|
\param numLoc: last # assigned to local variables
|
||||||
* current procedure.
|
*/
|
||||||
* indLevel: indentation level - used for formatting.
|
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, bool &repCond)
|
||||||
* numLoc: last # assigned to local variables */
|
|
||||||
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
|
|
||||||
{
|
{
|
||||||
latch = pProc->m_dfsLast[this->latchNode];
|
latch = pProc->m_dfsLast[this->latchNode];
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
@@ -179,10 +160,10 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
* the THEN path of the header node */
|
* the THEN path of the header node */
|
||||||
if (edges[ELSE].BBptr->dfsLastNum == loopFollow)
|
if (edges[ELSE].BBptr->dfsLastNum == loopFollow)
|
||||||
{
|
{
|
||||||
picode->hl()->replaceExpr(picode->hl()->expr()->inverse());
|
picode->hlU()->replaceExpr(picode->hl()->expr()->inverse());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc);
|
string e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
||||||
}
|
}
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@@ -196,6 +177,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
|
|
||||||
case ENDLESS_TYPE:
|
case ENDLESS_TYPE:
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
||||||
|
picode = &latch->back();
|
||||||
}
|
}
|
||||||
cCode.appendCode(ostr.str());
|
cCode.appendCode(ostr.str());
|
||||||
stats.numHLIcode += 1;
|
stats.numHLIcode += 1;
|
||||||
@@ -212,8 +194,8 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
int follow; /* ifFollow */
|
int follow; /* ifFollow */
|
||||||
BB * succ, *latch; /* Successor and latching node */
|
BB * succ, *latch; /* Successor and latching node */
|
||||||
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
||||||
char *l; /* Pointer to HLI_JCOND expression */
|
std::string l; /* Pointer to HLI_JCOND expression */
|
||||||
boolT emptyThen, /* THEN clause is empty */
|
bool emptyThen, /* THEN clause is empty */
|
||||||
repCond; /* Repeat condition for while() */
|
repCond; /* Repeat condition for while() */
|
||||||
|
|
||||||
/* Check if this basic block should be analysed */
|
/* Check if this basic block should be analysed */
|
||||||
@@ -226,7 +208,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
|
|
||||||
/* Check for start of loop */
|
/* Check for start of loop */
|
||||||
repCond = false;
|
repCond = false;
|
||||||
latch = NULL;
|
latch = nullptr;
|
||||||
if (loopType)
|
if (loopType)
|
||||||
{
|
{
|
||||||
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
|
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
|
||||||
@@ -245,7 +227,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check type of loop/node and process code */
|
/* Check type of loop/node and process code */
|
||||||
if ( loopType) /* there is a loop */
|
if ( loopType ) /* there is a loop */
|
||||||
{
|
{
|
||||||
assert(latch);
|
assert(latch);
|
||||||
if (this != latch) /* loop is over several bbs */
|
if (this != latch) /* loop is over several bbs */
|
||||||
@@ -282,12 +264,16 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
||||||
else if (loopType == REPEAT_TYPE)
|
else if (loopType == REPEAT_TYPE)
|
||||||
{
|
{
|
||||||
|
string e = "//*failed*//";
|
||||||
if (picode->hl()->opcode != HLI_JCOND)
|
if (picode->hl()->opcode != HLI_JCOND)
|
||||||
reportError (REPEAT_FAIL);
|
|
||||||
{
|
{
|
||||||
string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc);
|
reportError (REPEAT_FAIL);
|
||||||
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str());
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e=picode->hl()->expr()->walkCondExpr (pProc, numLoc);
|
||||||
|
}
|
||||||
|
cCode.appendCode( "%s} while (%s);\n", indentStr(indLevel),e.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recurse on the loop follow */
|
/* Recurse on the loop follow */
|
||||||
@@ -319,13 +305,13 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
if (succ->dfsLastNum != follow) /* THEN part */
|
if (succ->dfsLastNum != follow) /* THEN part */
|
||||||
{
|
{
|
||||||
l = writeJcond ( *back().hl(), pProc, numLoc);
|
l = writeJcond ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l);
|
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
|
||||||
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
|
succ->writeCode (indLevel, pProc, numLoc, _latchNode,follow);
|
||||||
}
|
}
|
||||||
else /* empty THEN part => negate ELSE part */
|
else /* empty THEN part => negate ELSE part */
|
||||||
{
|
{
|
||||||
l = writeJcondInv ( *back().hl(), pProc, numLoc);
|
l = writeJcondInv ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l);
|
cCode.appendCode( "\n%s%s", indentStr(indLevel-1), l.c_str());
|
||||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
|
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, follow);
|
||||||
emptyThen = true;
|
emptyThen = true;
|
||||||
}
|
}
|
||||||
@@ -361,7 +347,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
else /* no follow => if..then..else */
|
else /* no follow => if..then..else */
|
||||||
{
|
{
|
||||||
l = writeJcond ( *back().hl(), pProc, numLoc);
|
l = writeJcond ( *back().hl(), pProc, numLoc);
|
||||||
cCode.appendCode( "%s%s", indentStr(indLevel-1), l);
|
cCode.appendCode( "%s%s", indentStr(indLevel-1), l.c_str());
|
||||||
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
||||||
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
|
cCode.appendCode( "%s}\n%selse {\n", indentStr(indLevel-1), indentStr(indLevel - 1));
|
||||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, _latchNode, _ifFollow);
|
||||||
@@ -410,27 +396,26 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
|||||||
|
|
||||||
iICODE BB::begin()
|
iICODE BB::begin()
|
||||||
{
|
{
|
||||||
return instructions.begin();//range_start;
|
return instructions.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iICODE BB::end() const
|
iICODE BB::end() const
|
||||||
{
|
{
|
||||||
return instructions.end();//range_end
|
return instructions.end();
|
||||||
}
|
}
|
||||||
ICODE &BB::back()
|
ICODE &BB::back()
|
||||||
{
|
{
|
||||||
return instructions.back();//*rbegin();
|
return instructions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BB::size()
|
size_t BB::size()
|
||||||
{
|
{
|
||||||
|
|
||||||
return distance(instructions.begin(),instructions.end());
|
return distance(instructions.begin(),instructions.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
ICODE &BB::front()
|
ICODE &BB::front()
|
||||||
{
|
{
|
||||||
return instructions.front();//*begin();
|
return instructions.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
riICODE BB::rbegin()
|
riICODE BB::rbegin()
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
SET(dcc_test_SOURCES tests/comwrite.cpp)
|
SET(dcc_test_SOURCES
|
||||||
|
tests/comwrite.cpp
|
||||||
|
tests/project.cpp
|
||||||
|
tests/loader.cpp
|
||||||
|
|
||||||
|
)
|
||||||
include_directories(${GMOCK_INCLUDE_DIRS} ${GMOCK_ROOT}/gtest/include)
|
include_directories(${GMOCK_INCLUDE_DIRS} ${GMOCK_ROOT}/gtest/include)
|
||||||
enable_testing()
|
|
||||||
add_executable(tester ${dcc_test_SOURCES})
|
add_executable(tester ${dcc_test_SOURCES})
|
||||||
target_link_libraries(tester
|
ADD_DEPENDENCIES(tester dcc_lib)
|
||||||
|
|
||||||
|
target_link_libraries(tester dcc_lib disasm_s
|
||||||
${GMOCK_BOTH_LIBRARIES} ${REQ_LLVM_LIBRARIES})
|
${GMOCK_BOTH_LIBRARIES} ${REQ_LLVM_LIBRARIES})
|
||||||
add_test(dcc-tests tester)
|
add_test(dcc-tests tester)
|
||||||
|
|||||||
36
src/CallConvention.cpp
Normal file
36
src/CallConvention.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include <ostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include "CallConvention.h"
|
||||||
|
|
||||||
|
CConv *CConv::create(Type v)
|
||||||
|
{
|
||||||
|
static C_CallingConvention *c_call = nullptr;
|
||||||
|
static Pascal_CallingConvention *p_call = nullptr;
|
||||||
|
static Unknown_CallingConvention *u_call= nullptr;
|
||||||
|
if(!c_call)
|
||||||
|
c_call = new C_CallingConvention;
|
||||||
|
if(!p_call)
|
||||||
|
p_call = new Pascal_CallingConvention;
|
||||||
|
if(!u_call)
|
||||||
|
u_call = new Unknown_CallingConvention;
|
||||||
|
switch(v) {
|
||||||
|
case UNKNOWN: return u_call;
|
||||||
|
case C: return c_call;
|
||||||
|
case PASCAL: return p_call;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_CallingConvention::writeComments(std::ostream &ostr)
|
||||||
|
{
|
||||||
|
ostr << " * C calling convention.\n";
|
||||||
|
}
|
||||||
|
void Pascal_CallingConvention::writeComments(std::ostream &ostr)
|
||||||
|
{
|
||||||
|
ostr << " * Pascal calling convention.\n";
|
||||||
|
}
|
||||||
|
void Unknown_CallingConvention::writeComments(std::ostream &ostr)
|
||||||
|
{
|
||||||
|
ostr << " * Unknown calling convention.\n";
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ void JumpTable::pruneEntries(uint16_t cs)
|
|||||||
PROG *prg(Project::get()->binary());
|
PROG *prg(Project::get()->binary());
|
||||||
for (uint32_t i = start; i < finish; i += 2)
|
for (uint32_t i = start; i < finish; i += 2)
|
||||||
{
|
{
|
||||||
uint32_t target = cs + LH(&prg->Image[i]);
|
uint32_t target = cs + LH(&prg->image()[i]);
|
||||||
if (target < finish && target >= start)
|
if (target < finish && target >= start)
|
||||||
finish = target;
|
finish = target;
|
||||||
else if (target >= (uint32_t)prg->cbImage)
|
else if (target >= (uint32_t)prg->cbImage)
|
||||||
@@ -23,10 +23,15 @@ void JumpTable::pruneEntries(uint16_t cs)
|
|||||||
ICODE _Icode; // used as scan input
|
ICODE _Icode; // used as scan input
|
||||||
for (uint32_t i = start; i < finish; i += 2)
|
for (uint32_t i = start; i < finish; i += 2)
|
||||||
{
|
{
|
||||||
uint32_t target = cs + LH(&prg->Image[i]);
|
uint32_t target = cs + LH(&prg->image()[i]);
|
||||||
/* Be wary of 00 00 as code - it's probably data */
|
/* Be wary of 00 00 as code - it's probably data */
|
||||||
if (! (prg->Image[target] || prg->Image[target+1]) || scan(target, _Icode))
|
if (! (prg->image()[target] || prg->image()[target+1]) || scan(target, _Icode))
|
||||||
finish = i;
|
finish = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Function::callingConv(CConv::Type v) {
|
||||||
|
m_call_conv=CConv::create(v);
|
||||||
|
}
|
||||||
|
|||||||
121
src/RegisterNode.cpp
Normal file
121
src/RegisterNode.cpp
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <boost/range.hpp>
|
||||||
|
#include <boost/range/adaptors.hpp>
|
||||||
|
//#include <boost/range/algorithm.hpp>
|
||||||
|
//#include <boost/assign.hpp>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "ast.h"
|
||||||
|
#include "bundle.h"
|
||||||
|
|
||||||
|
#include "machine_x86.h"
|
||||||
|
#include "project.h"
|
||||||
|
using namespace std;
|
||||||
|
using namespace boost::adaptors;
|
||||||
|
RegisterNode::RegisterNode(const LLOperand &op, LOCAL_ID *locsym)
|
||||||
|
{
|
||||||
|
m_syms = locsym;
|
||||||
|
ident.type(REGISTER);
|
||||||
|
hlType type_sel;
|
||||||
|
regType reg_type;
|
||||||
|
if (op.byteWidth()==1)
|
||||||
|
{
|
||||||
|
type_sel = TYPE_BYTE_SIGN;
|
||||||
|
reg_type = BYTE_REG;
|
||||||
|
}
|
||||||
|
else /* uint16_t */
|
||||||
|
{
|
||||||
|
type_sel = TYPE_WORD_SIGN;
|
||||||
|
reg_type = WORD_REG;
|
||||||
|
}
|
||||||
|
regiIdx = locsym->newByteWordReg(type_sel, op.regi);
|
||||||
|
regiType = reg_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//RegisterNode::RegisterNode(eReg regi, uint32_t icodeFlg, LOCAL_ID *locsym)
|
||||||
|
//{
|
||||||
|
// ident.type(REGISTER);
|
||||||
|
// hlType type_sel;
|
||||||
|
// regType reg_type;
|
||||||
|
// if ((icodeFlg & B) || (icodeFlg & SRC_B))
|
||||||
|
// {
|
||||||
|
// type_sel = TYPE_BYTE_SIGN;
|
||||||
|
// reg_type = BYTE_REG;
|
||||||
|
// }
|
||||||
|
// else /* uint16_t */
|
||||||
|
// {
|
||||||
|
// type_sel = TYPE_WORD_SIGN;
|
||||||
|
// reg_type = WORD_REG;
|
||||||
|
// }
|
||||||
|
// regiIdx = locsym->newByteWordReg(type_sel, regi);
|
||||||
|
// regiType = reg_type;
|
||||||
|
//}
|
||||||
|
|
||||||
|
string RegisterNode::walkCondExpr(Function *pProc, int *numLoc) const
|
||||||
|
{
|
||||||
|
std::ostringstream codeOut;
|
||||||
|
|
||||||
|
std::ostringstream o;
|
||||||
|
assert(&pProc->localId==m_syms);
|
||||||
|
ID *id = &pProc->localId.id_arr[regiIdx];
|
||||||
|
if (id->name[0] == '\0') /* no name */
|
||||||
|
{
|
||||||
|
id->setLocalName(++(*numLoc));
|
||||||
|
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
|
||||||
|
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
|
||||||
|
}
|
||||||
|
if (id->hasMacro)
|
||||||
|
o << id->macro << "("<<id->name<<")";
|
||||||
|
else
|
||||||
|
o << id->name;
|
||||||
|
|
||||||
|
cCode.appendDecl(codeOut.str());
|
||||||
|
return o.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
int RegisterNode::hlTypeSize(Function *) const
|
||||||
|
{
|
||||||
|
if (regiType == BYTE_REG)
|
||||||
|
return (1);
|
||||||
|
else
|
||||||
|
return (2);
|
||||||
|
}
|
||||||
|
|
||||||
|
hlType RegisterNode::expType(Function *pproc) const
|
||||||
|
{
|
||||||
|
if (regiType == BYTE_REG)
|
||||||
|
return (TYPE_BYTE_SIGN);
|
||||||
|
else
|
||||||
|
return (TYPE_WORD_SIGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr *RegisterNode::insertSubTreeReg(Expr *_expr, eReg regi, const LOCAL_ID *locsym)
|
||||||
|
{
|
||||||
|
assert(locsym==m_syms);
|
||||||
|
eReg treeReg = locsym->id_arr[regiIdx].id.regi;
|
||||||
|
if (treeReg == regi) /* uint16_t reg */
|
||||||
|
{
|
||||||
|
return _expr;
|
||||||
|
}
|
||||||
|
else if(Machine_X86::isSubRegisterOf(treeReg,regi)) /* uint16_t/uint8_t reg */
|
||||||
|
{
|
||||||
|
return _expr;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
bool RegisterNode::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locId)
|
||||||
|
{
|
||||||
|
uint8_t regi = locId.id_arr[regiIdx].id.regi;
|
||||||
|
range_to_check.advance_begin(1);
|
||||||
|
auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level);
|
||||||
|
for (ICODE &i : all_valid_and_high_level_after_start)
|
||||||
|
if (i.du.def.testRegAndSubregs(regi))
|
||||||
|
return false;
|
||||||
|
if (all_valid_and_high_level_after_start.end().base() != lastBBinst)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
978
src/ast.cpp
978
src/ast.cpp
File diff suppressed because it is too large
Load Diff
@@ -6,15 +6,21 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/range.hpp>
|
||||||
|
#include <boost/range/adaptors.hpp>
|
||||||
|
#include <boost/range/algorithm.hpp>
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
#include "disassem.h"
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "dcc.h"
|
||||||
|
#include "disassem.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include "CallGraph.h"
|
||||||
|
using namespace boost;
|
||||||
|
using namespace boost::adaptors;
|
||||||
bundle cCode; /* Procedure declaration and code */
|
bundle cCode; /* Procedure declaration and code */
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -103,23 +109,23 @@ static void printGlobVar (std::ostream &ostr,SYM * psym)
|
|||||||
switch (psym->size)
|
switch (psym->size)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n";
|
ostr << "uint8_t\t"<<psym->name<<" = "<<prog.image()[relocOp]<<";\n";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
|
ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.image()+relocOp)<<";\n";
|
||||||
break;
|
break;
|
||||||
case 4: if (psym->type == TYPE_PTR) /* pointer */
|
case 4: if (psym->type == TYPE_PTR) /* pointer */
|
||||||
ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
|
ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.image()+relocOp)<<";\n";
|
||||||
else /* char */
|
else /* char */
|
||||||
ostr << "char\t"<<psym->name<<"[4] = \""<<
|
ostr << "char\t"<<psym->name<<"[4] = \""<<
|
||||||
prog.Image[relocOp]<<prog.Image[relocOp+1]<<
|
prog.image()[relocOp]<<prog.image()[relocOp+1]<<
|
||||||
prog.Image[relocOp+2]<<prog.Image[relocOp+3]<<";\n";
|
prog.image()[relocOp+2]<<prog.image()[relocOp+3]<<";\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ostringstream strContents;
|
ostringstream strContents;
|
||||||
for (j=0; j < psym->size; j++)
|
for (j=0; j < psym->size; j++)
|
||||||
strContents << cChar(prog.Image[relocOp + j]);
|
strContents << cChar(prog.image()[relocOp + j]);
|
||||||
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
|
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,11 +184,12 @@ static void writeHeader (std::ostream &_ios, char *fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: Not currently called!
|
// Note: Not currently called!
|
||||||
/* Checks the given icode to determine whether it has a label associated
|
/** Checks the given icode to determine whether it has a label associated
|
||||||
* to it. If so, a goto is emitted to this label; otherwise, a new label
|
* to it. If so, a goto is emitted to this label; otherwise, a new label
|
||||||
* is created and a goto is also emitted.
|
* is created and a goto is also emitted.
|
||||||
* Note: this procedure is to be used when the label is to be forward on
|
* Note: this procedure is to be used when the label is to be forward on
|
||||||
* the code; that is, the target code has not been traversed yet. */
|
* the code; that is, the target code has not been traversed yet. */
|
||||||
|
#if 0
|
||||||
static void emitFwdGotoLabel (ICODE * pt, int indLevel)
|
static void emitFwdGotoLabel (ICODE * pt, int indLevel)
|
||||||
{
|
{
|
||||||
if ( not pt->ll()->testFlags(HLL_LABEL)) /* node hasn't got a lab */
|
if ( not pt->ll()->testFlags(HLL_LABEL)) /* node hasn't got a lab */
|
||||||
@@ -193,7 +200,7 @@ static void emitFwdGotoLabel (ICODE * pt, int indLevel)
|
|||||||
}
|
}
|
||||||
cCode.appendCode( "%sgoto l%ld;\n", indentStr(indLevel), pt->ll()->hllLabNum);
|
cCode.appendCode( "%sgoto l%ld;\n", indentStr(indLevel), pt->ll()->hllLabNum);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Writes the procedure's declaration (including arguments), local variables,
|
/* Writes the procedure's declaration (including arguments), local variables,
|
||||||
* and invokes the procedure that writes the code of the given record *hli */
|
* and invokes the procedure that writes the code of the given record *hli */
|
||||||
@@ -214,12 +221,16 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
ostr<< "\nvoid "<<name<<" (";
|
ostr<< "\nvoid "<<name<<" (";
|
||||||
|
|
||||||
/* Write arguments */
|
/* Write arguments */
|
||||||
for (size_t i = 0; i < args.size(); i++)
|
struct validArg
|
||||||
{
|
{
|
||||||
if ( args[i].invalid )
|
bool operator()(STKSYM &s) { return s.invalid==false;}
|
||||||
continue;
|
};
|
||||||
ostr<<hlTypes[args[i].type]<<" "<<args[i].name;
|
auto valid_args = args | filtered(validArg());
|
||||||
if (i < (args.size() - 1))
|
int count_valid = std::distance(valid_args.begin(),valid_args.end());
|
||||||
|
for (STKSYM &arg : valid_args)
|
||||||
|
{
|
||||||
|
ostr<<hlTypes[arg.type]<<" "<<arg.name;
|
||||||
|
if(--count_valid!=0)
|
||||||
ostr<<", ";
|
ostr<<", ";
|
||||||
}
|
}
|
||||||
ostr<<")\n";
|
ostr<<")\n";
|
||||||
@@ -265,7 +276,7 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
}
|
}
|
||||||
else /* generate C */
|
else /* generate C */
|
||||||
{
|
{
|
||||||
m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
|
m_actual_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
cCode.appendCode( "}\n\n");
|
cCode.appendCode( "}\n\n");
|
||||||
@@ -296,7 +307,7 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
|
|
||||||
/* Recursive procedure. Displays the procedure's code in depth-first order
|
/* Recursive procedure. Displays the procedure's code in depth-first order
|
||||||
* of the call graph. */
|
* of the call graph. */
|
||||||
static void backBackEnd (char *filename, CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
static void backBackEnd (CALL_GRAPH * pcallGraph, std::ostream &_ios)
|
||||||
{
|
{
|
||||||
|
|
||||||
// IFace.Yield(); /* This is a good place to yield to other apps */
|
// IFace.Yield(); /* This is a good place to yield to other apps */
|
||||||
@@ -308,9 +319,9 @@ static void backBackEnd (char *filename, CALL_GRAPH * pcallGraph, std::ostream &
|
|||||||
pcallGraph->proc->flg |= PROC_OUTPUT;
|
pcallGraph->proc->flg |= PROC_OUTPUT;
|
||||||
|
|
||||||
/* Dfs if this procedure has any successors */
|
/* Dfs if this procedure has any successors */
|
||||||
for (size_t i = 0; i < pcallGraph->outEdges.size(); i++)
|
for (auto & elem : pcallGraph->outEdges)
|
||||||
{
|
{
|
||||||
backBackEnd (filename, pcallGraph->outEdges[i], _ios);
|
backBackEnd (elem, _ios);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code for this procedure */
|
/* Generate code for this procedure */
|
||||||
@@ -345,14 +356,14 @@ void BackEnd (char *fileName, CALL_GRAPH * pcallGraph)
|
|||||||
printf ("dcc: Writing C beta file %s\n", outNam.c_str());
|
printf ("dcc: Writing C beta file %s\n", outNam.c_str());
|
||||||
|
|
||||||
/* Header information */
|
/* Header information */
|
||||||
writeHeader (fs, fileName);
|
writeHeader (fs, option.filename);
|
||||||
|
|
||||||
/* Initialize total Icode instructions statistics */
|
/* Initialize total Icode instructions statistics */
|
||||||
stats.totalLL = 0;
|
stats.totalLL = 0;
|
||||||
stats.totalHL = 0;
|
stats.totalHL = 0;
|
||||||
|
|
||||||
/* Process each procedure at a time */
|
/* Process each procedure at a time */
|
||||||
backBackEnd (fileName, pcallGraph, fs);
|
backBackEnd (pcallGraph, fs);
|
||||||
|
|
||||||
/* Close output file */
|
/* Close output file */
|
||||||
fs.close();
|
fs.close();
|
||||||
|
|||||||
145
src/chklib.cpp
145
src/chklib.cpp
@@ -56,7 +56,7 @@ static uint16_t *T1base, *T2base; /* Pointers to start of T1, T2 */
|
|||||||
static uint16_t *g; /* g[] */
|
static uint16_t *g; /* g[] */
|
||||||
static HT *ht; /* The hash table */
|
static HT *ht; /* The hash table */
|
||||||
static PH_FUNC_STRUCT *pFunc; /* Points to the array of func names */
|
static PH_FUNC_STRUCT *pFunc; /* Points to the array of func names */
|
||||||
static hlType *pArg=0; /* Points to the array of param types */
|
static hlType *pArg=nullptr; /* Points to the array of param types */
|
||||||
static int numFunc; /* Number of func names actually stored */
|
static int numFunc; /* Number of func names actually stored */
|
||||||
static int numArg; /* Number of param names actually stored */
|
static int numArg; /* Number of param names actually stored */
|
||||||
#define DCCLIBS "dcclibs.dat" /* Name of the prototypes data file */
|
#define DCCLIBS "dcclibs.dat" /* Name of the prototypes data file */
|
||||||
@@ -74,7 +74,7 @@ void checkHeap(char *msg); /* For debugging */
|
|||||||
|
|
||||||
void fixWildCards(uint8_t pat[]); /* In fixwild.c */
|
void fixWildCards(uint8_t pat[]); /* In fixwild.c */
|
||||||
|
|
||||||
static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern,
|
static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern,
|
||||||
int iPatLen, int *index);
|
int iPatLen, int *index);
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * *\
|
/* * * * * * * * * * * * * * * *\
|
||||||
@@ -219,8 +219,8 @@ static uint8_t pattMainSmall[] =
|
|||||||
0xFF, 0x36, WILD, WILD, /* Push argv */
|
0xFF, 0x36, WILD, WILD, /* Push argv */
|
||||||
0xFF, 0x36, WILD, WILD, /* Push argc */
|
0xFF, 0x36, WILD, WILD, /* Push argc */
|
||||||
0xE8, WILD, WILD /* call _main */
|
0xE8, WILD, WILD /* call _main */
|
||||||
/* 0x50, /* push ax... not in Borland V3 */
|
// 0x50, /* push ax... not in Borland V3 */
|
||||||
/* 0xE8 /* call _exit */
|
// 0xE8 /* call _exit */
|
||||||
};
|
};
|
||||||
/* Num bytes from start pattern to the relative offset of main() */
|
/* Num bytes from start pattern to the relative offset of main() */
|
||||||
#define OFFMAINSMALL 13
|
#define OFFMAINSMALL 13
|
||||||
@@ -232,9 +232,9 @@ static uint8_t pattMainMedium[] =
|
|||||||
0xFF, 0x36, WILD, WILD, /* Push argv */
|
0xFF, 0x36, WILD, WILD, /* Push argv */
|
||||||
0xFF, 0x36, WILD, WILD, /* Push argc */
|
0xFF, 0x36, WILD, WILD, /* Push argc */
|
||||||
0x9A, WILD, WILD, WILD, WILD /* call far _main */
|
0x9A, WILD, WILD, WILD, WILD /* call far _main */
|
||||||
/* 0x50 /* push ax */
|
// 0x50 /* push ax */
|
||||||
/* 0x0E, /* push cs NB not tested Borland */
|
// 0x0E, /* push cs NB not tested Borland */
|
||||||
/* 0xE8 /* call _exit */
|
// 0xE8 /* call _exit */
|
||||||
};
|
};
|
||||||
/* Num bytes from start pattern to the relative offset of main() */
|
/* Num bytes from start pattern to the relative offset of main() */
|
||||||
#define OFFMAINMEDIUM 13
|
#define OFFMAINMEDIUM 13
|
||||||
@@ -248,8 +248,8 @@ static uint8_t pattMainCompact[] =
|
|||||||
0xFF, 0x36, WILD, WILD, /* Push argv hi */
|
0xFF, 0x36, WILD, WILD, /* Push argv hi */
|
||||||
0xFF, 0x36, WILD, WILD, /* Push argc */
|
0xFF, 0x36, WILD, WILD, /* Push argc */
|
||||||
0xE8, WILD, WILD, /* call _main */
|
0xE8, WILD, WILD, /* call _main */
|
||||||
/* 0x50, /* push ax */
|
// 0x50, /* push ax */
|
||||||
/* 0xE8 /* call _exit */
|
// 0xE8 /* call _exit */
|
||||||
};
|
};
|
||||||
/* Num bytes from start pattern to the relative offset of main() */
|
/* Num bytes from start pattern to the relative offset of main() */
|
||||||
#define OFFMAINCOMPACT 21
|
#define OFFMAINCOMPACT 21
|
||||||
@@ -263,9 +263,9 @@ static uint8_t pattMainLarge[] =
|
|||||||
0xFF, 0x36, WILD, WILD, /* Push argv hi */
|
0xFF, 0x36, WILD, WILD, /* Push argv hi */
|
||||||
0xFF, 0x36, WILD, WILD, /* Push argc */
|
0xFF, 0x36, WILD, WILD, /* Push argc */
|
||||||
0x9A, WILD, WILD, WILD, WILD /* call far _main */
|
0x9A, WILD, WILD, WILD, WILD /* call far _main */
|
||||||
/* 0x50 /* push ax */
|
// 0x50 /* push ax */
|
||||||
/* 0x0E, /* push cs */
|
// 0x0E, /* push cs */
|
||||||
/* 0xE8 /* call _exit */
|
// 0xE8 /* call _exit */
|
||||||
};
|
};
|
||||||
/* Num bytes from start pattern to the relative offset of main() */
|
/* Num bytes from start pattern to the relative offset of main() */
|
||||||
#define OFFMAINLARGE 21
|
#define OFFMAINLARGE 21
|
||||||
@@ -302,7 +302,7 @@ void SetupLibCheck(void)
|
|||||||
uint16_t w, len;
|
uint16_t w, len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((g_file = fopen(sSigName, "rb")) == NULL)
|
if ((g_file = fopen(sSigName, "rb")) == nullptr)
|
||||||
{
|
{
|
||||||
printf("Warning: cannot open signature file %s\n", sSigName);
|
printf("Warning: cannot open signature file %s\n", sSigName);
|
||||||
return;
|
return;
|
||||||
@@ -337,8 +337,7 @@ void SetupLibCheck(void)
|
|||||||
PatLen, /* The length of the pattern to be hashed */
|
PatLen, /* The length of the pattern to be hashed */
|
||||||
256, /* The character set of the pattern (0-FF) */
|
256, /* The character set of the pattern (0-FF) */
|
||||||
0, /* Minimum pattern character value */
|
0, /* Minimum pattern character value */
|
||||||
numVert); /* Specifies c, the sparseness of the graph.
|
numVert); /* Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details */
|
||||||
See Czech, Havas and Majewski for details */
|
|
||||||
T1base = g_pattern_hasher.readT1();
|
T1base = g_pattern_hasher.readT1();
|
||||||
T2base = g_pattern_hasher.readT2();
|
T2base = g_pattern_hasher.readT2();
|
||||||
g = g_pattern_hasher.readG();
|
g = g_pattern_hasher.readG();
|
||||||
@@ -393,7 +392,7 @@ void SetupLibCheck(void)
|
|||||||
/* This is now the hash table */
|
/* This is now the hash table */
|
||||||
/* First allocate space for the table */
|
/* First allocate space for the table */
|
||||||
ht = new HT[numKeys];
|
ht = new HT[numKeys];
|
||||||
if ( 0 == ht)
|
if ( nullptr == ht)
|
||||||
{
|
{
|
||||||
printf("Could not allocate hash table\n");
|
printf("Could not allocate hash table\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -458,12 +457,13 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.name = "main";
|
pProc.name = "main";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy(pat, &prog.Image[fileOffset], PATLEN);
|
if(fileOffset + PATLEN > prog.cbImage)
|
||||||
//memmove(pat, &prog.Image[fileOffset], PATLEN);
|
return false;
|
||||||
|
memcpy(pat, &prog.image()[fileOffset], PATLEN);
|
||||||
|
//memmove(pat, &prog.image()[fileOffset], PATLEN);
|
||||||
fixWildCards(pat); /* Fix wild cards in the copy */
|
fixWildCards(pat); /* Fix wild cards in the copy */
|
||||||
h = g_pattern_hasher.hash(pat); /* Hash the found proc */
|
h = g_pattern_hasher.hash(pat); /* Hash the found proc */
|
||||||
/* We always have to compare keys, because the hash function will
|
/* We always have to compare keys, because the hash function will always return a valid index */
|
||||||
always return a valid index */
|
|
||||||
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
||||||
{
|
{
|
||||||
/* We have a match. Save the name, if not already set */
|
/* We have a match. Save the name, if not already set */
|
||||||
@@ -477,6 +477,7 @@ bool LibCheck(Function & pProc)
|
|||||||
if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL)
|
if ((numFunc == 0) || (i=searchPList(ht[h].htSym)) != NIL)
|
||||||
{
|
{
|
||||||
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
pProc.flg |= PROC_ISLIB; /* It's a lib function */
|
||||||
|
pProc.callingConv(CConv::C);
|
||||||
if (i != NIL)
|
if (i != NIL)
|
||||||
{
|
{
|
||||||
/* Allocate space for the arg struct, and copy the hlType to
|
/* Allocate space for the arg struct, and copy the hlType to
|
||||||
@@ -494,19 +495,24 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.flg |= PROC_IS_FUNC;
|
pProc.flg |= PROC_IS_FUNC;
|
||||||
switch (pProc.retVal.type) {
|
switch (pProc.retVal.type) {
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
pProc.liveOut = duReg[rDX] | duReg[rAX];
|
pProc.liveOut.setReg(rDX).addReg(rAX);
|
||||||
break;
|
break;
|
||||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||||
pProc.liveOut = duReg[rAX];
|
pProc.liveOut.setReg(rAX);
|
||||||
break;
|
break;
|
||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
pProc.liveOut = duReg[rAL];
|
pProc.liveOut.setReg(rAL);
|
||||||
break;
|
break;
|
||||||
|
case TYPE_PTR:
|
||||||
|
fprintf(stderr,"Warning assuming Large memory model\n");
|
||||||
|
pProc.liveOut.setReg(rAX).addReg(rDS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"Unknown retval type %d for %s in LibCheck\n",pProc.retVal.type,pProc.name.c_str());
|
||||||
/*** other types are not considered yet ***/
|
/*** other types are not considered yet ***/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pFunc[i].bVararg)
|
pProc.getFunctionType()->m_vararg = pFunc[i].bVararg;
|
||||||
pProc.flg |= PROC_VARARG;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i == NIL)
|
else if (i == NIL)
|
||||||
@@ -516,7 +522,7 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.flg |= PROC_RUNTIME; /* => is a runtime routine */
|
pProc.flg |= PROC_RUNTIME; /* => is a runtime routine */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (locatePattern(prog.Image, pProc.procEntry,
|
if (locatePattern(prog.image(), pProc.procEntry,
|
||||||
pProc.procEntry+sizeof(pattMsChkstk),
|
pProc.procEntry+sizeof(pattMsChkstk),
|
||||||
pattMsChkstk, sizeof(pattMsChkstk), &Idx))
|
pattMsChkstk, sizeof(pattMsChkstk), &Idx))
|
||||||
{
|
{
|
||||||
@@ -526,7 +532,7 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.args.numArgs = 0; /* With no args */
|
pProc.args.numArgs = 0; /* With no args */
|
||||||
}
|
}
|
||||||
|
|
||||||
return (boolT)((pProc.flg & PROC_ISLIB) != 0);
|
return (bool)((pProc.flg & PROC_ISLIB) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -559,8 +565,7 @@ readFileShort(FILE *f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read a section of the file, considering endian issues
|
// Read a section of the file, considering endian issues
|
||||||
void
|
void readFileSection(uint16_t* p, int len, FILE* f)
|
||||||
readFileSection(uint16_t* p, int len, FILE* f)
|
|
||||||
{
|
{
|
||||||
for (int i=0; i < len; i += 2)
|
for (int i=0; i < len; i += 2)
|
||||||
{
|
{
|
||||||
@@ -569,12 +574,12 @@ readFileSection(uint16_t* p, int len, FILE* f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The following two functions are dummies, since we don't call map() */
|
/* The following two functions are dummies, since we don't call map() */
|
||||||
void getKey(int i, uint8_t **keys)
|
void getKey(int /*i*/, uint8_t **/*keys*/)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispKey(int i)
|
void dispKey(int /*i*/)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -583,11 +588,11 @@ void dispKey(int i)
|
|||||||
iPatLen). The pattern can contain wild bytes; if you really want to match
|
iPatLen). The pattern can contain wild bytes; if you really want to match
|
||||||
for the pattern that is used up by the WILD uint8_t, tough - it will match with
|
for the pattern that is used up by the WILD uint8_t, tough - it will match with
|
||||||
everything else as well. */
|
everything else as well. */
|
||||||
static boolT locatePattern(uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
|
static bool locatePattern(const uint8_t *source, int iMin, int iMax, uint8_t *pattern, int iPatLen,
|
||||||
int *index)
|
int *index)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
uint8_t *pSrc; /* Pointer to start of considered source */
|
const uint8_t *pSrc; /* Pointer to start of considered source */
|
||||||
int iLast;
|
int iLast;
|
||||||
|
|
||||||
iLast = iMax - iPatLen; /* Last source uint8_t to consider */
|
iLast = iMax - iPatLen; /* Last source uint8_t to consider */
|
||||||
@@ -641,18 +646,18 @@ void STATE::checkStartup()
|
|||||||
|
|
||||||
/* Check the Turbo Pascal signatures first, since they involve only the
|
/* Check the Turbo Pascal signatures first, since they involve only the
|
||||||
first 3 bytes, and false positives may be founf with the others later */
|
first 3 bytes, and false positives may be founf with the others later */
|
||||||
if (locatePattern(prog.Image, startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i))
|
if (locatePattern(prog.image(), startOff, startOff+5, pattBorl4on,sizeof(pattBorl4on), &i))
|
||||||
{
|
{
|
||||||
/* The first 5 bytes are a far call. Follow that call and
|
/* The first 5 bytes are a far call. Follow that call and
|
||||||
determine the version from that */
|
determine the version from that */
|
||||||
rel = LH(&prog.Image[startOff+1]); /* This is abs off of init */
|
rel = LH(&prog.image()[startOff+1]); /* This is abs off of init */
|
||||||
para= LH(&prog.Image[startOff+3]);/* This is abs seg of init */
|
para= LH(&prog.image()[startOff+3]);/* This is abs seg of init */
|
||||||
init = ((uint32_t)para << 4) + rel;
|
init = ((uint32_t)para << 4) + rel;
|
||||||
if (locatePattern(prog.Image, init, init+26, pattBorl4Init,
|
if (locatePattern(prog.image(), init, init+26, pattBorl4Init,
|
||||||
sizeof(pattBorl4Init), &i))
|
sizeof(pattBorl4Init), &i))
|
||||||
{
|
{
|
||||||
|
|
||||||
setState(rDS, LH(&prog.Image[i+1]));
|
setState(rDS, LH(&prog.image()[i+1]));
|
||||||
printf("Borland Pascal v4 detected\n");
|
printf("Borland Pascal v4 detected\n");
|
||||||
chVendor = 't'; /* Trubo */
|
chVendor = 't'; /* Trubo */
|
||||||
chModel = 'p'; /* Pascal */
|
chModel = 'p'; /* Pascal */
|
||||||
@@ -661,11 +666,11 @@ void STATE::checkStartup()
|
|||||||
prog.segMain = prog.initCS; /* At the 5 uint8_t jump */
|
prog.segMain = prog.initCS; /* At the 5 uint8_t jump */
|
||||||
goto gotVendor; /* Already have vendor */
|
goto gotVendor; /* Already have vendor */
|
||||||
}
|
}
|
||||||
else if (locatePattern(prog.Image, init, init+26, pattBorl5Init,
|
else if (locatePattern(prog.image(), init, init+26, pattBorl5Init,
|
||||||
sizeof(pattBorl5Init), &i))
|
sizeof(pattBorl5Init), &i))
|
||||||
{
|
{
|
||||||
|
|
||||||
setState( rDS, LH(&prog.Image[i+1]));
|
setState( rDS, LH(&prog.image()[i+1]));
|
||||||
printf("Borland Pascal v5.0 detected\n");
|
printf("Borland Pascal v5.0 detected\n");
|
||||||
chVendor = 't'; /* Trubo */
|
chVendor = 't'; /* Trubo */
|
||||||
chModel = 'p'; /* Pascal */
|
chModel = 'p'; /* Pascal */
|
||||||
@@ -674,11 +679,11 @@ void STATE::checkStartup()
|
|||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
goto gotVendor; /* Already have vendor */
|
goto gotVendor; /* Already have vendor */
|
||||||
}
|
}
|
||||||
else if (locatePattern(prog.Image, init, init+26, pattBorl7Init,
|
else if (locatePattern(prog.image(), init, init+26, pattBorl7Init,
|
||||||
sizeof(pattBorl7Init), &i))
|
sizeof(pattBorl7Init), &i))
|
||||||
{
|
{
|
||||||
|
|
||||||
setState( rDS, LH(&prog.Image[i+1]));
|
setState( rDS, LH(&prog.image()[i+1]));
|
||||||
printf("Borland Pascal v7 detected\n");
|
printf("Borland Pascal v7 detected\n");
|
||||||
chVendor = 't'; /* Trubo */
|
chVendor = 't'; /* Trubo */
|
||||||
chModel = 'p'; /* Pascal */
|
chModel = 'p'; /* Pascal */
|
||||||
@@ -695,45 +700,45 @@ void STATE::checkStartup()
|
|||||||
but decides the model required. Note: must do the far data models
|
but decides the model required. Note: must do the far data models
|
||||||
(large and compact) before the others, since they are the same pattern
|
(large and compact) before the others, since they are the same pattern
|
||||||
as near data, just more pushes at the start. */
|
as near data, just more pushes at the start. */
|
||||||
if(prog.cbImage>startOff+0x180+sizeof(pattMainLarge))
|
if(prog.cbImage>int(startOff+0x180+sizeof(pattMainLarge)))
|
||||||
{
|
{
|
||||||
if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i))
|
if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainLarge,sizeof(pattMainLarge), &i))
|
||||||
{
|
{
|
||||||
rel = LH(&prog.Image[i+OFFMAINLARGE]); /* This is abs off of main */
|
rel = LH(&prog.image()[i+OFFMAINLARGE]); /* This is abs off of main */
|
||||||
para= LH(&prog.Image[i+OFFMAINLARGE+2]);/* This is abs seg of main */
|
para= LH(&prog.image()[i+OFFMAINLARGE+2]);/* This is abs seg of main */
|
||||||
/* Save absolute image offset */
|
/* Save absolute image offset */
|
||||||
prog.offMain = ((uint32_t)para << 4) + rel;
|
prog.offMain = ((uint32_t)para << 4) + rel;
|
||||||
prog.segMain = (uint16_t)para;
|
prog.segMain = (uint16_t)para;
|
||||||
chModel = 'l'; /* Large model */
|
chModel = 'l'; /* Large model */
|
||||||
}
|
}
|
||||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact,
|
else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainCompact,
|
||||||
sizeof(pattMainCompact), &i))
|
sizeof(pattMainCompact), &i))
|
||||||
{
|
{
|
||||||
rel = LH_SIGNED(&prog.Image[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
|
rel = LH_SIGNED(&prog.image()[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
|
||||||
prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */
|
prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */
|
||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
chModel = 'c'; /* Compact model */
|
chModel = 'c'; /* Compact model */
|
||||||
}
|
}
|
||||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainMedium,
|
else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainMedium,
|
||||||
sizeof(pattMainMedium), &i))
|
sizeof(pattMainMedium), &i))
|
||||||
{
|
{
|
||||||
rel = LH(&prog.Image[i+OFFMAINMEDIUM]); /* This is abs off of main */
|
rel = LH(&prog.image()[i+OFFMAINMEDIUM]); /* This is abs off of main */
|
||||||
para= LH(&prog.Image[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */
|
para= LH(&prog.image()[i+OFFMAINMEDIUM+2]);/* This is abs seg of main */
|
||||||
prog.offMain = ((uint32_t)para << 4) + rel;
|
prog.offMain = ((uint32_t)para << 4) + rel;
|
||||||
prog.segMain = (uint16_t)para;
|
prog.segMain = (uint16_t)para;
|
||||||
chModel = 'm'; /* Medium model */
|
chModel = 'm'; /* Medium model */
|
||||||
}
|
}
|
||||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall,
|
else if (locatePattern(prog.image(), startOff, startOff+0x180, pattMainSmall,
|
||||||
sizeof(pattMainSmall), &i))
|
sizeof(pattMainSmall), &i))
|
||||||
{
|
{
|
||||||
rel = LH_SIGNED(&prog.Image[i+OFFMAINSMALL]); /* This is rel addr of main */
|
rel = LH_SIGNED(&prog.image()[i+OFFMAINSMALL]); /* This is rel addr of main */
|
||||||
prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */
|
prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */
|
||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
chModel = 's'; /* Small model */
|
chModel = 's'; /* Small model */
|
||||||
}
|
}
|
||||||
else if (memcmp(&prog.Image[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
|
else if (memcmp(&prog.image()[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
|
||||||
{
|
{
|
||||||
rel = LH_SIGNED(&prog.Image[startOff+1]); /* Get the jump offset */
|
rel = LH_SIGNED(&prog.image()[startOff+1]); /* Get the jump offset */
|
||||||
prog.offMain = rel+startOff+3; /* Save absolute image offset */
|
prog.offMain = rel+startOff+3; /* Save absolute image offset */
|
||||||
prog.offMain += 0x20; /* These first 32 bytes are setting up */
|
prog.offMain += 0x20; /* These first 32 bytes are setting up */
|
||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
@@ -757,30 +762,30 @@ void STATE::checkStartup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Model: %c\n", chModel);
|
printf("Model: %c\n", chModel);
|
||||||
|
prog.addressingMode = chModel;
|
||||||
|
|
||||||
/* Now decide the compiler vendor and version number */
|
/* Now decide the compiler vendor and version number */
|
||||||
if (memcmp(&prog.Image[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
|
if (memcmp(&prog.image()[startOff], pattMsC5Start, sizeof(pattMsC5Start)) == 0)
|
||||||
{
|
{
|
||||||
/* Yes, this is Microsoft startup code. The DS is sitting right here
|
/* Yes, this is Microsoft startup code. The DS is sitting right here
|
||||||
in the next 2 bytes */
|
in the next 2 bytes */
|
||||||
setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC5Start)]));
|
setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC5Start)]));
|
||||||
chVendor = 'm'; /* Microsoft compiler */
|
chVendor = 'm'; /* Microsoft compiler */
|
||||||
chVersion = '5'; /* Version 5 */
|
chVersion = '5'; /* Version 5 */
|
||||||
printf("MSC 5 detected\n");
|
printf("MSC 5 detected\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The C8 startup pattern is different from C5's */
|
/* The C8 startup pattern is different from C5's */
|
||||||
else if (memcmp(&prog.Image[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0)
|
else if (memcmp(&prog.image()[startOff], pattMsC8Start, sizeof(pattMsC8Start)) == 0)
|
||||||
{
|
{
|
||||||
setState( rDS, LH(&prog.Image[startOff+sizeof(pattMsC8Start)]));
|
setState( rDS, LH(&prog.image()[startOff+sizeof(pattMsC8Start)]));
|
||||||
printf("MSC 8 detected\n");
|
printf("MSC 8 detected\n");
|
||||||
chVendor = 'm'; /* Microsoft compiler */
|
chVendor = 'm'; /* Microsoft compiler */
|
||||||
chVersion = '8'; /* Version 8 */
|
chVersion = '8'; /* Version 8 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The C8 .com startup pattern is different again! */
|
/* The C8 .com startup pattern is different again! */
|
||||||
else if (memcmp(&prog.Image[startOff], pattMsC8ComStart,
|
else if (memcmp(&prog.image()[startOff], pattMsC8ComStart,
|
||||||
sizeof(pattMsC8ComStart)) == 0)
|
sizeof(pattMsC8ComStart)) == 0)
|
||||||
{
|
{
|
||||||
printf("MSC 8 .com detected\n");
|
printf("MSC 8 .com detected\n");
|
||||||
@@ -788,27 +793,27 @@ void STATE::checkStartup()
|
|||||||
chVersion = '8'; /* Version 8 */
|
chVersion = '8'; /* Version 8 */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl2Start,
|
else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl2Start,
|
||||||
sizeof(pattBorl2Start), &i))
|
sizeof(pattBorl2Start), &i))
|
||||||
{
|
{
|
||||||
/* Borland startup. DS is at the second uint8_t (offset 1) */
|
/* Borland startup. DS is at the second uint8_t (offset 1) */
|
||||||
setState( rDS, LH(&prog.Image[i+1]));
|
setState( rDS, LH(&prog.image()[i+1]));
|
||||||
printf("Borland v2 detected\n");
|
printf("Borland v2 detected\n");
|
||||||
chVendor = 'b'; /* Borland compiler */
|
chVendor = 'b'; /* Borland compiler */
|
||||||
chVersion = '2'; /* Version 2 */
|
chVersion = '2'; /* Version 2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattBorl3Start,
|
else if (locatePattern(prog.image(), startOff, startOff+0x30, pattBorl3Start,
|
||||||
sizeof(pattBorl3Start), &i))
|
sizeof(pattBorl3Start), &i))
|
||||||
{
|
{
|
||||||
/* Borland startup. DS is at the second uint8_t (offset 1) */
|
/* Borland startup. DS is at the second uint8_t (offset 1) */
|
||||||
setState( rDS, LH(&prog.Image[i+1]));
|
setState( rDS, LH(&prog.image()[i+1]));
|
||||||
printf("Borland v3 detected\n");
|
printf("Borland v3 detected\n");
|
||||||
chVendor = 'b'; /* Borland compiler */
|
chVendor = 'b'; /* Borland compiler */
|
||||||
chVersion = '3'; /* Version 3 */
|
chVersion = '3'; /* Version 3 */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (locatePattern(prog.Image, startOff, startOff+0x30, pattLogiStart,
|
else if (locatePattern(prog.image(), startOff, startOff+0x30, pattLogiStart,
|
||||||
sizeof(pattLogiStart), &i))
|
sizeof(pattLogiStart), &i))
|
||||||
{
|
{
|
||||||
/* Logitech modula startup. DS is 0, despite appearances */
|
/* Logitech modula startup. DS is 0, despite appearances */
|
||||||
@@ -884,7 +889,7 @@ void readProtoFile(void)
|
|||||||
}
|
}
|
||||||
strcat(szProFName, DCCLIBS);
|
strcat(szProFName, DCCLIBS);
|
||||||
|
|
||||||
if ((fProto = fopen(szProFName, "rb")) == NULL)
|
if ((fProto = fopen(szProFName, "rb")) == nullptr)
|
||||||
{
|
{
|
||||||
printf("Warning: cannot open library prototype data file %s\n", szProFName);
|
printf("Warning: cannot open library prototype data file %s\n", szProFName);
|
||||||
return;
|
return;
|
||||||
@@ -947,8 +952,7 @@ void readProtoFile(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int searchPList(char *name)
|
||||||
searchPList(char *name)
|
|
||||||
{
|
{
|
||||||
/* Search through the symbol names for the name */
|
/* Search through the symbol names for the name */
|
||||||
/* Use binary search */
|
/* Use binary search */
|
||||||
@@ -985,10 +989,7 @@ searchPList(char *name)
|
|||||||
{
|
{
|
||||||
return mn; /* Found! */
|
return mn; /* Found! */
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
|||||||
s<<"\t/* ";
|
s<<"\t/* ";
|
||||||
if (src_immed == 0x21)
|
if (src_immed == 0x21)
|
||||||
{
|
{
|
||||||
s <<int21h[dst.off];
|
s <<int21h[m_dst.off];
|
||||||
}
|
}
|
||||||
else if (src_immed > 0x1F && src_immed < 0x2F)
|
else if (src_immed > 0x1F && src_immed < 0x2F)
|
||||||
{
|
{
|
||||||
@@ -162,7 +162,7 @@ void LLInst::writeIntComment (std::ostringstream &s)
|
|||||||
}
|
}
|
||||||
else if (src_immed == 0x2F)
|
else if (src_immed == 0x2F)
|
||||||
{
|
{
|
||||||
switch (dst.off)
|
switch (m_dst.off)
|
||||||
{
|
{
|
||||||
case 0x01 :
|
case 0x01 :
|
||||||
s << "Print spooler";
|
s << "Print spooler";
|
||||||
@@ -207,16 +207,16 @@ void Function::writeProcComments(std::ostream &ostr)
|
|||||||
{
|
{
|
||||||
psym = &this->args[i];
|
psym = &this->args[i];
|
||||||
ostr << " * "<<psym->name<<" = ";
|
ostr << " * "<<psym->name<<" = ";
|
||||||
if (psym->regs->expr.ident.idType == REGISTER)
|
if (psym->regs->ident.type() == REGISTER)
|
||||||
{
|
{
|
||||||
id = &this->localId.id_arr[psym->regs->expr.ident.idNode.regiIdx];
|
id = &this->localId.id_arr[((RegisterNode *)psym->regs)->regiIdx];
|
||||||
ostr << Machine_X86::regName(id->id.regi);
|
ostr << Machine_X86::regName(id->id.regi);
|
||||||
}
|
}
|
||||||
else /* long register */
|
else /* long register */
|
||||||
{
|
{
|
||||||
id = &this->localId.id_arr[psym->regs->expr.ident.idNode.longIdx];
|
id = &this->localId.id_arr[psym->regs->ident.idNode.longIdx];
|
||||||
ostr << Machine_X86::regName(id->id.longId.h) << ":";
|
ostr << Machine_X86::regName(id->longId().h()) << ":";
|
||||||
ostr << Machine_X86::regName(id->id.longId.l);
|
ostr << Machine_X86::regName(id->longId().l());
|
||||||
}
|
}
|
||||||
ostr << ".\n";
|
ostr << ".\n";
|
||||||
|
|
||||||
@@ -244,17 +244,14 @@ void Function::writeProcComments(std::ostream &ostr)
|
|||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
ostr << " * Return value in registers dx:ax.\n";
|
ostr << " * Return value in registers dx:ax.\n";
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"Unknown retval type %d",this->retVal.type);
|
||||||
|
break;
|
||||||
} /* eos */
|
} /* eos */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calling convention */
|
/* Calling convention */
|
||||||
if (this->flg & CALL_PASCAL)
|
callingConv()->writeComments(ostr);
|
||||||
ostr << " * Pascal calling convention.\n";
|
|
||||||
else if (this->flg & CALL_C)
|
|
||||||
ostr << " * C calling convention.\n";
|
|
||||||
else if (this->flg & CALL_UNKNOWN)
|
|
||||||
ostr << " * Unknown calling convention.\n";
|
|
||||||
|
|
||||||
/* Other flags */
|
/* Other flags */
|
||||||
if (this->flg & (PROC_BADINST | PROC_IJMP))
|
if (this->flg & (PROC_BADINST | PROC_IJMP))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ static void freeList (nodeList &l)
|
|||||||
|
|
||||||
|
|
||||||
/* Returns whether the node n belongs to the queue list q. */
|
/* Returns whether the node n belongs to the queue list q. */
|
||||||
static boolT inInt(BB * n, queue &q)
|
static bool inInt(BB * n, queue &q)
|
||||||
{
|
{
|
||||||
return std::find(q.begin(),q.end(),n)!=q.end();
|
return std::find(q.begin(),q.end(),n)!=q.end();
|
||||||
}
|
}
|
||||||
@@ -276,13 +276,13 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
|
|
||||||
/* Structure loops */
|
/* Structure loops */
|
||||||
/* for all derived sequences Gi */
|
/* for all derived sequences Gi */
|
||||||
for(derSeq::iterator iter=derivedG->begin(); iter!=derivedG->end(); ++iter)
|
for(auto & elem : *derivedG)
|
||||||
{
|
{
|
||||||
level++;
|
level++;
|
||||||
Ii = iter->Ii;
|
Ii = elem.Ii;
|
||||||
while (Ii) /* for all intervals Ii of Gi */
|
while (Ii) /* for all intervals Ii of Gi */
|
||||||
{
|
{
|
||||||
latchNode = NULL;
|
latchNode = nullptr;
|
||||||
intNodes.clear();
|
intNodes.clear();
|
||||||
|
|
||||||
/* Find interval head (original BB node in G1) and create
|
/* Find interval head (original BB node in G1) and create
|
||||||
@@ -300,11 +300,10 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
{
|
{
|
||||||
pred = intHead->inEdges[i];
|
pred = intHead->inEdges[i];
|
||||||
if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
|
if (inInt(pred, intNodes) && isBackEdge(pred, intHead))
|
||||||
|
{
|
||||||
if (! latchNode)
|
if (! latchNode)
|
||||||
latchNode = pred;
|
latchNode = pred;
|
||||||
else
|
else if (pred->dfsLastNum > latchNode->dfsLastNum)
|
||||||
{
|
|
||||||
if (pred->dfsLastNum > latchNode->dfsLastNum)
|
|
||||||
latchNode = pred;
|
latchNode = pred;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,9 +336,7 @@ void Function::structLoops(derSeq *derivedG)
|
|||||||
* h. Note that h is a case node. */
|
* h. Note that h is a case node. */
|
||||||
static bool successor (int s, int h, Function * pProc)
|
static bool successor (int s, int h, Function * pProc)
|
||||||
{
|
{
|
||||||
BB * header;
|
BB * header = pProc->m_dfsLast[h];
|
||||||
|
|
||||||
header = pProc->m_dfsLast[h];
|
|
||||||
auto iter = std::find_if(header->edges.begin(),
|
auto iter = std::find_if(header->edges.begin(),
|
||||||
header->edges.end(),
|
header->edges.end(),
|
||||||
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
|
[s](const TYPEADR_TYPE &te)->bool{ return te.BBptr->dfsLastNum == s;});
|
||||||
@@ -352,8 +349,7 @@ static bool successor (int s, int h, Function * pProc)
|
|||||||
* case). */
|
* case). */
|
||||||
static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
||||||
{
|
{
|
||||||
int current, /* index to current node */
|
int current; /* index to current node */
|
||||||
i;
|
|
||||||
|
|
||||||
pBB->traversed = DFS_CASE;
|
pBB->traversed = DFS_CASE;
|
||||||
current = pBB->dfsLastNum;
|
current = pBB->dfsLastNum;
|
||||||
@@ -374,29 +370,31 @@ static void tagNodesInCase (BB * pBB, nodeList &l, int head, int tail)
|
|||||||
* has a case node. */
|
* has a case node. */
|
||||||
void Function::structCases()
|
void Function::structCases()
|
||||||
{
|
{
|
||||||
int i, j;
|
|
||||||
BB * caseHeader; /* case header node */
|
|
||||||
int exitNode = NO_NODE; /* case exit node */
|
int exitNode = NO_NODE; /* case exit node */
|
||||||
nodeList caseNodes; /* temporary: list of nodes in case */
|
nodeList caseNodes; /* temporary: list of nodes in case */
|
||||||
|
|
||||||
/* Linear scan of the nodes in reverse dfsLast order, searching for
|
/* Linear scan of the nodes in reverse dfsLast order, searching for
|
||||||
* case nodes */
|
* case nodes */
|
||||||
for (i = numBBs - 1; i >= 0; i--)
|
for (int i = numBBs - 1; i >= 0; i--)
|
||||||
if (m_dfsLast[i]->nodeType == MULTI_BRANCH)
|
|
||||||
{
|
{
|
||||||
caseHeader = m_dfsLast[i];
|
if ((m_dfsLast[i]->nodeType != MULTI_BRANCH))
|
||||||
|
continue;
|
||||||
|
BB * caseHeader = m_dfsLast[i];; /* case header node */
|
||||||
|
|
||||||
/* Find descendant node which has as immediate predecessor
|
/* Find descendant node which has as immediate predecessor
|
||||||
* the current header node, and is not a successor. */
|
* the current header node, and is not a successor. */
|
||||||
for (j = i + 2; j < numBBs; j++)
|
for (size_t j = i + 2; j < numBBs; j++)
|
||||||
|
{
|
||||||
|
if ((!successor(j, i, this)) && (m_dfsLast[j]->immedDom == i))
|
||||||
{
|
{
|
||||||
if ((!successor(j, i, this)) &&
|
|
||||||
(m_dfsLast[j]->immedDom == i))
|
|
||||||
if (exitNode == NO_NODE)
|
if (exitNode == NO_NODE)
|
||||||
|
{
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
|
}
|
||||||
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
|
else if (m_dfsLast[exitNode]->inEdges.size() < m_dfsLast[j]->inEdges.size())
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_dfsLast[i]->caseTail = exitNode;
|
m_dfsLast[i]->caseTail = exitNode;
|
||||||
|
|
||||||
/* Tag nodes that belong to the case by recording the
|
/* Tag nodes that belong to the case by recording the
|
||||||
@@ -431,9 +429,9 @@ static void flagNodes (nodeList &l, int f, Function * pProc)
|
|||||||
/* Structures if statements */
|
/* Structures if statements */
|
||||||
void Function::structIfs ()
|
void Function::structIfs ()
|
||||||
{
|
{
|
||||||
|
size_t followInEdges; /* Largest # in-edges so far */
|
||||||
int curr, /* Index for linear scan of nodes */
|
int curr, /* Index for linear scan of nodes */
|
||||||
desc, /* Index for descendant */
|
/*desc,*/ /* Index for descendant */
|
||||||
followInEdges, /* Largest # in-edges so far */
|
|
||||||
follow; /* Possible follow node */
|
follow; /* Possible follow node */
|
||||||
nodeList domDesc, /* List of nodes dominated by curr */
|
nodeList domDesc, /* List of nodes dominated by curr */
|
||||||
unresolved /* List of unresolved if nodes */
|
unresolved /* List of unresolved if nodes */
|
||||||
@@ -454,7 +452,7 @@ void Function::structIfs ()
|
|||||||
follow = 0;
|
follow = 0;
|
||||||
|
|
||||||
/* Find all nodes that have this node as immediate dominator */
|
/* Find all nodes that have this node as immediate dominator */
|
||||||
for (desc = curr+1; desc < numBBs; desc++)
|
for (size_t desc = curr+1; desc < numBBs; desc++)
|
||||||
{
|
{
|
||||||
if (m_dfsLast[desc]->immedDom == curr)
|
if (m_dfsLast[desc]->immedDom == curr)
|
||||||
{
|
{
|
||||||
@@ -507,14 +505,14 @@ void Function::replaceInEdge(BB* where, BB* which,BB* with)
|
|||||||
}
|
}
|
||||||
bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
||||||
{
|
{
|
||||||
HLTYPE &hl1(*pbb->back().hl());
|
HLTYPE &hl1(*pbb->back().hlU());
|
||||||
HLTYPE &hl2(*thenBB->back().hl());
|
HLTYPE &hl2(*thenBB->back().hlU());
|
||||||
|
|
||||||
BB* obb = elseBB->edges[THEN].BBptr;
|
BB* obb = elseBB->edges[THEN].BBptr;
|
||||||
|
|
||||||
/* Construct compound DBL_OR expression */
|
/* Construct compound DBL_OR expression */
|
||||||
hl1.replaceExpr(hl1.expr()->inverse());
|
hl1.replaceExpr(hl1.expr()->inverse());
|
||||||
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR));
|
hl1.expr(BinaryOperator::Create(DBL_OR,hl1.expr(), hl2.expr()));
|
||||||
|
|
||||||
/* Replace in-edge to obb from e to pbb */
|
/* Replace in-edge to obb from e to pbb */
|
||||||
replaceInEdge(obb,elseBB,pbb);
|
replaceInEdge(obb,elseBB,pbb);
|
||||||
@@ -528,12 +526,14 @@ bool Function::Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
|||||||
}
|
}
|
||||||
bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
||||||
{
|
{
|
||||||
HLTYPE &hl1(*pbb->back().hl());
|
HLTYPE &hl1(*pbb->back().hlU());
|
||||||
HLTYPE &hl2(*thenBB->back().hl());
|
HLTYPE &hl2(*thenBB->back().hlU());
|
||||||
BB* obb = elseBB->edges[ELSE].BBptr;
|
BB* obb = elseBB->edges[ELSE].BBptr;
|
||||||
|
Expr * hl2_expr = hl2.getMyExpr();
|
||||||
/* Construct compound DBL_AND expression */
|
/* Construct compound DBL_AND expression */
|
||||||
hl1.expr(COND_EXPR::boolOp (hl1.expr(),hl2.expr(), DBL_AND));
|
assert(hl1.expr());
|
||||||
|
assert(hl2_expr);
|
||||||
|
hl1.expr(BinaryOperator::Create(DBL_AND,hl1.expr(),hl2_expr));
|
||||||
|
|
||||||
/* Replace in-edge to obb from e to pbb */
|
/* Replace in-edge to obb from e to pbb */
|
||||||
replaceInEdge(obb,elseBB,pbb);
|
replaceInEdge(obb,elseBB,pbb);
|
||||||
@@ -547,15 +547,15 @@ bool Function::Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
|||||||
|
|
||||||
bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
||||||
{
|
{
|
||||||
HLTYPE &hl1(*pbb->back().hl());
|
HLTYPE &hl1(*pbb->back().hlU());
|
||||||
HLTYPE &hl2(*thenBB->back().hl());
|
HLTYPE &hl2(*thenBB->back().hlU());
|
||||||
|
|
||||||
BB* obb = thenBB->edges[ELSE].BBptr;
|
BB* obb = thenBB->edges[ELSE].BBptr;
|
||||||
|
|
||||||
/* Construct compound DBL_AND expression */
|
/* Construct compound DBL_AND expression */
|
||||||
|
|
||||||
hl1.replaceExpr(hl1.expr()->inverse());
|
hl1.replaceExpr(hl1.expr()->inverse());
|
||||||
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_AND));
|
hl1.expr(BinaryOperator::LogicAnd(hl1.expr(), hl2.expr()));
|
||||||
|
|
||||||
/* Replace in-edge to obb from t to pbb */
|
/* Replace in-edge to obb from t to pbb */
|
||||||
replaceInEdge(obb,thenBB,pbb);
|
replaceInEdge(obb,thenBB,pbb);
|
||||||
@@ -570,13 +570,13 @@ bool Function::Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
|||||||
|
|
||||||
bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
||||||
{
|
{
|
||||||
HLTYPE &hl1(*pbb->back().hl());
|
HLTYPE &hl1(*pbb->back().hlU());
|
||||||
HLTYPE &hl2(*thenBB->back().hl());
|
HLTYPE &hl2(*thenBB->back().hlU());
|
||||||
|
|
||||||
BB * obb = thenBB->edges[THEN].BBptr;
|
BB * obb = thenBB->edges[THEN].BBptr;
|
||||||
|
|
||||||
/* Construct compound DBL_OR expression */
|
/* Construct compound DBL_OR expression */
|
||||||
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR));
|
hl1.expr(BinaryOperator::LogicOr(hl1.expr(), hl2.expr()));
|
||||||
|
|
||||||
/* Replace in-edge to obb from t to pbb */
|
/* Replace in-edge to obb from t to pbb */
|
||||||
|
|
||||||
@@ -603,7 +603,7 @@ void Function::compoundCond()
|
|||||||
|
|
||||||
/* Traverse nodes in postorder, this way, the header node of a
|
/* Traverse nodes in postorder, this way, the header node of a
|
||||||
* compound condition is analysed first */
|
* compound condition is analysed first */
|
||||||
for (int i = 0; i < this->numBBs; i++)
|
for (size_t i = 0; i < this->numBBs; i++)
|
||||||
{
|
{
|
||||||
pbb = this->m_dfsLast[i];
|
pbb = this->m_dfsLast[i];
|
||||||
if (pbb->flg & INVALID_BB)
|
if (pbb->flg & INVALID_BB)
|
||||||
|
|||||||
757
src/dataflow.cpp
757
src/dataflow.cpp
File diff suppressed because it is too large
Load Diff
116
src/dcc.cpp
116
src/dcc.cpp
@@ -4,16 +4,17 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
#include "CallGraph.h"
|
||||||
/* Global variables - extern to other modules */
|
/* Global variables - extern to other modules */
|
||||||
char *asm1_name, *asm2_name; /* Assembler output filenames */
|
extern char *asm1_name, *asm2_name; /* Assembler output filenames */
|
||||||
SYMTAB symtab; /* Global symbol table */
|
extern SYMTAB symtab; /* Global symbol table */
|
||||||
STATS stats; /* cfg statistics */
|
extern STATS stats; /* cfg statistics */
|
||||||
//PROG prog; /* programs fields */
|
//PROG prog; /* programs fields */
|
||||||
OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
//Function * pProcList; /* List of procedures, topologically sort */
|
//Function * pProcList; /* List of procedures, topologically sort */
|
||||||
//Function * pLastProc; /* Pointer to last node in procedure list */
|
//Function * pLastProc; /* Pointer to last node in procedure list */
|
||||||
//FunctionListType pProcList;
|
//FunctionListType pProcList;
|
||||||
@@ -22,19 +23,97 @@ OPTION option; /* Command line options */
|
|||||||
static char *initargs(int argc, char *argv[]);
|
static char *initargs(int argc, char *argv[]);
|
||||||
static void displayTotalStats(void);
|
static void displayTotalStats(void);
|
||||||
#include <llvm/Support/raw_os_ostream.h>
|
#include <llvm/Support/raw_os_ostream.h>
|
||||||
|
#include <llvm/Support/CommandLine.h>
|
||||||
|
#include <llvm/Support/TargetSelect.h>
|
||||||
|
#include <llvm/Support/TargetRegistry.h>
|
||||||
|
#include <llvm/Support/PrettyStackTrace.h>
|
||||||
|
#include <llvm/Support/Signals.h>
|
||||||
|
#include <llvm/Support/Host.h>
|
||||||
|
#include <llvm/Target/TargetMachine.h>
|
||||||
|
#include <llvm/Target/TargetInstrInfo.h>
|
||||||
|
#include <llvm/MC/MCAsmInfo.h>
|
||||||
|
#include <llvm/CodeGen/MachineInstrBuilder.h>
|
||||||
|
|
||||||
|
#include <llvm/TableGen/Main.h>
|
||||||
|
#include <llvm/TableGen/TableGenBackend.h>
|
||||||
|
#include <llvm/TableGen/Record.h>
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* main
|
* main
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
extern Project g_proj;
|
using namespace llvm;
|
||||||
int main(int argc, char *argv[])
|
bool TVisitor(raw_ostream &OS, RecordKeeper &Records)
|
||||||
|
{
|
||||||
|
Record *rec = Records.getDef("ADD8i8");
|
||||||
|
if(rec)
|
||||||
|
{
|
||||||
|
if(not rec->getTemplateArgs().empty())
|
||||||
|
std::cout << "Has template args\n";
|
||||||
|
auto classes(rec->getSuperClasses());
|
||||||
|
for(auto val : rec->getSuperClasses())
|
||||||
|
std::cout << "Super "<<val->getName()<<"\n";
|
||||||
|
|
||||||
|
// DagInit * in = rec->getValueAsDag(val.getName());
|
||||||
|
// in->dump();
|
||||||
|
for(const RecordVal &val : rec->getValues())
|
||||||
|
{
|
||||||
|
// val.dump();
|
||||||
|
}
|
||||||
|
rec->dump();
|
||||||
|
|
||||||
|
}
|
||||||
|
// rec = Records.getDef("CCR");
|
||||||
|
// if(rec)
|
||||||
|
// rec->dump();
|
||||||
|
for(auto val : Records.getDefs())
|
||||||
|
{
|
||||||
|
//std::cout<< "Def "<<val.first<<"\n";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int testTblGen(int argc, char **argv)
|
||||||
|
{
|
||||||
|
using namespace llvm;
|
||||||
|
sys::PrintStackTraceOnErrorSignal();
|
||||||
|
PrettyStackTraceProgram(argc,argv);
|
||||||
|
cl::ParseCommandLineOptions(argc,argv);
|
||||||
|
return llvm::TableGenMain(argv[0],TVisitor);
|
||||||
|
InitializeNativeTarget();
|
||||||
|
Triple TheTriple;
|
||||||
|
std::string def = sys::getDefaultTargetTriple();
|
||||||
|
std::string MCPU="i386";
|
||||||
|
std::string MARCH="x86";
|
||||||
|
InitializeAllTargetInfos();
|
||||||
|
InitializeAllTargetMCs();
|
||||||
|
InitializeAllAsmPrinters();
|
||||||
|
InitializeAllAsmParsers();
|
||||||
|
InitializeAllDisassemblers();
|
||||||
|
std::string TargetTriple("i386-pc-linux-gnu");
|
||||||
|
TheTriple = Triple(Triple::normalize(TargetTriple));
|
||||||
|
MCOperand op=llvm::MCOperand::CreateImm(11);
|
||||||
|
MCAsmInfo info;
|
||||||
|
raw_os_ostream wrap(std::cerr);
|
||||||
|
op.print(wrap,&info);
|
||||||
|
wrap.flush();
|
||||||
|
std::cerr<<"\n";
|
||||||
|
std::string lookuperr;
|
||||||
|
TargetRegistry::printRegisteredTargetsForVersion();
|
||||||
|
const Target *t = TargetRegistry::lookupTarget(MARCH,TheTriple,lookuperr);
|
||||||
|
TargetOptions opts;
|
||||||
|
std::string Features;
|
||||||
|
opts.PrintMachineCode=1;
|
||||||
|
TargetMachine *tm = t->createTargetMachine(TheTriple.getTriple(),MCPU,Features,opts);
|
||||||
|
std::cerr<<tm->getInstrInfo()->getName(97)<<"\n";
|
||||||
|
const MCInstrDesc &ds(tm->getInstrInfo()->get(97));
|
||||||
|
const MCOperandInfo *op1=ds.OpInfo;
|
||||||
|
uint16_t impl_def = ds.getImplicitDefs()[0];
|
||||||
|
std::cerr<<lookuperr<<"\n";
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// llvm::MCOperand op=llvm::MCOperand::CreateImm(11);
|
|
||||||
// llvm::MCAsmInfo info;
|
|
||||||
// llvm::raw_os_ostream wrap(std::cerr);
|
|
||||||
// op.print(wrap,&info);
|
|
||||||
// wrap.flush();
|
|
||||||
/* Extract switches and filename */
|
/* Extract switches and filename */
|
||||||
strcpy(option.filename, initargs(argc, argv));
|
strcpy(option.filename, initargs(argc, argv));
|
||||||
|
|
||||||
@@ -45,20 +124,23 @@ int main(int argc, char *argv[])
|
|||||||
DccFrontend fe(option.filename);
|
DccFrontend fe(option.filename);
|
||||||
if(false==fe.FrontEnd ())
|
if(false==fe.FrontEnd ())
|
||||||
return -1;
|
return -1;
|
||||||
|
if(option.asm1)
|
||||||
|
return 0;
|
||||||
/* In the middle is a so called Universal Decompiling Machine.
|
/* In the middle is a so called Universal Decompiling Machine.
|
||||||
* It processes the procedure list and I-code and attaches where it can
|
* It processes the procedure list and I-code and attaches where it can
|
||||||
* to each procedure an optimised cfg and ud lists
|
* to each procedure an optimised cfg and ud lists
|
||||||
*/
|
*/
|
||||||
udm();
|
udm();
|
||||||
|
if(option.asm2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Back end converts each procedure into C using I-code, interval
|
/* Back end converts each procedure into C using I-code, interval
|
||||||
* analysis, data flow etc. and outputs it to output file ready for
|
* analysis, data flow etc. and outputs it to output file ready for
|
||||||
* re-compilation.
|
* re-compilation.
|
||||||
*/
|
*/
|
||||||
BackEnd(option.filename, g_proj.callGraph);
|
BackEnd(asm1_name ? asm1_name:option.filename, Project::get()->callGraph);
|
||||||
|
|
||||||
g_proj.callGraph->write();
|
Project::get()->callGraph->write();
|
||||||
|
|
||||||
if (option.Stats)
|
if (option.Stats)
|
||||||
displayTotalStats();
|
displayTotalStats();
|
||||||
@@ -153,8 +235,8 @@ displayTotalStats ()
|
|||||||
/* Displays final statistics for the complete program */
|
/* Displays final statistics for the complete program */
|
||||||
{
|
{
|
||||||
printf ("\nFinal Program Statistics\n");
|
printf ("\nFinal Program Statistics\n");
|
||||||
printf (" Total number of low-level Icodes : %ld\n", stats.totalLL);
|
printf (" Total number of low-level Icodes : %d\n", stats.totalLL);
|
||||||
printf (" Total number of high-level Icodes: %ld\n", stats.totalHL);
|
printf (" Total number of high-level Icodes: %d\n", stats.totalHL);
|
||||||
printf (" Total reduction of instructions : %2.2f%%\n", 100.0 -
|
printf (" Total reduction of instructions : %2.2f%%\n", 100.0 -
|
||||||
(stats.totalHL * 100.0) / stats.totalLL);
|
(stats.totalHL * 100.0) / stats.totalLL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,21 +70,21 @@ static const char *szFlops3C[] =
|
|||||||
|
|
||||||
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
static const char *szPtr[2] = { "word ptr ", "byte ptr " };
|
||||||
|
|
||||||
static void formatRM(ostringstream &p, uint32_t flg, const LLOperand &pm);
|
static void formatRM(ostringstream &p, const LLOperand &pm);
|
||||||
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
|
static ostringstream &strDst(ostringstream &os, uint32_t flg, const LLOperand &pm);
|
||||||
|
|
||||||
static char *strHex(uint32_t d);
|
static char *strHex(uint32_t d);
|
||||||
//static int checkScanned(uint32_t pcCur);
|
//static int checkScanned(uint32_t pcCur);
|
||||||
//static void setProc(Function * proc);
|
//static void setProc(Function * proc);
|
||||||
//static void dispData(uint16_t dataSeg);
|
//static void dispData(uint16_t dataSeg);
|
||||||
boolT callArg(uint16_t off, char *temp); /* Check for procedure name */
|
bool callArg(uint16_t off, char *temp); /* Check for procedure name */
|
||||||
|
|
||||||
//static FILE *dis_g_fp;
|
//static FILE *dis_g_fp;
|
||||||
static CIcodeRec pc;
|
static CIcodeRec pc;
|
||||||
static int cb, j, numIcode, allocIcode;
|
static int cb, j, numIcode, allocIcode;
|
||||||
static map<int,int> pl;
|
static map<int,int> pl;
|
||||||
static uint32_t nextInst;
|
static uint32_t nextInst;
|
||||||
static boolT fImpure;
|
static bool fImpure;
|
||||||
//static int g_lab;
|
//static int g_lab;
|
||||||
static Function * pProc; /* Points to current proc struct */
|
static Function * pProc; /* Points to current proc struct */
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ struct POSSTACK_ENTRY
|
|||||||
Function * pProc; /* A pointer to a PROCEDURE structure */
|
Function * pProc; /* A pointer to a PROCEDURE structure */
|
||||||
} ;
|
} ;
|
||||||
static vector<POSSTACK_ENTRY> posStack; /* position stack */
|
static vector<POSSTACK_ENTRY> posStack; /* position stack */
|
||||||
static uint8_t iPS; /* Index into the stack */
|
//static uint8_t iPS; /* Index into the stack */
|
||||||
|
|
||||||
|
|
||||||
// These are "curses equivalent" functions. (Used to use curses for all this,
|
// These are "curses equivalent" functions. (Used to use curses for all this,
|
||||||
@@ -247,7 +247,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
{
|
{
|
||||||
for (j = 0; j < cb; j++)
|
for (j = 0; j < cb; j++)
|
||||||
{
|
{
|
||||||
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.Image[inst.label + j]);
|
hex_bytes << hex << setw(2) << setfill('0') << uint16_t(prog.image()[inst.label + j]);
|
||||||
}
|
}
|
||||||
hex_bytes << ' ';
|
hex_bytes << ' ';
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
oper_stream << setw(5)<<left; // align for the labels
|
oper_stream << setw(5)<<left; // align for the labels
|
||||||
{
|
{
|
||||||
ostringstream lab_contents;
|
ostringstream lab_contents;
|
||||||
if (readVal(lab_contents, inst.label, 0))
|
if (readVal(lab_contents, inst.label, nullptr))
|
||||||
{
|
{
|
||||||
lab_contents << ':'; /* Also removes the null */
|
lab_contents << ':'; /* Also removes the null */
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
{
|
{
|
||||||
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
||||||
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
||||||
strDst(operands_s,inst.getFlag(), inst.dst);
|
strDst(operands_s,inst.getFlag(), inst.m_dst);
|
||||||
inst.strSrc(operands_s);
|
inst.strSrc(operands_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -293,7 +293,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
|
|
||||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||||
case iROR:
|
case iROR:
|
||||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||||
if(inst.testFlags(I))
|
if(inst.testFlags(I))
|
||||||
inst.strSrc(operands_s);
|
inst.strSrc(operands_s);
|
||||||
else
|
else
|
||||||
@@ -301,7 +301,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iPUSH:
|
case iPUSH:
|
||||||
@@ -311,15 +311,15 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strDst(operands_s,inst.getFlag() | I, inst.dst);
|
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||||
if (inst.testFlags(I))
|
if (inst.testFlags(I))
|
||||||
{
|
{
|
||||||
strDst(operands_s,inst.getFlag(), inst.dst) <<", ";
|
strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
|
||||||
formatRM(operands_s, inst.getFlag(), inst.src());
|
formatRM(operands_s, inst.src());
|
||||||
inst.strSrc(operands_s);
|
inst.strSrc(operands_s);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -327,7 +327,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iLDS: case iLES: case iBOUND:
|
case iLDS: case iLES: case iBOUND:
|
||||||
strDst(operands_s,inst.getFlag(), inst.dst)<<", dword ptr";
|
strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
|
||||||
inst.strSrc(operands_s,true);
|
inst.strSrc(operands_s,true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
||||||
selectTable(Label);
|
selectTable(Label);
|
||||||
if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */
|
if ((inst.src().getImm2() < (uint32_t)numIcode) && /* Ensure in range */
|
||||||
readVal(operands_s, lab->ll()->label, 0))
|
readVal(operands_s, lab->ll()->label, nullptr))
|
||||||
{
|
{
|
||||||
break; /* Symbolic label. Done */
|
break; /* Symbolic label. Done */
|
||||||
}
|
}
|
||||||
@@ -397,8 +397,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iENTER:
|
case iENTER:
|
||||||
operands_s<<strHex(inst.dst.off)<<", ";
|
operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
|
||||||
operands_s<<strHex(inst.src().getImm2());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iRET: case iRETF: case iINT:
|
case iRET: case iRETF: case iINT:
|
||||||
@@ -484,7 +483,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
/* Check for user supplied comment */
|
/* Check for user supplied comment */
|
||||||
selectTable(Comment);
|
selectTable(Comment);
|
||||||
ostringstream cbuf;
|
ostringstream cbuf;
|
||||||
if (readVal(cbuf, inst.label, 0))
|
if (readVal(cbuf, inst.label, nullptr))
|
||||||
{
|
{
|
||||||
result_stream <<"; "<<cbuf.str();
|
result_stream <<"; "<<cbuf.str();
|
||||||
}
|
}
|
||||||
@@ -552,7 +551,7 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* formatRM
|
* formatRM
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void formatRM(std::ostringstream &p, uint32_t flg, const LLOperand &pm)
|
static void formatRM(std::ostringstream &p, const LLOperand &pm)
|
||||||
{
|
{
|
||||||
//char seg[4];
|
//char seg[4];
|
||||||
|
|
||||||
@@ -595,7 +594,7 @@ static ostringstream & strDst(ostringstream &os,uint32_t flg, const LLOperand &p
|
|||||||
//os << setw(WID_PTR);
|
//os << setw(WID_PTR);
|
||||||
if ((flg & I) and not pm.isReg())
|
if ((flg & I) and not pm.isReg())
|
||||||
os << szPtr[flg & B];
|
os << szPtr[flg & B];
|
||||||
formatRM(os, flg, pm);
|
formatRM(os, pm);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,7 +611,7 @@ ostringstream &LLInst::strSrc(ostringstream &os,bool skip_comma)
|
|||||||
else if (testFlags(IM_SRC)) /* level 2 */
|
else if (testFlags(IM_SRC)) /* level 2 */
|
||||||
os<<"dx:ax";
|
os<<"dx:ax";
|
||||||
else
|
else
|
||||||
formatRM(os, getFlag(), src());
|
formatRM(os, src());
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@@ -627,14 +626,14 @@ static char *strHex(uint32_t d)
|
|||||||
static char buf[10];
|
static char buf[10];
|
||||||
|
|
||||||
d &= 0xFFFF;
|
d &= 0xFFFF;
|
||||||
sprintf(buf, "0%lX%s", d, (d > 9)? "h": "");
|
sprintf(buf, "0%X%s", d, (d > 9)? "h": "");
|
||||||
return (buf + (buf[1] <= '9'));
|
return (buf + (buf[1] <= '9'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* interactDis - interactive disassembler *
|
* interactDis - interactive disassembler *
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void interactDis(Function * initProc, int initIC)
|
void interactDis(Function * /*initProc*/, int /*initIC*/)
|
||||||
{
|
{
|
||||||
printf("Sorry - interactive disasassembler option not available for Unix\n");
|
printf("Sorry - interactive disasassembler option not available for Unix\n");
|
||||||
return;
|
return;
|
||||||
@@ -643,13 +642,13 @@ void interactDis(Function * initProc, int initIC)
|
|||||||
/* Handle the floating point opcodes (icode iESC) */
|
/* Handle the floating point opcodes (icode iESC) */
|
||||||
void LLInst::flops(std::ostringstream &out)
|
void LLInst::flops(std::ostringstream &out)
|
||||||
{
|
{
|
||||||
char bf[30];
|
//char bf[30];
|
||||||
uint8_t op = (uint8_t)src().getImm2();
|
uint8_t op = (uint8_t)src().getImm2();
|
||||||
|
|
||||||
/* Note that op is set to the escape number, e.g.
|
/* Note that op is set to the escape number, e.g.
|
||||||
esc 0x38 is FILD */
|
esc 0x38 is FILD */
|
||||||
|
|
||||||
if ( not dst.isReg() )
|
if ( not m_dst.isReg() )
|
||||||
{
|
{
|
||||||
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
/* The mod/rm mod bits are not set to 11 (i.e. register). This is the normal floating point opcode */
|
||||||
out<<Machine_X86::floatOpName(op)<<' ';
|
out<<Machine_X86::floatOpName(op)<<' ';
|
||||||
@@ -685,7 +684,7 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formatRM(out, getFlag(), dst);
|
formatRM(out, m_dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -694,7 +693,7 @@ void LLInst::flops(std::ostringstream &out)
|
|||||||
normal opcodes. Because the opcodes are slightly different for
|
normal opcodes. Because the opcodes are slightly different for
|
||||||
this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
|
this case (e.g. op=04 means FSUB if reg != 3, but FSUBR for
|
||||||
reg == 3), a separate table is used (szFlops2). */
|
reg == 3), a separate table is used (szFlops2). */
|
||||||
int destRegIdx=dst.regi - rAX;
|
int destRegIdx=m_dst.regi - rAX;
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ TwoWild(uint8_t pat[])
|
|||||||
static bool
|
static bool
|
||||||
FourWild(uint8_t pat[])
|
FourWild(uint8_t pat[])
|
||||||
{
|
{
|
||||||
TwoWild(pat);
|
if(TwoWild(pat))
|
||||||
|
return true;
|
||||||
return TwoWild(pat);
|
return TwoWild(pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,8 +181,7 @@ static bool op0F(uint8_t pat[])
|
|||||||
processor is in 16 bit address mode (real mode).
|
processor is in 16 bit address mode (real mode).
|
||||||
PATLEN bytes are scanned.
|
PATLEN bytes are scanned.
|
||||||
*/
|
*/
|
||||||
void
|
void fixWildCards(uint8_t pat[])
|
||||||
fixWildCards(uint8_t pat[])
|
|
||||||
{
|
{
|
||||||
|
|
||||||
uint8_t op, quad, intArg;
|
uint8_t op, quad, intArg;
|
||||||
|
|||||||
@@ -7,10 +7,17 @@
|
|||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "disassem.h"
|
#include "disassem.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h> /* For malloc, free, realloc */
|
#include <malloc.h> /* For malloc, free, realloc */
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
class Loader
|
||||||
|
{
|
||||||
|
bool loadIntoProject(IProject *);
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct { /* PSP structure */
|
typedef struct { /* PSP structure */
|
||||||
uint16_t int20h; /* interrupt 20h */
|
uint16_t int20h; /* interrupt 20h */
|
||||||
uint16_t eof; /* segment, end of allocation block */
|
uint16_t eof; /* segment, end of allocation block */
|
||||||
@@ -50,7 +57,7 @@ static struct { /* EXE file header */
|
|||||||
|
|
||||||
#define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */
|
#define EXE_RELOCATION 0x10 /* EXE images rellocated to above PSP */
|
||||||
|
|
||||||
static void LoadImage(char *filename);
|
//static void LoadImage(char *filename);
|
||||||
static void displayLoadInfo(void);
|
static void displayLoadInfo(void);
|
||||||
static void displayMemMap(void);
|
static void displayMemMap(void);
|
||||||
|
|
||||||
@@ -58,22 +65,20 @@ static void displayMemMap(void);
|
|||||||
* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
|
* FrontEnd - invokes the loader, parser, disassembler (if asm1), icode
|
||||||
* rewritter, and displays any useful information.
|
* rewritter, and displays any useful information.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
extern Project g_proj;
|
|
||||||
bool DccFrontend::FrontEnd ()
|
bool DccFrontend::FrontEnd ()
|
||||||
{
|
{
|
||||||
|
Project::get()->callGraph = nullptr;
|
||||||
g_proj.callGraph = 0;
|
Project::get()->create(m_fname);
|
||||||
g_proj.m_fname = m_fname;
|
|
||||||
|
|
||||||
/* Load program into memory */
|
/* Load program into memory */
|
||||||
LoadImage(g_proj);
|
LoadImage(*Project::get());
|
||||||
|
|
||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
displayLoadInfo();
|
displayLoadInfo();
|
||||||
|
|
||||||
/* Do depth first flow analysis building call graph and procedure list,
|
/* Do depth first flow analysis building call graph and procedure list,
|
||||||
* and attaching the I-code to each procedure */
|
* and attaching the I-code to each procedure */
|
||||||
parse (g_proj);
|
parse (*Project::get());
|
||||||
|
|
||||||
if (option.asm1)
|
if (option.asm1)
|
||||||
{
|
{
|
||||||
@@ -82,7 +87,7 @@ bool DccFrontend::FrontEnd ()
|
|||||||
|
|
||||||
/* Search through code looking for impure references and flag them */
|
/* Search through code looking for impure references and flag them */
|
||||||
Disassembler ds(1);
|
Disassembler ds(1);
|
||||||
for(Function &f : g_proj.pProcList)
|
for(Function &f : Project::get()->pProcList)
|
||||||
{
|
{
|
||||||
f.markImpure();
|
f.markImpure();
|
||||||
if (option.asm1)
|
if (option.asm1)
|
||||||
@@ -92,11 +97,11 @@ bool DccFrontend::FrontEnd ()
|
|||||||
}
|
}
|
||||||
if (option.Interact)
|
if (option.Interact)
|
||||||
{
|
{
|
||||||
interactDis(&g_proj.pProcList.front(), 0); /* Interactive disassembler */
|
interactDis(&Project::get()->pProcList.front(), 0); /* Interactive disassembler */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts jump target addresses to icode offsets */
|
/* Converts jump target addresses to icode offsets */
|
||||||
for(Function &f : g_proj.pProcList)
|
for(Function &f : Project::get()->pProcList)
|
||||||
{
|
{
|
||||||
f.bindIcodeOff();
|
f.bindIcodeOff();
|
||||||
}
|
}
|
||||||
@@ -125,7 +130,7 @@ static void displayLoadInfo(void)
|
|||||||
printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc));
|
printf("Minimum allocation = %04X paras\n", LH(&header.minAlloc));
|
||||||
printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc));
|
printf("Maximum allocation = %04X paras\n", LH(&header.maxAlloc));
|
||||||
}
|
}
|
||||||
printf("Load image size = %04X\n", prog.cbImage - sizeof(PSP));
|
printf("Load image size = %04" PRIiPTR "\n", prog.cbImage - sizeof(PSP));
|
||||||
printf("Initial SS:SP = %04X:%04X\n", prog.initSS, prog.initSP);
|
printf("Initial SS:SP = %04X:%04X\n", prog.initSS, prog.initSP);
|
||||||
printf("Initial CS:IP = %04X:%04X\n", prog.initCS, prog.initIP);
|
printf("Initial CS:IP = %04X:%04X\n", prog.initCS, prog.initIP);
|
||||||
|
|
||||||
@@ -134,7 +139,7 @@ static void displayLoadInfo(void)
|
|||||||
printf("\nRelocation Table\n");
|
printf("\nRelocation Table\n");
|
||||||
for (i = 0; i < prog.cReloc; i++)
|
for (i = 0; i < prog.cReloc; i++)
|
||||||
{
|
{
|
||||||
printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.Image + prog.relocTable[i]));
|
printf("%06X -> [%04X]\n", prog.relocTable[i],LH(prog.image() + prog.relocTable[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -208,23 +213,23 @@ void DccFrontend::LoadImage(Project &proj)
|
|||||||
uint8_t buf[4];
|
uint8_t buf[4];
|
||||||
|
|
||||||
/* Open the input file */
|
/* Open the input file */
|
||||||
if ((fp = fopen(proj.m_fname.c_str(), "rb")) == NULL)
|
if ((fp = fopen(proj.binary_path().c_str(), "rb")) == nullptr)
|
||||||
{
|
{
|
||||||
fatalError(CANNOT_OPEN, proj.m_fname.c_str());
|
fatalError(CANNOT_OPEN, proj.binary_path().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in first 2 bytes to check EXE signature */
|
/* Read in first 2 bytes to check EXE signature */
|
||||||
if (fread(&header, 1, 2, fp) != 2)
|
if (fread(&header, 1, 2, fp) != 2)
|
||||||
{
|
{
|
||||||
fatalError(CANNOT_READ, proj.m_fname.c_str());
|
fatalError(CANNOT_READ, proj.binary_path().c_str());
|
||||||
}
|
}
|
||||||
|
prog.fCOM = (header.sigLo != 0x4D || header.sigHi != 0x5A);
|
||||||
if (! (prog.fCOM = (boolT)(header.sigLo != 0x4D || header.sigHi != 0x5A))) {
|
if (! prog.fCOM ) {
|
||||||
/* Read rest of header */
|
/* Read rest of header */
|
||||||
fseek(fp, 0, SEEK_SET);
|
fseek(fp, 0, SEEK_SET);
|
||||||
if (fread(&header, sizeof(header), 1, fp) != 1)
|
if (fread(&header, sizeof(header), 1, fp) != 1)
|
||||||
{
|
{
|
||||||
fatalError(CANNOT_READ, proj.m_fname.c_str());
|
fatalError(CANNOT_READ, proj.binary_path().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a typical DOS kludge! */
|
/* This is a typical DOS kludge! */
|
||||||
@@ -245,13 +250,13 @@ void DccFrontend::LoadImage(Project &proj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We quietly ignore minAlloc and maxAlloc since for our
|
/* We quietly ignore minAlloc and maxAlloc since for our
|
||||||
* purposes it doesn't really matter where in real memory
|
* purposes it doesn't really matter where in real memory
|
||||||
* the program would end up. EXE programs can't really rely on
|
* the program would end up. EXE programs can't really rely on
|
||||||
* their load location so setting the PSP segment to 0 is fine.
|
* their load location so setting the PSP segment to 0 is fine.
|
||||||
* Certainly programs that prod around in DOS or BIOS are going
|
* Certainly programs that prod around in DOS or BIOS are going
|
||||||
* to have to load DS from a constant so it'll be pretty
|
* to have to load DS from a constant so it'll be pretty
|
||||||
* obvious.
|
* obvious.
|
||||||
*/
|
*/
|
||||||
prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION;
|
prog.initCS = (int16_t)LH(&header.initCS) + EXE_RELOCATION;
|
||||||
prog.initIP = (int16_t)LH(&header.initIP);
|
prog.initIP = (int16_t)LH(&header.initIP);
|
||||||
prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION;
|
prog.initSS = (int16_t)LH(&header.initSS) + EXE_RELOCATION;
|
||||||
@@ -298,14 +303,14 @@ void DccFrontend::LoadImage(Project &proj)
|
|||||||
|
|
||||||
/* Allocate a block of memory for the program. */
|
/* Allocate a block of memory for the program. */
|
||||||
prog.cbImage = cb + sizeof(PSP);
|
prog.cbImage = cb + sizeof(PSP);
|
||||||
prog.Image = new uint8_t [prog.cbImage];
|
prog.Imagez = new uint8_t [prog.cbImage];
|
||||||
prog.Image[0] = 0xCD; /* Fill in PSP int 20h location */
|
prog.Imagez[0] = 0xCD; /* Fill in PSP int 20h location */
|
||||||
prog.Image[1] = 0x20; /* for termination checking */
|
prog.Imagez[1] = 0x20; /* for termination checking */
|
||||||
|
|
||||||
/* Read in the image past where a PSP would go */
|
/* Read in the image past where a PSP would go */
|
||||||
if (cb != (int)fread(prog.Image + sizeof(PSP), 1, (size_t)cb, fp))
|
if (cb != (int)fread(prog.Imagez + sizeof(PSP), 1, (size_t)cb, fp))
|
||||||
{
|
{
|
||||||
fatalError(CANNOT_READ, proj.m_fname.c_str());
|
fatalError(CANNOT_READ, proj.binary_path().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up memory map */
|
/* Set up memory map */
|
||||||
@@ -318,7 +323,7 @@ void DccFrontend::LoadImage(Project &proj)
|
|||||||
{
|
{
|
||||||
for (i = 0; i < prog.cReloc; i++)
|
for (i = 0; i < prog.cReloc; i++)
|
||||||
{
|
{
|
||||||
uint8_t *p = &prog.Image[prog.relocTable[i]];
|
uint8_t *p = &prog.Imagez[prog.relocTable[i]];
|
||||||
uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION;
|
uint16_t w = (uint16_t)LH(p) + EXE_RELOCATION;
|
||||||
*p++ = (uint8_t)(w & 0x00FF);
|
*p++ = (uint8_t)(w & 0x00FF);
|
||||||
*p = (uint8_t)((w & 0xFF00) >> 8);
|
*p = (uint8_t)((w & 0xFF00) >> 8);
|
||||||
|
|||||||
171
src/graph.cpp
171
src/graph.cpp
@@ -3,15 +3,21 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "dcc.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h> /* For free() */
|
#include <boost/range/rbegin.hpp>
|
||||||
|
#include <boost/range/rend.hpp>
|
||||||
|
#include <boost/range/adaptors.hpp>
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace boost;
|
||||||
extern Project g_proj;
|
extern Project g_proj;
|
||||||
//static BB * rmJMP(Function * pProc, int marker, BB * pBB);
|
//static BB * rmJMP(Function * pProc, int marker, BB * pBB);
|
||||||
static void mergeFallThrough(Function * pProc, BB * pBB);
|
//static void mergeFallThrough(Function * pProc, BB * pBB);
|
||||||
static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
|
//static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, int *first, int *last);
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* createCFG - Create the basic control flow graph
|
* createCFG - Create the basic control flow graph
|
||||||
@@ -29,17 +35,22 @@ void Function::createCFG()
|
|||||||
* 5) Repeated string instructions
|
* 5) Repeated string instructions
|
||||||
* 6) End of procedure
|
* 6) End of procedure
|
||||||
*/
|
*/
|
||||||
int i;
|
|
||||||
int ip;
|
|
||||||
BB * psBB;
|
BB * psBB;
|
||||||
BB * pBB;
|
BB * pBB;
|
||||||
iICODE pIcode = Icode.begin();
|
iICODE pIcode = Icode.begin();
|
||||||
iICODE iStart = Icode.begin();
|
|
||||||
stats.numBBbef = stats.numBBaft = 0;
|
stats.numBBbef = stats.numBBaft = 0;
|
||||||
for (; pIcode!=Icode.end(); ++pIcode)
|
rICODE current_range=make_iterator_range(pIcode,++iICODE(pIcode));
|
||||||
|
for (; pIcode!=Icode.end(); ++pIcode,current_range.advance_end(1))
|
||||||
{
|
{
|
||||||
iICODE nextIcode = ++iICODE(pIcode);
|
iICODE nextIcode = ++iICODE(pIcode);
|
||||||
|
pBB = nullptr;
|
||||||
|
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
|
/* Only process icodes that have valid instructions */
|
||||||
|
if(ll->testFlags(NO_CODE))
|
||||||
|
continue;
|
||||||
/* Stick a NOWHERE_NODE on the end if we terminate
|
/* Stick a NOWHERE_NODE on the end if we terminate
|
||||||
* with anything other than a ret, jump or terminate */
|
* with anything other than a ret, jump or terminate */
|
||||||
if (nextIcode == Icode.end() and
|
if (nextIcode == Icode.end() and
|
||||||
@@ -47,124 +58,97 @@ void Function::createCFG()
|
|||||||
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and
|
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and
|
||||||
(not ll->match(iRET)) and (not ll->match(iRETF)))
|
(not ll->match(iRET)) and (not ll->match(iRETF)))
|
||||||
{
|
{
|
||||||
//pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
pBB=BB::Create(current_range, NOWHERE_NODE, this);
|
||||||
pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Only process icodes that have valid instructions */
|
|
||||||
else if (not ll->testFlags(NO_CODE) )
|
|
||||||
{
|
|
||||||
switch (ll->getOpcode()) {
|
switch (ll->getOpcode()) {
|
||||||
case iJB: case iJBE: case iJAE: case iJA:
|
case iJB: case iJBE: case iJAE: case iJA:
|
||||||
case iJL: case iJLE: case iJGE: case iJG:
|
case iJL: case iJLE: case iJGE: case iJG:
|
||||||
case iJE: case iJNE: case iJS: case iJNS:
|
case iJE: case iJNE: case iJS: case iJNS:
|
||||||
case iJO: case iJNO: case iJP: case iJNP:
|
case iJO: case iJNO: case iJP: case iJNP:
|
||||||
case iJCXZ:
|
case iJCXZ:
|
||||||
pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this);
|
pBB = BB::Create(current_range, TWO_BRANCH, this);
|
||||||
CondJumps:
|
CondJumps:
|
||||||
//start = ip + 1;
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
iStart = ++iICODE(pIcode);
|
/* This is checking for jumps off into nowhere */
|
||||||
pBB->edges[0].ip = (uint32_t)iStart->loc_ip;
|
if ( not ll->testFlags(NO_LABEL) )
|
||||||
/* This is for jumps off into nowhere */
|
pBB->addOutEdge(ll->src().getImm2());
|
||||||
if ( ll->testFlags(NO_LABEL) )
|
|
||||||
{
|
|
||||||
pBB->edges.pop_back();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pBB->edges[1].ip = ll->src().getImm2();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iLOOP: case iLOOPE: case iLOOPNE:
|
case iLOOP: case iLOOPE: case iLOOPNE:
|
||||||
//pBB = BB::Create(start, ip, LOOP_NODE, 2, this);
|
pBB = BB::Create(current_range, LOOP_NODE, this);
|
||||||
pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this);
|
|
||||||
goto CondJumps;
|
goto CondJumps;
|
||||||
|
|
||||||
case iJMPF: case iJMP:
|
case iJMPF: case iJMP:
|
||||||
if (ll->testFlags(SWITCH))
|
if (ll->testFlags(SWITCH))
|
||||||
{
|
{
|
||||||
//pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
|
pBB = BB::Create(current_range, MULTI_BRANCH, this);
|
||||||
pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl2.size(), this);
|
for (auto & elem : ll->caseTbl2)
|
||||||
for (i = 0; i < ll->caseTbl2.size(); i++)
|
pBB->addOutEdge(elem);
|
||||||
pBB->edges[i].ip = ll->caseTbl2[i];
|
|
||||||
hasCase = true;
|
hasCase = true;
|
||||||
}
|
}
|
||||||
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
||||||
{
|
{
|
||||||
//pBB = BB::Create(start, ip, ONE_BRANCH, 1, this);
|
pBB = BB::Create(current_range, ONE_BRANCH, this);
|
||||||
pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this);
|
pBB->addOutEdge(ll->src().getImm2());
|
||||||
|
|
||||||
pBB->edges[0].ip = ll->src().getImm2();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
|
pBB = BB::Create(current_range, NOWHERE_NODE, this);
|
||||||
iStart = ++iICODE(pIcode);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iCALLF: case iCALL:
|
case iCALLF: case iCALL:
|
||||||
{
|
{
|
||||||
Function * p = ll->src().proc.proc;
|
Function * p = ll->src().proc.proc;
|
||||||
if (p)
|
pBB = BB::Create(current_range, CALL_NODE, this);
|
||||||
i = ((p->flg) & TERMINATES) ? 0 : 1;
|
if (p && not ((p->flg) & TERMINATES) )
|
||||||
else
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
i = 1;
|
|
||||||
pBB = BB::Create(iStart, pIcode, CALL_NODE, i, this);
|
|
||||||
iStart = ++iICODE(pIcode);//start = ip + 1;
|
|
||||||
if (i)
|
|
||||||
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case iRET: case iRETF:
|
case iRET: case iRETF:
|
||||||
//BB::Create(start, ip, RETURN_NODE, 0, this);
|
pBB = BB::Create(current_range, RETURN_NODE, this);
|
||||||
BB::Create(iStart, pIcode, RETURN_NODE, 0, this);
|
|
||||||
iStart = ++iICODE(pIcode);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Check for exit to DOS */
|
/* Check for exit to DOS */
|
||||||
iICODE next1=++iICODE(pIcode);
|
|
||||||
if ( ll->testFlags(TERMINATES) )
|
if ( ll->testFlags(TERMINATES) )
|
||||||
{
|
{
|
||||||
pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this);
|
pBB = BB::Create(current_range, TERMINATE_NODE, this);
|
||||||
//pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
|
|
||||||
iStart = ++iICODE(pIcode); // start = ip + 1;
|
|
||||||
}
|
}
|
||||||
/* Check for a fall through */
|
/* Check for a fall through */
|
||||||
else if (next1 != Icode.end())
|
else if (nextIcode != Icode.end())
|
||||||
{
|
{
|
||||||
if (next1->ll()->testFlags(TARGET | CASE))
|
if (nextIcode->ll()->testFlags(TARGET | CASE))
|
||||||
{
|
{
|
||||||
//pBB = BB::Create(start, ip, FALL_NODE, 1, this);
|
pBB = BB::Create(current_range, FALL_NODE, this);
|
||||||
pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this);
|
pBB->addOutEdge(nextIcode->loc_ip);
|
||||||
iStart = ++iICODE(pIcode); // start = ip + 1;
|
|
||||||
pBB->addOutEdge(iStart->loc_ip);
|
|
||||||
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(pBB!=nullptr) // created a new Basic block
|
||||||
|
{
|
||||||
|
// restart the range
|
||||||
|
// end iterator will be updated by expression in for statement
|
||||||
|
current_range=make_iterator_range(nextIcode,nextIcode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto iter=heldBBs.begin();
|
for (auto pr : m_ip_to_bb)
|
||||||
/* Convert list of BBs into a graph */
|
|
||||||
for (; iter!=heldBBs.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
pBB = *iter;
|
BB* pBB=pr.second;
|
||||||
for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++)
|
for (auto & elem : pBB->edges)
|
||||||
{
|
{
|
||||||
uint32_t ip = pBB->edges[edeg_idx].ip;
|
int32_t ip = elem.ip;
|
||||||
if (ip >= SYNTHESIZED_MIN)
|
if (ip >= SYNTHESIZED_MIN)
|
||||||
{
|
{
|
||||||
fatalError (INVALID_SYNTHETIC_BB);
|
fatalError (INVALID_SYNTHETIC_BB);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
|
auto iter2=m_ip_to_bb.find(ip);
|
||||||
[ip](BB *psBB)->bool {return psBB->begin()->loc_ip==ip;});
|
if(iter2==m_ip_to_bb.end())
|
||||||
if(iter2==heldBBs.end())
|
|
||||||
fatalError(NO_BB, ip, name.c_str());
|
fatalError(NO_BB, ip, name.c_str());
|
||||||
psBB = *iter2;
|
psBB = iter2->second;
|
||||||
pBB->edges[edeg_idx].BBptr = psBB;
|
elem.BBptr = psBB;
|
||||||
psBB->inEdges.push_back((BB *)nullptr);
|
psBB->inEdges.push_back((BB *)nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,8 +163,8 @@ void Function::markImpure()
|
|||||||
continue;
|
continue;
|
||||||
//assert that case tbl has less entries then symbol table ????
|
//assert that case tbl has less entries then symbol table ????
|
||||||
//WARNING: Case entries are held in symbol table !
|
//WARNING: Case entries are held in symbol table !
|
||||||
assert(g_proj.validSymIdx(icod.ll()->caseEntry));
|
assert(Project::get()->validSymIdx(icod.ll()->caseEntry));
|
||||||
const SYM &psym(g_proj.getSymByIdx(icod.ll()->caseEntry));
|
const SYM &psym(Project::get()->getSymByIdx(icod.ll()->caseEntry));
|
||||||
for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
|
for (int c = (int)psym.label; c < (int)psym.label+psym.size; c++)
|
||||||
{
|
{
|
||||||
if (BITMAP(c, BM_CODE))
|
if (BITMAP(c, BM_CODE))
|
||||||
@@ -194,21 +178,16 @@ void Function::markImpure()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* newBB - Allocate new BB and link to end of list
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* freeCFG - Deallocates a cfg
|
* freeCFG - Deallocates a cfg
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void Function::freeCFG()
|
void Function::freeCFG()
|
||||||
{
|
{
|
||||||
for(BB *p : heldBBs)
|
for(auto p : m_ip_to_bb)
|
||||||
{
|
{
|
||||||
delete p;
|
delete p.second;
|
||||||
}
|
}
|
||||||
|
m_ip_to_bb.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +201,7 @@ void Function::compressCFG()
|
|||||||
|
|
||||||
/* First pass over BB list removes redundant jumps of the form
|
/* First pass over BB list removes redundant jumps of the form
|
||||||
* (Un)Conditional -> Unconditional jump */
|
* (Un)Conditional -> Unconditional jump */
|
||||||
for (BB *pBB : m_cfg)
|
for (BB *pBB : m_actual_cfg) //m_cfg
|
||||||
{
|
{
|
||||||
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
||||||
continue;
|
continue;
|
||||||
@@ -244,18 +223,17 @@ void Function::compressCFG()
|
|||||||
/* Next is a depth-first traversal merging any FALL_NODE or
|
/* Next is a depth-first traversal merging any FALL_NODE or
|
||||||
* ONE_BRANCH that fall through to a node with that as their only
|
* ONE_BRANCH that fall through to a node with that as their only
|
||||||
* in-edge. */
|
* in-edge. */
|
||||||
m_cfg.front()->mergeFallThrough(Icode);
|
m_actual_cfg.front()->mergeFallThrough(Icode);
|
||||||
|
|
||||||
/* Remove redundant BBs created by the above compressions
|
/* Remove redundant BBs created by the above compressions
|
||||||
* and allocate in-edge arrays as required. */
|
* and allocate in-edge arrays as required. */
|
||||||
stats.numBBaft = stats.numBBbef;
|
stats.numBBaft = stats.numBBbef;
|
||||||
|
bool entry_node=true;
|
||||||
for(auto iter=m_cfg.begin(); iter!=m_cfg.end(); ++iter)
|
for(BB *pBB : m_actual_cfg)
|
||||||
{
|
{
|
||||||
BB * pBB = *iter;
|
|
||||||
if (pBB->inEdges.empty())
|
if (pBB->inEdges.empty())
|
||||||
{
|
{
|
||||||
if (iter == m_cfg.begin()) /* Init it misses out on */
|
if (entry_node) /* Init it misses out on */
|
||||||
pBB->index = UN_INIT;
|
pBB->index = UN_INIT;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -267,15 +245,16 @@ void Function::compressCFG()
|
|||||||
{
|
{
|
||||||
pBB->inEdgeCount = pBB->inEdges.size();
|
pBB->inEdgeCount = pBB->inEdges.size();
|
||||||
}
|
}
|
||||||
|
entry_node=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate storage for dfsLast[] array */
|
/* Allocate storage for dfsLast[] array */
|
||||||
numBBs = stats.numBBaft;
|
numBBs = stats.numBBaft;
|
||||||
m_dfsLast.resize(numBBs,0); // = (BB **)allocMem(numBBs * sizeof(BB *))
|
m_dfsLast.resize(numBBs,nullptr); // = (BB **)allocMem(numBBs * sizeof(BB *))
|
||||||
|
|
||||||
/* Now do a dfs numbering traversal and fill in the inEdges[] array */
|
/* Now do a dfs numbering traversal and fill in the inEdges[] array */
|
||||||
last = numBBs - 1;
|
last = numBBs - 1;
|
||||||
m_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
|
m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -335,8 +314,6 @@ BB *BB::rmJMP(int marker, BB * pBB)
|
|||||||
void BB::mergeFallThrough( CIcodeRec &Icode)
|
void BB::mergeFallThrough( CIcodeRec &Icode)
|
||||||
{
|
{
|
||||||
BB * pChild;
|
BB * pChild;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!this)
|
if (!this)
|
||||||
{
|
{
|
||||||
printf("mergeFallThrough on empty BB!\n");
|
printf("mergeFallThrough on empty BB!\n");
|
||||||
@@ -375,9 +352,11 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
|
|||||||
traversed = DFS_MERGE;
|
traversed = DFS_MERGE;
|
||||||
|
|
||||||
/* Process all out edges recursively */
|
/* Process all out edges recursively */
|
||||||
for (i = 0; i < edges.size(); i++)
|
for (auto & elem : edges)
|
||||||
if (edges[i].BBptr->traversed != DFS_MERGE)
|
{
|
||||||
edges[i].BBptr->mergeFallThrough(Icode);
|
if (elem.BBptr->traversed != DFS_MERGE)
|
||||||
|
elem.BBptr->mergeFallThrough(Icode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -399,7 +378,7 @@ void BB::dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last)
|
|||||||
pChild->inEdges[pChild->index++] = this;
|
pChild->inEdges[pChild->index++] = this;
|
||||||
|
|
||||||
/* Is this the last visit? */
|
/* Is this the last visit? */
|
||||||
if (pChild->index == pChild->inEdges.size())
|
if (pChild->index == int(pChild->inEdges.size()))
|
||||||
pChild->index = UN_INIT;
|
pChild->index = UN_INIT;
|
||||||
|
|
||||||
if (pChild->traversed != DFS_NUM)
|
if (pChild->traversed != DFS_NUM)
|
||||||
|
|||||||
302
src/hlicode.cpp
302
src/hlicode.cpp
@@ -10,26 +10,15 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#define ICODE_DELTA 25
|
|
||||||
|
|
||||||
/* Masks off bits set by duReg[] */
|
|
||||||
std::bitset<32> maskDuReg[] = { 0x00,
|
|
||||||
0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
|
|
||||||
0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
|
|
||||||
0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
|
|
||||||
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
|
|
||||||
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
|
|
||||||
0xEFFFFF, /* tmp reg */
|
|
||||||
0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
|
|
||||||
0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
|
|
||||||
|
|
||||||
static char buf[lineSize]; /* Line buffer for hl icode output */
|
static char buf[lineSize]; /* Line buffer for hl icode output */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
|
/* Places the new HLI_ASSIGN high-level operand in the high-level icode array */
|
||||||
void HLTYPE::setAsgn(COND_EXPR *lhs, COND_EXPR *rhs)
|
void HLTYPE::setAsgn(Expr *lhs, Expr *rhs)
|
||||||
{
|
{
|
||||||
|
assert(lhs);
|
||||||
set(lhs,rhs);
|
set(lhs,rhs);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -41,14 +30,12 @@ void ICODE::checkHlCall()
|
|||||||
void ICODE::newCallHl()
|
void ICODE::newCallHl()
|
||||||
{
|
{
|
||||||
type = HIGH_LEVEL;
|
type = HIGH_LEVEL;
|
||||||
hl()->opcode = HLI_CALL;
|
hlU()->setCall(ll()->src().proc.proc);
|
||||||
hl()->call.proc = ll()->src().proc.proc;
|
|
||||||
hl()->call.args = new STKFRAME;
|
|
||||||
|
|
||||||
if (ll()->src().proc.cb != 0)
|
if (ll()->src().proc.cb != 0)
|
||||||
hl()->call.args->cb = ll()->src().proc.cb;
|
hlU()->call.args->cb = ll()->src().proc.cb;
|
||||||
else if(hl()->call.proc)
|
else if(hl()->call.proc)
|
||||||
hl()->call.args->cb =hl()->call.proc->cbParam;
|
hlU()->call.args->cb = hl()->call.proc->cbParam;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
|
printf("Function with no cb set, and no valid oper.call.proc , probaby indirect call\n");
|
||||||
@@ -59,18 +46,18 @@ void ICODE::newCallHl()
|
|||||||
|
|
||||||
/* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
|
/* Places the new HLI_POP/HLI_PUSH/HLI_RET high-level operand in the high-level icode
|
||||||
* array */
|
* array */
|
||||||
void ICODE::setUnary(hlIcode op, COND_EXPR *_exp)
|
void ICODE::setUnary(hlIcode op, Expr *_exp)
|
||||||
{
|
{
|
||||||
type = HIGH_LEVEL;
|
type = HIGH_LEVEL;
|
||||||
hl()->set(op,_exp);
|
hlU()->set(op,_exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Places the new HLI_JCOND high-level operand in the high-level icode array */
|
/* Places the new HLI_JCOND high-level operand in the high-level icode array */
|
||||||
void ICODE::setJCond(COND_EXPR *cexp)
|
void ICODE::setJCond(Expr *cexp)
|
||||||
{
|
{
|
||||||
type = HIGH_LEVEL;
|
type = HIGH_LEVEL;
|
||||||
hl()->set(HLI_JCOND,cexp);
|
hlU()->set(HLI_JCOND,cexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,13 +77,13 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
|||||||
{
|
{
|
||||||
int numDefs;
|
int numDefs;
|
||||||
|
|
||||||
numDefs = du1.numRegsDef;
|
numDefs = du1.getNumRegsDef();
|
||||||
if (numDefs == thisDefIdx)
|
if (numDefs == thisDefIdx)
|
||||||
{
|
{
|
||||||
for ( ; numDefs > 0; numDefs--)
|
for ( ; numDefs > 0; numDefs--)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (du1.used(numDefs-1)||(du.lastDefRegi[regi]))
|
if (du1.used(numDefs-1)||(du.lastDefRegi.testReg(regi)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,11 +93,12 @@ bool ICODE::removeDefRegi (eReg regi, int thisDefIdx, LOCAL_ID *locId)
|
|||||||
invalidate();
|
invalidate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
HlTypeSupport *p=hl()->get();
|
HlTypeSupport *p=hlU()->get();
|
||||||
if(p and p->removeRegFromLong(regi,locId))
|
if(p and p->removeRegFromLong(regi,locId))
|
||||||
{
|
{
|
||||||
du1.numRegsDef--;
|
du1.removeDef(regi); //du1.numRegsDef--;
|
||||||
du.def &= maskDuReg[regi];
|
//du.def &= maskDuReg[regi];
|
||||||
|
du.def.clrReg(regi);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -158,7 +146,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iDEC:
|
case iDEC:
|
||||||
rhs = COND_EXPR::idKte (1, 2);
|
rhs = AstIdent::idKte (1, 2);
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
|
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
|
||||||
res.setAsgn(lhs, rhs);
|
res.setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
@@ -168,12 +156,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
|||||||
rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
|
rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
|
||||||
if ( ll->testFlags(B) )
|
if ( ll->testFlags(B) )
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idReg (rAL, 0, &localId);
|
lhs = AstIdent::idReg (rAL, 0, &localId);
|
||||||
pIcode->setRegDU( rAL, eDEF);
|
pIcode->setRegDU( rAL, eDEF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idReg (rAX, 0, &localId);
|
lhs = AstIdent::idReg (rAX, 0, &localId);
|
||||||
pIcode->setRegDU( rAX, eDEF);
|
pIcode->setRegDU( rAX, eDEF);
|
||||||
}
|
}
|
||||||
res.setAsgn(lhs, rhs);
|
res.setAsgn(lhs, rhs);
|
||||||
@@ -181,12 +169,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
|||||||
|
|
||||||
case iIMUL:
|
case iIMUL:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
|
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
|
||||||
lhs = COND_EXPR::id (*pIcode, LHS_OP, func, i, *pIcode, NONE);
|
lhs = AstIdent::id (*pIcode, LHS_OP, func, i, *pIcode, NONE);
|
||||||
res.setAsgn(lhs, rhs);
|
res.setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iINC:
|
case iINC:
|
||||||
rhs = COND_EXPR::idKte (1, 2);
|
rhs = AstIdent::idKte (1, 2);
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
|
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
|
||||||
res.setAsgn(lhs, rhs);
|
res.setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
@@ -200,12 +188,12 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
|||||||
rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
|
rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
|
||||||
if ( ll->testFlags(B) )
|
if ( ll->testFlags(B) )
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idReg (rAH, 0, &localId);
|
lhs = AstIdent::idReg (rAH, 0, &localId);
|
||||||
pIcode->setRegDU( rAH, eDEF);
|
pIcode->setRegDU( rAH, eDEF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idReg (rDX, 0, &localId);
|
lhs = AstIdent::idReg (rDX, 0, &localId);
|
||||||
pIcode->setRegDU( rDX, eDEF);
|
pIcode->setRegDU( rDX, eDEF);
|
||||||
}
|
}
|
||||||
res.setAsgn(lhs, rhs);
|
res.setAsgn(lhs, rhs);
|
||||||
@@ -216,7 +204,7 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
|||||||
|
|
||||||
case iMUL:
|
case iMUL:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
|
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
|
||||||
lhs = COND_EXPR::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
|
lhs = AstIdent::id (*pIcode, LHS_OP, this, i, *pIcode, NONE);
|
||||||
res.setAsgn(lhs, rhs);
|
res.setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -277,42 +265,89 @@ HLTYPE LLInst::toHighLevel(COND_EXPR *lhs,COND_EXPR *rhs,Function *func)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
static bool needsLhs(unsigned opc)
|
||||||
|
{
|
||||||
|
switch (opc)
|
||||||
|
{
|
||||||
|
case iCALL:
|
||||||
|
case iCALLF:
|
||||||
|
case iRET:
|
||||||
|
case iRETF:
|
||||||
|
default: return false;
|
||||||
|
case iADD:
|
||||||
|
case iAND:
|
||||||
|
case iDEC:
|
||||||
|
case iDIV:
|
||||||
|
case iIDIV:/* should be signed div */
|
||||||
|
case iIMUL:
|
||||||
|
case iINC:
|
||||||
|
case iLEA:
|
||||||
|
case iMOD:
|
||||||
|
case iMOV:
|
||||||
|
case iMUL:
|
||||||
|
case iNEG:
|
||||||
|
case iNOT:
|
||||||
|
case iOR:
|
||||||
|
case iPOP:
|
||||||
|
case iPUSH:
|
||||||
|
case iSHL:
|
||||||
|
case iSAR: /* signed */
|
||||||
|
case iSHR:
|
||||||
|
case iSIGNEX:
|
||||||
|
case iSUB:
|
||||||
|
case iXCHG:
|
||||||
|
case iXOR:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
|
/* Translates LOW_LEVEL icodes to HIGH_LEVEL icodes - 1st stage.
|
||||||
* Note: this process should be done before data flow analysis, which
|
* Note: this process should be done before data flow analysis, which
|
||||||
* refines the HIGH_LEVEL icodes. */
|
* refines the HIGH_LEVEL icodes. */
|
||||||
void Function::highLevelGen()
|
void Function::highLevelGen()
|
||||||
{
|
{
|
||||||
int numIcode; /* number of icode instructions */
|
size_t numIcode; /* number of icode instructions */
|
||||||
iICODE pIcode; /* ptr to current icode node */
|
iICODE pIcode; /* ptr to current icode node */
|
||||||
COND_EXPR *lhs, *rhs; /* left- and right-hand side of expression */
|
Expr *rhs; /* left- and right-hand side of expression */
|
||||||
uint32_t _flg; /* icode flags */
|
uint32_t _flg; /* icode flags */
|
||||||
numIcode = Icode.size();
|
numIcode = Icode.size();
|
||||||
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
|
for (iICODE i = Icode.begin(); i!=Icode.end() ; ++i)
|
||||||
{
|
{
|
||||||
|
Expr *lhs=nullptr;
|
||||||
assert(numIcode==Icode.size());
|
assert(numIcode==Icode.size());
|
||||||
pIcode = i; //Icode.GetIcode(i)
|
pIcode = i; //Icode.GetIcode(i)
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
|
LLOperand *dst_ll = ll->get(DST);
|
||||||
|
LLOperand *src_ll = ll->get(SRC);
|
||||||
if ( ll->testFlags(NOT_HLL) )
|
if ( ll->testFlags(NOT_HLL) )
|
||||||
pIcode->invalidate();
|
pIcode->invalidate();
|
||||||
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
|
if ((pIcode->type != LOW_LEVEL) or not pIcode->valid() )
|
||||||
continue;
|
continue;
|
||||||
_flg = ll->getFlag();
|
_flg = ll->getFlag();
|
||||||
if ((_flg & IM_OPS) != IM_OPS) /* not processing IM_OPS yet */
|
if (not ll->testFlags(IM_OPS)) /* not processing IM_OPS yet */
|
||||||
if ((_flg & NO_OPS) != NO_OPS) /* if there are opers */
|
if ( not ll->testFlags(NO_OPS) ) /* if there are opers */
|
||||||
{
|
{
|
||||||
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
|
if ( not ll->testFlags(NO_SRC) ) /* if there is src op */
|
||||||
rhs = COND_EXPR::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
|
rhs = AstIdent::id (*pIcode->ll(), SRC, this, i, *pIcode, NONE);
|
||||||
lhs = COND_EXPR::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
if(ll->m_dst.isSet() || (ll->getOpcode()==iMOD))
|
||||||
|
lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
||||||
}
|
}
|
||||||
|
if(ll->getOpcode()==iPUSH) {
|
||||||
|
if(ll->testFlags(I)) {
|
||||||
|
lhs = new Constant(src_ll->opz,src_ll->byteWidth());
|
||||||
|
}
|
||||||
|
// lhs = AstIdent::id (*pIcode->ll(), DST, this, i, *pIcode, NONE);
|
||||||
|
}
|
||||||
|
if(needsLhs(ll->getOpcode()))
|
||||||
|
assert(lhs!=nullptr);
|
||||||
switch (ll->getOpcode())
|
switch (ll->getOpcode())
|
||||||
{
|
{
|
||||||
case iADD:
|
case iADD:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
|
rhs = new BinaryOperator(ADD,lhs, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iAND:
|
case iAND:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, AND);
|
rhs = BinaryOperator::And(lhs, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -323,101 +358,91 @@ void Function::highLevelGen()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iDEC:
|
case iDEC:
|
||||||
rhs = COND_EXPR::idKte (1, 2);
|
rhs = new BinaryOperator(SUB,lhs, new Constant(1, 2));
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
|
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iDIV:
|
case iDIV:
|
||||||
case iIDIV:/* should be signed div */
|
case iIDIV:/* should be signed div */
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, DIV);
|
|
||||||
if ( ll->testFlags(B) )
|
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idReg (rAL, 0, &localId);
|
eReg v = ( dst_ll->byteWidth()==1) ? rAL:rAX;
|
||||||
pIcode->setRegDU( rAL, eDEF);
|
rhs = new BinaryOperator(DIV,lhs, rhs);
|
||||||
}
|
lhs = new RegisterNode(LLOperand(v, dst_ll->byteWidth()), &localId);
|
||||||
else
|
pIcode->setRegDU( v, eDEF);
|
||||||
{
|
|
||||||
lhs = COND_EXPR::idReg (rAX, 0, &localId);
|
|
||||||
pIcode->setRegDU( rAX, eDEF);
|
|
||||||
}
|
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iIMUL:
|
case iIMUL:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
|
rhs = new BinaryOperator(MUL,lhs, rhs);
|
||||||
lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE);
|
lhs = AstIdent::id (*ll, LHS_OP, this, i, *pIcode, NONE);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iINC:
|
case iINC:
|
||||||
rhs = COND_EXPR::idKte (1, 2);
|
rhs = new BinaryOperator(ADD,lhs, new Constant(1, 2));
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, ADD);
|
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iLEA:
|
case iLEA:
|
||||||
rhs = COND_EXPR::unary (ADDRESSOF, rhs);
|
rhs =UnaryOperator::Create(ADDRESSOF, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iMOD:
|
case iMOD:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, MOD);
|
|
||||||
if ( ll->testFlags(B) )
|
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idReg (rAH, 0, &localId);
|
rhs = new BinaryOperator(MOD,lhs, rhs);
|
||||||
pIcode->setRegDU( rAH, eDEF);
|
eReg lhs_reg = (dst_ll->byteWidth()==1) ? rAH : rDX;
|
||||||
}
|
lhs = new RegisterNode(LLOperand(lhs_reg, dst_ll->byteWidth()), &localId);
|
||||||
else
|
pIcode->setRegDU( lhs_reg, eDEF);
|
||||||
{
|
|
||||||
lhs = COND_EXPR::idReg (rDX, 0, &localId);
|
|
||||||
pIcode->setRegDU( rDX, eDEF);
|
|
||||||
}
|
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iMOV: pIcode->setAsgn(lhs, rhs);
|
case iMOV: pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iMUL:
|
case iMUL:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, MUL);
|
rhs = new BinaryOperator(MUL,lhs, rhs);
|
||||||
lhs = COND_EXPR::id (*ll, LHS_OP, this, i, *pIcode, NONE);
|
lhs = AstIdent::id (*ll, LHS_OP, this, i, *pIcode, NONE);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iNEG:
|
case iNEG:
|
||||||
rhs = COND_EXPR::unary (NEGATION, lhs);
|
rhs = UnaryOperator::Create(NEGATION, lhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iNOT:
|
case iNOT:
|
||||||
rhs = COND_EXPR::boolOp (NULL, rhs, NOT);
|
rhs = new BinaryOperator(NOT,nullptr, rhs); // TODO: change this to unary NOT ?
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iOR:
|
case iOR:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, OR);
|
rhs = new BinaryOperator(OR,lhs, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iPOP: pIcode->setUnary(HLI_POP, lhs);
|
case iPOP:
|
||||||
|
pIcode->setUnary(HLI_POP, lhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iPUSH: pIcode->setUnary(HLI_PUSH, lhs);
|
case iPUSH:
|
||||||
|
pIcode->setUnary(HLI_PUSH, lhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iRET:
|
case iRET:
|
||||||
case iRETF: pIcode->setUnary(HLI_RET, NULL);
|
case iRETF: pIcode->setUnary(HLI_RET, nullptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iSHL:
|
case iSHL:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, SHL);
|
rhs = new BinaryOperator(SHL,lhs, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iSAR: /* signed */
|
case iSAR: /* signed */
|
||||||
case iSHR:
|
case iSHR:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, SHR); /* unsigned*/
|
rhs = new BinaryOperator(SHR,lhs, rhs); /* unsigned*/
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -425,7 +450,7 @@ void Function::highLevelGen()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iSUB:
|
case iSUB:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, SUB);
|
rhs = new BinaryOperator(SUB,lhs, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -433,7 +458,7 @@ void Function::highLevelGen()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iXOR:
|
case iXOR:
|
||||||
rhs = COND_EXPR::boolOp (lhs, rhs, XOR);
|
rhs = new BinaryOperator(XOR,lhs, rhs);
|
||||||
pIcode->setAsgn(lhs, rhs);
|
pIcode->setAsgn(lhs, rhs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -442,59 +467,27 @@ void Function::highLevelGen()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Modifies the given conditional operator to its inverse. This is used
|
/**
|
||||||
* in if..then[..else] statements, to reflect the condition that takes the
|
\fn COND_EXPR::inverse
|
||||||
* then part. */
|
Modifies the given conditional operator to its inverse. This is used
|
||||||
COND_EXPR *COND_EXPR::inverse () const
|
in if..then[..else] statements, to reflect the condition that takes the
|
||||||
{
|
then part.
|
||||||
static condOp invCondOp[] = {GREATER, GREATER_EQUAL, NOT_EQUAL, EQUAL,
|
*/
|
||||||
LESS_EQUAL, LESS, DUMMY,DUMMY,DUMMY,DUMMY,
|
|
||||||
DUMMY, DUMMY, DUMMY, DUMMY, DUMMY, DUMMY,
|
|
||||||
DUMMY, DBL_OR, DBL_AND};
|
|
||||||
COND_EXPR *res=0;
|
|
||||||
if (m_type == BOOLEAN_OP)
|
|
||||||
{
|
|
||||||
switch ( op() )
|
|
||||||
{
|
|
||||||
case LESS_EQUAL: case LESS: case EQUAL:
|
|
||||||
case NOT_EQUAL: case GREATER: case GREATER_EQUAL:
|
|
||||||
res = this->clone();
|
|
||||||
res->boolExpr.op = invCondOp[op()];
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case AND: case OR: case XOR: case NOT: case ADD:
|
|
||||||
case SUB: case MUL: case DIV: case SHR: case SHL: case MOD:
|
|
||||||
return COND_EXPR::unary (NEGATION, this->clone());
|
|
||||||
|
|
||||||
case DBL_AND: case DBL_OR:
|
|
||||||
// Binary::Create(invertop,lhs->inverse(),rhs->inverse());
|
|
||||||
res = this->clone();
|
|
||||||
res->boolExpr.op = invCondOp[op()];
|
|
||||||
res->boolExpr.lhs=lhs()->inverse ();
|
|
||||||
res->boolExpr.rhs=rhs()->inverse ();
|
|
||||||
return res;
|
|
||||||
} /* eos */
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (m_type == NEGATION) //TODO: memleak here
|
|
||||||
{
|
|
||||||
return expr.unaryExp->clone();
|
|
||||||
}
|
|
||||||
return this->clone();
|
|
||||||
/* other types are left unmodified */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the string that represents the procedure call of tproc (ie. with
|
/* Returns the string that represents the procedure call of tproc (ie. with
|
||||||
* actual parameters) */
|
* actual parameters) */
|
||||||
std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc)
|
std::string Function::writeCall (Function * tproc, STKFRAME & args, int *numLoc)
|
||||||
{
|
{
|
||||||
int i; /* counter of # arguments */
|
//string condExp;
|
||||||
string condExp;
|
|
||||||
ostringstream ostr;
|
ostringstream ostr;
|
||||||
ostr<<tproc->name<<" (";
|
ostr<<tproc->name<<" (";
|
||||||
for(const STKSYM &sym : args)
|
for(const STKSYM &sym : args)
|
||||||
{
|
{
|
||||||
ostr << walkCondExpr (sym.actual, pproc, numLoc);
|
if(sym.actual)
|
||||||
|
ostr << sym.actual->walkCondExpr (this, numLoc);
|
||||||
|
else
|
||||||
|
ostr << "";
|
||||||
if((&sym)!=&(args.back()))
|
if((&sym)!=&(args.back()))
|
||||||
ostr << ", ";
|
ostr << ", ";
|
||||||
}
|
}
|
||||||
@@ -504,15 +497,19 @@ std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int
|
|||||||
|
|
||||||
|
|
||||||
/* Displays the output of a HLI_JCOND icode. */
|
/* Displays the output of a HLI_JCOND icode. */
|
||||||
char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
const char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
assert(h.expr());
|
|
||||||
memset (buf, ' ', sizeof(buf));
|
memset (buf, ' ', sizeof(buf));
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
strcat (buf, "if ");
|
strcat (buf, "if ");
|
||||||
COND_EXPR *inverted=h.expr()->inverse();
|
if(h.opcode==HLI_INVALID)
|
||||||
|
{
|
||||||
|
return "if (*HLI_INVALID*) {\n";
|
||||||
|
}
|
||||||
|
assert(h.expr());
|
||||||
|
Expr *inverted=h.expr()->inverse();
|
||||||
//inverseCondOp (&h.exp);
|
//inverseCondOp (&h.exp);
|
||||||
std::string e = walkCondExpr (inverted, pProc, numLoc);
|
std::string e = inverted->walkCondExpr (pProc, numLoc);
|
||||||
delete inverted;
|
delete inverted;
|
||||||
strcat (buf, e.c_str());
|
strcat (buf, e.c_str());
|
||||||
strcat (buf, " {\n");
|
strcat (buf, " {\n");
|
||||||
@@ -523,47 +520,64 @@ char *writeJcond (const HLTYPE &h, Function * pProc, int *numLoc)
|
|||||||
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case
|
/* Displays the inverse output of a HLI_JCOND icode. This is used in the case
|
||||||
* when the THEN clause of an if..then..else is empty. The clause is
|
* when the THEN clause of an if..then..else is empty. The clause is
|
||||||
* negated and the ELSE clause is used instead. */
|
* negated and the ELSE clause is used instead. */
|
||||||
char *writeJcondInv (HLTYPE h, Function * pProc, int *numLoc)
|
const char *writeJcondInv(HLTYPE h, Function * pProc, int *numLoc)
|
||||||
{
|
{
|
||||||
memset (buf, ' ', sizeof(buf));
|
memset (buf, ' ', sizeof(buf));
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
strcat (buf, "if ");
|
strcat (buf, "if ");
|
||||||
std::string e = walkCondExpr (h.expr(), pProc, numLoc);
|
std::string e;
|
||||||
|
if(h.expr()==nullptr)
|
||||||
|
e = "( *failed condition recovery* )";
|
||||||
|
else
|
||||||
|
e = h.expr()->walkCondExpr (pProc, numLoc);
|
||||||
|
|
||||||
strcat (buf, e.c_str());
|
strcat (buf, e.c_str());
|
||||||
strcat (buf, " {\n");
|
strcat (buf, " {\n");
|
||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AssignType::writeOut(Function *pProc, int *numLoc)
|
string AssignType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
ostringstream ostr;
|
||||||
ostr << walkCondExpr (lhs, pProc, numLoc);
|
ostr << m_lhs->walkCondExpr (pProc, numLoc);
|
||||||
ostr << " = ";
|
ostr << " = ";
|
||||||
ostr << walkCondExpr (rhs, pProc, numLoc);
|
ostr << rhs->walkCondExpr (pProc, numLoc);
|
||||||
ostr << ";\n";
|
ostr << ";\n";
|
||||||
return ostr.str();
|
return ostr.str();
|
||||||
}
|
}
|
||||||
string CallType::writeOut(Function *pProc, int *numLoc)
|
string CallType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
ostringstream ostr;
|
ostringstream ostr;
|
||||||
ostr << writeCall (proc, *args, pProc,numLoc);
|
ostr << pProc->writeCall (proc, *args, numLoc);
|
||||||
ostr << ";\n";
|
ostr << ";\n";
|
||||||
return ostr.str();
|
return ostr.str();
|
||||||
}
|
}
|
||||||
string ExpType::writeOut(Function *pProc, int *numLoc)
|
string ExpType::writeOut(Function *pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
return walkCondExpr (v, pProc, numLoc);
|
if(v==nullptr)
|
||||||
|
return "";
|
||||||
|
return v->walkCondExpr (pProc, numLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HLTYPE::set(Expr *l, Expr *r)
|
||||||
|
{
|
||||||
|
assert(l);
|
||||||
|
assert(r);
|
||||||
|
opcode = HLI_ASSIGN;
|
||||||
|
//assert((asgn.lhs==0) and (asgn.rhs==0)); //prevent memory leaks
|
||||||
|
assert(dynamic_cast<UnaryOperator *>(l));
|
||||||
|
asgn.m_lhs=l;
|
||||||
|
asgn.rhs=r;
|
||||||
|
}
|
||||||
/* Returns a string with the contents of the current high-level icode.
|
/* Returns a string with the contents of the current high-level icode.
|
||||||
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
* Note: this routine does not output the contens of HLI_JCOND icodes. This is
|
||||||
* done in a separate routine to be able to support the removal of
|
* done in a separate routine to be able to support the removal of
|
||||||
* empty THEN clauses on an if..then..else. */
|
* empty THEN clauses on an if..then..else. */
|
||||||
string HLTYPE::write1HlIcode (Function * pProc, int *numLoc)
|
string HLTYPE::write1HlIcode (Function * pProc, int *numLoc) const
|
||||||
{
|
{
|
||||||
string e;
|
string e;
|
||||||
ostringstream ostr;
|
ostringstream ostr;
|
||||||
HlTypeSupport *p = get();
|
const HlTypeSupport *p = get();
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
@@ -585,6 +599,10 @@ string HLTYPE::write1HlIcode (Function * pProc, int *numLoc)
|
|||||||
ostr << p->writeOut(pProc,numLoc);
|
ostr << p->writeOut(pProc,numLoc);
|
||||||
ostr << "\n";
|
ostr << "\n";
|
||||||
break;
|
break;
|
||||||
|
case HLI_JCOND: //Handled elsewhere
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr," HLTYPE::write1HlIcode - Unhandled opcode %d\n",opcode);
|
||||||
}
|
}
|
||||||
return ostr.str();
|
return ostr.str();
|
||||||
}
|
}
|
||||||
@@ -614,7 +632,7 @@ void ICODE::writeDU()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print du1 chain */
|
/* Print du1 chain */
|
||||||
printf ("# regs defined = %d\n", du1.numRegsDef);
|
printf ("# regs defined = %d\n", du1.getNumRegsDef());
|
||||||
for (int i = 0; i < MAX_REGS_DEF; i++)
|
for (int i = 0; i < MAX_REGS_DEF; i++)
|
||||||
{
|
{
|
||||||
if (not du1.used(i))
|
if (not du1.used(i))
|
||||||
|
|||||||
25
src/hltype.cpp
Normal file
25
src/hltype.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "icode.h"
|
||||||
|
#include "ast.h"
|
||||||
|
|
||||||
|
void HLTYPE::replaceExpr(Expr *e)
|
||||||
|
{
|
||||||
|
assert(e);
|
||||||
|
delete exp.v;
|
||||||
|
exp.v=e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HlTypeSupport *HLTYPE::get()
|
||||||
|
{
|
||||||
|
switch(opcode)
|
||||||
|
{
|
||||||
|
case HLI_ASSIGN: return &asgn;
|
||||||
|
case HLI_RET:
|
||||||
|
case HLI_POP:
|
||||||
|
case HLI_JCOND:
|
||||||
|
case HLI_PUSH: return &exp;
|
||||||
|
case HLI_CALL: return &call;
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,15 +2,12 @@
|
|||||||
// (C) 1997 Mike Van Emmerik
|
// (C) 1997 Mike Van Emmerik
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
|
||||||
#include <memory.h>
|
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "types.h" // Common types like uint8_t, etc
|
#include "types.h" // Common types like uint8_t, etc
|
||||||
#include "ast.h" // Some icode types depend on these
|
#include "ast.h" // Some icode types depend on these
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
|
|
||||||
#define ICODE_DELTA 25 // Amount to allocate for new chunk
|
|
||||||
|
|
||||||
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
|
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
|
||||||
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
|
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
|
||||||
@@ -31,9 +28,7 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode)
|
|||||||
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
|
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
|
||||||
{
|
{
|
||||||
for(ICODE &ic : rang)
|
for(ICODE &ic : rang)
|
||||||
{
|
|
||||||
ic.setParent(pnewBB);
|
ic.setParent(pnewBB);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
||||||
@@ -57,9 +52,9 @@ CIcodeRec::iterator CIcodeRec::labelSrch(uint32_t target)
|
|||||||
{
|
{
|
||||||
return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ll()->label==target;});
|
return find_if(begin(),end(),[target](ICODE &l) -> bool {return l.ll()->label==target;});
|
||||||
}
|
}
|
||||||
ICODE * CIcodeRec::GetIcode(int ip)
|
ICODE * CIcodeRec::GetIcode(size_t ip)
|
||||||
{
|
{
|
||||||
assert(ip>=0 && ip<size());
|
assert(ip<size());
|
||||||
iICODE res=begin();
|
iICODE res=begin();
|
||||||
advance(res,ip);
|
advance(res,ip);
|
||||||
return &(*res);
|
return &(*res);
|
||||||
@@ -94,9 +89,26 @@ bool LLOperand::isReg() const
|
|||||||
{
|
{
|
||||||
return (regi>=rAX) && (regi<=rTMP);
|
return (regi>=rAX) && (regi<=rTMP);
|
||||||
}
|
}
|
||||||
void LLOperand::addProcInformation(int param_count, uint32_t call_conv)
|
void LLOperand::addProcInformation(int param_count, CConv::Type call_conv)
|
||||||
{
|
{
|
||||||
proc.proc->cbParam = (int16_t)param_count;
|
proc.proc->cbParam = (int16_t)param_count;
|
||||||
proc.cb = param_count;
|
proc.cb = param_count;
|
||||||
proc.proc->flg |= call_conv;
|
proc.proc->callingConv(call_conv);
|
||||||
}
|
}
|
||||||
|
void HLTYPE::setCall(Function *proc)
|
||||||
|
{
|
||||||
|
opcode = HLI_CALL;
|
||||||
|
call.proc = proc;
|
||||||
|
call.args = new STKFRAME;
|
||||||
|
}
|
||||||
|
bool AssignType::removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
||||||
|
{
|
||||||
|
m_lhs=lhs()->performLongRemoval(regi,locId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void AssignType::lhs(Expr *l)
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<UnaryOperator *>(l));
|
||||||
|
m_lhs=l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <llvm/Support/PatternMatch.h>
|
||||||
|
#include <boost/iterator/filter_iterator.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include "idiom.h"
|
#include "idiom.h"
|
||||||
@@ -15,8 +17,6 @@
|
|||||||
#include "shift_idioms.h"
|
#include "shift_idioms.h"
|
||||||
#include "arith_idioms.h"
|
#include "arith_idioms.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include <llvm/Support/PatternMatch.h>
|
|
||||||
#include <boost/iterator/filter_iterator.hpp>
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* JmpInst - Returns true if opcode is a conditional or unconditional jump
|
* JmpInst - Returns true if opcode is a conditional or unconditional jump
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -116,13 +116,13 @@ void Function::findIdioms()
|
|||||||
case iCALL: case iCALLF:
|
case iCALL: case iCALLF:
|
||||||
/* Check for library functions that return a long register.
|
/* Check for library functions that return a long register.
|
||||||
* Propagate this result */
|
* Propagate this result */
|
||||||
if (pIcode->ll()->src().proc.proc != 0)
|
if (pIcode->ll()->src().proc.proc != nullptr)
|
||||||
if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) &&
|
if ((pIcode->ll()->src().proc.proc->flg & PROC_ISLIB) &&
|
||||||
(pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC))
|
(pIcode->ll()->src().proc.proc->flg & PROC_IS_FUNC))
|
||||||
{
|
{
|
||||||
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|
if ((pIcode->ll()->src().proc.proc->retVal.type==TYPE_LONG_SIGN)
|
||||||
|| (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
|
|| (pIcode->ll()->src().proc.proc->retVal.type == TYPE_LONG_UNSIGN))
|
||||||
localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, pIcode/*ip*/);
|
localId.newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(rDX,rAX), pIcode/*ip*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for idioms */
|
/* Check for idioms */
|
||||||
@@ -211,7 +211,7 @@ void Function::findIdioms()
|
|||||||
if (cbParam != delta)
|
if (cbParam != delta)
|
||||||
{
|
{
|
||||||
cbParam = delta;
|
cbParam = delta;
|
||||||
flg |= (CALL_MASK & CALL_UNKNOWN);
|
callingConv(CConv::UNKNOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,11 @@ bool Idiom5::match(iICODE pIcode)
|
|||||||
|
|
||||||
int Idiom5::action()
|
int Idiom5::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *rhs,*lhs,*expr;
|
AstIdent *rhs,*lhs;
|
||||||
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
|
Expr *expr;
|
||||||
rhs = COND_EXPR::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
|
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, ADD);
|
rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
|
||||||
|
expr = new BinaryOperator(ADD,lhs, rhs);
|
||||||
m_icodes[0]->setAsgn(lhs, expr);
|
m_icodes[0]->setAsgn(lhs, expr);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
@@ -58,10 +59,12 @@ bool Idiom6::match(iICODE pIcode)
|
|||||||
|
|
||||||
int Idiom6::action()
|
int Idiom6::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *rhs,*lhs,*expr;
|
|
||||||
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
|
AstIdent *rhs,*lhs;
|
||||||
rhs = COND_EXPR::idLong (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
|
Expr *expr;
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, SUB);
|
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], LOW_FIRST, m_icodes[0], USE_DEF, *m_icodes[1]->ll());
|
||||||
|
rhs = AstIdent::Long (&m_func->localId, SRC, m_icodes[0], LOW_FIRST, m_icodes[0], eUSE, *m_icodes[1]->ll());
|
||||||
|
expr = new BinaryOperator(SUB,lhs, rhs);
|
||||||
m_icodes[0]->setAsgn(lhs, expr);
|
m_icodes[0]->setAsgn(lhs, expr);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
@@ -95,64 +98,66 @@ bool Idiom18::match(iICODE picode)
|
|||||||
for(int i=0; i<4; ++i)
|
for(int i=0; i<4; ++i)
|
||||||
m_icodes[i] =picode++;
|
m_icodes[i] =picode++;
|
||||||
|
|
||||||
|
m_idiom_type=-1;
|
||||||
m_is_dec = m_icodes[1]->ll()->match(iDEC);
|
m_is_dec = m_icodes[1]->ll()->match(iDEC);
|
||||||
int type = -1; /* type of variable: 1 = reg-var, 2 = local */
|
|
||||||
uint8_t regi; /* register of the MOV */
|
|
||||||
|
|
||||||
|
uint8_t regi; /* register of the MOV */
|
||||||
|
if(not m_icodes[0]->ll()->matchWithRegDst(iMOV) )
|
||||||
|
return false;
|
||||||
|
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
|
if( not ( m_icodes[2]->ll()->match(iCMP,regi) &&
|
||||||
|
m_icodes[3]->ll()->conditionalJump() ) )
|
||||||
|
return false;
|
||||||
|
// Simple matching finished, select apropriate matcher based on dst type
|
||||||
/* Get variable */
|
/* Get variable */
|
||||||
if (m_icodes[1]->ll()->dst.regi == 0) /* global variable */
|
if (m_icodes[1]->ll()->m_dst.regi == 0) /* global variable */
|
||||||
{
|
{
|
||||||
/* not supported yet */
|
/* not supported yet */
|
||||||
type = 0;
|
m_idiom_type = 0;
|
||||||
}
|
}
|
||||||
else if ( m_icodes[1]->ll()->dst.isReg() ) /* register */
|
else if ( m_icodes[1]->ll()->m_dst.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
|
m_idiom_type = 1;
|
||||||
type = 1;
|
// if ((m_icodes[1]->ll()->dst.regi == rSI) && (m_func->flg & SI_REGVAR))
|
||||||
else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
|
// m_idiom_type = 1;
|
||||||
type = 1;
|
// else if ((m_icodes[1]->ll()->dst.regi == rDI) && (m_func->flg & DI_REGVAR))
|
||||||
|
// m_idiom_type = 1;
|
||||||
}
|
}
|
||||||
else if (m_icodes[1]->ll()->dst.off) /* local variable */
|
else if (m_icodes[1]->ll()->m_dst.off) /* local variable */
|
||||||
type = 2;
|
m_idiom_type = 2;
|
||||||
else /* indexed */
|
else /* indexed */
|
||||||
{
|
{
|
||||||
type=3;
|
m_idiom_type=3;
|
||||||
/* not supported yet */
|
/* not supported yet */
|
||||||
printf("Unsupported idiom18 type: indexed");
|
ICODE &ic(*picode);
|
||||||
|
const Function *my_proc(ic.getParent()->getParent());
|
||||||
|
printf("Unsupported idiom18 type at %x in %s:%x : indexed\n",ic.loc_ip,my_proc->name.c_str(),my_proc->procEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type)
|
switch(m_idiom_type)
|
||||||
{
|
{
|
||||||
case 0: // global
|
case 0: // global
|
||||||
printf("Unsupported idiom18 type: global variable");
|
printf("Unsupported idiom18 type at %x : global variable\n",picode->loc_ip);
|
||||||
break;
|
break;
|
||||||
case 1: /* register variable */
|
case 1: /* register variable */
|
||||||
/* Check previous instruction for a MOV */
|
/* Check previous instruction for a MOV */
|
||||||
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->dst.regi))
|
if ( (m_icodes[0]->ll()->src().regi == m_icodes[1]->ll()->m_dst.regi))
|
||||||
{
|
{
|
||||||
regi = m_icodes[0]->ll()->dst.regi;
|
|
||||||
if ( m_icodes[0]->ll()->dst.isReg() )
|
|
||||||
{
|
|
||||||
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
|
||||||
m_icodes[3]->ll()->conditionalJump() )
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 2: /* local */
|
case 2: /* local */
|
||||||
if (m_icodes[0]->ll()->match(iMOV) && (m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->dst.off))
|
if ((m_icodes[0]->ll()->src().off == m_icodes[1]->ll()->m_dst.off))
|
||||||
{
|
{
|
||||||
regi = m_icodes[0]->ll()->dst.regi;
|
|
||||||
if ( m_icodes[0]->ll()->dst.isReg() )
|
|
||||||
{
|
|
||||||
if ( m_icodes[2]->ll()->match(iCMP) && (m_icodes[2]->ll()->dst.regi == regi) &&
|
|
||||||
m_icodes[3]->ll()->conditionalJump() )
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 3: // indexed
|
case 3: // indexed
|
||||||
printf("Unsupported idiom18 type: indexed");
|
printf("Untested idiom18 type: indexed\n");
|
||||||
|
if ((m_icodes[0]->ll()->src() == m_icodes[1]->ll()->m_dst))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -160,12 +165,12 @@ bool Idiom18::match(iICODE picode)
|
|||||||
|
|
||||||
int Idiom18::action() // action length
|
int Idiom18::action() // action length
|
||||||
{
|
{
|
||||||
COND_EXPR *rhs, *lhs; /* Pointers to left and right hand side exps */
|
Expr *rhs,*lhs;/* Pointers to left and right hand side exps */
|
||||||
COND_EXPR *expr;
|
Expr *expr;
|
||||||
lhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE);
|
lhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[1], *m_icodes[1], eUSE);
|
||||||
lhs = COND_EXPR::unary ( m_is_dec ? POST_DEC : POST_INC, lhs);
|
lhs = UnaryOperator::Create(m_is_dec ? POST_DEC : POST_INC, lhs);
|
||||||
rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE);
|
rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[1], *m_icodes[3], eUSE);
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]);
|
expr = new BinaryOperator(condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB],lhs, rhs);
|
||||||
m_icodes[3]->setJCond(expr);
|
m_icodes[3]->setJCond(expr);
|
||||||
|
|
||||||
m_icodes[0]->invalidate();
|
m_icodes[0]->invalidate();
|
||||||
@@ -188,35 +193,41 @@ bool Idiom19::match(iICODE picode)
|
|||||||
{
|
{
|
||||||
if(std::distance(picode,m_end)<2)
|
if(std::distance(picode,m_end)<2)
|
||||||
return false;
|
return false;
|
||||||
|
ICODE &ic(*picode);
|
||||||
|
int type;
|
||||||
for(int i=0; i<2; ++i)
|
for(int i=0; i<2; ++i)
|
||||||
m_icodes[i] =picode++;
|
m_icodes[i] =picode++;
|
||||||
m_is_dec = m_icodes[0]->ll()->match(iDEC);
|
m_is_dec = m_icodes[0]->ll()->match(iDEC);
|
||||||
if (m_icodes[0]->ll()->dst.regi == 0) /* global variable */
|
if ( not m_icodes[1]->ll()->conditionalJump() )
|
||||||
|
return false;
|
||||||
|
if (m_icodes[0]->ll()->m_dst.regi == 0) /* global variable */
|
||||||
/* not supported yet */ ;
|
/* not supported yet */ ;
|
||||||
else if ( m_icodes[0]->ll()->dst.isReg() ) /* register */
|
else if ( m_icodes[0]->ll()->m_dst.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
|
// if (((picode->ll()->dst.regi == rSI) && (pproc->flg & SI_REGVAR)) ||
|
||||||
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
// ((picode->ll()->dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
||||||
if (m_icodes[1]->ll()->conditionalJump())
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (m_icodes[0]->ll()->dst.off) /* stack variable */
|
else if (m_icodes[0]->ll()->m_dst.off) /* stack variable */
|
||||||
{
|
{
|
||||||
if ( m_icodes[1]->ll()->conditionalJump() )
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else /* indexed */
|
else /* indexed */
|
||||||
/* not supported yet */ ;
|
{
|
||||||
|
fprintf(stderr,"idiom19 : Untested type [indexed]\n");
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* not supported yet */
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int Idiom19::action()
|
int Idiom19::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs,*expr;
|
Expr *lhs,*expr;
|
||||||
lhs = COND_EXPR::id (*m_icodes[1]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
|
|
||||||
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs);
|
lhs = AstIdent::id (*m_icodes[0]->ll(), DST, m_func, m_icodes[0], *m_icodes[1], eUSE);
|
||||||
rhs = COND_EXPR::idKte (0, 2);
|
lhs = UnaryOperator::Create(m_is_dec ? PRE_DEC : PRE_INC, lhs);
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB]);
|
expr = new BinaryOperator(condOpJCond[m_icodes[1]->ll()->getOpcode() - iJB],lhs, new Constant(0, 2));
|
||||||
m_icodes[1]->setJCond(expr);
|
m_icodes[1]->setJCond(expr);
|
||||||
m_icodes[0]->invalidate();
|
m_icodes[0]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
@@ -245,10 +256,13 @@ bool Idiom20::match(iICODE picode)
|
|||||||
return false;
|
return false;
|
||||||
for(int i=0; i<4; ++i)
|
for(int i=0; i<4; ++i)
|
||||||
m_icodes[i] =picode++;
|
m_icodes[i] =picode++;
|
||||||
|
/* Check second instruction for a MOV */
|
||||||
|
if( not m_icodes[1]->ll()->matchWithRegDst(iMOV) )
|
||||||
|
return false;
|
||||||
|
|
||||||
m_is_dec = m_icodes[0]->ll()->match(iDEC);
|
m_is_dec = m_icodes[0]->ll()->match(iDEC) ? PRE_DEC : PRE_INC;
|
||||||
|
|
||||||
LLOperand &ll_dest(m_icodes[0]->ll()->dst);
|
const LLOperand &ll_dest(m_icodes[0]->ll()->m_dst);
|
||||||
/* Get variable */
|
/* Get variable */
|
||||||
if (ll_dest.regi == 0) /* global variable */
|
if (ll_dest.regi == 0) /* global variable */
|
||||||
{
|
{
|
||||||
@@ -256,57 +270,56 @@ bool Idiom20::match(iICODE picode)
|
|||||||
}
|
}
|
||||||
else if ( ll_dest.isReg() ) /* register */
|
else if ( ll_dest.isReg() ) /* register */
|
||||||
{
|
{
|
||||||
if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
|
|
||||||
type = 1;
|
|
||||||
else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
|
|
||||||
type = 1;
|
type = 1;
|
||||||
|
// if ((ll_dest.regi == rSI) && (m_func->flg & SI_REGVAR))
|
||||||
|
// type = 1;
|
||||||
|
// else if ((ll_dest.regi == rDI) && (m_func->flg & DI_REGVAR))
|
||||||
|
// type = 1;
|
||||||
}
|
}
|
||||||
else if (ll_dest.off) /* local variable */
|
else if (ll_dest.off) /* local variable */
|
||||||
type = 2;
|
type = 2;
|
||||||
else /* indexed */
|
else /* indexed */
|
||||||
{
|
{
|
||||||
printf("idiom20 : Unsupported type [indexed]\n");
|
printf("idiom20 : Untested type [indexed]\n");
|
||||||
|
type = 3;
|
||||||
/* not supported yet */ ;
|
/* not supported yet */ ;
|
||||||
}
|
}
|
||||||
|
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||||
/* Check previous instruction for a MOV */
|
const LLOperand &mov_src(m_icodes[1]->ll()->src());
|
||||||
if (type == 1) /* register variable */
|
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) && m_icodes[3]->ll()->conditionalJump())
|
||||||
{
|
{
|
||||||
if (m_icodes[1]->ll()->match(iMOV) &&
|
switch(type)
|
||||||
(m_icodes[1]->ll()->src().regi == ll_dest.regi))
|
|
||||||
{
|
{
|
||||||
regi = m_icodes[1]->ll()->dst.regi;
|
case 1: /* register variable */
|
||||||
if ( m_icodes[1]->ll()->dst.isReg() )
|
if ((mov_src.regi == ll_dest.regi))
|
||||||
{
|
{
|
||||||
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
|
|
||||||
m_icodes[3]->ll()->conditionalJump())
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
case 2: // local
|
||||||
else if (type == 2) /* local */
|
if ((mov_src.off == ll_dest.off))
|
||||||
{
|
{
|
||||||
if ( m_icodes[0]->ll()->match(iMOV) &&
|
|
||||||
(m_icodes[1]->ll()->src().off == ll_dest.off))
|
|
||||||
{
|
|
||||||
regi = m_icodes[1]->ll()->dst.regi;
|
|
||||||
if ( m_icodes[1]->ll()->dst.isReg() )
|
|
||||||
{
|
|
||||||
if (m_icodes[2]->ll()->match(iCMP,(eReg)regi) &&
|
|
||||||
m_icodes[3]->ll()->conditionalJump())
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
fprintf(stderr,"Test 3 ");
|
||||||
|
if ((mov_src == ll_dest))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int Idiom20::action()
|
int Idiom20::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs,*expr;
|
Expr *lhs,*rhs,*expr;
|
||||||
lhs = COND_EXPR::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
|
lhs = AstIdent::id (*m_icodes[1]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], eUSE);
|
||||||
lhs = COND_EXPR::unary (m_is_dec ? PRE_DEC : PRE_INC, lhs);
|
lhs = UnaryOperator::Create(m_is_dec, lhs);
|
||||||
rhs = COND_EXPR::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);
|
rhs = AstIdent::id (*m_icodes[2]->ll(), SRC, m_func, m_icodes[0], *m_icodes[3], eUSE);
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB]);
|
expr = new BinaryOperator(condOpJCond[m_icodes[3]->ll()->getOpcode() - iJB],lhs, rhs);
|
||||||
m_icodes[3]->setJCond(expr);
|
m_icodes[3]->setJCond(expr);
|
||||||
for(int i=0; i<3; ++i)
|
for(int i=0; i<3; ++i)
|
||||||
m_icodes[i]->invalidate();
|
m_icodes[i]->invalidate();
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ int Idiom3::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I) )
|
if (m_icodes[0]->ll()->testFlags(I) )
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -77,13 +77,13 @@ bool Idiom17::match(iICODE picode)
|
|||||||
if (m_icodes[1]->ll()->match(iPOP))
|
if (m_icodes[1]->ll()->match(iPOP))
|
||||||
{
|
{
|
||||||
int i=0;
|
int i=0;
|
||||||
regi = m_icodes[1]->ll()->dst.regi;
|
regi = m_icodes[1]->ll()->m_dst.regi;
|
||||||
if ((regi >= rAX) && (regi <= rBX))
|
if ((regi >= rAX) && (regi <= rBX))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
while (picode != m_end && picode->ll()->match(iPOP))
|
while (picode != m_end && picode->ll()->match(iPOP))
|
||||||
{
|
{
|
||||||
if (picode->ll()->dst.regi != regi)
|
if (picode->ll()->m_dst.regi != regi)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
m_icodes.push_back(picode++);
|
m_icodes.push_back(picode++);
|
||||||
@@ -96,7 +96,7 @@ int Idiom17::action()
|
|||||||
{
|
{
|
||||||
if (m_icodes[0]->ll()->testFlags(I))
|
if (m_icodes[0]->ll()->testFlags(I))
|
||||||
{
|
{
|
||||||
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CALL_C);
|
m_icodes[0]->ll()->src().addProcInformation(m_param_count,CConv::C);
|
||||||
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
for(size_t idx=1; idx<m_icodes.size(); ++idx)
|
||||||
{
|
{
|
||||||
m_icodes[idx]->invalidate();
|
m_icodes[idx]->invalidate();
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ int Idiom4::action()
|
|||||||
if(m_param_count)
|
if(m_param_count)
|
||||||
{
|
{
|
||||||
m_func->cbParam = (int16_t)m_param_count;
|
m_func->cbParam = (int16_t)m_param_count;
|
||||||
m_func->flg |= CALL_PASCAL;
|
m_func->callingConv(CConv::PASCAL);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
/* checkStkVars - Checks for PUSH SI
|
* checkStkVars - Checks for PUSH SI
|
||||||
* [PUSH DI]
|
* [PUSH DI]
|
||||||
* or PUSH DI
|
* or PUSH DI
|
||||||
* [PUSH SI]
|
* [PUSH SI]
|
||||||
@@ -115,7 +115,7 @@ bool Idiom1::match(iICODE picode)
|
|||||||
else // push di [push si] / push si [push di]
|
else // push di [push si] / push si [push di]
|
||||||
{
|
{
|
||||||
size_t n = checkStkVars (picode);
|
size_t n = checkStkVars (picode);
|
||||||
for(int i=0; i<n; ++i)
|
for(size_t i=0; i<n; ++i)
|
||||||
m_icodes.push_back(picode++);
|
m_icodes.push_back(picode++);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,14 +27,15 @@ bool Idiom14::match(iICODE pIcode)
|
|||||||
return false;
|
return false;
|
||||||
m_icodes[0]=pIcode++;
|
m_icodes[0]=pIcode++;
|
||||||
m_icodes[1]=pIcode++;
|
m_icodes[1]=pIcode++;
|
||||||
|
LLInst * matched [] = {m_icodes[0]->ll(),m_icodes[1]->ll()};
|
||||||
/* Check for regL */
|
/* Check for regL */
|
||||||
m_regL = m_icodes[0]->ll()->dst.regi;
|
m_regL = m_icodes[0]->ll()->m_dst.regi;
|
||||||
if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
|
if (not m_icodes[0]->ll()->testFlags(I) && ((m_regL == rAX) || (m_regL ==rBX)))
|
||||||
{
|
{
|
||||||
/* Check for XOR regH, regH */
|
/* Check for XOR regH, regH */
|
||||||
if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
|
if (m_icodes[1]->ll()->match(iXOR) && not m_icodes[1]->ll()->testFlags(I))
|
||||||
{
|
{
|
||||||
m_regH = m_icodes[1]->ll()->dst.regi;
|
m_regH = m_icodes[1]->ll()->m_dst.regi;
|
||||||
if (m_regH == m_icodes[1]->ll()->src().getReg2())
|
if (m_regH == m_icodes[1]->ll()->src().getReg2())
|
||||||
{
|
{
|
||||||
if ((m_regL == rAX) && (m_regH == rDX))
|
if ((m_regL == rAX) && (m_regH == rDX))
|
||||||
@@ -49,11 +50,13 @@ bool Idiom14::match(iICODE pIcode)
|
|||||||
int Idiom14::action()
|
int Idiom14::action()
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
COND_EXPR *lhs,*rhs;
|
AstIdent *lhs;
|
||||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, m_regH, m_regL, m_icodes[0]);
|
Expr *rhs;
|
||||||
lhs = COND_EXPR::idLongIdx (idx);
|
|
||||||
|
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(m_regH,m_regL), m_icodes[0]);
|
||||||
|
lhs = AstIdent::LongIdx (idx);
|
||||||
m_icodes[0]->setRegDU( m_regH, eDEF);
|
m_icodes[0]->setRegDU( m_regH, eDEF);
|
||||||
rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
||||||
m_icodes[0]->setAsgn(lhs, rhs);
|
m_icodes[0]->setAsgn(lhs, rhs);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
@@ -80,13 +83,13 @@ bool Idiom13::match(iICODE pIcode)
|
|||||||
eReg regi;
|
eReg regi;
|
||||||
|
|
||||||
/* Check for regL */
|
/* Check for regL */
|
||||||
regi = m_icodes[0]->ll()->dst.regi;
|
regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
|
if (not m_icodes[0]->ll()->testFlags(I) && (regi >= rAL) && (regi <= rBH))
|
||||||
{
|
{
|
||||||
/* Check for MOV regH, 0 */
|
/* Check for MOV regH, 0 */
|
||||||
if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
|
if (m_icodes[1]->ll()->match(iMOV,I) && (m_icodes[1]->ll()->src().getImm2() == 0))
|
||||||
{
|
{
|
||||||
if (m_icodes[1]->ll()->dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
|
if (m_icodes[1]->ll()->m_dst.regi == (regi + 4)) //WARNING: based on distance between AH-AL,BH-BL etc.
|
||||||
{
|
{
|
||||||
m_loaded_reg=(eReg)(regi - rAL + rAX);
|
m_loaded_reg=(eReg)(regi - rAL + rAX);
|
||||||
return true;
|
return true;
|
||||||
@@ -98,11 +101,14 @@ bool Idiom13::match(iICODE pIcode)
|
|||||||
|
|
||||||
int Idiom13::action()
|
int Idiom13::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs;
|
AstIdent *lhs;
|
||||||
lhs = COND_EXPR::idReg (m_loaded_reg, 0, &m_func->localId);
|
Expr *rhs;
|
||||||
|
eReg regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
|
m_icodes[0]->du1.removeDef(regi);
|
||||||
|
//m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
|
||||||
|
lhs = new RegisterNode(LLOperand(m_loaded_reg, 0), &m_func->localId);
|
||||||
m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
|
m_icodes[0]->setRegDU( m_loaded_reg, eDEF);
|
||||||
m_icodes[0]->du1.numRegsDef--; /* prev uint8_t reg def */
|
rhs = AstIdent::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
||||||
rhs = COND_EXPR::id (*m_icodes[0]->ll(), SRC, m_func, m_icodes[0], *m_icodes[0], NONE);
|
|
||||||
m_icodes[0]->setAsgn(lhs, rhs);
|
m_icodes[0]->setAsgn(lhs, rhs);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ using namespace std;
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
bool Idiom11::match (iICODE picode)
|
bool Idiom11::match (iICODE picode)
|
||||||
{
|
{
|
||||||
const char *matchstring="(oNEG rH) (oNEG rL) (SBB \rH i0)";
|
//const char *matchstring="(oNEG rH) (oNEG rL) (SBB \rH i0)";
|
||||||
condId type; /* type of argument */
|
condId type; /* type of argument */
|
||||||
if(distance(picode,m_end)<3)
|
if(distance(picode,m_end)<3)
|
||||||
return false;
|
return false;
|
||||||
@@ -32,27 +32,30 @@ bool Idiom11::match (iICODE picode)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case GLOB_VAR:
|
case GLOB_VAR:
|
||||||
if ((m_icodes[2]->ll()->dst.segValue == m_icodes[0]->ll()->dst.segValue) &&
|
if ((m_icodes[2]->ll()->m_dst.segValue == m_icodes[0]->ll()->m_dst.segValue) &&
|
||||||
(m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off))
|
(m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
if (m_icodes[2]->ll()->dst.regi == m_icodes[0]->ll()->dst.regi)
|
if (m_icodes[2]->ll()->m_dst.regi == m_icodes[0]->ll()->m_dst.regi)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case PARAM:
|
case PARAM:
|
||||||
case LOCAL_VAR:
|
case LOCAL_VAR:
|
||||||
if (m_icodes[2]->ll()->dst.off == m_icodes[0]->ll()->dst.off)
|
if (m_icodes[2]->ll()->m_dst.off == m_icodes[0]->ll()->m_dst.off)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"Idiom11::match unhandled type %d\n",type);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int Idiom11::action()
|
int Idiom11::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs;
|
AstIdent *lhs;
|
||||||
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
|
Expr *rhs;
|
||||||
rhs = COND_EXPR::unary (NEGATION, lhs);
|
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0], HIGH_FIRST,m_icodes[0], USE_DEF, *m_icodes[1]->ll());
|
||||||
|
rhs = UnaryOperator::Create(NEGATION, lhs);
|
||||||
m_icodes[0]->setAsgn(lhs, rhs);
|
m_icodes[0]->setAsgn(lhs, rhs);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
m_icodes[2]->invalidate();
|
m_icodes[2]->invalidate();
|
||||||
@@ -73,17 +76,17 @@ int Idiom11::action()
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
bool Idiom16::match (iICODE picode)
|
bool Idiom16::match (iICODE picode)
|
||||||
{
|
{
|
||||||
const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)";
|
//const char *matchstring="(oNEG rR) (oSBB rR rR) (oINC rR)";
|
||||||
if(distance(picode,m_end)<3)
|
if(distance(picode,m_end)<3)
|
||||||
return false;
|
return false;
|
||||||
for(int i=0; i<3; ++i)
|
for(int i=0; i<3; ++i)
|
||||||
m_icodes[i]=picode++;
|
m_icodes[i]=picode++;
|
||||||
|
|
||||||
uint8_t regi = m_icodes[0]->ll()->dst.regi;
|
uint8_t regi = m_icodes[0]->ll()->m_dst.regi;
|
||||||
if ((regi >= rAX) && (regi < INDEX_BX_SI))
|
if ((regi >= rAX) && (regi < INDEX_BX_SI))
|
||||||
{
|
{
|
||||||
if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
|
if (m_icodes[1]->ll()->match(iSBB) && m_icodes[2]->ll()->match(iINC))
|
||||||
if ((m_icodes[1]->ll()->dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
|
if ((m_icodes[1]->ll()->m_dst.regi == (m_icodes[1]->ll()->src().getReg2())) &&
|
||||||
m_icodes[1]->ll()->match((eReg)regi) &&
|
m_icodes[1]->ll()->match((eReg)regi) &&
|
||||||
m_icodes[2]->ll()->match((eReg)regi))
|
m_icodes[2]->ll()->match((eReg)regi))
|
||||||
return true;
|
return true;
|
||||||
@@ -92,9 +95,10 @@ bool Idiom16::match (iICODE picode)
|
|||||||
}
|
}
|
||||||
int Idiom16::action()
|
int Idiom16::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs;
|
AstIdent *lhs;
|
||||||
lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi, m_icodes[0]->ll()->getFlag(),&m_func->localId);
|
Expr *rhs;
|
||||||
rhs = COND_EXPR::unary (NEGATION, lhs->clone());
|
lhs = new RegisterNode(*m_icodes[0]->ll()->get(DST),&m_func->localId);
|
||||||
|
rhs = UnaryOperator::Create(NEGATION, lhs->clone());
|
||||||
m_icodes[0]->setAsgn(lhs, rhs);
|
m_icodes[0]->setAsgn(lhs, rhs);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
m_icodes[2]->invalidate();
|
m_icodes[2]->invalidate();
|
||||||
|
|||||||
@@ -28,16 +28,16 @@ bool Idiom8::match(iICODE pIcode)
|
|||||||
int Idiom8::action()
|
int Idiom8::action()
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
COND_EXPR *rhs,*lhs,*expr;
|
AstIdent *lhs;
|
||||||
|
Expr *expr;
|
||||||
eReg regH,regL;
|
eReg regH,regL;
|
||||||
regH=m_icodes[0]->ll()->dst.regi;
|
regH=m_icodes[0]->ll()->m_dst.regi;
|
||||||
regL=m_icodes[1]->ll()->dst.regi;
|
regL=m_icodes[1]->ll()->m_dst.regi;
|
||||||
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, regH, regL, m_icodes[0]);
|
idx = m_func->localId.newLongReg (TYPE_LONG_SIGN, LONGID_TYPE(regH,regL), m_icodes[0]);
|
||||||
lhs = COND_EXPR::idLongIdx (idx);
|
lhs = AstIdent::LongIdx (idx);
|
||||||
m_icodes[0]->setRegDU( regL, USE_DEF);
|
m_icodes[0]->setRegDU( regL, USE_DEF);
|
||||||
|
|
||||||
rhs = COND_EXPR::idKte(1,2);
|
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
|
||||||
expr = COND_EXPR::boolOp(lhs, rhs, SHR);
|
|
||||||
m_icodes[0]->setAsgn(lhs, expr);
|
m_icodes[0]->setAsgn(lhs, expr);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
@@ -65,7 +65,7 @@ bool Idiom15::match(iICODE pIcode)
|
|||||||
if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
|
if (not pIcode->ll()->testFlags(I) or (pIcode->ll()->src().getImm2() != 1))
|
||||||
return false;
|
return false;
|
||||||
m_icodes.clear();
|
m_icodes.clear();
|
||||||
regi = pIcode->ll()->dst.regi;
|
regi = pIcode->ll()->m_dst.regi;
|
||||||
m_icodes.push_back(pIcode++);
|
m_icodes.push_back(pIcode++);
|
||||||
while( (pIcode!=m_end) and
|
while( (pIcode!=m_end) and
|
||||||
pIcode->ll()->match(iSHL,(eReg)regi,I) and
|
pIcode->ll()->match(iSHL,(eReg)regi,I) and
|
||||||
@@ -78,12 +78,12 @@ bool Idiom15::match(iICODE pIcode)
|
|||||||
|
|
||||||
int Idiom15::action()
|
int Idiom15::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs,*_exp;
|
AstIdent *lhs;
|
||||||
lhs = COND_EXPR::idReg (m_icodes[0]->ll()->dst.regi,
|
|
||||||
m_icodes[0]->ll()->getFlag() & NO_SRC_B,
|
Expr *rhs,*_exp;
|
||||||
&m_func->localId);
|
lhs = new RegisterNode(*m_icodes[0]->ll()->get(DST), &m_func->localId);
|
||||||
rhs = COND_EXPR::idKte (m_icodes.size(), 2);
|
rhs = new Constant(m_icodes.size(), 2);
|
||||||
_exp = COND_EXPR::boolOp (lhs, rhs, SHL);
|
_exp = new BinaryOperator(SHL,lhs, rhs);
|
||||||
m_icodes[0]->setAsgn(lhs, _exp);
|
m_icodes[0]->setAsgn(lhs, _exp);
|
||||||
for (size_t i=1; i<m_icodes.size()-1; ++i)
|
for (size_t i=1; i<m_icodes.size()-1; ++i)
|
||||||
{
|
{
|
||||||
@@ -116,16 +116,17 @@ bool Idiom12::match(iICODE pIcode)
|
|||||||
int Idiom12::action()
|
int Idiom12::action()
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
COND_EXPR *rhs,*lhs,*expr;
|
Expr *expr;
|
||||||
eReg regH,regL;
|
AstIdent *lhs;
|
||||||
regL=m_icodes[0]->ll()->dst.regi;
|
|
||||||
regH=m_icodes[1]->ll()->dst.regi;
|
|
||||||
|
|
||||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, regH, regL,m_icodes[0]);
|
eReg regH,regL;
|
||||||
lhs = COND_EXPR::idLongIdx (idx);
|
regL=m_icodes[0]->ll()->m_dst.regi;
|
||||||
|
regH=m_icodes[1]->ll()->m_dst.regi;
|
||||||
|
|
||||||
|
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN, LONGID_TYPE(regH,regL),m_icodes[0]);
|
||||||
|
lhs = AstIdent::LongIdx (idx);
|
||||||
m_icodes[0]->setRegDU( regH, USE_DEF);
|
m_icodes[0]->setRegDU( regH, USE_DEF);
|
||||||
rhs = COND_EXPR::idKte (1, 2);
|
expr = new BinaryOperator(SHL,lhs, new Constant(1, 2));
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, SHL);
|
|
||||||
m_icodes[0]->setAsgn(lhs, expr);
|
m_icodes[0]->setAsgn(lhs, expr);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
@@ -155,15 +156,15 @@ bool Idiom9::match(iICODE pIcode)
|
|||||||
int Idiom9::action()
|
int Idiom9::action()
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
COND_EXPR *rhs,*lhs,*expr;
|
AstIdent *lhs;
|
||||||
|
Expr *expr;
|
||||||
eReg regH,regL;
|
eReg regH,regL;
|
||||||
regL=m_icodes[1]->ll()->dst.regi;
|
regL=m_icodes[1]->ll()->m_dst.regi;
|
||||||
regH=m_icodes[0]->ll()->dst.regi;
|
regH=m_icodes[0]->ll()->m_dst.regi;
|
||||||
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,regH,regL,m_icodes[0]);
|
idx = m_func->localId.newLongReg (TYPE_LONG_UNSIGN,LONGID_TYPE(regH,regL),m_icodes[0]);
|
||||||
lhs = COND_EXPR::idLongIdx (idx);
|
lhs = AstIdent::LongIdx (idx);
|
||||||
m_icodes[0]->setRegDU(regL, USE_DEF);
|
m_icodes[0]->setRegDU(regL, USE_DEF);
|
||||||
rhs = COND_EXPR::idKte (1, 2);
|
expr = new BinaryOperator(SHR,lhs, new Constant(1, 2));
|
||||||
expr = COND_EXPR::boolOp (lhs, rhs, SHR);
|
|
||||||
m_icodes[0]->setAsgn(lhs, expr);
|
m_icodes[0]->setAsgn(lhs, expr);
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ bool Idiom21::match (iICODE picode)
|
|||||||
if (not m_icodes[1]->ll()->testFlags(I))
|
if (not m_icodes[1]->ll()->testFlags(I))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
dst = &m_icodes[0]->ll()->dst;
|
dst = &m_icodes[0]->ll()->m_dst;
|
||||||
src = &m_icodes[0]->ll()->src();
|
src = &m_icodes[0]->ll()->src();
|
||||||
if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
|
if ((dst->regi == src->getReg2()) && (dst->getReg2() > 0) && (dst->getReg2() < INDEX_BX_SI))
|
||||||
{
|
{
|
||||||
@@ -39,11 +39,13 @@ bool Idiom21::match (iICODE picode)
|
|||||||
}
|
}
|
||||||
int Idiom21::action()
|
int Idiom21::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs;
|
Expr *rhs;
|
||||||
lhs = COND_EXPR::idLong (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
|
AstIdent *lhs;
|
||||||
rhs = COND_EXPR::idKte (m_icodes[1]->ll()->src().getImm2() , 4);
|
|
||||||
|
lhs = AstIdent::Long (&m_func->localId, DST, m_icodes[0],HIGH_FIRST, m_icodes[0], eDEF, *m_icodes[1]->ll());
|
||||||
|
rhs = new Constant(m_icodes[1]->ll()->src().getImm2(), 4);
|
||||||
m_icodes[0]->setAsgn(lhs, rhs);
|
m_icodes[0]->setAsgn(lhs, rhs);
|
||||||
m_icodes[0]->du.use = 0; /* clear register used in iXOR */
|
m_icodes[0]->du.use.reset(); /* clear register used in iXOR */
|
||||||
m_icodes[1]->invalidate();
|
m_icodes[1]->invalidate();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@@ -61,7 +63,7 @@ bool Idiom7::match(iICODE picode)
|
|||||||
return false;
|
return false;
|
||||||
const LLOperand *dst, *src;
|
const LLOperand *dst, *src;
|
||||||
m_icode=picode;
|
m_icode=picode;
|
||||||
dst = &picode->ll()->dst;
|
dst = &picode->ll()->m_dst;
|
||||||
src = &picode->ll()->src();
|
src = &picode->ll()->src();
|
||||||
if (dst->regi == 0) /* global variable */
|
if (dst->regi == 0) /* global variable */
|
||||||
{
|
{
|
||||||
@@ -82,11 +84,10 @@ bool Idiom7::match(iICODE picode)
|
|||||||
}
|
}
|
||||||
int Idiom7::action()
|
int Idiom7::action()
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs,*rhs;
|
Expr *lhs;
|
||||||
lhs = COND_EXPR::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
|
lhs = AstIdent::id (*m_icode->ll(), DST, m_func, m_icode, *m_icode, NONE);
|
||||||
rhs = COND_EXPR::idKte (0, 2);
|
m_icode->setAsgn(dynamic_cast<AstIdent *>(lhs), new Constant(0, 2));
|
||||||
m_icode->setAsgn(lhs, rhs);
|
m_icode->du.use.reset(); /* clear register used in iXOR */
|
||||||
m_icode->du.use = 0; /* clear register used in iXOR */
|
|
||||||
m_icode->ll()->setFlags(I);
|
m_icode->ll()->setFlags(I);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -115,7 +116,7 @@ bool Idiom10::match(iICODE pIcode)
|
|||||||
/* Check OR reg, reg */
|
/* Check OR reg, reg */
|
||||||
if (not m_icodes[0]->ll()->testFlags(I) &&
|
if (not m_icodes[0]->ll()->testFlags(I) &&
|
||||||
m_icodes[0]->ll()->src().isReg() &&
|
m_icodes[0]->ll()->src().isReg() &&
|
||||||
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->dst.getReg2()))
|
(m_icodes[0]->ll()->src().getReg2() == m_icodes[0]->ll()->m_dst.getReg2()))
|
||||||
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
|
if (m_icodes[1]->ll()->match(iJNE)) //.conditionalJump()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -127,8 +128,9 @@ int Idiom10::action()
|
|||||||
{
|
{
|
||||||
m_icodes[0]->ll()->set(iCMP,I);
|
m_icodes[0]->ll()->set(iCMP,I);
|
||||||
m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
|
m_icodes[0]->ll()->replaceSrc(LLOperand::CreateImm2(0));
|
||||||
m_icodes[0]->du.def = 0;
|
m_icodes[0]->du.def.reset(); //TODO: this defines FLAGS
|
||||||
m_icodes[0]->du1.numRegsDef = 0;
|
m_icodes[0]->du1.clearAllDefs();
|
||||||
|
//m_icodes[0]->du1.numRegsDef = 0;
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/liveness_set.cpp
Normal file
54
src/liveness_set.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "BasicBlock.h"
|
||||||
|
#include "machine_x86.h"
|
||||||
|
|
||||||
|
/* DU bit definitions for each reg value - including index registers */
|
||||||
|
LivenessSet duReg[] = { {},
|
||||||
|
//AH AL . . AX, BH
|
||||||
|
{rAH,rAL,rAX},{rCH,rCL,rCX},{rDH,rDL,rDX},{rBH,rBL,rBX},
|
||||||
|
/* uint16_t regs */
|
||||||
|
{rSP},{rBP},{rSI},{rDI},
|
||||||
|
/* seg regs */
|
||||||
|
{rES},{rCS},{rSS},{rDS},
|
||||||
|
/* uint8_t regs */
|
||||||
|
{rAL},{rCL},{rDL},{rBL},
|
||||||
|
{rAH},{rCH},{rDH},{rBH},
|
||||||
|
/* tmp reg */
|
||||||
|
{rTMP},{rTMP2},
|
||||||
|
/* index regs */
|
||||||
|
{rBX,rSI},{rBX,rDI},{rBP,rSI},{rBP,rDI},
|
||||||
|
{rSI},{rDI},{rBP},{rBX}
|
||||||
|
};
|
||||||
|
|
||||||
|
LivenessSet &LivenessSet::setReg(int r)
|
||||||
|
{
|
||||||
|
this->reset();
|
||||||
|
*this |= duReg[r];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
LivenessSet &LivenessSet::clrReg(int r)
|
||||||
|
{
|
||||||
|
return *this -= duReg[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
LivenessSet &LivenessSet::addReg(int r)
|
||||||
|
{
|
||||||
|
*this |= duReg[r];
|
||||||
|
// postProcessCompositeRegs();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LivenessSet::testRegAndSubregs(int r) const
|
||||||
|
{
|
||||||
|
return (*this & duReg[r]).any();
|
||||||
|
}
|
||||||
|
void LivenessSet::postProcessCompositeRegs()
|
||||||
|
{
|
||||||
|
if(testReg(rAL) and testReg(rAH))
|
||||||
|
registers.insert(rAX);
|
||||||
|
if(testReg(rCL) and testReg(rCH))
|
||||||
|
registers.insert(rCX);
|
||||||
|
if(testReg(rDL) and testReg(rDH))
|
||||||
|
registers.insert(rDX);
|
||||||
|
if(testReg(rBL) and testReg(rBH))
|
||||||
|
registers.insert(rBX);
|
||||||
|
}
|
||||||
156
src/locident.cpp
156
src/locident.cpp
@@ -10,22 +10,45 @@
|
|||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
||||||
{
|
{
|
||||||
return (a->ll()->src().getReg2()==l) and (b->ll()->dst.getReg2()==h);
|
return (a->ll()->src().getReg2()==m_l) and (b->ll()->m_dst.getReg2()==m_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
|
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
|
||||||
{
|
{
|
||||||
name[0]=0;
|
|
||||||
macro[0]=0;
|
macro[0]=0;
|
||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
}
|
}
|
||||||
ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
||||||
{
|
{
|
||||||
name[0]=0;
|
|
||||||
macro[0]=0;
|
macro[0]=0;
|
||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
loc=f;
|
loc=f;
|
||||||
|
assert(not ((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN)));
|
||||||
|
}
|
||||||
|
ID::ID(hlType t,const LONGID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
||||||
|
{
|
||||||
|
macro[0]=0;
|
||||||
|
memset(&id,0,sizeof(id));
|
||||||
|
loc=REG_FRAME;
|
||||||
|
m_longId = s;
|
||||||
|
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||||
|
}
|
||||||
|
ID::ID(hlType t,const LONG_STKID_TYPE &s) : type(t),illegal(false),hasMacro(false)
|
||||||
|
{
|
||||||
|
macro[0]=0;
|
||||||
|
memset(&id,0,sizeof(id));
|
||||||
|
loc=STK_FRAME;
|
||||||
|
id.longStkId = s;
|
||||||
|
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||||
|
}
|
||||||
|
|
||||||
|
ID::ID(hlType t, const LONGGLB_TYPE &s) : type(t),illegal(false)
|
||||||
|
{
|
||||||
|
macro[0]=0;
|
||||||
|
memset(&id,0,sizeof(id));
|
||||||
|
loc=GLB_FRAME;
|
||||||
|
id.longGlb = s;
|
||||||
|
assert((t==TYPE_LONG_SIGN)||(t==TYPE_LONG_UNSIGN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,7 +95,6 @@ int LOCAL_ID::newByteWordReg(hlType t, eReg regi)
|
|||||||
* flagging this entry as illegal is all that can be done. */
|
* flagging this entry as illegal is all that can be done. */
|
||||||
void LOCAL_ID::flagByteWordId (int off)
|
void LOCAL_ID::flagByteWordId (int off)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
|
auto found=std::find_if(id_arr.begin(),id_arr.end(),[off](ID &en)->bool {
|
||||||
//if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) &&
|
//if (((en.type == TYPE_WORD_SIGN) || (en.type == TYPE_BYTE_SIGN)) &&
|
||||||
if ((en.typeBitsize()<=16) &&
|
if ((en.typeBitsize()<=16) &&
|
||||||
@@ -121,12 +143,10 @@ int LOCAL_ID::newByteWordStk(hlType t, int off, uint8_t regOff)
|
|||||||
* regi: indexed register into global variable
|
* regi: indexed register into global variable
|
||||||
* ix: index into icode array
|
* ix: index into icode array
|
||||||
* t: HIGH_LEVEL type */
|
* t: HIGH_LEVEL type */
|
||||||
int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t)
|
int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t)
|
||||||
{
|
{
|
||||||
int idx;
|
|
||||||
|
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (size_t idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
if (/*(locSym->id[idx].type == t) && Not checking type */
|
||||||
(id_arr[idx].id.bwGlb.seg == seg) &&
|
(id_arr[idx].id.bwGlb.seg == seg) &&
|
||||||
@@ -137,28 +157,32 @@ int LOCAL_ID::newIntIdx(int16_t seg, int16_t off, eReg regi, int ix, hlType t)
|
|||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
newIdent (t, GLB_FRAME);
|
newIdent (t, GLB_FRAME);
|
||||||
idx = id_arr.size() - 1;
|
id_arr.back().id.bwGlb.seg = seg;
|
||||||
id_arr[idx].id.bwGlb.seg = seg;
|
id_arr.back().id.bwGlb.off = off;
|
||||||
id_arr[idx].id.bwGlb.off = off;
|
id_arr.back().id.bwGlb.regi = regi;
|
||||||
id_arr[idx].id.bwGlb.regi = regi;
|
return id_arr.size() - 1;
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
||||||
* entry; otherwise creates a new register identifier node of type
|
* entry; otherwise creates a new register identifier node of type
|
||||||
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
|
* TYPE_LONG_(UN)SIGN and returns the index to this new entry. */
|
||||||
int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
int LOCAL_ID::newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_)
|
||||||
{
|
{
|
||||||
|
eReg regH,regL;
|
||||||
|
regL = longT.l();
|
||||||
|
regH = longT.h();
|
||||||
size_t idx;
|
size_t idx;
|
||||||
//iICODE ix_;
|
//iICODE ix_;
|
||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
ID &entry(id_arr[idx]);
|
ID &entry(id_arr[idx]);
|
||||||
|
if(!entry.isLong() || (entry.loc != REG_FRAME))
|
||||||
|
continue;
|
||||||
if (/*(locSym->id[idx].type == t) && Not checking type */
|
if (/*(locSym->id[idx].type == t) && Not checking type */
|
||||||
(entry.id.longId.h == regH) &&
|
(entry.longId().h() == regH) &&
|
||||||
(entry.id.longId.l == regL))
|
(entry.longId().l() == regL))
|
||||||
{
|
{
|
||||||
/* Check for occurrence in the list */
|
/* Check for occurrence in the list */
|
||||||
if (entry.idx.inList(ix_))
|
if (entry.idx.inList(ix_))
|
||||||
@@ -167,25 +191,21 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
|||||||
{
|
{
|
||||||
/* Insert icode index in list */
|
/* Insert icode index in list */
|
||||||
entry.idx.push_back(ix_);
|
entry.idx.push_back(ix_);
|
||||||
//entry.idx.insert(ix_);
|
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
newIdent (t, REG_FRAME);
|
id_arr.push_back(ID(t, LONGID_TYPE(regH,regL)));
|
||||||
id_arr[id_arr.size()-1].idx.push_back(ix_);//insert(ix_);
|
id_arr.back().idx.push_back(ix_);
|
||||||
idx = id_arr.size() - 1;
|
return (id_arr.size() - 1);
|
||||||
id_arr[idx].id.longId.h = regH;
|
|
||||||
id_arr[idx].id.longId.l = regL;
|
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
||||||
* TYPE_WORD_SIGN */
|
* TYPE_WORD_SIGN */
|
||||||
COND_EXPR * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
AstIdent * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
||||||
{
|
{
|
||||||
return COND_EXPR::idID(retVal,this,ix_);
|
return AstIdent::idID(retVal,this,ix_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
||||||
@@ -204,14 +224,11 @@ int LOCAL_ID::newLongGlb(int16_t seg, int16_t offH, int16_t offL,hlType t)
|
|||||||
(id_arr[idx].id.longGlb.offL == offL))
|
(id_arr[idx].id.longGlb.offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
printf("%d",t);
|
||||||
/* Not in the table, create new identifier */
|
/* Not in the table, create new identifier */
|
||||||
newIdent (t, GLB_FRAME);
|
id_arr.push_back(ID(t, LONGGLB_TYPE(seg,offH,offL)));
|
||||||
idx = id_arr.size() - 1;
|
return (id_arr.size() - 1);
|
||||||
id_arr[idx].id.longGlb.seg = seg;
|
|
||||||
id_arr[idx].id.longGlb.offH = offH;
|
|
||||||
id_arr[idx].id.longGlb.offL = offL;
|
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -253,9 +270,11 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
/* Check for entry in the table */
|
/* Check for entry in the table */
|
||||||
for (idx = 0; idx < id_arr.size(); idx++)
|
for (idx = 0; idx < id_arr.size(); idx++)
|
||||||
{
|
{
|
||||||
|
if(id_arr[idx].loc!=STK_FRAME)
|
||||||
|
continue;
|
||||||
if ((id_arr[idx].type == t) &&
|
if ((id_arr[idx].type == t) &&
|
||||||
(id_arr[idx].id.longStkId.offH == offH) &&
|
(id_arr[idx].longStkId().offH == offH) &&
|
||||||
(id_arr[idx].id.longStkId.offL == offL))
|
(id_arr[idx].longStkId().offL == offL))
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,11 +283,8 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
flagByteWordId (offL);
|
flagByteWordId (offL);
|
||||||
|
|
||||||
/* Create new identifier */
|
/* Create new identifier */
|
||||||
newIdent (t, STK_FRAME);
|
id_arr.push_back(ID(t,LONG_STKID_TYPE(offH,offL)));
|
||||||
idx = id_arr.size() - 1;
|
return (id_arr.size() - 1);
|
||||||
id_arr[idx].id.longStkId.offH = offH;
|
|
||||||
id_arr[idx].id.longStkId.offL = offL;
|
|
||||||
return (idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -277,7 +293,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
* number in an expression record. */
|
* number in an expression record. */
|
||||||
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
|
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
size_t idx;
|
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
|
||||||
const LLOperand *pmH, *pmL;
|
const LLOperand *pmH, *pmL;
|
||||||
LLInst &p_ll(*pIcode->ll());
|
LLInst &p_ll(*pIcode->ll());
|
||||||
if (f == LOW_FIRST)
|
if (f == LOW_FIRST)
|
||||||
@@ -296,7 +312,7 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
|||||||
|
|
||||||
else if (pmL->regi < INDEX_BX_SI) /* register */
|
else if (pmL->regi < INDEX_BX_SI) /* register */
|
||||||
{
|
{
|
||||||
idx = newLongReg(TYPE_LONG_SIGN, pmH->regi, pmL->regi, ix);
|
idx = newLongReg(TYPE_LONG_SIGN, LONGID_TYPE(pmH->regi, pmL->regi), ix);
|
||||||
if (f == HIGH_FIRST)
|
if (f == HIGH_FIRST)
|
||||||
pIcode->setRegDU( pmL->regi, du); /* low part */
|
pIcode->setRegDU( pmL->regi, du); /* low part */
|
||||||
else
|
else
|
||||||
@@ -332,30 +348,46 @@ int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, L
|
|||||||
* idx : idx into icode array
|
* idx : idx into icode array
|
||||||
* pProc : ptr to current procedure record
|
* pProc : ptr to current procedure record
|
||||||
* rhs, lhs : return expressions if successful. */
|
* rhs, lhs : return expressions if successful. */
|
||||||
boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
|
bool checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
/* pointers to LOW_LEVEL icodes */
|
/* pointers to LOW_LEVEL icodes */
|
||||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||||
|
|
||||||
pmHdst = &pIcode->ll()->dst;
|
pmHdst = &pIcode->ll()->m_dst;
|
||||||
pmLdst = &atOffset.dst;
|
pmLdst = &atOffset.m_dst;
|
||||||
pmHsrc = &pIcode->ll()->src();
|
pmHsrc = &pIcode->ll()->src();
|
||||||
pmLsrc = &atOffset.src();
|
pmLsrc = &atOffset.src();
|
||||||
|
// if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
||||||
|
// {
|
||||||
|
// asgn.lhs = AstIdent::LongIdx (i);
|
||||||
|
|
||||||
|
// if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||||
|
// {
|
||||||
|
// asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// else if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
||||||
|
// {
|
||||||
|
// asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
||||||
|
// asgn.rhs = AstIdent::LongIdx (i);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
if ((longId.offH == pmHdst->off) && (longId.offL == pmLdst->off))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (i);
|
asgn.lhs = AstIdent::LongIdx (i);
|
||||||
|
|
||||||
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||||
{
|
{
|
||||||
asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode,eDEF, atOffset);
|
||||||
asgn.rhs = COND_EXPR::idLongIdx (i);
|
asgn.rhs = AstIdent::LongIdx (i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -371,30 +403,30 @@ boolT checkLongEq (LONG_STKID_TYPE longId, iICODE pIcode, int i, Function * pPro
|
|||||||
* idx : idx into icode array
|
* idx : idx into icode array
|
||||||
* pProc : ptr to current procedure record
|
* pProc : ptr to current procedure record
|
||||||
* rhs, lhs : return expressions if successful. */
|
* rhs, lhs : return expressions if successful. */
|
||||||
boolT checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
bool checkLongRegEq (LONGID_TYPE longId, iICODE pIcode, int i,
|
||||||
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
Function * pProc, Assignment &asgn, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
/* pointers to LOW_LEVEL icodes */
|
/* pointers to LOW_LEVEL icodes */
|
||||||
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
const LLOperand *pmHdst, *pmLdst, *pmHsrc, *pmLsrc;
|
||||||
|
|
||||||
pmHdst = &pIcode->ll()->dst;
|
pmHdst = &pIcode->ll()->m_dst;
|
||||||
pmLdst = &atOffset.dst;
|
pmLdst = &atOffset.m_dst;
|
||||||
pmHsrc = &pIcode->ll()->src();
|
pmHsrc = &pIcode->ll()->src();
|
||||||
pmLsrc = &atOffset.src();
|
pmLsrc = &atOffset.src();
|
||||||
|
|
||||||
if ((longId.h == pmHdst->regi) && (longId.l == pmLdst->regi))
|
if ((longId.h() == pmHdst->regi) && (longId.l() == pmLdst->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (i);
|
asgn.lhs = AstIdent::LongIdx (i);
|
||||||
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
if ( not pIcode->ll()->testFlags(NO_SRC) )
|
||||||
{
|
{
|
||||||
asgn.rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
asgn.rhs = AstIdent::Long (&pProc->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, atOffset);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
|
else if ((longId.h() == pmHsrc->regi) && (longId.l() == pmLsrc->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
|
asgn.lhs = AstIdent::Long (&pProc->localId, DST, pIcode, HIGH_FIRST, pIcode, eDEF, atOffset);
|
||||||
asgn.rhs = COND_EXPR::idLongIdx (i);
|
asgn.rhs = AstIdent::LongIdx (i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -413,10 +445,10 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
|
|||||||
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
if ((id->loc == REG_FRAME) && ((id->type == TYPE_LONG_SIGN) ||
|
||||||
(id->type == TYPE_LONG_UNSIGN)))
|
(id->type == TYPE_LONG_UNSIGN)))
|
||||||
{
|
{
|
||||||
if (id->id.longId.h == regi)
|
if (id->longId().h() == regi)
|
||||||
return (id->id.longId.l);
|
return (id->longId().l());
|
||||||
else if (id->id.longId.l == regi)
|
else if (id->longId().l() == regi)
|
||||||
return (id->id.longId.h);
|
return (id->longId().h());
|
||||||
}
|
}
|
||||||
return rUNDEF; // Cristina: please check this!
|
return rUNDEF; // Cristina: please check this!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "machine_x86.h"
|
#include "machine_x86.h"
|
||||||
|
#include "icode.h"
|
||||||
// Index registers **** temp solution
|
// Index registers **** temp solution
|
||||||
static const std::string regNames[] = {
|
static const std::string regNames[] = {
|
||||||
"undef",
|
"undef",
|
||||||
@@ -8,7 +9,7 @@ static const std::string regNames[] = {
|
|||||||
"es", "cs", "ss", "ds",
|
"es", "cs", "ss", "ds",
|
||||||
"al", "cl", "dl", "bl",
|
"al", "cl", "dl", "bl",
|
||||||
"ah", "ch", "dh", "bh",
|
"ah", "ch", "dh", "bh",
|
||||||
"tmp",
|
"tmp","tmp2",
|
||||||
"bx+si", "bx+di", "bp+si", "bp+di",
|
"bx+si", "bx+di", "bp+si", "bp+di",
|
||||||
"si", "di", "bp", "bx"
|
"si", "di", "bp", "bx"
|
||||||
};
|
};
|
||||||
@@ -109,3 +110,35 @@ bool Machine_X86::isSubRegisterOf(eReg reg,eReg parent)
|
|||||||
return false; // only AX -> BX are coverede by subregisters
|
return false; // only AX -> BX are coverede by subregisters
|
||||||
return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
|
return ((reg==subRegH(parent)) || (reg == subRegL(parent)));
|
||||||
}
|
}
|
||||||
|
bool Machine_X86::hasSubregisters(eReg reg)
|
||||||
|
{
|
||||||
|
return ((reg >= rAX) && (reg <= rBX));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Machine_X86::isPartOfComposite(eReg reg)
|
||||||
|
{
|
||||||
|
return ((reg >= rAL) && (reg <= rBH));
|
||||||
|
}
|
||||||
|
|
||||||
|
eReg Machine_X86::compositeParent(eReg reg)
|
||||||
|
{
|
||||||
|
switch(reg)
|
||||||
|
{
|
||||||
|
case rAL: case rAH: return rAX;
|
||||||
|
case rCL: case rCH: return rCX;
|
||||||
|
case rDL: case rDH: return rDX;
|
||||||
|
case rBL: case rBH: return rBX;
|
||||||
|
default:
|
||||||
|
return rUNDEF;
|
||||||
|
}
|
||||||
|
return rUNDEF;
|
||||||
|
}
|
||||||
|
void Machine_X86::writeRegVector (std::ostream &ostr,const LivenessSet ®i)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = rAX; j < INDEX_BX_SI; j++)
|
||||||
|
{
|
||||||
|
if (regi.testReg(j))
|
||||||
|
ostr << regName(eReg(j))<<" ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
513
src/parser.cpp
513
src/parser.cpp
File diff suppressed because it is too large
Load Diff
@@ -14,19 +14,17 @@
|
|||||||
static uint16_t *T1, *T2; /* Pointers to T1[i], T2[i] */
|
static uint16_t *T1, *T2; /* Pointers to T1[i], T2[i] */
|
||||||
static short *g; /* g[] */
|
static short *g; /* g[] */
|
||||||
|
|
||||||
static int numEdges; /* An edge counter */
|
//static int numEdges; /* An edge counter */
|
||||||
//static bool *visited; /* Array of bools: whether visited */
|
//static bool *visited; /* Array of bools: whether visited */
|
||||||
|
|
||||||
/* Private prototypes */
|
/* Private prototypes */
|
||||||
static void initGraph(void);
|
//static void initGraph(void);
|
||||||
static void addToGraph(int e, int v1, int v2);
|
//static void addToGraph(int e, int v1, int v2);
|
||||||
static bool isCycle(void);
|
//static bool isCycle(void);
|
||||||
static void duplicateKeys(int v1, int v2);
|
//static void duplicateKeys(int v1, int v2);
|
||||||
PatternHasher g_pattern_hasher;
|
PatternHasher g_pattern_hasher;
|
||||||
|
|
||||||
void
|
void PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin, int _NumVert)
|
||||||
PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
|
|
||||||
int _NumVert)
|
|
||||||
{
|
{
|
||||||
/* These parameters are stored in statics so as to obviate the need for
|
/* These parameters are stored in statics so as to obviate the need for
|
||||||
passing all these (or defererencing pointers) for every call to hash()
|
passing all these (or defererencing pointers) for every call to hash()
|
||||||
|
|||||||
176
src/procs.cpp
176
src/procs.cpp
@@ -9,6 +9,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
#include "CallGraph.h"
|
||||||
|
|
||||||
extern Project g_proj;
|
extern Project g_proj;
|
||||||
/* Static indentation buffer */
|
/* Static indentation buffer */
|
||||||
@@ -43,8 +44,6 @@ void CALL_GRAPH::insertArc (ilFunction newProc)
|
|||||||
/* Inserts a (caller, callee) arc in the call graph tree. */
|
/* Inserts a (caller, callee) arc in the call graph tree. */
|
||||||
bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
|
bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
if (proc == caller)
|
if (proc == caller)
|
||||||
{
|
{
|
||||||
insertArc (callee);
|
insertArc (callee);
|
||||||
@@ -52,8 +51,8 @@ bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < outEdges.size(); i++)
|
for (CALL_GRAPH *edg : outEdges)
|
||||||
if (outEdges[i]->insertCallGraph (caller, callee))
|
if (edg->insertCallGraph (caller, callee))
|
||||||
return true;
|
return true;
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -61,7 +60,7 @@ bool CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
|
|||||||
|
|
||||||
bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
|
bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
|
||||||
{
|
{
|
||||||
return insertCallGraph(g_proj.funcIter(caller),callee);
|
return insertCallGraph(Project::get()->funcIter(caller),callee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -69,11 +68,9 @@ bool CALL_GRAPH::insertCallGraph(Function *caller, ilFunction callee)
|
|||||||
* the nodes the procedure invokes. */
|
* the nodes the procedure invokes. */
|
||||||
void CALL_GRAPH::writeNodeCallGraph(int indIdx)
|
void CALL_GRAPH::writeNodeCallGraph(int indIdx)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
printf ("%s%s\n", indentStr(indIdx), proc->name.c_str());
|
printf ("%s%s\n", indentStr(indIdx), proc->name.c_str());
|
||||||
for (i = 0; i < outEdges.size(); i++)
|
for (CALL_GRAPH *cg : outEdges)
|
||||||
outEdges[i]->writeNodeCallGraph (indIdx + 1);
|
cg->writeNodeCallGraph (indIdx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -94,14 +91,15 @@ void CALL_GRAPH::write()
|
|||||||
* Note: register(s) are only included once in the table. */
|
* Note: register(s) are only included once in the table. */
|
||||||
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs;
|
AstIdent *lhs;
|
||||||
STKFRAME * call_args_stackframe, *target_stackframe;
|
STKFRAME * call_args_stackframe, *target_stackframe;
|
||||||
const ID *id;
|
const ID *id;
|
||||||
int tidx;
|
int tidx;
|
||||||
boolT regExist;
|
bool regExist=false;
|
||||||
condId type;
|
condId type;
|
||||||
Function * tproc;
|
Function * tproc;
|
||||||
eReg regL, regH; /* Registers involved in arguments */
|
eReg regL = rUNDEF;
|
||||||
|
eReg regH; /* Registers involved in arguments */
|
||||||
|
|
||||||
/* Flag ticode as having register arguments */
|
/* Flag ticode as having register arguments */
|
||||||
tproc = ticode->hl()->call.proc;
|
tproc = ticode->hl()->call.proc;
|
||||||
@@ -110,48 +108,56 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
/* Get registers and index into target procedure's local list */
|
/* Get registers and index into target procedure's local list */
|
||||||
call_args_stackframe = ticode->hl()->call.args;
|
call_args_stackframe = ticode->hl()->call.args;
|
||||||
target_stackframe = &tproc->args;
|
target_stackframe = &tproc->args;
|
||||||
lhs = picode->hl()->asgn.lhs;
|
lhs = dynamic_cast<AstIdent *>(picode->hl()->asgn.lhs());
|
||||||
type = lhs->expr.ident.idType;
|
RegisterNode *lhs_reg = dynamic_cast<RegisterNode *>(lhs);
|
||||||
if (type == REGISTER)
|
assert(lhs);
|
||||||
|
type = lhs->ident.type();
|
||||||
|
if(type==REGISTER)
|
||||||
|
assert(lhs_reg);
|
||||||
|
if(type==LONG_VAR)
|
||||||
|
assert(!lhs_reg);
|
||||||
|
if (lhs_reg)
|
||||||
{
|
{
|
||||||
regL = id_arr[lhs->expr.ident.idNode.regiIdx].id.regi;
|
regL = id_arr[lhs_reg->regiIdx].id.regi;
|
||||||
|
assert(regL!=rUNDEF);
|
||||||
if (regL < rAL)
|
if (regL < rAL)
|
||||||
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
||||||
else
|
else
|
||||||
tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL);
|
tidx = tproc->localId.newByteWordReg(TYPE_BYTE_SIGN, regL);
|
||||||
}
|
|
||||||
else if (type == LONG_VAR)
|
|
||||||
{
|
|
||||||
int longIdx = lhs->expr.ident.idNode.longIdx;
|
|
||||||
regL = id_arr[longIdx].id.longId.l;
|
|
||||||
regH = id_arr[longIdx].id.longId.h;
|
|
||||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if register argument already on the formal argument list */
|
/* Check if register argument already on the formal argument list */
|
||||||
regExist = false;
|
|
||||||
for(STKSYM &tgt_sym : *target_stackframe)
|
for(STKSYM &tgt_sym : *target_stackframe)
|
||||||
{
|
{
|
||||||
if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
|
RegisterNode *tgt_sym_regs = dynamic_cast<RegisterNode *>(tgt_sym.regs);
|
||||||
|
if( tgt_sym_regs == nullptr ) // both REGISTER and LONG_VAR require this precondition
|
||||||
continue;
|
continue;
|
||||||
if (type == REGISTER)
|
if ( tgt_sym_regs->regiIdx == tidx )
|
||||||
{
|
|
||||||
if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx )
|
|
||||||
{
|
{
|
||||||
regExist = true;
|
regExist = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == LONG_VAR)
|
else if (type == LONG_VAR)
|
||||||
{
|
{
|
||||||
if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx )
|
int longIdx = lhs->ident.idNode.longIdx;
|
||||||
|
LONGID_TYPE regHL = id_arr[longIdx].longId();
|
||||||
|
regH=regHL.h();
|
||||||
|
regL=regHL.l();
|
||||||
|
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regHL, tproc->Icode.begin() /*0*/);
|
||||||
|
/* Check if register argument already on the formal argument list */
|
||||||
|
for(STKSYM &tgt_sym : *target_stackframe)
|
||||||
|
{
|
||||||
|
if( tgt_sym.regs == nullptr ) // both REGISTER and LONG_VAR require this precondition
|
||||||
|
continue;
|
||||||
|
if ( tgt_sym.regs->ident.idNode.longIdx == tidx )
|
||||||
{
|
{
|
||||||
regExist = true;
|
regExist = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
if(regExist == true)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
;//regExist = false;
|
||||||
/* Do ts (formal arguments) */
|
/* Do ts (formal arguments) */
|
||||||
if (regExist == false)
|
if (regExist == false)
|
||||||
{
|
{
|
||||||
@@ -161,22 +167,18 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
|
|
||||||
if (type == REGISTER)
|
if (type == REGISTER)
|
||||||
{
|
{
|
||||||
if (regL < rAL)
|
regType rType = WORD_REG;
|
||||||
{
|
if (regL >= rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
rType = BYTE_REG;
|
||||||
newsym.regs = COND_EXPR::idRegIdx(tidx, WORD_REG);
|
newsym.type = (regL < rAL) ? TYPE_WORD_SIGN : TYPE_BYTE_SIGN;
|
||||||
}
|
newsym.regs = new RegisterNode(tidx, rType,this);
|
||||||
else
|
|
||||||
{
|
|
||||||
newsym.type = TYPE_BYTE_SIGN;
|
|
||||||
newsym.regs = COND_EXPR::idRegIdx(tidx, BYTE_REG);
|
|
||||||
}
|
|
||||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||||
}
|
}
|
||||||
else if (type == LONG_VAR)
|
else if (type == LONG_VAR)
|
||||||
{
|
{
|
||||||
newsym.regs = COND_EXPR::idLongIdx (tidx);
|
newsym.regs = AstIdent::LongIdx (tidx);
|
||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
|
assert(regL!=rUNDEF);
|
||||||
tproc->localId.id_arr[tidx].name = newsym.name;
|
tproc->localId.id_arr[tidx].name = newsym.name;
|
||||||
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
|
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
|
||||||
}
|
}
|
||||||
@@ -192,19 +194,21 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
/* Mask off high and low register(s) in picode */
|
/* Mask off high and low register(s) in picode */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
id = &id_arr[lhs->expr.ident.idNode.regiIdx];
|
id = &id_arr[lhs_reg->regiIdx];
|
||||||
picode->du.def &= maskDuReg[id->id.regi];
|
picode->du.def.clrReg(id->id.regi);
|
||||||
if (id->id.regi < rAL)
|
if (id->id.regi < rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
newsym.type = TYPE_WORD_SIGN;
|
||||||
else
|
else
|
||||||
newsym.type = TYPE_BYTE_SIGN;
|
newsym.type = TYPE_BYTE_SIGN;
|
||||||
break;
|
break;
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
id = &id_arr[lhs->expr.ident.idNode.longIdx];
|
id = &id_arr[lhs->ident.idNode.longIdx];
|
||||||
picode->du.def &= maskDuReg[id->id.longId.h];
|
picode->du.def.clrReg(id->longId().h());
|
||||||
picode->du.def &= maskDuReg[id->id.longId.l];
|
picode->du.def.clrReg(id->longId().l());
|
||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"LOCAL_ID::newRegArg unhandled type %d in masking low\n",type);
|
||||||
}
|
}
|
||||||
call_args_stackframe->push_back(newsym);
|
call_args_stackframe->push_back(newsym);
|
||||||
call_args_stackframe->numArgs++;
|
call_args_stackframe->numArgs++;
|
||||||
@@ -216,22 +220,20 @@ void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
|||||||
* @return true if it was a near call that made use of a segment register.
|
* @return true if it was a near call that made use of a segment register.
|
||||||
* false elsewhere
|
* false elsewhere
|
||||||
*/
|
*/
|
||||||
bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
|
bool CallType::newStkArg(Expr *exp, llIcode opcode, Function * pproc)
|
||||||
{
|
{
|
||||||
|
RegisterNode *expr = dynamic_cast<RegisterNode *>(exp);
|
||||||
|
|
||||||
uint8_t regi;
|
uint8_t regi;
|
||||||
/* Check for far procedure call, in which case, references to segment
|
/* Check for far procedure call, in which case, references to segment
|
||||||
* registers are not be considered another parameter (i.e. they are
|
* registers are not be considered another parameter (i.e. they are
|
||||||
* long references to another segment) */
|
* long references to another segment) */
|
||||||
if (exp)
|
if (expr)
|
||||||
{
|
{
|
||||||
if ((exp->m_type == IDENTIFIER) && (exp->expr.ident.idType == REGISTER))
|
regi = pproc->localId.id_arr[expr->regiIdx].id.regi;
|
||||||
{
|
|
||||||
regi = pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi;
|
|
||||||
if ((regi >= rES) && (regi <= rDS))
|
if ((regi >= rES) && (regi <= rDS))
|
||||||
if (opcode == iCALLF)
|
{
|
||||||
return false;
|
return (opcode == iCALLF) ? false : true;
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,33 +248,34 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
|
|||||||
|
|
||||||
/* Places the actual argument exp in the position given by pos in the
|
/* Places the actual argument exp in the position given by pos in the
|
||||||
* argument list of picode. */
|
* argument list of picode. */
|
||||||
void CallType::placeStkArg (COND_EXPR *exp, int pos)
|
void CallType::placeStkArg (Expr *exp, int pos)
|
||||||
{
|
{
|
||||||
(*args)[pos].actual = exp;
|
(*args)[pos].actual = exp;
|
||||||
(*args)[pos].setArgName(pos);
|
(*args)[pos].setArgName(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
COND_EXPR *CallType::toId()
|
Expr *CallType::toAst()
|
||||||
{
|
{
|
||||||
return COND_EXPR::idFunc( proc, args);
|
return new FuncNode( proc, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks to determine whether the expression (actual argument) has the
|
/* Checks to determine whether the expression (actual argument) has the
|
||||||
* same type as the given type (from the procedure's formal list). If not,
|
* same type as the given type (from the procedure's formal list). If not,
|
||||||
* the actual argument gets modified */
|
* the actual argument gets modified */
|
||||||
void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc)
|
Expr *Function::adjustActArgType (Expr *_exp, hlType forType)
|
||||||
{
|
{
|
||||||
|
AstIdent *expr = dynamic_cast<AstIdent *>(_exp);
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
hlType actType;
|
hlType actType;
|
||||||
int offset, offL;
|
int offset, offL;
|
||||||
|
|
||||||
if (exp == NULL)
|
if (expr == nullptr)
|
||||||
return;
|
return _exp;
|
||||||
|
|
||||||
actType = exp-> expType (pproc);
|
actType = expr-> expType (this);
|
||||||
if (((actType == forType) || (exp->m_type != IDENTIFIER)))
|
if (actType == forType)
|
||||||
return;
|
return _exp;
|
||||||
switch (forType)
|
switch (forType)
|
||||||
{
|
{
|
||||||
case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
|
case TYPE_UNKNOWN: case TYPE_BYTE_SIGN:
|
||||||
@@ -288,16 +291,20 @@ void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc)
|
|||||||
case TYPE_STR:
|
case TYPE_STR:
|
||||||
switch (actType) {
|
switch (actType) {
|
||||||
case TYPE_CONST:
|
case TYPE_CONST:
|
||||||
/* It's an offset into image where a string is
|
/* It's an offset into image where a string is found. Point to the string. */
|
||||||
* found. Point to the string. */
|
{
|
||||||
offL = exp->expr.ident.idNode.kte.kte;
|
Constant *c=dynamic_cast<Constant *>(expr);
|
||||||
|
assert(c);
|
||||||
|
offL = c->kte.kte;
|
||||||
if (prog.fCOM)
|
if (prog.fCOM)
|
||||||
offset = (pproc->state.r[rDS]<<4) + offL + 0x100;
|
offset = (state.r[rDS]<<4) + offL + 0x100;
|
||||||
else
|
else
|
||||||
offset = (pproc->state.r[rDS]<<4) + offL;
|
offset = (state.r[rDS]<<4) + offL;
|
||||||
exp->expr.ident.idNode.strIdx = offset;
|
expr->ident.idNode.strIdx = offset;
|
||||||
exp->expr.ident.idType = STRING;
|
expr->ident.type(STRING);
|
||||||
break;
|
delete c;
|
||||||
|
return AstIdent::String(offset);
|
||||||
|
}
|
||||||
|
|
||||||
case TYPE_PTR:
|
case TYPE_PTR:
|
||||||
/* It's a pointer to a char rather than a pointer to
|
/* It's a pointer to a char rather than a pointer to
|
||||||
@@ -308,20 +315,25 @@ void adjustActArgType (COND_EXPR *exp, hlType forType, Function * pproc)
|
|||||||
case TYPE_WORD_SIGN:
|
case TYPE_WORD_SIGN:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"adjustForArgType unhandled actType_ %d \n",actType);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"adjustForArgType unhandled forType %d \n",forType);
|
||||||
}
|
}
|
||||||
|
return _exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Determines whether the formal argument has the same type as the given
|
/* Determines whether the formal argument has the same type as the given
|
||||||
* type (type of the actual argument). If not, the formal argument is
|
* type (type of the actual argument). If not, the formal argument is
|
||||||
* changed its type */
|
* changed its type */
|
||||||
void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
|
void STKFRAME::adjustForArgType(size_t numArg_, hlType actType_)
|
||||||
{
|
{
|
||||||
hlType forType;
|
hlType forType;
|
||||||
STKSYM * psym, * nsym;
|
STKSYM * psym, * nsym;
|
||||||
int off, i;
|
int off;
|
||||||
/* If formal argument does not exist, do not create new ones, just
|
/* If formal argument does not exist, do not create new ones, just
|
||||||
* ignore actual argument
|
* ignore actual argument
|
||||||
*/
|
*/
|
||||||
@@ -330,7 +342,7 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
|
|||||||
|
|
||||||
/* Find stack offset for this argument */
|
/* Find stack offset for this argument */
|
||||||
off = m_minOff;
|
off = m_minOff;
|
||||||
i=0;
|
size_t i=0;
|
||||||
for(STKSYM &s : *this) // walk formal arguments upto numArg_
|
for(STKSYM &s : *this) // walk formal arguments upto numArg_
|
||||||
{
|
{
|
||||||
if(i>=numArg_)
|
if(i>=numArg_)
|
||||||
@@ -343,7 +355,7 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
|
|||||||
//psym = &at(numArg_);
|
//psym = &at(numArg_);
|
||||||
//i = numArg_;
|
//i = numArg_;
|
||||||
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
|
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
|
||||||
auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {s.label==off;});
|
auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {return s.label==off;});
|
||||||
if(iter==end()) // symbol not found
|
if(iter==end()) // symbol not found
|
||||||
return;
|
return;
|
||||||
psym = &(*iter);
|
psym = &(*iter);
|
||||||
@@ -380,6 +392,8 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
|
|||||||
case TYPE_CONST:
|
case TYPE_CONST:
|
||||||
case TYPE_STR:
|
case TYPE_STR:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"STKFRAME::adjustForArgType unhandled actType_ %d \n",actType_);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,38 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "dcc.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
Project g_proj;
|
using namespace std;
|
||||||
|
//Project g_proj;
|
||||||
|
char *asm1_name, *asm2_name; /* Assembler output filenames */
|
||||||
|
SYMTAB symtab; /* Global symbol table */
|
||||||
|
STATS stats; /* cfg statistics */
|
||||||
|
//PROG prog; /* programs fields */
|
||||||
|
OPTION option; /* Command line options */
|
||||||
|
Project *Project::s_instance = nullptr;
|
||||||
|
Project::Project() : callGraph(nullptr)
|
||||||
|
{
|
||||||
|
memset(&prog,0,sizeof(prog));
|
||||||
|
}
|
||||||
|
void Project::initialize()
|
||||||
|
{
|
||||||
|
delete callGraph;
|
||||||
|
callGraph = nullptr;
|
||||||
|
}
|
||||||
|
void Project::create(const string &a)
|
||||||
|
{
|
||||||
|
m_fname=a;
|
||||||
|
string::size_type ext_loc=a.find_last_of('.');
|
||||||
|
string::size_type slash_loc=a.find_last_of('/',ext_loc);
|
||||||
|
if(slash_loc==string::npos)
|
||||||
|
slash_loc=0;
|
||||||
|
else
|
||||||
|
slash_loc++;
|
||||||
|
if(ext_loc!=string::npos)
|
||||||
|
m_project_name = a.substr(slash_loc,(ext_loc-slash_loc));
|
||||||
|
else
|
||||||
|
m_project_name = a.substr(slash_loc);
|
||||||
|
}
|
||||||
bool Project::valid(ilFunction iter)
|
bool Project::valid(ilFunction iter)
|
||||||
{
|
{
|
||||||
return iter!=pProcList.end();
|
return iter!=pProcList.end();
|
||||||
@@ -18,14 +49,13 @@ ilFunction Project::findByEntry(uint32_t entry)
|
|||||||
{
|
{
|
||||||
/* Search procedure list for one with appropriate entry point */
|
/* Search procedure list for one with appropriate entry point */
|
||||||
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||||
[entry](const Function &f) ->
|
[entry](const Function &f) { return f.procEntry==entry; });
|
||||||
bool { return f.procEntry==entry; });
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ilFunction Project::createFunction()
|
ilFunction Project::createFunction(FunctionType *f,const std::string &name)
|
||||||
{
|
{
|
||||||
pProcList.push_back(Function::Create());
|
pProcList.push_back(Function::Create(f,0,name,0));
|
||||||
return (++pProcList.rbegin()).base();
|
return (++pProcList.rbegin()).base();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +93,10 @@ const std::string &Project::symbolName(size_t idx)
|
|||||||
}
|
}
|
||||||
Project *Project::get()
|
Project *Project::get()
|
||||||
{
|
{
|
||||||
return &g_proj;
|
//WARNING: poor man's singleton, not thread safe
|
||||||
|
if(s_instance==nullptr)
|
||||||
|
s_instance=new Project;
|
||||||
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,3 +104,4 @@ SourceMachine *Project::machine()
|
|||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
162
src/proplong.cpp
162
src/proplong.cpp
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
/* Returns whether the given icode opcode is within the range of valid
|
/* Returns whether the given icode opcode is within the range of valid
|
||||||
* high-level conditional jump icodes (iJB..iJG) */
|
* high-level conditional jump icodes (iJB..iJG) */
|
||||||
static boolT isJCond (llIcode opcode)
|
static bool isJCond (llIcode opcode)
|
||||||
{
|
{
|
||||||
if ((opcode >= iJB) && (opcode <= iJG))
|
if ((opcode >= iJB) && (opcode <= iJG))
|
||||||
return true;
|
return true;
|
||||||
@@ -59,7 +59,7 @@ static bool isLong23 (BB * pbb, iICODE &off, int *arc)
|
|||||||
|
|
||||||
|
|
||||||
/* Returns whether the conditions for a 2-2 long variable are satisfied */
|
/* Returns whether the conditions for a 2-2 long variable are satisfied */
|
||||||
static boolT isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
|
static bool isLong22 (iICODE pIcode, iICODE pEnd, iICODE &off)
|
||||||
{
|
{
|
||||||
iICODE initial_icode=pIcode;
|
iICODE initial_icode=pIcode;
|
||||||
if(distance(pIcode,pEnd)<4)
|
if(distance(pIcode,pEnd)<4)
|
||||||
@@ -142,7 +142,8 @@ static int longJCond23 (Assignment &asgn, iICODE pIcode, int arc, iICODE atOffse
|
|||||||
iICODE atOffset1(atOffset),next1(++iICODE(pIcode));
|
iICODE atOffset1(atOffset),next1(++iICODE(pIcode));
|
||||||
advance(atOffset1,1);
|
advance(atOffset1,1);
|
||||||
/* Create new HLI_JCOND and condition */
|
/* Create new HLI_JCOND and condition */
|
||||||
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[atOffset1->ll()->getOpcode()-iJB]);
|
condOp oper=condOpJCond[atOffset1->ll()->getOpcode()-iJB];
|
||||||
|
asgn.lhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs);
|
||||||
next1->setJCond(asgn.lhs);
|
next1->setJCond(asgn.lhs);
|
||||||
next1->copyDU(*pIcode, eUSE, eUSE);
|
next1->copyDU(*pIcode, eUSE, eUSE);
|
||||||
next1->du.use |= atOffset->du.use;
|
next1->du.use |= atOffset->du.use;
|
||||||
@@ -177,7 +178,8 @@ static int longJCond22 (Assignment &asgn, iICODE pIcode,iICODE pEnd)
|
|||||||
iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ };
|
iICODE icodes[] = { pIcode++,pIcode++,pIcode++,pIcode++ };
|
||||||
|
|
||||||
/* Form conditional expression */
|
/* Form conditional expression */
|
||||||
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[icodes[3]->ll()->getOpcode() - iJB]);
|
condOp oper=condOpJCond[icodes[3]->ll()->getOpcode() - iJB];
|
||||||
|
asgn.lhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs);
|
||||||
icodes[1]->setJCond(asgn.lhs);
|
icodes[1]->setJCond(asgn.lhs);
|
||||||
icodes[1]->copyDU (*icodes[0], eUSE, eUSE);
|
icodes[1]->copyDU (*icodes[0], eUSE, eUSE);
|
||||||
icodes[1]->du.use |= icodes[2]->du.use;
|
icodes[1]->du.use |= icodes[2]->du.use;
|
||||||
@@ -236,7 +238,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
iICODE l23;
|
iICODE l23;
|
||||||
/* Check all icodes for offHi:offLo */
|
/* Check all icodes for offHi:offLo */
|
||||||
pEnd = Icode.end();
|
pEnd = Icode.end();
|
||||||
int stat_size=Icode.size();
|
size_t stat_size=Icode.size();
|
||||||
// for (idx = 0; idx < (Icode.size() - 1); idx++)
|
// for (idx = 0; idx < (Icode.size() - 1); idx++)
|
||||||
for(auto pIcode = Icode.begin(); ;++pIcode)
|
for(auto pIcode = Icode.begin(); ;++pIcode)
|
||||||
{
|
{
|
||||||
@@ -248,25 +250,32 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
continue;
|
continue;
|
||||||
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
if (pIcode->ll()->getOpcode() == next1->ll()->getOpcode())
|
||||||
{
|
{
|
||||||
if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *next1->ll()) == true)
|
if (checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *next1->ll()) == true)
|
||||||
{
|
{
|
||||||
switch (pIcode->ll()->getOpcode())
|
switch (pIcode->ll()->getOpcode())
|
||||||
{
|
{
|
||||||
case iMOV:
|
case iMOV:
|
||||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iAND: case iOR: case iXOR:
|
case iAND: case iOR: case iXOR:
|
||||||
|
{
|
||||||
|
condOp oper = DUMMY;
|
||||||
switch (pIcode->ll()->getOpcode())
|
switch (pIcode->ll()->getOpcode())
|
||||||
{
|
{
|
||||||
case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); break;
|
case iAND: oper=AND; break;
|
||||||
case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); break;
|
case iOR: oper=OR; break;
|
||||||
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); break;
|
case iXOR: oper=XOR; break;
|
||||||
}
|
}
|
||||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
if(DUMMY!=oper)
|
||||||
|
{
|
||||||
|
asgn.rhs = new BinaryOperator(oper,asgn.lhs, asgn.rhs);
|
||||||
|
}
|
||||||
|
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case iPUSH:
|
case iPUSH:
|
||||||
pIcode->setUnary( HLI_PUSH, asgn.lhs);
|
pIcode->setUnary( HLI_PUSH, asgn.lhs);
|
||||||
@@ -281,7 +290,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||||
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
|
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), l23, &arc)))
|
||||||
{
|
{
|
||||||
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, *l23->ll()) )
|
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this, asgn, *l23->ll()) )
|
||||||
{
|
{
|
||||||
advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
|
advance(pIcode,longJCond23 (asgn, pIcode, arc, l23));
|
||||||
}
|
}
|
||||||
@@ -291,7 +300,7 @@ void Function::propLongStk (int i, const ID &pLocId)
|
|||||||
* 2 CMPs and 2 branches */
|
* 2 CMPs and 2 branches */
|
||||||
else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
|
else if ((pIcode->ll()->getOpcode() == iCMP) && isLong22 (pIcode, pEnd, l23))
|
||||||
{
|
{
|
||||||
if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, *l23->ll()) )
|
if ( checkLongEq (pLocId.longStkId(), pIcode, i, this,asgn, *l23->ll()) )
|
||||||
{
|
{
|
||||||
advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
|
advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
|
||||||
}
|
}
|
||||||
@@ -320,14 +329,14 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
switch (icode.ll()->getOpcode())
|
switch (icode.ll()->getOpcode())
|
||||||
{
|
{
|
||||||
case iMOV:
|
case iMOV:
|
||||||
pmH = &icode.ll()->dst;
|
pmH = &icode.ll()->m_dst;
|
||||||
pmL = &next1->ll()->dst;
|
pmL = &next1->ll()->m_dst;
|
||||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
|
localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
|
||||||
icode.setRegDU( pmL->regi, eDEF);
|
icode.setRegDU( pmL->regi, eDEF);
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll());
|
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, *next1->ll());
|
||||||
icode.setAsgn(asgn.lhs, asgn.rhs);
|
icode.setAsgn(asgn.lhs, asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
forced_finish=true; /* to exit the loop */
|
forced_finish=true; /* to exit the loop */
|
||||||
@@ -335,15 +344,15 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iPOP:
|
case iPOP:
|
||||||
pmH = &next1->ll()->dst;
|
pmH = &next1->ll()->m_dst;
|
||||||
pmL = &icode.ll()->dst;
|
pmL = &icode.ll()->m_dst;
|
||||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
icode.setRegDU( pmH->regi, eDEF);
|
icode.setRegDU( pmH->regi, eDEF);
|
||||||
icode.setUnary(HLI_POP, asgn.lhs);
|
icode.setUnary(HLI_POP, asgn.lhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
asgn.lhs=0;
|
asgn.lhs=nullptr;
|
||||||
forced_finish=true; /* to exit the loop */
|
forced_finish=true; /* to exit the loop */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -351,23 +360,22 @@ int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
// /**** others missing ***/
|
// /**** others missing ***/
|
||||||
|
|
||||||
case iAND: case iOR: case iXOR:
|
case iAND: case iOR: case iXOR:
|
||||||
pmL = &icode.ll()->dst;
|
pmL = &icode.ll()->m_dst;
|
||||||
pmH = &next1->ll()->dst;
|
pmH = &next1->ll()->m_dst;
|
||||||
if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
|
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
|
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode, LOW_FIRST, pIcode, eUSE, *next1->ll());
|
||||||
icode.setRegDU( pmH->regi, USE_DEF);
|
icode.setRegDU( pmH->regi, USE_DEF);
|
||||||
|
condOp toCreate=DUMMY;
|
||||||
switch (icode.ll()->getOpcode())
|
switch (icode.ll()->getOpcode())
|
||||||
{
|
{
|
||||||
case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND);
|
case iAND: toCreate = AND; break;
|
||||||
break;
|
case iOR: toCreate = OR; break;
|
||||||
case iOR:
|
case iXOR: toCreate = XOR; break;
|
||||||
asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR);
|
|
||||||
break;
|
|
||||||
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR);
|
|
||||||
break;
|
|
||||||
} /* eos */
|
} /* eos */
|
||||||
|
if(toCreate != DUMMY)
|
||||||
|
asgn.rhs = new BinaryOperator(toCreate,asgn.lhs, asgn.rhs);
|
||||||
icode.setAsgn(asgn.lhs, asgn.rhs);
|
icode.setAsgn(asgn.lhs, asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
forced_finish=true; /* to exit the loop */
|
forced_finish=true; /* to exit the loop */
|
||||||
@@ -398,53 +406,64 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
switch (pIcode->ll()->getOpcode())
|
switch (pIcode->ll()->getOpcode())
|
||||||
{
|
{
|
||||||
case iMOV:
|
case iMOV:
|
||||||
if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) &&
|
|
||||||
(pLocId.id.longId.l == next1->ll()->src().getReg2()))
|
|
||||||
{
|
{
|
||||||
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
|
const LONGID_TYPE &ref_long(pLocId.longId());
|
||||||
|
const LLOperand &src_op1(pIcode->ll()->src());
|
||||||
|
const LLOperand &src_op2(next1->ll()->src());
|
||||||
|
eReg srcReg1=src_op1.getReg2();
|
||||||
|
eReg nextReg2=src_op2.getReg2();
|
||||||
|
if ((ref_long.h() == srcReg1) && (ref_long.l() == nextReg2))
|
||||||
|
{
|
||||||
|
pIcode->setRegDU( nextReg2, eUSE);
|
||||||
|
|
||||||
asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
asgn.lhs = COND_EXPR::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll());
|
asgn.lhs = AstIdent::Long (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, *next1->ll());
|
||||||
|
|
||||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
forced_finish =true; /* to exit the loop */
|
forced_finish =true; /* to exit the loop */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case iPUSH:
|
case iPUSH:
|
||||||
if ((pLocId.id.longId.h == pIcode->ll()->src().getReg2()) &&
|
|
||||||
(pLocId.id.longId.l == next1->ll()->src().getReg2()))
|
|
||||||
{
|
{
|
||||||
asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
const LONGID_TYPE &ref_long(pLocId.longId());
|
||||||
|
const LLOperand &src_op1(pIcode->ll()->src());
|
||||||
|
const LLOperand &src_op2(next1->ll()->src());
|
||||||
|
if ((ref_long.h() == src_op1.getReg2()) && (ref_long.l() == src_op2.getReg2()))
|
||||||
|
{
|
||||||
|
asgn.rhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
|
pIcode->setRegDU( next1->ll()->src().getReg2(), eUSE);
|
||||||
pIcode->setUnary(HLI_PUSH, asgn.rhs);
|
pIcode->setUnary(HLI_PUSH, asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
}
|
}
|
||||||
forced_finish =true; /* to exit the loop */
|
forced_finish =true; /* to exit the loop */
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*** others missing ****/
|
/*** others missing ****/
|
||||||
|
|
||||||
case iAND: case iOR: case iXOR:
|
case iAND: case iOR: case iXOR:
|
||||||
pmL = &pIcode->ll()->dst;
|
pmL = &pIcode->ll()->m_dst;
|
||||||
pmH = &next1->ll()->dst;
|
pmH = &next1->ll()->m_dst;
|
||||||
if ((pLocId.id.longId.h == pmH->regi) &&
|
if ((pLocId.longId().h() == pmH->regi) && (pLocId.longId().l() == pmL->regi))
|
||||||
(pLocId.id.longId.l == pmL->regi))
|
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
pIcode->setRegDU( pmH->regi, USE_DEF);
|
pIcode->setRegDU( pmH->regi, USE_DEF);
|
||||||
asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode,
|
asgn.rhs = AstIdent::Long (&this->localId, SRC, pIcode,
|
||||||
LOW_FIRST, pIcode, eUSE, *next1->ll());
|
LOW_FIRST, pIcode, eUSE, *next1->ll());
|
||||||
|
condOp toCreate=DUMMY;
|
||||||
switch (pIcode->ll()->getOpcode()) {
|
switch (pIcode->ll()->getOpcode()) {
|
||||||
case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND);
|
case iAND: toCreate=AND; break;
|
||||||
break;
|
case iOR: toCreate=OR; break;
|
||||||
case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR);
|
case iXOR: toCreate= XOR; break;
|
||||||
break;
|
|
||||||
case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
pIcode->setAsgn(asgn.lhs, asgn.rhs);
|
if(DUMMY!=toCreate)
|
||||||
|
{
|
||||||
|
asgn.rhs = new BinaryOperator(toCreate,asgn.lhs, asgn.rhs);
|
||||||
|
}
|
||||||
|
pIcode->setAsgn(dynamic_cast<AstIdent *>(asgn.lhs), asgn.rhs);
|
||||||
next1->invalidate();
|
next1->invalidate();
|
||||||
// ftw loop restart ????
|
// ftw loop restart ????
|
||||||
//idx = 0;
|
//idx = 0;
|
||||||
@@ -457,7 +476,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
/* Check long conditional (i.e. 2 CMPs and 3 branches */
|
||||||
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
|
else if ((pIcode->ll()->getOpcode() == iCMP) && (isLong23 (pIcode->getParent(), long_loc, &arc)))
|
||||||
{
|
{
|
||||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
|
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()))
|
||||||
{
|
{
|
||||||
// reduce the advance by 1 here (loop increases) ?
|
// reduce the advance by 1 here (loop increases) ?
|
||||||
advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
|
advance(pIcode,longJCond23 (asgn, pIcode, arc, long_loc));
|
||||||
@@ -468,7 +487,7 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
* 2 CMPs and 2 branches */
|
* 2 CMPs and 2 branches */
|
||||||
else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
|
else if (pIcode->ll()->match(iCMP) && (isLong22 (pIcode, pEnd, long_loc)))
|
||||||
{
|
{
|
||||||
if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
|
if (checkLongRegEq (pLocId.longId(), pIcode, loc_ident_idx, this, asgn, *long_loc->ll()) )
|
||||||
{
|
{
|
||||||
// TODO: verify that removing -1 does not change anything !
|
// TODO: verify that removing -1 does not change anything !
|
||||||
advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
|
advance(pIcode,longJCond22 (asgn, pIcode,pEnd));
|
||||||
@@ -481,17 +500,18 @@ int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE be
|
|||||||
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
* This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
|
||||||
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
|
else if (pIcode->ll()->match(iOR) && (next1 != pEnd) && (isJCond ((llIcode)next1->ll()->getOpcode())))
|
||||||
{
|
{
|
||||||
if (pLocId.id.longId.srcDstRegMatch(pIcode,pIcode))
|
if (pLocId.longId().srcDstRegMatch(pIcode,pIcode))
|
||||||
{
|
{
|
||||||
asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
|
asgn.lhs = AstIdent::LongIdx (loc_ident_idx);
|
||||||
asgn.rhs = COND_EXPR::idKte (0, 4); /* long 0 */
|
asgn.rhs = new Constant(0, 4); /* long 0 */
|
||||||
asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[next1->ll()->getOpcode() - iJB]);
|
asgn.lhs = new BinaryOperator(condOpJCond[next1->ll()->getOpcode() - iJB],asgn.lhs, asgn.rhs);
|
||||||
next1->setJCond(asgn.lhs);
|
next1->setJCond(asgn.lhs);
|
||||||
next1->copyDU(*pIcode, eUSE, eUSE);
|
next1->copyDU(*pIcode, eUSE, eUSE);
|
||||||
pIcode->invalidate();
|
pIcode->invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* end for */
|
} /* end for */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Finds the definition of the long register pointed to by pLocId, and
|
/** Finds the definition of the long register pointed to by pLocId, and
|
||||||
@@ -504,8 +524,8 @@ void Function::propLongReg (int loc_ident_idx, const ID &pLocId)
|
|||||||
{
|
{
|
||||||
/* Process all definitions/uses of long registers at an icode position */
|
/* Process all definitions/uses of long registers at an icode position */
|
||||||
// WARNING: this loop modifies the iterated-over container.
|
// WARNING: this loop modifies the iterated-over container.
|
||||||
size_t initial_size=pLocId.idx.size();
|
//size_t initial_size=pLocId.idx.size();
|
||||||
for (int j = 0; j < pLocId.idx.size(); j++)
|
for (size_t j = 0; j < pLocId.idx.size(); j++)
|
||||||
{
|
{
|
||||||
auto idx_iter=pLocId.idx.begin();
|
auto idx_iter=pLocId.idx.begin();
|
||||||
std::advance(idx_iter,j);
|
std::advance(idx_iter,j);
|
||||||
@@ -524,7 +544,7 @@ void Function::propLongReg (int loc_ident_idx, const ID &pLocId)
|
|||||||
|
|
||||||
/* Propagates the long global address across all LOW_LEVEL icodes.
|
/* Propagates the long global address across all LOW_LEVEL icodes.
|
||||||
* Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
|
* Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
|
||||||
void Function::propLongGlb (int i, const ID &pLocId)
|
void Function::propLongGlb (int /*i*/, const ID &/*pLocId*/)
|
||||||
{
|
{
|
||||||
printf("WARN: Function::propLongGlb not implemented");
|
printf("WARN: Function::propLongGlb not implemented");
|
||||||
}
|
}
|
||||||
@@ -534,14 +554,13 @@ void Function::propLongGlb (int i, const ID &pLocId)
|
|||||||
* into HIGH_LEVEL icodes. */
|
* into HIGH_LEVEL icodes. */
|
||||||
void Function::propLong()
|
void Function::propLong()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
/* Pointer to current local identifier */
|
/* Pointer to current local identifier */
|
||||||
|
//TODO: change into range based for
|
||||||
for (i = 0; i < localId.csym(); i++)
|
for (size_t i = 0; i < localId.csym(); i++)
|
||||||
{
|
{
|
||||||
const ID &pLocId(localId.id_arr[i]);
|
const ID &pLocId(localId.id_arr[i]);
|
||||||
if ((pLocId.type==TYPE_LONG_SIGN) || (pLocId.type==TYPE_LONG_UNSIGN))
|
if ((pLocId.type!=TYPE_LONG_SIGN) and (pLocId.type!=TYPE_LONG_UNSIGN))
|
||||||
{
|
continue;
|
||||||
switch (pLocId.loc)
|
switch (pLocId.loc)
|
||||||
{
|
{
|
||||||
case STK_FRAME:
|
case STK_FRAME:
|
||||||
@@ -555,6 +574,5 @@ void Function::propLong()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdint.h>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <malloc.h> /* For free() */
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static int numInt; /* Number of intervals */
|
static int numInt; /* Number of intervals */
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ BB *interval::firstOfInt ()
|
|||||||
{
|
{
|
||||||
auto pq = currNode;
|
auto pq = currNode;
|
||||||
if (pq == nodes.end())
|
if (pq == nodes.end())
|
||||||
return 0;
|
return nullptr;
|
||||||
++currNode;
|
++currNode;
|
||||||
return *pq;
|
return *pq;
|
||||||
}
|
}
|
||||||
@@ -66,16 +66,16 @@ BB *interval::firstOfInt ()
|
|||||||
* node->inInterval.
|
* node->inInterval.
|
||||||
* Note: nodes are added to the interval list in interval order (which
|
* Note: nodes are added to the interval list in interval order (which
|
||||||
* topsorts the dominance relation). */
|
* topsorts the dominance relation). */
|
||||||
static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
void interval::appendNodeInt(queue &pqH, BB *node)
|
||||||
{
|
{
|
||||||
queue::iterator pq; /* Pointer to current node of the list */
|
queue::iterator pq; /* Pointer to current node of the list */
|
||||||
|
|
||||||
/* Append node if it is not already in the interval list */
|
/* Append node if it is not already in the interval list */
|
||||||
pq = appendQueue (pI->nodes, node);
|
pq = appendQueue (nodes, node);
|
||||||
|
|
||||||
/* Update currNode if necessary */
|
/* Update currNode if necessary */
|
||||||
if (pI->currNode == pI->nodes.end())
|
if (currNode == nodes.end())
|
||||||
pI->currNode = pq;
|
currNode = pq;
|
||||||
|
|
||||||
/* Check header list for occurrence of node, if found, remove it
|
/* Check header list for occurrence of node, if found, remove it
|
||||||
* and decrement number of out-edges from this interval. */
|
* and decrement number of out-edges from this interval. */
|
||||||
@@ -84,12 +84,12 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
|||||||
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
||||||
if(found_iter!=pqH.end())
|
if(found_iter!=pqH.end())
|
||||||
{
|
{
|
||||||
pI->numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
|
numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
|
||||||
pqH.erase(found_iter);
|
pqH.erase(found_iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Update interval header information for this basic block */
|
/* Update interval header information for this basic block */
|
||||||
node->inInterval = pI;
|
node->inInterval = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -103,13 +103,12 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
BB *h, /* Node being processed */
|
BB *h, /* Node being processed */
|
||||||
*header, /* Current interval's header node */
|
*header, /* Current interval's header node */
|
||||||
*succ; /* Successor basic block */
|
*succ; /* Successor basic block */
|
||||||
int i; /* Counter */
|
|
||||||
queue H; /* Queue of possible header nodes */
|
queue H; /* Queue of possible header nodes */
|
||||||
boolT first = true; /* First pass through the loop */
|
bool first = true; /* First pass through the loop */
|
||||||
|
|
||||||
appendQueue (H, Gi); /* H = {first node of G} */
|
appendQueue (H, Gi); /* H = {first node of G} */
|
||||||
Gi->beenOnH = true;
|
Gi->beenOnH = true;
|
||||||
Gi->reachingInt = BB::Create(0,"",c); /* ^ empty BB */
|
Gi->reachingInt = BB::Create(nullptr,"",c); /* ^ empty BB */
|
||||||
|
|
||||||
/* Process header nodes list H */
|
/* Process header nodes list H */
|
||||||
while (!H.empty())
|
while (!H.empty())
|
||||||
@@ -118,23 +117,26 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
pI = new interval;
|
pI = new interval;
|
||||||
pI->numInt = (uint8_t)numInt++;
|
pI->numInt = (uint8_t)numInt++;
|
||||||
if (first) /* ^ to first interval */
|
if (first) /* ^ to first interval */
|
||||||
|
{
|
||||||
Ii = J = pI;
|
Ii = J = pI;
|
||||||
appendNodeInt (H, header, pI); /* pI(header) = {header} */
|
m_intervals.push_back(pI);
|
||||||
|
}
|
||||||
|
pI->appendNodeInt (H, header); /* pI(header) = {header} */
|
||||||
|
|
||||||
/* Process all nodes in the current interval list */
|
/* Process all nodes in the current interval list */
|
||||||
while ((h = pI->firstOfInt()) != NULL)
|
while ((h = pI->firstOfInt()) != nullptr)
|
||||||
{
|
{
|
||||||
/* Check all immediate successors of h */
|
/* Check all immediate successors of h */
|
||||||
for (i = 0; i < h->edges.size(); i++)
|
for (auto & elem : h->edges)
|
||||||
{
|
{
|
||||||
succ = h->edges[i].BBptr;
|
succ = elem.BBptr;
|
||||||
succ->inEdgeCount--;
|
succ->inEdgeCount--;
|
||||||
|
|
||||||
if (succ->reachingInt == NULL) /* first visit */
|
if (succ->reachingInt == nullptr) /* first visit */
|
||||||
{
|
{
|
||||||
succ->reachingInt = header;
|
succ->reachingInt = header;
|
||||||
if (succ->inEdgeCount == 0)
|
if (succ->inEdgeCount == 0)
|
||||||
appendNodeInt (H, succ, pI);
|
pI->appendNodeInt (H, succ);
|
||||||
else if (! succ->beenOnH) /* out edge */
|
else if (! succ->beenOnH) /* out edge */
|
||||||
{
|
{
|
||||||
appendQueue (H, succ);
|
appendQueue (H, succ);
|
||||||
@@ -148,7 +150,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
|
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
|
||||||
{
|
{
|
||||||
if (succ != header)
|
if (succ != header)
|
||||||
appendNodeInt (H, succ, pI);
|
pI->appendNodeInt (H, succ);
|
||||||
}
|
}
|
||||||
else /* out edge */
|
else /* out edge */
|
||||||
pI->numOutEdges++;
|
pI->numOutEdges++;
|
||||||
@@ -161,6 +163,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
/* Link interval I to list of intervals */
|
/* Link interval I to list of intervals */
|
||||||
if (! first)
|
if (! first)
|
||||||
{
|
{
|
||||||
|
m_intervals.push_back(pI);
|
||||||
J->next = pI;
|
J->next = pI;
|
||||||
J = pI;
|
J = pI;
|
||||||
}
|
}
|
||||||
@@ -176,11 +179,11 @@ static void displayIntervals (interval *pI)
|
|||||||
|
|
||||||
while (pI)
|
while (pI)
|
||||||
{
|
{
|
||||||
printf (" Interval #: %ld\t#OutEdges: %ld\n", pI->numInt, pI->numOutEdges);
|
printf (" Interval #: %d\t#OutEdges: %d\n", pI->numInt, pI->numOutEdges);
|
||||||
for(BB *node : pI->nodes)
|
for(BB *node : pI->nodes)
|
||||||
{
|
{
|
||||||
if (node->correspInt == NULL) /* real BBs */
|
if (node->correspInt == nullptr) /* real BBs */
|
||||||
printf (" Node: %ld\n", node->begin()->loc_ip);
|
printf (" Node: %d\n", node->begin()->loc_ip);
|
||||||
else // BBs represent intervals
|
else // BBs represent intervals
|
||||||
printf (" Node (corresp int): %d\n", node->correspInt->numInt);
|
printf (" Node (corresp int): %d\n", node->correspInt->numInt);
|
||||||
}
|
}
|
||||||
@@ -190,17 +193,17 @@ static void displayIntervals (interval *pI)
|
|||||||
|
|
||||||
|
|
||||||
/* Allocates space for a new derSeq node. */
|
/* Allocates space for a new derSeq node. */
|
||||||
static derSeq_Entry *newDerivedSeq()
|
//static derSeq_Entry *newDerivedSeq()
|
||||||
{
|
//{
|
||||||
return new derSeq_Entry;
|
// return new derSeq_Entry;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
/* Frees the storage allocated for the queue q*/
|
/* Frees the storage allocated for the queue q*/
|
||||||
static void freeQueue (queue &q)
|
//static void freeQueue (queue &q)
|
||||||
{
|
//{
|
||||||
q.clear();
|
// q.clear();
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
/* Frees the storage allocated for the interval pI */
|
/* Frees the storage allocated for the interval pI */
|
||||||
@@ -236,29 +239,23 @@ derSeq_Entry::~derSeq_Entry()
|
|||||||
bool Function::nextOrderGraph (derSeq &derivedGi)
|
bool Function::nextOrderGraph (derSeq &derivedGi)
|
||||||
{
|
{
|
||||||
interval *Ii; /* Interval being processed */
|
interval *Ii; /* Interval being processed */
|
||||||
BB *BBnode, /* New basic block of intervals */
|
BB *BBnode; /* New basic block of intervals */
|
||||||
*curr, /* BB being checked for out edges */
|
bool sameGraph; /* Boolean, isomorphic graphs */
|
||||||
*succ /* Successor node */
|
|
||||||
;
|
|
||||||
//queue *listIi; /* List of intervals */
|
|
||||||
int i, /* Index to outEdges array */
|
|
||||||
j; /* Index to successors */
|
|
||||||
boolT sameGraph; /* Boolean, isomorphic graphs */
|
|
||||||
|
|
||||||
/* Process Gi's intervals */
|
/* Process Gi's intervals */
|
||||||
derSeq_Entry &prev_entry(derivedGi.back());
|
derSeq_Entry &prev_entry(derivedGi.back());
|
||||||
derivedGi.push_back(derSeq_Entry());
|
derivedGi.push_back(derSeq_Entry());
|
||||||
derSeq_Entry &new_entry(derivedGi.back());
|
derSeq_Entry &new_entry(derivedGi.back());
|
||||||
Ii = prev_entry.Ii;
|
|
||||||
sameGraph = true;
|
sameGraph = true;
|
||||||
BBnode = 0;
|
BBnode = nullptr;
|
||||||
std::vector<BB *> bbs;
|
std::vector<BB *> bbs;
|
||||||
while (Ii)
|
for(Ii = prev_entry.Ii; Ii != nullptr; Ii = Ii->next)
|
||||||
{
|
{
|
||||||
i = 0;
|
|
||||||
bbs.push_back(BB::Create(-1, -1, INTERVAL_NODE, Ii->numOutEdges, this));
|
BBnode = BB::CreateIntervalBB(this);
|
||||||
BBnode = bbs.back();
|
|
||||||
BBnode->correspInt = Ii;
|
BBnode->correspInt = Ii;
|
||||||
|
bbs.push_back(BBnode);
|
||||||
const queue &listIi(Ii->nodes);
|
const queue &listIi(Ii->nodes);
|
||||||
|
|
||||||
/* Check for more than 1 interval */
|
/* Check for more than 1 interval */
|
||||||
@@ -267,27 +264,24 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
|
|||||||
|
|
||||||
/* Find out edges */
|
/* Find out edges */
|
||||||
|
|
||||||
if (BBnode->edges.size() > 0)
|
if (Ii->numOutEdges <= 0)
|
||||||
{
|
continue;
|
||||||
for(BB *curr : listIi)
|
for(BB *curr : listIi)
|
||||||
{
|
{
|
||||||
for (j = 0; j < curr->edges.size(); j++)
|
for (size_t j = 0; j < curr->edges.size(); j++)
|
||||||
{
|
{
|
||||||
succ = curr->edges[j].BBptr;
|
BB *successor_node = curr->edges[j].BBptr;
|
||||||
if (succ->inInterval != curr->inInterval)
|
if (successor_node->inInterval != curr->inInterval)
|
||||||
BBnode->edges[i++].intPtr = succ->inInterval;
|
BBnode->addOutEdgeInterval(successor_node->inInterval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next interval */
|
|
||||||
Ii = Ii->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert list of pointers to intervals into a real graph.
|
/* Convert list of pointers to intervals into a real graph.
|
||||||
* Determines the number of in edges to each new BB, and places it
|
* Determines the number of in edges to each new BB, and places it
|
||||||
* in numInEdges and inEdgeCount for later interval processing. */
|
* in numInEdges and inEdgeCount for later interval processing. */
|
||||||
curr = new_entry.Gi = bbs.front();
|
//curr = new_entry.Gi = bbs.front();
|
||||||
|
new_entry.Gi = bbs.front();
|
||||||
for(BB *curr : bbs)
|
for(BB *curr : bbs)
|
||||||
{
|
{
|
||||||
for(TYPEADR_TYPE &edge : curr->edges)
|
for(TYPEADR_TYPE &edge : curr->edges)
|
||||||
@@ -302,7 +296,7 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
|
|||||||
(*iter)->inEdgeCount++;
|
(*iter)->inEdgeCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (boolT)(! sameGraph);
|
return not sameGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -310,12 +304,11 @@ bool Function::nextOrderGraph (derSeq &derivedGi)
|
|||||||
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
||||||
* Constructs the n-th order graph and places all the intermediate graphs
|
* Constructs the n-th order graph and places all the intermediate graphs
|
||||||
* in the derivedG list sequence. */
|
* in the derivedG list sequence. */
|
||||||
uint8_t Function::findDerivedSeq (derSeq &derivedGi)
|
bool Function::findDerivedSeq (derSeq &derivedGi)
|
||||||
{
|
{
|
||||||
BB *Gi; /* Current derived sequence graph */
|
|
||||||
|
|
||||||
derSeq::iterator iter=derivedGi.begin();
|
derSeq::iterator iter=derivedGi.begin();
|
||||||
Gi = iter->Gi;
|
assert(iter!=derivedGi.end());
|
||||||
|
BB *Gi = iter->Gi; /* Current derived sequence graph */
|
||||||
while (! trivialGraph (Gi))
|
while (! trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
||||||
@@ -341,13 +334,6 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts the irreducible graph G into an equivalent reducible one, by
|
|
||||||
* means of node splitting. */
|
|
||||||
static void nodeSplitting (std::list<BB *> &G)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Displays the derived sequence and intervals of the graph G */
|
/* Displays the derived sequence and intervals of the graph G */
|
||||||
void derSeq::display()
|
void derSeq::display()
|
||||||
{
|
{
|
||||||
@@ -356,7 +342,7 @@ void derSeq::display()
|
|||||||
derSeq::iterator iter=this->begin();
|
derSeq::iterator iter=this->begin();
|
||||||
while (iter!=this->end())
|
while (iter!=this->end())
|
||||||
{
|
{
|
||||||
printf ("\nIntervals for G%lX\n", n++);
|
printf ("\nIntervals for G%X\n", n++);
|
||||||
displayIntervals (iter->Ii);
|
displayIntervals (iter->Ii);
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
@@ -377,13 +363,13 @@ derSeq * Function::checkReducibility()
|
|||||||
stats.nOrder = 1; /* nOrder(cfg) = 1 */
|
stats.nOrder = 1; /* nOrder(cfg) = 1 */
|
||||||
der_seq = new derSeq;
|
der_seq = new derSeq;
|
||||||
der_seq->resize(1);
|
der_seq->resize(1);
|
||||||
der_seq->back().Gi = m_cfg.front();
|
der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
|
||||||
reducible = findDerivedSeq(*der_seq);
|
reducible = findDerivedSeq(*der_seq);
|
||||||
|
|
||||||
if (! reducible)
|
if (! reducible)
|
||||||
{
|
{
|
||||||
flg |= GRAPH_IRRED;
|
flg |= GRAPH_IRRED;
|
||||||
nodeSplitting (m_cfg);
|
m_actual_cfg.nodeSplitting();
|
||||||
}
|
}
|
||||||
return der_seq;
|
return der_seq;
|
||||||
}
|
}
|
||||||
|
|||||||
250
src/scanner.cpp
250
src/scanner.cpp
@@ -6,6 +6,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
@@ -14,7 +16,7 @@
|
|||||||
#define S_EXT 0x000200 /* sign extend */
|
#define S_EXT 0x000200 /* sign extend */
|
||||||
#define OP386 0x000400 /* 386 op-code */
|
#define OP386 0x000400 /* 386 op-code */
|
||||||
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
||||||
#define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
// defined in Enums.h #define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
||||||
|
|
||||||
static void rm(int i);
|
static void rm(int i);
|
||||||
static void modrm(int i);
|
static void modrm(int i);
|
||||||
@@ -314,14 +316,29 @@ static struct {
|
|||||||
} ;
|
} ;
|
||||||
|
|
||||||
static uint16_t SegPrefix, RepPrefix;
|
static uint16_t SegPrefix, RepPrefix;
|
||||||
static uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
|
static const uint8_t *pInst; /* Ptr. to current uint8_t of instruction */
|
||||||
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
|
static ICODE * pIcode; /* Ptr to Icode record filled in by scan() */
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
static void decodeBranchTgt(x86_insn_t &insn)
|
||||||
Scans one machine instruction at offset ip in prog.Image and returns error.
|
{
|
||||||
At the same time, fill in low-level icode details for the scanned inst.
|
x86_op_t *tgt_op = insn.x86_get_branch_target();
|
||||||
****************************************************************************/
|
if(tgt_op->type==op_expression)
|
||||||
|
return; // unhandled for now
|
||||||
|
if(tgt_op->type==op_register)
|
||||||
|
return; // unhandled for now
|
||||||
|
int32_t addr = tgt_op->getAddress();
|
||||||
|
if(tgt_op->is_relative())
|
||||||
|
{
|
||||||
|
addr += insn.addr+insn.size;
|
||||||
|
}
|
||||||
|
pIcode->ll()->replaceSrc((uint32_t)addr);
|
||||||
|
pIcode->ll()->setFlags(I);
|
||||||
|
// PROG &prog(Project::get()->prog);
|
||||||
|
// long off = (short)getWord(); /* Signed displacement */
|
||||||
|
// assert(addr==(uint32_t)(off + (unsigned)(pInst - prog.image())));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void convertUsedFlags(x86_insn_t &from,ICODE &to)
|
static void convertUsedFlags(x86_insn_t &from,ICODE &to)
|
||||||
{
|
{
|
||||||
@@ -345,11 +362,20 @@ static void convertUsedFlags(x86_insn_t &from,ICODE &to)
|
|||||||
if(from.containsFlag(insn_eflag_direction,from.flags_tested))
|
if(from.containsFlag(insn_eflag_direction,from.flags_tested))
|
||||||
to.ll()->flagDU.u |= Df;
|
to.ll()->flagDU.u |= Df;
|
||||||
}
|
}
|
||||||
|
static void convertPrefix(x86_insn_prefix prefix,ICODE &to)
|
||||||
|
{
|
||||||
|
if(prefix ==insn_no_prefix)
|
||||||
|
return;
|
||||||
|
// insn_lock - no need to handle
|
||||||
|
RepPrefix = (uint16_t)prefix & ~insn_lock;
|
||||||
|
}
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Checks for int 34 to int 3B - if so, converts to ESC nn instruction
|
Checks for int 34 to int 3B - if so, converts to ESC nn instruction
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void fixFloatEmulation(x86_insn_t &insn)
|
static void fixFloatEmulation(x86_insn_t &insn)
|
||||||
{
|
{
|
||||||
|
if(insn.operand_count==0)
|
||||||
|
return;
|
||||||
if(insn.group!=x86_insn_t::insn_interrupt)
|
if(insn.group!=x86_insn_t::insn_interrupt)
|
||||||
return;
|
return;
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
@@ -357,11 +383,10 @@ static void fixFloatEmulation(x86_insn_t &insn)
|
|||||||
if ((wOp < 0x34) || (wOp > 0x3B))
|
if ((wOp < 0x34) || (wOp > 0x3B))
|
||||||
return;
|
return;
|
||||||
uint8_t buf[16];
|
uint8_t buf[16];
|
||||||
/* This is a Borland/Microsoft floating point emulation instruction.
|
/* This is a Borland/Microsoft floating point emulation instruction. Treat as if it is an ESC opcode */
|
||||||
Treat as if it is an ESC opcode */
|
|
||||||
|
|
||||||
int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
|
int actual_valid_bytes=std::min(16U,prog.cbImage-insn.offset);
|
||||||
memcpy(buf,prog.Image+insn.offset,actual_valid_bytes);
|
memcpy(buf,prog.image()+insn.offset,actual_valid_bytes);
|
||||||
X86_Disasm ds(opt_16_bit);
|
X86_Disasm ds(opt_16_bit);
|
||||||
x86_insn_t patched_insn;
|
x86_insn_t patched_insn;
|
||||||
//patch actual instruction into buffer;
|
//patch actual instruction into buffer;
|
||||||
@@ -377,7 +402,7 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
|
|||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
X86_Disasm ds(opt_16_bit);
|
X86_Disasm ds(opt_16_bit);
|
||||||
int cnt=ds.x86_disasm(prog.Image,prog.cbImage,0,ip,&l);
|
int cnt=ds.x86_disasm(prog.image(),prog.cbImage,0,ip,&l);
|
||||||
if(cnt && l.is_valid())
|
if(cnt && l.is_valid())
|
||||||
{
|
{
|
||||||
fixFloatEmulation(l); //can change 'l'
|
fixFloatEmulation(l); //can change 'l'
|
||||||
@@ -388,28 +413,122 @@ int disassembleOneLibDisasm(uint32_t ip,x86_insn_t &l)
|
|||||||
}
|
}
|
||||||
eReg convertRegister(const x86_reg_t ®)
|
eReg convertRegister(const x86_reg_t ®)
|
||||||
{
|
{
|
||||||
|
if( (reg_pc==reg.type) || (0==reg.id))
|
||||||
|
return rUNDEF;
|
||||||
|
|
||||||
eReg regmap[]={ rUNDEF,
|
eReg regmap[]={ rUNDEF,
|
||||||
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx
|
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //eax ecx ebx edx
|
||||||
rUNDEF,rUNDEF,rUNDEF,rUNDEF, //esp ebp esi edi
|
rSP,rUNDEF,rUNDEF,rDI, //esp ebp esi edi
|
||||||
rAX,rCX,rDX,rBX,
|
rAX,rCX,rDX,rBX,
|
||||||
rSP,rBP,rSI,rDI,
|
rSP,rBP,rSI,rDI,
|
||||||
rAL,rCL,rDL,rBL,
|
rAL,rCL,rDL,rBL,
|
||||||
rAH,rCH,rDH,rBH
|
rAH,rCH,rDH,rBH
|
||||||
};
|
};
|
||||||
|
std::map<std::string,eReg> nameToEnum = {{"es",rES},{"ds",rDS},{"cs",rCS},{"ss",rSS}};
|
||||||
|
if(nameToEnum.find(reg.name)!=nameToEnum.end())
|
||||||
|
return nameToEnum[reg.name];
|
||||||
assert(reg.id<sizeof(regmap)/sizeof(eReg));
|
assert(reg.id<sizeof(regmap)/sizeof(eReg));
|
||||||
|
assert(regmap[reg.id]!=rUNDEF);
|
||||||
return regmap[reg.id];
|
return regmap[reg.id];
|
||||||
}
|
}
|
||||||
|
LLOperand convertExpression(const x86_ea_t &from)
|
||||||
|
{
|
||||||
|
// BASE + Scale*Index + Disp
|
||||||
|
LLOperand res;
|
||||||
|
res.seg = rDS;
|
||||||
|
/*
|
||||||
|
INDEX_BX_SI = 22, // "bx+si"
|
||||||
|
INDEX_BX_DI, // "bx+di"
|
||||||
|
INDEX_BP_SI, // "bp+si"
|
||||||
|
INDEX_BP_DI, // "bp+di"
|
||||||
|
INDEX_SI, // "si"
|
||||||
|
INDEX_DI, // "di"
|
||||||
|
INDEX_BP, // "bp"
|
||||||
|
INDEX_BX, // "bx"
|
||||||
|
*/
|
||||||
|
if(from.base.id)
|
||||||
|
{
|
||||||
|
eReg base_reg = convertRegister(from.base);
|
||||||
|
eReg index_reg = convertRegister(from.index);
|
||||||
|
// if(base_reg==rBX)
|
||||||
|
switch(base_reg)
|
||||||
|
{
|
||||||
|
case rDI:
|
||||||
|
res.regi = INDEX_DI; break;
|
||||||
|
case rBP:
|
||||||
|
res.seg=rSS;
|
||||||
|
switch(index_reg)
|
||||||
|
{
|
||||||
|
case rDI:
|
||||||
|
res.regi = INDEX_BP_DI; break;
|
||||||
|
case rSI:
|
||||||
|
res.regi = INDEX_BP_SI; break;
|
||||||
|
case rUNDEF:
|
||||||
|
res.regi = INDEX_BP; break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case rBX:
|
||||||
|
switch(index_reg)
|
||||||
|
{
|
||||||
|
case rDI:
|
||||||
|
res.regi = INDEX_BX_DI; break;
|
||||||
|
case rSI:
|
||||||
|
res.regi = INDEX_BX_SI; break;
|
||||||
|
case rUNDEF:
|
||||||
|
res.regi = INDEX_BX; break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(index_reg==rUNDEF);
|
||||||
|
}
|
||||||
|
assert(from.scale==0);
|
||||||
|
if(from.index.id)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
res.off = from.disp;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
LLOperand convertOperand(const x86_op_t &from)
|
LLOperand convertOperand(const x86_op_t &from)
|
||||||
{
|
{
|
||||||
|
LLOperand res;
|
||||||
switch(from.type)
|
switch(from.type)
|
||||||
{
|
{
|
||||||
case op_unused:
|
case op_unused:
|
||||||
break;
|
break;
|
||||||
case op_register:
|
case op_register:
|
||||||
return LLOperand::CreateReg2(convertRegister(from.data.reg));
|
res.regi = convertRegister(from.data.reg); break;
|
||||||
|
case op_immediate:
|
||||||
|
res.opz = from.data.sdword;
|
||||||
|
case op_expression:
|
||||||
|
res = convertExpression(from.data.expression); break;
|
||||||
|
case op_offset:
|
||||||
|
{
|
||||||
|
LLOperand res;
|
||||||
|
res.seg = rDS;
|
||||||
|
res.off = from.data.offset;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
fprintf(stderr,"convertOperand does not know how to convert %d\n",from.type);
|
||||||
|
}
|
||||||
|
if(res.isSet() && (res.seg == rUNDEF))
|
||||||
|
{
|
||||||
|
res.seg = rDS;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
/*****************************************************************************
|
||||||
|
Scans one machine instruction at offset ip in prog.Image and returns error.
|
||||||
|
At the same time, fill in low-level icode details for the scanned inst.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
eErrorId scan(uint32_t ip, ICODE &p)
|
eErrorId scan(uint32_t ip, ICODE &p)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
@@ -425,10 +544,12 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
if(cnt)
|
if(cnt)
|
||||||
{
|
{
|
||||||
convertUsedFlags(p.insn,p);
|
convertUsedFlags(p.insn,p);
|
||||||
|
convertPrefix(p.insn.prefix,p);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SegPrefix = RepPrefix = 0;
|
SegPrefix = RepPrefix = 0;
|
||||||
pInst = prog.Image + ip;
|
pInst = prog.image() + ip;
|
||||||
pIcode = &p;
|
pIcode = &p;
|
||||||
|
|
||||||
do
|
do
|
||||||
@@ -440,12 +561,20 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
(*stateTable[op].state2)(op); /* Third state */
|
(*stateTable[op].state2)(op); /* Third state */
|
||||||
|
|
||||||
} while (stateTable[op].state1 == prefix); /* Loop if prefix */
|
} while (stateTable[op].state1 == prefix); /* Loop if prefix */
|
||||||
|
if(p.insn.group == x86_insn_t::insn_controlflow)
|
||||||
|
{
|
||||||
|
if(p.insn.x86_get_branch_target())
|
||||||
|
decodeBranchTgt(p.insn);
|
||||||
|
}
|
||||||
|
// LLOperand conv = convertOperand(*p.insn.get_dest());
|
||||||
|
// assert(conv==p.ll()->dst);
|
||||||
if (p.ll()->getOpcode())
|
if (p.ll()->getOpcode())
|
||||||
{
|
{
|
||||||
/* Save bytes of image used */
|
/* Save bytes of image used */
|
||||||
p.ll()->numBytes = (uint8_t)((pInst - prog.Image) - ip);
|
p.ll()->numBytes = (uint8_t)((pInst - prog.image()) - ip);
|
||||||
if(p.insn.is_valid())
|
if(p.insn.is_valid())
|
||||||
assert(p.ll()->numBytes == p.insn.size);
|
assert(p.ll()->numBytes == p.insn.size);
|
||||||
|
p.ll()->numBytes = p.insn.size;
|
||||||
return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */
|
return ((SegPrefix)? FUNNY_SEGOVR: /* Seg. Override invalid */
|
||||||
(RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
|
(RepPrefix ? FUNNY_REP: NO_ERR));/* REP prefix invalid */
|
||||||
}
|
}
|
||||||
@@ -456,11 +585,11 @@ eErrorId scan(uint32_t ip, ICODE &p)
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
relocItem - returns true if uint16_t pointed at is in relocation table
|
relocItem - returns true if uint16_t pointed at is in relocation table
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
static bool relocItem(uint8_t *p)
|
static bool relocItem(const uint8_t *p)
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
PROG &prog(Project::get()->prog);
|
||||||
int i;
|
int i;
|
||||||
uint32_t off = p - prog.Image;
|
uint32_t off = p - prog.image();
|
||||||
|
|
||||||
for (i = 0; i < prog.cReloc; i++)
|
for (i = 0; i < prog.cReloc; i++)
|
||||||
if (prog.relocTable[i] == off)
|
if (prog.relocTable[i] == off)
|
||||||
@@ -495,16 +624,14 @@ static int signex(uint8_t b)
|
|||||||
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
|
* Note: fdst == true is for the r/m part of the field (dest, unless TO_REG)
|
||||||
* fdst == false is for reg part of the field
|
* fdst == false is for reg part of the field
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void setAddress(int i, boolT fdst, uint16_t seg, int16_t reg, uint16_t off)
|
static void setAddress(int i, bool fdst, uint16_t seg, int16_t reg, uint16_t off)
|
||||||
{
|
{
|
||||||
LLOperand *pm;
|
|
||||||
|
|
||||||
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
/* If not to register (i.e. to r/m), and talking about r/m, then this is dest */
|
||||||
pm = (!(stateTable[i].flg & TO_REG) == fdst) ?
|
LLOperand *pm = (!(stateTable[i].flg & TO_REG) == fdst) ? &pIcode->ll()->m_dst : &pIcode->ll()->src();
|
||||||
&pIcode->ll()->dst : &pIcode->ll()->src();
|
|
||||||
|
|
||||||
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
/* Set segment. A later procedure (lookupAddr in proclist.c) will
|
||||||
* provide the value of this segment in the field segValue. */
|
* provide the value of this segment in the field segValue.
|
||||||
|
*/
|
||||||
if (seg) /* segment override */
|
if (seg) /* segment override */
|
||||||
{
|
{
|
||||||
pm->seg = pm->segOver = (eReg)seg;
|
pm->seg = pm->segOver = (eReg)seg;
|
||||||
@@ -566,9 +693,9 @@ static void rm(int i)
|
|||||||
setAddress(i, true, 0, rm + rAX, 0);
|
setAddress(i, true, 0, rm + rAX, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
//pIcode->insn.get_dest()->
|
||||||
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
|
if ((stateTable[i].flg & NSP) && (pIcode->ll()->src().getReg2()==rSP ||
|
||||||
pIcode->ll()->dst.getReg2()==rSP))
|
pIcode->ll()->m_dst.getReg2()==rSP))
|
||||||
pIcode->ll()->setFlags(NOT_HLL);
|
pIcode->ll()->setFlags(NOT_HLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,17 +731,19 @@ static void segrm(int i)
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void regop(int i)
|
static void regop(int i)
|
||||||
{
|
{
|
||||||
setAddress(i, false, 0, ((int16_t)i & 7) + rAX, 0);
|
setAddress(i, false, 0, ((int16_t)i & 0x7) + rAX, 0);
|
||||||
pIcode->ll()->replaceDst(LLOperand::CreateReg2(pIcode->ll()->src().getReg2()));
|
pIcode->ll()->replaceDst(pIcode->ll()->src());
|
||||||
// pIcode->ll()->dst.regi = pIcode->ll()->src.regi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
segop - seg encoded in middle of opcode
|
segop - seg encoded in middle of opcode
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void segop(int i)
|
static void segop(int i)
|
||||||
{
|
{
|
||||||
|
if(i==0x1E) {
|
||||||
|
printf("es");
|
||||||
|
}
|
||||||
setAddress(i, true, 0, (((int16_t)i & 0x18) >> 3) + rES, 0);
|
setAddress(i, true, 0, (((int16_t)i & 0x18) >> 3) + rES, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,14 +838,17 @@ static void trans(int i)
|
|||||||
{
|
{
|
||||||
static llIcode transTable[8] =
|
static llIcode transTable[8] =
|
||||||
{
|
{
|
||||||
(llIcode)iINC, (llIcode)iDEC, (llIcode)iCALL, (llIcode)iCALLF,
|
(llIcode)iINC, iDEC, (llIcode)iCALL, (llIcode)iCALLF,
|
||||||
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
|
(llIcode)iJMP, (llIcode)iJMPF,(llIcode)iPUSH, (llIcode)0
|
||||||
};
|
};
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
|
// if(transTable[REG(*pInst)]==iPUSH) {
|
||||||
|
// printf("es");
|
||||||
|
// }
|
||||||
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
if ((uint8_t)REG(*pInst) < 2 || !(stateTable[i].flg & B)) { /* INC & DEC */
|
||||||
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
ll->setOpcode(transTable[REG(*pInst)]); /* valid on bytes */
|
||||||
rm(i);
|
rm(i);
|
||||||
ll->replaceSrc( pIcode->ll()->dst );
|
ll->replaceSrc( pIcode->ll()->m_dst );
|
||||||
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
|
if (ll->match(iJMP) || ll->match(iCALL) || ll->match(iCALLF))
|
||||||
ll->setFlags(NO_OPS);
|
ll->setFlags(NO_OPS);
|
||||||
else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
|
else if (ll->match(iINC) || ll->match(iPUSH) || ll->match(iDEC))
|
||||||
@@ -733,7 +865,7 @@ static void arith(int i)
|
|||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
static llIcode arithTable[8] =
|
static llIcode arithTable[8] =
|
||||||
{
|
{
|
||||||
iTEST , (llIcode)0, iNOT, iNEG,
|
iTEST, (llIcode)0, iNOT, iNEG,
|
||||||
iMUL , iIMUL, iDIV, iIDIV
|
iMUL , iIMUL, iDIV, iIDIV
|
||||||
};
|
};
|
||||||
opcode = arithTable[REG(*pInst)];
|
opcode = arithTable[REG(*pInst)];
|
||||||
@@ -748,7 +880,7 @@ static void arith(int i)
|
|||||||
}
|
}
|
||||||
else if (!(opcode == iNOT || opcode == iNEG))
|
else if (!(opcode == iNOT || opcode == iNEG))
|
||||||
{
|
{
|
||||||
pIcode->ll()->replaceSrc( pIcode->ll()->dst );
|
pIcode->ll()->replaceSrc( pIcode->ll()->m_dst );
|
||||||
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
setAddress(i, true, 0, rAX, 0); /* dst = AX */
|
||||||
}
|
}
|
||||||
else if (opcode == iNEG || opcode == iNOT)
|
else if (opcode == iNEG || opcode == iNOT)
|
||||||
@@ -767,7 +899,7 @@ static void arith(int i)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void data1(int i)
|
static void data1(int i)
|
||||||
{
|
{
|
||||||
pIcode->ll()->replaceSrc(LLOperand::CreateImm2((stateTable[i].flg & S_EXT)? signex(*pInst++): *pInst++));
|
pIcode->ll()->replaceSrc(LLOperand::CreateImm2((stateTable[i].flg & S_EXT)? signex(*pInst++): *pInst++,1));
|
||||||
pIcode->ll()->setFlags(I);
|
pIcode->ll()->setFlags(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,7 +919,7 @@ static void data2(int )
|
|||||||
* set to NO_OPS. */
|
* set to NO_OPS. */
|
||||||
if (pIcode->ll()->getOpcode() == iENTER)
|
if (pIcode->ll()->getOpcode() == iENTER)
|
||||||
{
|
{
|
||||||
pIcode->ll()->dst.off = getWord();
|
pIcode->ll()->m_dst.off = getWord();
|
||||||
pIcode->ll()->setFlags(NO_OPS);
|
pIcode->ll()->setFlags(NO_OPS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -804,47 +936,42 @@ static void dispM(int i)
|
|||||||
{
|
{
|
||||||
setAddress(i, false, SegPrefix, 0, getWord());
|
setAddress(i, false, SegPrefix, 0, getWord());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
dispN - 2 uint8_t disp as immed relative to ip
|
dispN - 2 uint8_t disp as immed relative to ip
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static void dispN(int )
|
static void dispN(int )
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
|
||||||
long off = (short)getWord(); /* Signed displacement */
|
//PROG &prog(Project::get()->prog);
|
||||||
|
/*long off = (short)*/getWord(); /* Signed displacement */
|
||||||
|
|
||||||
/* Note: the result of the subtraction could be between 32k and 64k, and
|
/* Note: the result of the subtraction could be between 32k and 64k, and
|
||||||
still be positive; it is an offset from prog.Image. So this must be
|
still be positive; it is an offset from prog.Image. So this must be
|
||||||
treated as unsigned */
|
treated as unsigned */
|
||||||
pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image)));
|
// decodeBranchTgt();
|
||||||
pIcode->ll()->setFlags(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
dispS - 1 uint8_t disp as immed relative to ip
|
dispS - 1 byte disp as immed relative to ip
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void dispS(int )
|
static void dispS(int )
|
||||||
{
|
{
|
||||||
PROG &prog(Project::get()->prog);
|
/*long off =*/ signex(*pInst++); /* Signed displacement */
|
||||||
long off = signex(*pInst++); /* Signed displacement */
|
|
||||||
|
|
||||||
pIcode->ll()->replaceSrc((uint32_t)(off + (unsigned)(pInst - prog.Image)));
|
// decodeBranchTgt();
|
||||||
pIcode->ll()->setFlags(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
dispF - 4 uint8_t disp as immed 20-bit target address
|
dispF - 4 byte disp as immed 20-bit target address
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void dispF(int )
|
static void dispF(int i)
|
||||||
{
|
{
|
||||||
uint32_t off = (unsigned)getWord();
|
uint16_t off = (unsigned)getWord();
|
||||||
uint32_t seg = (unsigned)getWord();
|
uint16_t seg = (unsigned)getWord();
|
||||||
|
setAddress(i, true, seg, 0, off);
|
||||||
pIcode->ll()->replaceSrc(off + ((uint32_t)(unsigned)seg << 4));
|
// decodeBranchTgt();
|
||||||
pIcode->ll()->setFlags(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -874,12 +1001,19 @@ static void strop(int )
|
|||||||
{
|
{
|
||||||
if (RepPrefix)
|
if (RepPrefix)
|
||||||
{
|
{
|
||||||
// pIcode->ll()->getOpcode() += ((pIcode->ll()->getOpcode() == iCMPS ||
|
if ( pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) )
|
||||||
// pIcode->ll()->getOpcode() == iSCAS)
|
{
|
||||||
// && RepPrefix == iREPE)? 2: 1;
|
if(pIcode->insn.prefix & insn_rep_zero)
|
||||||
if ((pIcode->ll()->match(iCMPS) || pIcode->ll()->match(iSCAS) ) && RepPrefix == iREPE)
|
{
|
||||||
BumpOpcode(*pIcode->ll()); // += 2
|
BumpOpcode(*pIcode->ll()); // iCMPS -> iREPE_CMPS
|
||||||
BumpOpcode(*pIcode->ll()); // else += 1
|
BumpOpcode(*pIcode->ll());
|
||||||
|
}
|
||||||
|
else if(pIcode->insn.prefix & insn_rep_notzero)
|
||||||
|
BumpOpcode(*pIcode->ll()); // iX -> iREPNE_X
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(pIcode->insn.prefix & insn_rep_zero)
|
||||||
|
BumpOpcode(*pIcode->ll()); // iX -> iREPE_X
|
||||||
if (pIcode->ll()->match(iREP_LODS) )
|
if (pIcode->ll()->match(iREP_LODS) )
|
||||||
pIcode->ll()->setFlags(NOT_HLL);
|
pIcode->ll()->setFlags(NOT_HLL);
|
||||||
RepPrefix = 0;
|
RepPrefix = 0;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#define TABLESIZE 16 /* Number of entries added each expansion */
|
#define TABLESIZE 16 /* Number of entries added each expansion */
|
||||||
/* Probably has to be a power of 2 */
|
/* Probably has to be a power of 2 */
|
||||||
#define STRTABSIZE 256 /* Size string table is inc'd by */
|
#define STRTABSIZE 256 /* Size string table is inc'd by */
|
||||||
#define NIL ((uint16_t)-1)
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
static char *pStrTab; /* Pointer to the current string table */
|
static char *pStrTab; /* Pointer to the current string table */
|
||||||
static int strTabNext; /* Next free index into pStrTab */
|
static int strTabNext; /* Next free index into pStrTab */
|
||||||
@@ -53,7 +53,7 @@ struct TABLEINFO_TYPE
|
|||||||
{
|
{
|
||||||
TABLEINFO_TYPE()
|
TABLEINFO_TYPE()
|
||||||
{
|
{
|
||||||
symTab=valTab=0;
|
symTab=valTab=nullptr;
|
||||||
}
|
}
|
||||||
//void deleteVal(uint32_t symOff, Function *symProc, boolT bSymToo);
|
//void deleteVal(uint32_t symOff, Function *symProc, boolT bSymToo);
|
||||||
void create(tableType type);
|
void create(tableType type);
|
||||||
@@ -80,7 +80,7 @@ void TABLEINFO_TYPE::create(tableType type)
|
|||||||
numEntry = 0;
|
numEntry = 0;
|
||||||
tableSize = TABLESIZE;
|
tableSize = TABLESIZE;
|
||||||
valTab = new SYMTABLE [TABLESIZE];
|
valTab = new SYMTABLE [TABLESIZE];
|
||||||
symTab = 0;
|
symTab = nullptr;
|
||||||
break;
|
break;
|
||||||
case Label:
|
case Label:
|
||||||
currentTabInfo.numEntry = 0;
|
currentTabInfo.numEntry = 0;
|
||||||
@@ -133,7 +133,7 @@ void destroySymTables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Using the value, read the symbolic name */
|
/* Using the value, read the symbolic name */
|
||||||
boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc)
|
bool readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
|
||||||
{
|
{
|
||||||
return false; // no symbolic names for now
|
return false; // no symbolic names for now
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,6 @@ boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc)
|
|||||||
* if necessary (0 means no update necessary). */
|
* if necessary (0 means no update necessary). */
|
||||||
void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
|
void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
auto iter=findByLabel(symbol);
|
auto iter=findByLabel(symbol);
|
||||||
if(iter==end())
|
if(iter==end())
|
||||||
return;
|
return;
|
||||||
|
|||||||
14
src/tests/loader.cpp
Normal file
14
src/tests/loader.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "project.h"
|
||||||
|
#include "loader.h"
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
TEST(Loader, NewProjectIsInitalized) {
|
||||||
|
Project p;
|
||||||
|
EXPECT_EQ(nullptr,p.callGraph);
|
||||||
|
ASSERT_TRUE(p.pProcList.empty());
|
||||||
|
ASSERT_TRUE(p.binary_path().empty());
|
||||||
|
ASSERT_TRUE(p.project_name().empty());
|
||||||
|
ASSERT_TRUE(p.symtab.empty());
|
||||||
|
}
|
||||||
|
|
||||||
27
src/tests/project.cpp
Normal file
27
src/tests/project.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include "project.h"
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
TEST(Project, NewProjectIsInitalized) {
|
||||||
|
Project p;
|
||||||
|
EXPECT_EQ(nullptr,p.callGraph);
|
||||||
|
ASSERT_TRUE(p.pProcList.empty());
|
||||||
|
ASSERT_TRUE(p.binary_path().empty());
|
||||||
|
ASSERT_TRUE(p.project_name().empty());
|
||||||
|
ASSERT_TRUE(p.symtab.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Project, CreatedProjectHasValidNames) {
|
||||||
|
Project p;
|
||||||
|
std::vector<std::string> strs = {"./Project1.EXE","/home/Project2.EXE","/home/Pro\\ ject3"};
|
||||||
|
std::vector<std::string> expected = {"Project1","Project2","Pro\\ ject3"};
|
||||||
|
for(size_t i=0; i<strs.size(); i++)
|
||||||
|
{
|
||||||
|
p.create(strs[i]);
|
||||||
|
EXPECT_EQ(nullptr,p.callGraph);
|
||||||
|
ASSERT_TRUE(p.pProcList.empty());
|
||||||
|
EXPECT_EQ(expected[i],p.project_name());
|
||||||
|
EXPECT_EQ(strs[i],p.binary_path());
|
||||||
|
ASSERT_TRUE(p.symtab.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/udm.cpp
22
src/udm.cpp
@@ -12,8 +12,8 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
extern Project g_proj;
|
extern Project g_proj;
|
||||||
static void displayCFG(Function * pProc);
|
//static void displayCFG(Function * pProc);
|
||||||
static void displayDfs(BB * pBB);
|
//static void displayDfs(BB * pBB);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* udm
|
* udm
|
||||||
@@ -31,6 +31,7 @@ void Function::buildCFG(Disassembler &ds)
|
|||||||
if (option.asm2)
|
if (option.asm2)
|
||||||
{
|
{
|
||||||
ds.disassem(this); // Print 2nd pass assembler listing
|
ds.disassem(this); // Print 2nd pass assembler listing
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Idiom analysis and propagation of long type */
|
/* Idiom analysis and propagation of long type */
|
||||||
@@ -43,7 +44,7 @@ void Function::controlFlowAnalysis()
|
|||||||
{
|
{
|
||||||
if (flg & PROC_ISLIB)
|
if (flg & PROC_ISLIB)
|
||||||
return; /* Ignore library functions */
|
return; /* Ignore library functions */
|
||||||
derSeq *derivedG=0;
|
derSeq *derivedG=nullptr;
|
||||||
|
|
||||||
/* Make cfg reducible and build derived sequences */
|
/* Make cfg reducible and build derived sequences */
|
||||||
derivedG=checkReducibility();
|
derivedG=checkReducibility();
|
||||||
@@ -60,7 +61,8 @@ void Function::controlFlowAnalysis()
|
|||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
{
|
{
|
||||||
printf("\nDepth first traversal - Proc %s\n", name.c_str());
|
printf("\nDepth first traversal - Proc %s\n", name.c_str());
|
||||||
m_cfg.front()->displayDfs();
|
(*m_actual_cfg.begin())->displayDfs();
|
||||||
|
//m_cfg.front()->displayDfs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free storage occupied by this procedure */
|
/* Free storage occupied by this procedure */
|
||||||
@@ -73,20 +75,22 @@ void udm(void)
|
|||||||
/* Build the control flow graph, find idioms, and convert low-level
|
/* Build the control flow graph, find idioms, and convert low-level
|
||||||
* icodes to high-level ones */
|
* icodes to high-level ones */
|
||||||
Disassembler ds(2);
|
Disassembler ds(2);
|
||||||
for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter)
|
for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter)
|
||||||
{
|
{
|
||||||
iter->buildCFG(ds);
|
iter->buildCFG(ds);
|
||||||
}
|
}
|
||||||
|
if (option.asm2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
/* Data flow analysis - eliminate condition codes, extraneous registers
|
/* Data flow analysis - eliminate condition codes, extraneous registers
|
||||||
* and intermediate instructions. Find expressions by forward
|
* and intermediate instructions. Find expressions by forward
|
||||||
* substitution algorithm */
|
* substitution algorithm */
|
||||||
std::bitset<32> live_regs;
|
LivenessSet live_regs;
|
||||||
g_proj.pProcList.front().dataFlow (live_regs);
|
Project::get()->pProcList.front().dataFlow (live_regs);
|
||||||
|
|
||||||
/* Control flow analysis - structuring algorithm */
|
/* Control flow analysis - structuring algorithm */
|
||||||
for (auto iter = g_proj.pProcList.rbegin(); iter!=g_proj.pProcList.rend(); ++iter)
|
for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter)
|
||||||
{
|
{
|
||||||
iter->controlFlowAnalysis();
|
iter->controlFlowAnalysis();
|
||||||
}
|
}
|
||||||
@@ -98,7 +102,7 @@ void udm(void)
|
|||||||
void Function::displayCFG()
|
void Function::displayCFG()
|
||||||
{
|
{
|
||||||
printf("\nBasic Block List - Proc %s", name.c_str());
|
printf("\nBasic Block List - Proc %s", name.c_str());
|
||||||
for (BB *pBB : m_cfg)
|
for (BB *pBB : /*m_cfg*/m_actual_cfg)
|
||||||
{
|
{
|
||||||
pBB->display();
|
pBB->display();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,15 @@ int proc_2 (long arg0, long arg1)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
char loc1; /* al */
|
char loc1; /* al */
|
||||||
int loc2; /* al */
|
int loc2; /* bx */
|
||||||
int loc3; /* bx */
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
arg0 = (arg0 + 1);
|
arg0 = (arg0 + 1);
|
||||||
loc1 = es[bx];
|
loc1 = es[bx];
|
||||||
arg1 = (arg1 + 1);
|
arg1 = (arg1 + 1);
|
||||||
es[bx] = loc1;
|
es[bx] = loc1;
|
||||||
} while ((loc2 != 0));
|
} while ((loc1 != 0));
|
||||||
return (loc3);
|
return (loc2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +34,6 @@ int proc_3 (long arg0, long arg1)
|
|||||||
int loc1; /* ax */
|
int loc1; /* ax */
|
||||||
|
|
||||||
while ((es[bx] == es[bx])) {
|
while ((es[bx] == es[bx])) {
|
||||||
|
|
||||||
if (es[bx] == 0) {
|
if (es[bx] == 0) {
|
||||||
loc1 = 0;
|
loc1 = 0;
|
||||||
return (loc1);
|
return (loc1);
|
||||||
@@ -57,9 +55,9 @@ int proc_1 (int arg0, int arg1, int arg2, int arg3)
|
|||||||
{
|
{
|
||||||
int loc1; /* si */
|
int loc1; /* si */
|
||||||
int loc2; /* di */
|
int loc2; /* di */
|
||||||
|
|
||||||
loc1 = 0;
|
loc1 = 0;
|
||||||
loc2 = 0;
|
loc2 = 0;
|
||||||
|
|
||||||
while ((loc1 < 0x2328)) {
|
while ((loc1 < 0x2328)) {
|
||||||
proc_2 (arg1, arg0, 311);
|
proc_2 (arg1, arg0, 311);
|
||||||
proc_2 (arg3, arg2, 328);
|
proc_2 (arg3, arg2, 328);
|
||||||
@@ -79,13 +77,12 @@ int loc1;
|
|||||||
int loc2;
|
int loc2;
|
||||||
int loc3;
|
int loc3;
|
||||||
int loc4;
|
int loc4;
|
||||||
loc3 = 0;
|
|
||||||
|
|
||||||
|
loc3 = 0;
|
||||||
while ((loc3 < 0x3e8)) {
|
while ((loc3 < 0x3e8)) {
|
||||||
loc1 = 0;
|
loc1 = 0;
|
||||||
loc4 = 0;
|
loc4 = 0;
|
||||||
loc2 = 1;
|
loc2 = 1;
|
||||||
|
|
||||||
while ((loc4 < 179)) {
|
while ((loc4 < 179)) {
|
||||||
loc1 = (loc1 + loc2);
|
loc1 = (loc1 + loc2);
|
||||||
loc2 = (loc2 + 2);
|
loc2 = (loc2 + 2);
|
||||||
@@ -105,8 +102,8 @@ int proc_5 (int arg0)
|
|||||||
{
|
{
|
||||||
int loc1; /* si */
|
int loc1; /* si */
|
||||||
int loc2; /* ax */
|
int loc2; /* ax */
|
||||||
loc1 = arg0;
|
|
||||||
|
|
||||||
|
loc1 = arg0;
|
||||||
if (loc1 > 2) {
|
if (loc1 > 2) {
|
||||||
loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe)));
|
loc2 = (proc_5 ((loc1 - 1)) + proc_5 ((loc1 + 0xfffe)));
|
||||||
}
|
}
|
||||||
@@ -179,7 +176,7 @@ void proc_8 (int arg0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc_7 (int arg0, int arg1, int arg2, int arg3)
|
void proc_7 (int arg0, int arg1, int arg2, int arg3)
|
||||||
/* Takes 8 bytes of parameters.
|
/* Takes 8 bytes of parameters.
|
||||||
* High-level language prologue code.
|
* High-level language prologue code.
|
||||||
* Untranslatable routine. Assembler provided.
|
* Untranslatable routine. Assembler provided.
|
||||||
@@ -245,7 +242,7 @@ void proc_8 (int arg0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc_9 (int arg0)
|
void proc_9 (int arg0)
|
||||||
/* Takes 8 bytes of parameters.
|
/* Takes 8 bytes of parameters.
|
||||||
* High-level language prologue code.
|
* High-level language prologue code.
|
||||||
* C calling convention.
|
* C calling convention.
|
||||||
@@ -256,106 +253,62 @@ void proc_8 (int arg0)
|
|||||||
int loc1;
|
int loc1;
|
||||||
int loc2;
|
int loc2;
|
||||||
int loc3; /* ax */
|
int loc3; /* ax */
|
||||||
|
|
||||||
loc2 = 100;
|
loc2 = 100;
|
||||||
loc3 = loc2;
|
loc3 = loc2;
|
||||||
loc2 = (loc2 - 1);
|
loc2 = (loc2 - 1);
|
||||||
|
|
||||||
while (((loc3 | loc3) != 0)) {
|
while (((loc3 | loc3) != 0)) {
|
||||||
loc3 = loc2;
|
loc3 = loc2;
|
||||||
loc2 = (loc2 - 1);
|
loc2 = (loc2 - 1);
|
||||||
} /* end of while */
|
} /* end of while */
|
||||||
return (var06278);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int proc_10 ()
|
int proc_10 ()
|
||||||
/* Takes no parameters.
|
/* Takes no parameters.
|
||||||
* High-level language prologue code.
|
* High-level language prologue code.
|
||||||
* Untranslatable routine. Assembler provided.
|
|
||||||
* Return value in register ax.
|
|
||||||
* Contains instructions not normally used by compilers.
|
* Contains instructions not normally used by compilers.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PUSH bp
|
int loc1;
|
||||||
MOV bp, sp
|
int loc2;
|
||||||
SUB sp, 68h
|
int loc3;
|
||||||
PUSH si
|
int loc4;
|
||||||
PUSH di
|
int loc5;
|
||||||
PUSH ds
|
int loc6; /* bx */
|
||||||
MOV ax, 159h
|
int loc7; /* dx */
|
||||||
PUSH ax
|
int loc8; /* ax */
|
||||||
PUSH ss
|
loc6 = proc_2 (&loc1, 345, , );
|
||||||
LEA ax, [bp-64h]
|
fopen ("zyxw.vut", 368);
|
||||||
PUSH ax
|
loc2 = loc7;
|
||||||
PUSH cs
|
loc3 = loc8;
|
||||||
CALL near ptr proc_2
|
|
||||||
ADD sp, 8
|
|
||||||
PUSH ds
|
|
||||||
MOV ax, 170h
|
|
||||||
PUSH ax
|
|
||||||
PUSH ds
|
|
||||||
MOV ax, 167h
|
|
||||||
PUSH ax
|
|
||||||
CALL far ptr fopen
|
|
||||||
ADD sp, 8
|
|
||||||
MOV [bp-66h], dx
|
|
||||||
MOV [bp-68h], ax
|
|
||||||
OR dx, ax
|
|
||||||
JNE L1
|
|
||||||
PUSH ds
|
|
||||||
MOV ax, 172h
|
|
||||||
PUSH ax
|
|
||||||
CALL far ptr printf
|
|
||||||
POP cx
|
|
||||||
POP cx
|
|
||||||
MOV ax, 0FFFFh
|
|
||||||
PUSH ax
|
|
||||||
CALL far ptr exit
|
|
||||||
POP cx
|
|
||||||
|
|
||||||
L1: XOR di, 0
|
if ((loc7 | loc8) == 0) {
|
||||||
|
printf ("Cannot open file");
|
||||||
|
exit (0xffff);
|
||||||
|
}
|
||||||
|
l1:
|
||||||
|
if (++loc5 >= 0x3e8) {
|
||||||
|
fclose (loc3, loc2);
|
||||||
|
return (loc5);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
loc4 = 0;
|
||||||
|
|
||||||
L2: INC di
|
while ((ss[bp+si-0x64] != 0)) {
|
||||||
MOV ax, di
|
|
||||||
CMP ax, 3E8h
|
|
||||||
JL L3
|
|
||||||
PUSH word ptr [bp-66h]
|
|
||||||
PUSH word ptr [bp-68h]
|
|
||||||
CALL far ptr fclose
|
|
||||||
POP cx
|
|
||||||
POP cx
|
|
||||||
MOV ax, di
|
|
||||||
POP di
|
|
||||||
POP si
|
|
||||||
MOV sp, bp
|
|
||||||
POP bp
|
|
||||||
RETF
|
|
||||||
|
|
||||||
L3: XOR si, 0
|
if (++es[bx] < 0) {
|
||||||
|
es[bx+0xc] = (es[bx+0xc] + 1);
|
||||||
L4: CMP byte ptr ss:[bp+si-64h], 0
|
loc6 = (loc6 - 1);
|
||||||
JNE L5
|
es[bx] = ss[bp+si-0x64];
|
||||||
|
}
|
||||||
L5: LES bx, dword ptr[bp-68h]
|
else {
|
||||||
INC word ptr es:[bx]
|
_fputc (ss[bp+si-0x64], loc3, loc2);
|
||||||
JGE L6
|
}
|
||||||
MOV al, ss:[bp+si-64h]
|
loc4 = (loc4 + 1);
|
||||||
LES bx, dword ptr[bp-68h]
|
} /* end of while */
|
||||||
INC word ptr es:[bx+0Ch]
|
goto L1;
|
||||||
LES bx, dword ptres:[bx+0Ch]
|
}
|
||||||
DEC bx
|
|
||||||
MOV es:[bx], al
|
|
||||||
MOV ah, 0
|
|
||||||
|
|
||||||
L7: INC si
|
|
||||||
JMP L4 ;Synthetic inst
|
|
||||||
|
|
||||||
L6: PUSH word ptr [bp-66h]
|
|
||||||
PUSH word ptr [bp-68h]
|
|
||||||
PUSH word ptr ss:[bp+si-64h]
|
|
||||||
CALL far ptr _fputc
|
|
||||||
ADD sp, 6
|
|
||||||
JMP L7 ;Synthetic inst
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -379,11 +332,11 @@ int loc10;
|
|||||||
int loc11;
|
int loc11;
|
||||||
int loc12; /* ax */
|
int loc12; /* ax */
|
||||||
int loc13; /* bx */
|
int loc13; /* bx */
|
||||||
printf ("Start...%c\n\n", 7);
|
|
||||||
|
|
||||||
|
loc11 = 0;
|
||||||
|
printf ("Start...%c\n\n", 7);
|
||||||
while ((loc11 < 6)) {
|
while ((loc11 < 6)) {
|
||||||
loc12 = loc11;
|
loc12 = loc11;
|
||||||
|
|
||||||
if (loc12 <= 5) {
|
if (loc12 <= 5) {
|
||||||
loc13 = (loc12 << 1);
|
loc13 = (loc12 << 1);
|
||||||
var06278 = proc_1 (&loc2, &loc1, , );
|
var06278 = proc_1 (&loc2, &loc1, , );
|
||||||
|
|||||||
@@ -15,30 +15,32 @@ long LXMUL@ (long arg0, long arg1)
|
|||||||
{
|
{
|
||||||
int loc1;
|
int loc1;
|
||||||
int loc2; /* tmp */
|
int loc2; /* tmp */
|
||||||
|
|
||||||
loc2 = LO(arg0);
|
loc2 = LO(arg0);
|
||||||
LO(arg0) = loc1;
|
LO(arg0) = loc1;
|
||||||
loc1 = loc2;
|
loc1 = loc2;
|
||||||
loc2 = LO(arg0);
|
loc2 = LO(arg0);
|
||||||
LO(arg0) = HI(arg0);
|
LO(arg0) = HI(arg0);
|
||||||
|
|
||||||
if ((LO(arg0) & LO(arg0)) != 0) {
|
if ((LO(arg0) & LO(arg0)) != 0) {
|
||||||
|
LO(arg0) = (LO(arg0) * LO(arg1));
|
||||||
}
|
}
|
||||||
loc2 = LO(arg0);
|
loc2 = LO(arg0);
|
||||||
LO(arg0) = HI(arg1);
|
LO(arg0) = HI(arg1);
|
||||||
HI(arg1) = loc2;
|
HI(arg1) = loc2;
|
||||||
|
|
||||||
if ((LO(arg0) & LO(arg0)) != 0) {
|
if ((LO(arg0) & LO(arg0)) != 0) {
|
||||||
LO(arg0) = (LO(arg0) * loc1);
|
LO(arg0) = (LO(arg0) * loc1);
|
||||||
HI(arg1) = (HI(arg1) + LO(arg0));
|
HI(arg1) = (HI(arg1) + LO(arg0));
|
||||||
}
|
}
|
||||||
loc2 = LO(arg0);
|
loc2 = LO(arg0);
|
||||||
arg0 = (loc1 * LO(arg1));
|
LO(arg0) = loc1;
|
||||||
|
loc1 = loc2;
|
||||||
|
arg0 = (LO(arg0) * LO(arg1));
|
||||||
HI(arg0) = (HI(arg0) + HI(arg1));
|
HI(arg0) = (HI(arg0) + HI(arg1));
|
||||||
return (arg0);
|
return (arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long LDIV@ (long arg0, int arg3)
|
long LDIV@ (long arg0, long arg2)
|
||||||
/* Takes 8 bytes of parameters.
|
/* Takes 8 bytes of parameters.
|
||||||
* Runtime support routine of the compiler.
|
* Runtime support routine of the compiler.
|
||||||
* High-level language prologue code.
|
* High-level language prologue code.
|
||||||
@@ -131,7 +133,7 @@ long LDIV@ (long arg0, int arg3)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long LMOD@ (long arg0, int arg3)
|
long LMOD@ (long arg0, long arg2)
|
||||||
/* Takes 8 bytes of parameters.
|
/* Takes 8 bytes of parameters.
|
||||||
* Runtime support routine of the compiler.
|
* Runtime support routine of the compiler.
|
||||||
* High-level language prologue code.
|
* High-level language prologue code.
|
||||||
@@ -280,6 +282,7 @@ void main ()
|
|||||||
{
|
{
|
||||||
long loc1;
|
long loc1;
|
||||||
long loc2;
|
long loc2;
|
||||||
|
|
||||||
loc2 = 255;
|
loc2 = 255;
|
||||||
loc1 = 143;
|
loc1 = 143;
|
||||||
loc1 = (loc2 + loc1);
|
loc1 = (loc2 + loc1);
|
||||||
|
|||||||
@@ -15,16 +15,14 @@ void proc_1 (int arg0, int arg1, int arg2)
|
|||||||
int loc1;
|
int loc1;
|
||||||
int loc2;
|
int loc2;
|
||||||
int loc3;
|
int loc3;
|
||||||
loc2 = 0;
|
|
||||||
|
|
||||||
|
loc2 = 0;
|
||||||
while ((loc2 < 5)) {
|
while ((loc2 < 5)) {
|
||||||
loc3 = 0;
|
loc3 = 0;
|
||||||
|
|
||||||
while ((loc3 < 4)) {
|
while ((loc3 < 4)) {
|
||||||
loc1 = 0;
|
loc1 = 0;
|
||||||
|
|
||||||
while ((loc1 < 4)) {
|
while ((loc1 < 4)) {
|
||||||
*((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*(((((loc2 << 3) << 1) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
|
*((((loc2 * 10) + arg2) + (loc3 << 1))) = ((*((((loc2 << 3) + arg0) + (loc1 << 1))) * *((((loc1 * 10) + arg1) + (loc3 << 1)))) + *((((loc2 * 10) + arg2) + (loc3 << 1))));
|
||||||
loc1 = (loc1 + 1);
|
loc1 = (loc1 + 1);
|
||||||
} /* end of while */
|
} /* end of while */
|
||||||
loc3 = (loc3 + 1);
|
loc3 = (loc3 + 1);
|
||||||
@@ -42,6 +40,7 @@ void main ()
|
|||||||
int loc1;
|
int loc1;
|
||||||
int loc2;
|
int loc2;
|
||||||
int loc3;
|
int loc3;
|
||||||
|
|
||||||
proc_1 (&loc3, &loc2, &loc1);
|
proc_1 (&loc3, &loc2, &loc1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
valgrind_base.sh
Executable file
6
valgrind_base.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cd bld
|
||||||
|
make -j5
|
||||||
|
cd ..
|
||||||
|
./test_use_base.sh
|
||||||
|
./valgrind_tester ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
||||||
Reference in New Issue
Block a user