📄 dynamicarmcode.cpp
字号:
next_set = true;
}
virtual void MoveBack(){ move_back = true; } //was: MB()
//void DS(){ delay_slot = true; }
void InstPost(S_instruction *p){
InstAdd(p);
InstInit();
}
//----------------------------
virtual void *Label(bool do_post){
S_instruction *p = InstCreate(NULL, 0, NONE, NONE, NONE, 0, 0);
p->branch = true;
if(do_post)
InstPost(p);
return p;
}
//----------------------------
virtual void PutLabel(void *label){
S_instruction *ins = (S_instruction*)label;
//make sure it was not already posted
assert(!ins->next);
InstPost(ins);
}
//----------------------------
virtual void *DeclareData(void *data, dword data_size){
S_instruction *p = InstCreate(data, data_size, NONE, NONE, NONE, 0, 0);
p->branch = true;
return p;
}
//----------------------------
virtual void StoreLabelAddress(void *label){
S_instruction *p = InstCreate32(NULL, NONE, NONE, NONE, 0, 0);
p->realloc = (S_instruction*)label;
p->branch = true;
InstPost(p);
}
//----------------------------
virtual void Align(dword bytes){
S_instruction *p = InstCreate(NULL, -(int)bytes, NONE, NONE, NONE, 0, 0);
p->branch = true;
InstPost(p);
max_align = Max(max_align, bytes);
}
//----------------------------
/*
void Break(){
S_instruction *p = InstCreate32((next_cond << 28) | (15 << 24));
p->branch = true;
InstPost(p);
}
*/
//----------------------------
virtual void FunctionBegin(dword _local_vars_size){
// stmfd sp!, { r4 - r11, lr }
S_instruction *p = InstCreate32(0xe92d4ff0, sp);
p->is_function = true;
for(int i=4; i<16; ++i)
p->read_regs |= 1 << i;
InstPost(p);
//allocate space for local variables
local_vars_size = _local_vars_size;
if(local_vars_size)
I2C(SUB, sp, sp, local_vars_size);
}
//----------------------------
virtual void FunctionEnd(){
if(local_vars_size){
I2C(ADD, sp, sp, local_vars_size);
local_vars_size = 0;
}
// ldmfd sp!, { r4 - r11, pc }
S_instruction *p = InstCreate32(0xe8bd8ff0, sp);
for(int i=4;i<16;++i)
p->write_regs |= 1 << i;
InstPost(p);
}
//----------------------------
virtual void CodeBuild();
//----------------------------
virtual void I3C(int code, byte Dest, byte op_1, byte Op2, int constant);
virtual void I3(int code, byte Dest, byte op_1, byte Op2);
virtual void I3S(int code, byte Dest, byte op_1, byte Op2, E_SHIFT_TYPE ShiftType, int Shift);
virtual void I4(int code, byte Dest, byte op_1, byte Op2, byte Op3);
virtual void IConst(byte Dest, int constant);
virtual void I2(int code, byte Dest, byte op_1);
virtual void I2C(int code, byte Dest, byte op_1, int constant);
virtual void I1P(int code, byte Dest, void *block, int Ofs);
virtual void I0P(int code, int Cond, void *target);
virtual void MulC(E_REGISTER dst, E_REGISTER src, int constant);
//----------------------------
virtual void *Code(dword fnc_index) const{
if(fnc_index >= dynamic_code.functions.Size())
return NULL;
return dynamic_code.functions[fnc_index];
}
};
//----------------------------
void C_dyn_code_imp::InstInit(){
next_cond = AL;
next_set = false;
next_byte = false;
next_half = false;
next_sign = false;
}
//----------------------------
C_dyn_code_imp::S_instruction *C_dyn_code_imp::InstCreate(const void *code, int code_size, byte write_reg, byte read_reg_1, byte read_reg_2, int read_flags, int write_flags){
S_instruction *p = new(true) S_instruction();
p->read_flags = read_flags;
p->write_flags = write_flags;
p->code_size = code_size;
if(code_size <= (int)sizeof(p->code_small)){
if(code)
p->code_small = *(dword*)code;
}else{
p->code_large = new(true) byte[code_size];
if(code)
MemCpy(p->code_large, code, code_size);
else
MemSet(p->code_large, 0, code_size);
}
StoreReg(p->write_regs, write_reg);
StoreReg(p->read_regs, read_reg_1);
StoreReg(p->read_regs, read_reg_2);
/*
if(write_reg != NONE){
if(write_reg<32)
p->write_regs |= 1 << write_reg;
else
p->write_flags |= 256 << (write_reg-32);
}
if(read_reg_1 != NONE){
if(read_reg_1<32)
p->read_regs |= 1 << read_reg_1;
else
p->read_flags |= 256 << (read_reg_1-32);
}
if(read_reg_2 != NONE){
if(read_reg_2<32)
p->read_regs |= 1 << read_reg_2;
else
p->read_flags |= 256 << (read_reg_2-32);
}
*/
return p;
}
//----------------------------
void C_dyn_code_imp::FreeInstructions(){
for(S_instruction *p = inst_begin; p; ){
S_instruction *q = p;
p = p->next;
if(q->code_large)
delete[] q->code_large;
delete q;
}
inst_begin = NULL;
inst_end = NULL;
}
//----------------------------
bool C_dyn_code_imp::InstReAlloc(S_instruction *p, const S_instruction *realloc){
int Diff = realloc->address - (p->address+8);
int *code = (int*)InstCode(p);
if(((*code >> 25) & 7) == 6){ //wldr,wstr
int Ofs = Diff + p->tag;
int OfsUnsigned = 1;
if(Ofs < 0){
Ofs = -Ofs;
OfsUnsigned = 0;
}
if(*code & 256){
if(Ofs & 3)
Ofs = 256;
else
Ofs >>= 2;
}
if(Ofs < 256){
*code &= ~(1<<23);
*code |= OfsUnsigned<<23;
*code &= ~255;
*code |= Ofs;
return true;
}
//DEBUG_MSG1(-1,T("Realloc failed for wldr,wstr %d"),Ofs);
}else
if(((*code >> 25) & 7) == 5){
//branch
*code &= 0xff000000;
*code |= (Diff >> 2) & ~0xff000000;
return true;
}else
if(((*code >> 25) & 7) == 1){ //add dest,pc,#const
int Shift;
int Ofs = Diff + p->tag;
*code &= ~((15 << 21)|4095);
if(Ofs < 0){
Ofs = -Ofs;
*code |= (SUB << 21);
}else
*code |= (ADD << 21);
for(Shift = 0;Shift<32;Shift+=2){
if (Ofs >= 0 && Ofs <= 255)
break;
Ofs = (Ofs << 2) | ((Ofs >> 30) & 3);
}
if(Ofs >= 0 && Ofs <= 255){
*code |= (Shift << 7) | Ofs;
return true;
}
//DEBUG_MSG1(-1,T("Realloc failed for add dest,pc,#const %d"),Ofs);
}else
if(((*code >> 25) & 7) == 2){ //ldr,str
int Ofs = Diff + p->tag;
int OfsUnsigned = 1;
if(Ofs < 0){
Ofs = -Ofs;
OfsUnsigned = 0;
}
if(Ofs < 4096){
*code &= ~(1<<23);
*code |= OfsUnsigned<<23;
*code &= ~4095;
*code |= Ofs;
return true;
}
//DEBUG_MSG1(-1,T("Realloc failed for ldr,str %d"),Ofs);
}else
if(!*code){
//plain address instantiation
*code = (int)realloc->address;
return true;
}
return false;
}
//----------------------------
void C_dyn_code_imp::IPLD(int *code, byte *dest){
switch(*code){
case PLD:
next_cond = NV; next_byte = true; *code = LDR; *dest = pc; break;
case PLD_PRE:
next_cond = NV; next_byte = true; *code = LDR_PRE; *dest = pc; break;
case PLD_POST:
next_cond = NV; next_byte = true; *code = LDR_POST; *dest = pc; break;
case PLD_PRESUB:
next_cond = NV; next_byte = true; *code = LDR_PRESUB; *dest = pc; break;
case PLD_POSTSUB:
next_cond = NV; next_byte = true; *code = LDR_POSTSUB; *dest = pc; break;
}
}
//----------------------------
#define MODE(x) ((dword)(x) >> 28)
#define MODEMASK ~0xF0000000
void C_dyn_code_imp::I3C(int code, byte Dest, byte op_1, byte Op2, int constant){
S_instruction *p = NULL;
if(MODE(code) == 8 && constant>=0 && constant<8){
p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16) | ((Op2 & 15) << 0) | (constant << 20),
Dest, op_1, Op2, (next_cond != AL)?1:0, 0);
}
InstPost(p);
}
//----------------------------
void C_dyn_code_imp::I3(int code, byte Dest, byte op_1, byte Op2){
if(MODE(code) == 4){
S_instruction *p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 0) | ((op_1 & 15) << 12) | ((Op2 & 15) << 16),
Dest, op_1, Op2, (next_cond != AL)?1:0, 0);
InstPost(p);
}else
if(MODE(code) == 7){
S_instruction *p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16) | ((Op2 & 15) << 0),
Dest, op_1, Op2, (next_cond != AL)?1:0, 0);
InstPost(p);
}else
I3S(code,Dest,op_1,Op2, LSL, 0);
}
//----------------------------
void C_dyn_code_imp::I3S(int code, byte Dest, byte op_1, byte Op2, E_SHIFT_TYPE ShiftType, int Shift){
S_instruction *p = NULL;
//if(Shift == 0)
//ShiftType = LSL;
if(ShiftType == LSL && Shift < 0){
ShiftType = LSR;
Shift = -Shift;
}
if((ShiftType == LSR || ShiftType == ASR) && Shift < 0){
ShiftType = LSL;
Shift = -Shift;
}
if(ShiftType == ROR && Shift < 0)
Shift = Shift & 31;
assert(Shift >= 0 && Shift < 32);
if(code >= 0 && code < 16){
if (code == CMP || code == TST || code == CMN || code == TEQ)
next_set = 1;
p = InstCreate32((next_cond << 28) | (code << 21) | ((next_set?1:0)<<20) |
((op_1==NONE ? r0 : op_1) << 16) | ((Dest==NONE ? r0 : Dest) << 12) | (Shift << 7) | (ShiftType << 5) | (Op2),
Dest, op_1, Op2, (next_cond != AL)?1:0, next_set?1:0);
}
if (Shift == 0){
if (code == MUL && Dest != op_1){
p = InstCreate32((next_cond << 28) | ((next_set?1:0)<<20) |
(Dest << 16) | (Op2 << 8) | 0x90 | (op_1),
Dest, op_1, Op2, (next_cond != AL)?1:0, next_set?1:0);
}
if (code >= QADD && code <= QDSUB){
p = InstCreate32((next_cond << 28) |
(Dest << 12) | (op_1) | (Op2 << 16) | (0x5 << 4) | (1<<24) | ((code-QADD)<<21),
Dest, op_1, Op2, (next_cond != AL)?1:0, next_set?1:0);
}
}
IPLD(&code, &Dest);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -