📄 dynamicarmcode.cpp
字号:
if (code == LDR || code == STR ||
code == LDR_PRE || code == STR_PRE ||
code == LDR_POST|| code == STR_POST ||
code == LDR_PRESUB || code == STR_PRESUB ||
code == LDR_POSTSUB || code == STR_POSTSUB)
{
bool pre = (code != LDR_POST) && (code != STR_POST) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);
bool pre_write = (code == LDR_PRE) || (code == STR_PRE) || (code == LDR_PRESUB) || (code == STR_PRESUB);
bool load = (code == LDR) || (code == LDR_PRE) || (code == LDR_POST) || (code == LDR_PRESUB) || (code == LDR_POSTSUB);
bool un_signed = (code != LDR_PRESUB) && (code != STR_PRESUB) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);
if(next_half || next_sign){
if(Shift==0 && (next_half || next_byte)){
p = InstCreate32((next_cond << 28) |
((pre ? 1 : 0)<<24) | (un_signed<<23) |
((pre_write ? 1 : 0)<<21) | (load<<20) | (next_sign << 6) | (next_half << 5) |
(op_1 << 16) | (Dest << 12) | (9 << 4) | Op2,
NONE, op_1, Op2, (next_cond != AL)?1:0, 0);
}
}else{
p = InstCreate32((next_cond << 28) | (3 << 25) |
((pre ? 1 : 0)<<24) | (un_signed<<23) | (next_byte<<22) |
((pre_write ? 1 : 0)<<21) | (load<<20) |
(op_1 << 16) | (Dest << 12) | (Shift << 7) | (ShiftType << 5) | Op2,
NONE, op_1, Op2, (next_cond != AL)?1:0, 0);
}
if(p){
if(load)
p->write_regs |= 1 << Dest;
else
p->read_regs |= 1 << Dest;
if(!pre || pre_write)
p->write_regs |= 1 << op_1;
}
}
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::I4(int code, byte Dest, byte op_1, byte Op2, byte Op3){
S_instruction *p = NULL;
if (code == MLA){
p = InstCreate32((next_cond << 28) | (1 << 21) | ((next_set?1:0)<<20) |
(Dest << 16) | (Op3 << 12) | (Op2 << 8) | 0x90 | (op_1),
Dest, op_1, Op2, (next_cond != AL)?1:0, next_set?1:0);
p->read_regs |= 1 << Op3;
}
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::MulC(E_REGISTER dst, E_REGISTER src, int constant){
if(dst == src){
assert(0);
InstPost(NULL);
}
switch(constant){
case 0: Mov(dst, 0); break;
case 1: Mov(dst, src); break;
case 2: Mov(dst, src, LSL, 1); break;
case 3: Add(dst, src, src, LSL, 1); break;
case 4: Mov(dst, src, LSL, 2); break;
case 5: Add(dst, src, src, LSL, 2); break;
case 6: Mov(dst, src, LSL, 1); Add(dst, dst, dst, LSL, 1); break; //2*3
case 7: Rsb(dst, src, src, LSL, 3); break;
case 8: Mov(dst, src, LSL, 3); break;
case 9: Add(dst, src, src, LSL, 3); break;
case 10: Mov(dst, src, LSL, 1); Add(dst, dst, dst, LSL, 2); break; //2*5
case 11: Rsb(dst, src, src, LSL, 3); Add(dst, dst, src, LSL, 2); break; //7+4
case 12: Add(dst, src, src, LSL, 1); Mov(dst, dst, LSL, 2); break; //3*4
case 13: Add(dst, src, src, LSL, 3); Add(dst, dst, src, LSL, 2); break; //9+4
case 14: Rsb(dst, src, src, LSL, 3); Add(dst, dst, dst); break; //7*2
case 15: Rsb(dst, src, src, LSL, 4); break;
case 16: Mov(dst, src, LSL, 4); break;
case 17: Add(dst, src, src, LSL, 4); break;
default: Mov(dst, constant); Mul(dst, src, dst); break;
}
}
//----------------------------
void C_dyn_code_imp::IConst(byte Dest, int constant){
S_instruction *p = NULL;
int Shift,code;
if(constant < 0){
code = MVN;
constant = -constant-1;
}else
code = MOV;
constant = (constant << 8) | ((constant >> 24) & 255);
for(Shift=8;Shift<=32;Shift+=2){
if(constant & 0xC0)
break;
constant = (constant << 2) | ((constant >> 30) & 3);
}
Shift &= 31;
constant &= 255;
p = InstCreate32((next_cond << 28) | (1<<25) | (code << 21) | ((next_set?1:0)<<20) |
(Dest << 12) | (Shift << 7) | constant, Dest, NONE, NONE, (next_cond != AL)?1:0, next_set?1:0);
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::I2(int code, byte Dest, byte op_1){
if (MODE(code) == 1){
S_instruction *p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 16) | ((op_1 & 15) << 12),
Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
InstPost(p);
}
else
if (MODE(code) == 6){
S_instruction *p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16),
Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
InstPost(p);
}else
I2C(code,Dest,op_1,0);
}
//----------------------------
void C_dyn_code_imp::I2C(int code, byte Dest, byte op_1, int constant){
S_instruction *p = NULL;
if(MODE(code) == 2 && constant>=0 && constant<8){
p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 16) | ((op_1 & 15) << 12) | (constant << 0),
Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
}
if(MODE(code) == 9 && constant>=0 && constant<256){
p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16) | ((constant & 15) << 0) | ((constant & 0xF0) << 16),
Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
}
if(MODE(code) == 15){
if(constant<0){
code ^= (1<<23);
constant = -constant;
}
if(code & 256){ // dword or qword
if(constant & 3)
constant = -1;
else
constant >>= 2;
}
if(constant>=0 && constant<256){
p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16) | (constant << 0),
NONE, op_1, NONE, (next_cond != AL)?1:0, 0);
if(code & (1<<20))
p->write_regs |= 1 << Dest;
else
p->read_regs |= 1 << Dest;
if(!(code & (1<<24)) || (code & (1<<21)))
p->write_regs |= 1 << op_1;
}
}
if(code >= 0 && code < 16){
if(code==MOV && constant<0){
code = MVN;
constant = -constant-1;
}else
if(code==ADD && constant<0){
code = SUB;
constant = -constant;
}
else
if(code==SUB && constant<0){
code = ADD;
constant = -constant;
}
if(code == CMP || code == TST || code == CMN || code == TEQ)
next_set = 1;
int shift;
for(shift = 0; shift<32; shift+=2){
if(constant>=0 && constant<=255)
break;
constant = (constant << 2) | ((constant >> 30) & 3);
}
if(constant >= 0 && constant <= 255){
p = InstCreate32((next_cond << 28) | (1<<25) | (code << 21) | ((next_set?1:0)<<20) |
((op_1==NONE ? r0 : op_1) << 16) | ((Dest==NONE ? r0 : Dest) << 12) | (shift << 7) | constant,
Dest, op_1, NONE, (next_cond != AL)?1:0, next_set?1:0);
}
}
IPLD(&code,&Dest);
if(code == LDR || code == STR ||
code == LDR_PRE || code == STR_PRE ||
code == LDR_POST|| code == STR_POST ||
code == LDR_PRESUB || code == STR_PRESUB ||
code == LDR_POSTSUB || code == STR_POSTSUB){
bool pre = (code != LDR_POST) && (code != STR_POST) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);
bool pre_write = (code == LDR_PRE) || (code == STR_PRE) || (code == LDR_PRESUB) || (code == STR_PRESUB);
bool load = (code == LDR) || (code == LDR_PRE) || (code == LDR_POST) || (code == LDR_PRESUB) || (code == LDR_POSTSUB);
bool un_signed = (code != LDR_PRESUB) && (code != STR_PRESUB) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);
if(constant == 0){
pre = true;
pre_write = false;
}
if(constant < 0){
constant = -constant;
un_signed = !un_signed;
}
if(next_half || next_sign){
if (constant >= 0 && constant < 256 && (next_half || next_byte))
p = InstCreate32((next_cond << 28) |
((pre ? 1 : 0)<<24) | (un_signed<<23) | (1 << 22) |
((pre_write ? 1 : 0)<<21) | (load<<20) | (next_sign << 6) | (next_half << 5) |
(op_1 << 16) | (Dest << 12) | ((constant >> 4) << 8) | (9 << 4) | (constant & 15),
NONE, op_1, NONE, (next_cond != AL)?1:0, 0);
}else
if(constant >= 0 && constant < 4096){
p = InstCreate32((next_cond << 28) | (1 << 26) |
((pre ? 1 : 0)<<24) | (un_signed<<23) | (next_byte<<22) |
((pre_write ? 1 : 0)<<21) | (load<<20) |
(op_1 << 16) | (Dest << 12) | constant,
NONE, op_1, NONE, (next_cond != AL)?1:0, 0);
}
if(p){
if(load)
p->write_regs |= 1 << Dest;
else
p->read_regs |= 1 << Dest;
if(!pre || pre_write)
p->write_regs |= 1 << op_1;
}
}
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::I1P(int code, byte Dest, void *block, int Ofs){
S_instruction *p = NULL;
if(MODE(code)==15){
p = InstCreate32((next_cond << 28) | (code & MODEMASK) | (pc << 16) | ((Dest & 15) << 12), Dest, pc, NONE, (next_cond != AL)?1:0, 0);
p->tag = Ofs;
p->realloc = (S_instruction*)block;
}
if(code == LDR || code == STR){
int load = (code == LDR);
p = InstCreate32((next_cond << 28) | (1 << 26) | (1<<24) | (next_byte<<22) | (load<<20) | (pc << 16) | (Dest << 12),
Dest, pc, NONE, (next_cond != AL)?1:0, 0);
p->tag = Ofs;
p->realloc = (S_instruction*)block;
}else
if(code == MOV){ // ADD|SUB,Dst,R15,Ofs
p = InstCreate32((next_cond << 28) | (1<<25) | (pc << 16) | (Dest << 12), Dest, pc, NONE, (next_cond != AL)?1:0, 0);
p->tag = Ofs;
p->realloc = (S_instruction*)block;
}
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::I0P(int code, int Cond, void *target){
S_instruction *p = NULL;
if(code == B || code == BL){
p = InstCreate32((Cond << 28) | (5 << 25) | ((code == BL?1:0)<<24), pc, NONE, NONE, (Cond != AL)?1:0, 0);
if(code == BL)
p->write_regs |= 1 << lr;
p->realloc = (S_instruction*)target;
p->branch = true;
}
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::CodeBuild(){
//determine code size
int code_size = 0;
int num_functions = 0;
for(S_instruction *p=inst_begin; p; p=p->next){
code_size += InstructionSize(p, code_size);
if(p->is_function)
++num_functions;
}
dynamic_code.functions.Resize(num_functions);
//allocate code
//if(code_size > dynamic_code.allocated){
dynamic_code.Free();
dynamic_code.alloc_size = code_size;
if(max_align)
dynamic_code.alloc_size += max_align-1;
dynamic_code.alloc_base = (byte*)CodeAlloc(dynamic_code.alloc_size);
if(!dynamic_code.alloc_base)
return;
dynamic_code.code = dynamic_code.alloc_base;
if(max_align)
dynamic_code.code = (byte*)((dword(dynamic_code.alloc_base)+max_align-1) & -max_align);
//}
//dynamic_code.size = code_size;
//if(dynamic_code.code)
{
int fnc_index = 0;
CodeLock(dynamic_code.alloc_base, dynamic_code.alloc_size);
byte *addr = dynamic_code.code;
S_instruction *p;
for(p=inst_begin; p; p=p->next){
p->address = addr;
if(p->is_function)
dynamic_code.functions[fnc_index++] = addr;
addr += InstructionSize(p, addr - dynamic_code.code);
}
for(p=inst_begin; p; p=p->next){
if(p->realloc && (!p->realloc->address || !InstReAlloc(p, p->realloc))){
//dynamic_code.size = 0;
assert(0);
break;
}
if(p->code_large)
MemCpy(p->address, p->code_large, p->code_size);
else
if(p->code_size>0){
if(p->code_size == sizeof(dword))
*(dword*)p->address = p->code_small;
else{
assert(0);
}
}
}
CodeUnlock(dynamic_code.alloc_base, dynamic_code.alloc_size);
}//else
//dynamic_code.size = 0;
FreeInstructions();
}
//----------------------------
C_dyn_code *C_dyn_code::Create(){
return new(true) C_dyn_code_imp;
}
//----------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -