Exemplo n.º 1
0
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);
	}

	
	
}
Exemplo n.º 2
0
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);
	}
}
Exemplo n.º 3
0
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;

}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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");
	}
}
Exemplo n.º 7
0
int pop (Instruction ins, Emulator* emul) {
	

	int t;
	int i;
	long registers;
	vaddr32 adress;


	if (ins.encoding == 1 ) {
		if (pop_T1 (ins, &registers)) {
			return 1;
		}
	}

	else if (ins.encoding == 2 ) {
		if (pop_T2 (ins, &registers)) {
			return 1;
		}
	}
	
	else if (ins.encoding == 3 ) {
		if (pop_T3 (ins, &registers, &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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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);
	}
	


}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
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;
}