void b_t4(int i) { /* I1 = NOT(J1 EOR S); I2 = NOT(J2 EOR S); imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); if InITBlock() && !LastInITBlock() then UNPREDICTABLE; if ConditionPassed() then EncodingSpecificOperations(); BranchWritePC(PC + imm32); */ int imm32,i1,i2; *((int *)(&branch)) = i; i1=!(branch.j1^branch.s); i2=!(branch.j2^branch.s); imm32=(branch.s<<24)|(i1<<23)+(i2<<22)|(branch.off2<<12)|(branch.off1<<1); imm32 &= 0xFFFFFFFE; //SignExtend if(imm32 & 0x01000000) imm32 |= 0xFE000000; else imm32 &= 0x01FFFFFF; if(InITBlock() && !LastInITBlock()) printf("UNPREDICTABLE instruction.\n"); else{ EncodingSpecificOperations(); BranchWritePC(get_pc()+imm32); } }
void bl(int i) { /* I1 = NOT(J1 EOR S); I2 = NOT(J2 EOR S); imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); if InITBlock() && !LastInITBlock() then UNPREDICTABLE; if ConditionPassed() then EncodingSpecificOperations(); next_instr_addr = PC; LR = next_instr_addr<31:1> : '1'; SelectInstrSet(InstrSet_Thumb); BranchWritePC(PC + imm32); */ int i1,i2,imm32,next_instr_addr; *((int *)(&branchWithLink)) = i; i1=!(branchWithLink.j1^branchWithLink.s); i2=!(branchWithLink.j2^branchWithLink.s); imm32=(branchWithLink.s<<24)|(i1<<23)|(i2<<22)|(branchWithLink.off2<<12)|(branchWithLink.off1<<1); imm32 &= 0xFFFFFFFE; //SignExtend if(imm32 & 0x01000000) imm32 |= 0xFE000000; else imm32 &= 0x01FFFFFF; if(InITBlock() && !LastInITBlock()) printf("UNPREDICTABLE instruction.\n"); else{ EncodingSpecificOperations(); next_instr_addr=get_pc(); set_lr(next_instr_addr | 0x00000001); //SelectInstrSet(InstrSet_Thumb); questionhi BranchWritePC(get_pc()+imm32); } }
int bl (Instruction ins, Emulator* emul) { long next_instr_addr; //int targetInstrSet = CurrentInstrSet(); long imm32; imm32 = ins.imm.plages[0].value; if ( ins.encoding == 1 ) { if ( bl_T1 (ins, &imm32) ) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } printf ("pc avant : %lx\n" , emul->reg[15]); next_instr_addr = emul->reg[15]; next_instr_addr = next_instr_addr & 0xFFFFFFFE; emul->reg[14] = next_instr_addr | 0x00000001; printf("pc : %lx\t pc + imm32 : %lx\n " , emul->reg[15], emul->reg[15]+imm32); BranchWritePC (emul->reg[15]+imm32, emul); return 0; }
int mov_reg (Instruction ins, Emulator* emul) { int d, m; int setflags = 0; long result; d = ins.reg.plages[0].value; m = ins.reg.plages[1].value; if (ins.encoding == 1 ) { if ( mov_reg_T1 (ins, &setflags, &d)) { return 1; } } else if (ins.encoding == 2 ) { if (mov_reg_T2 (ins, &setflags)) { return 1; } } else if (ins.encoding == 3 ) { if (mov_reg_T3 (ins, &setflags, &d, &m)) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } result = emul->reg[m]; if (d==15) { BranchWritePC (result, emul); //setflags is always false here } else { emul->reg[d] = result; if (setflags) { emul->reg[16] = emul->reg[16] & 0x7FFFFFFF; if (result & (1u << 31) ){ emul->reg[16] = emul->reg[16] | (1u << 31); // APSR.N = 1; } //APSR.Z = IsZeroBit (result); emul->reg[16] = emul->reg[16] & 0xBFFFFFFF; if (IsZeroBit(result)) { emul->reg[16] = emul->reg[16] | (1u << 30); } // APSR.C & APSR.V unchanged } } return 0; }
int ldr_litt (Instruction ins, Emulator* emul) { int t; long imm32, base, address, data; int add; t = ins.reg.plages[0].value; imm32 = ins.imm.plages[0].value; if ( ins.encoding == 1 ) { if ( ldr_litt_T1 (ins, &imm32, &add) ) { return 1; } } else if ( ins.encoding == 2 ) { if (ldr_litt_T2 (ins, &imm32, &t, &add)) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } base = emul->reg[15]; if (add) { address = base + imm32; } else { address = base - imm32; } data = address; if (t==15) { if ((address & (1u << 0)) && (address & (1u << 1))) { WARNING_MSG ("Erreur"); return 1; } else { BranchWritePC (data , emul); } } else { emul->reg[t] = data; } return 0; }
void tbh(int i){ int n,m,halfwords; *((int *)(&TbH)) = i; n = TbH.rn; m = TbH.rm; if(n == 13 || Bad_Reg(m)) printf(" It is unpredictable!"); else if(InITBlock() && !LastInITBlock()) printf(" It is unpredictable!"); else{ halfwords = get_MemU(get_general_register(n) + lsl(get_general_register(m),1),1); halfwords = halfwords << 1; BranchWritePC(get_pc() + halfwords); //printf(" *****tbh"); } }
int pop (Instruction ins, Emulator* emul) { int t; int i; long registers; vaddr32 adress; if (ins.encoding == 1 ) { if (pop_T1 (ins, ®isters)) { return 1; } } else if (ins.encoding == 2 ) { if (pop_T2 (ins, ®isters)) { return 1; } } else if (ins.encoding == 3 ) { if (pop_T3 (ins, ®isters, &t)) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } adress = emul->reg[13]; for (i = 0 ; i<=14 ; i++) { if (registers & (1u << i )) { emul->reg[i] = adress; //MemA(adress, 4); adress = adress +4; } } if (registers & (1u << 15 ) ) { BranchWritePC(adress, emul);//MemA(adress, 4)); } emul->reg[13] = emul->reg[13] + 4*BitCount(registers); return 0; }
int b (Instruction ins, Emulator * emul) { long imm32; int cond; imm32 = ins.imm.plages[0].value; cond = ins.ext.plages[0].value; if ( ins.encoding == 1 ) { if ( b_T1 (ins, &cond, &imm32)) { return 1; } } else if ( ins.encoding == 2 ) { if (b_T2 (ins, &imm32)) { return 1; } } else if ( ins.encoding == 3 ) { } else if (ins.encoding == 4 ) { if( b_T4 (ins, &imm32)) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } if (condition (cond, emul)) { BranchWritePC(emul->reg[15] + imm32, emul); } return 0; }
void b_t3(int i) { /* imm32 = SignExtend(S:J2:J1:imm6:imm11:'0', 32); if cond<3:1> == '111' then SEE Branches, miscellaneous control instructions on page A4-30; if InITBlock() then UNPREDICTABLE; if ConditionPassed() then EncodingSpecificOperations(); BranchWritePC(PC + imm32); */ int imm32; *((int*)(&conditionalBranch))=i; imm32=(conditionalBranch.s<<20)|(conditionalBranch.j2<<19)|(conditionalBranch.j1<<18)| (conditionalBranch.off2<<12)|(conditionalBranch.off1<<1); imm32 &= 0xFFFFFFFE; //SignExtend if(imm32 & 0x00100000) imm32 |= 0xFFE00000; else imm32 &= 0x001FFFFF; if(conditionalBranch.cond>=14){ //question? printf("Error!Branch conditonal instruction,con<3:1>=111\n"); return; } else if(InITBlock()) printf("UNPREDICTABLE instruction\n"); else if(ConditionPassed(conditionalBranch.cond)){ EncodingSpecificOperations(); BranchWritePC(get_pc()+imm32); } }
int ldr_imm (Instruction ins, Emulator* emul) { int t,n; long imm32; long offset_addr, address, data; int index, wback, add; imm32 = ins.imm.plages[0].value; if (ins.encoding == 1 ) { if (ldr_imm_T1 (ins, &imm32, &index, &add, &wback, &n, &t)) { return 1; } } else if (ins.encoding == 2 ) { if (ldr_imm_T2 (ins, &imm32, &index, &add, &wback, &n, &t)) { return 1; } } else if (ins.encoding == 3 ) { if ( ldr_imm_T3 (ins, &imm32, &index, &add, &wback, &n, &t)) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } if (add) { offset_addr = emul->reg[n] + imm32; } else { offset_addr = emul->reg[n] - imm32; } if (index) { address = offset_addr; } else { address = emul->reg[n]; } data = address; if (wback) { emul->reg[n] = offset_addr; } if (t==15) { if ( (address & (1u << 0)) && (address & (1u << 1)) ) { return 1; } else { BranchWritePC (data, emul) ; } } else { emul->reg[t] = data; } return 0; }
int sub_reg (Instruction ins, Emulator* emul ) { int n,d,m; int setflags, carry, overflow; long result, shifted; shifted = 0; n = ins.reg.plages[1].value; d = ins.reg.plages[0].value; m = ins.reg.plages[2].value; if ( ins.encoding == 1 ) { if (sub_reg_T1 (ins, &setflags)) { return 1; } } else if (ins.encoding == 2 ) { if (sub_reg_T2 (ins, &setflags, &n, &d, &m, &shifted)) { return 1; } } else { WARNING_MSG ("Cet encodage n'est pas dans le dictionnaire"); return 1; } shifted = emul->reg[m] + shifted; result = AddWithCarry (emul->reg[n] , ~shifted + 1, &carry, &overflow); if (d==15) { BranchWritePC(result, emul); } else { emul->reg[d]=result; if(setflags) { emul->reg[16] = emul->reg[16] & 0x7FFFFFFF; if (result & (1u << 31) ){ emul->reg[16] = emul->reg[16] | (1u << 31); // APSR.N = 1; } //APSR.Z = IsZeroBit (result); emul->reg[16] = emul->reg[16] & 0xBFFFFFFF; if (IsZeroBit(result)) { emul->reg[16] = emul->reg[16] | (1u << 30); } //APSR.C = carry; emul->reg[16] = emul->reg[16] & 0xDFFFFFFF; if (carry) { emul->reg[16] = emul->reg[16] | (1u << 29); } //APSR.V = overflow; emul->reg[16] = emul->reg[16] & 0xEFFFFFFF; if (overflow) { emul->reg[16] = emul->reg[16] | (1u << 28); } } } return 0; }