/*
Armator - simulateur de jeu d'instruction ARMv5T à but pédagogique
Copyright (C) 2011 Guillaume Huard
Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon les
termes de la Licence Publique Générale GNU publiée par la Free Software
Foundation (version 2 ou bien toute autre version ultérieure choisie par vous).
Ce programme est distribué car potentiellement utile, mais SANS AUCUNE
GARANTIE, ni explicite ni implicite, y compris les garanties de
commercialisation ou d'adaptation dans un but spécifique. Reportez-vous à la
Licence Publique Générale GNU pour plus de détails.
Vous devez avoir reçu une copie de la Licence Publique Générale GNU en même
temps que ce programme ; si ce n'est pas le cas, écrivez à la Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
États-Unis.
Contact:
Guillaume.Huard@imag.fr Bâtiment IMAG
700 avenue centrale, domaine universitaire
38401 Saint Martin d'Hères
*/
#include "arm_data_processing.h"
#include "arm_exception.h"
#include "arm_constants.h"
#include "arm_branch_other.h"
#include "util.h"
#include "debug.h"
/* Decoding functions for different classes of instructions */
int arm_data_processing_shift(arm_core p, uint32_t ins) {
if((get_bit(ins,4) == 1) && (get_bit(ins,7) == 1))
return arm_load_store(p,ins);
else
return traitement(p,ins);
}
int arm_data_processing_immediate_msr(arm_core p, uint32_t ins) {
return UNDEFINED_INSTRUCTION;
}
/*Fonction qui donne la valeur de Shift_val : cas valeur immédiate / cas registre */
uint32_t shiftval(arm_core p, uint32_t ins, int *shifter_carry_out){
uint32_t rotate_imm;
uint32_t I;
uint32_t Cflag = 0;
uint32_t CPSRflag = 0;
CPSRflag = read_cpsr(p); // On récupère CPSR
Cflag = get_bit(CPSRflag,C) // On récupère le flag C de CPSR
rotate_imm = get_bits(ins,11,8);
I = get_bits(ins,25);
if (I == 1){ //Valeur immédiate
//??? shifter_operand = immed_8 Rotate_Right (rotate_imm * 2)
if (rotate_imm == 0){
shifter_carry_out = Cflag;
}
else {
shifter_carry_out = get_bits(shifter_operand,31);
}
return shifter_operand;
}
else if (I == 0){ //Registre
if(((ins >> 4)& 1)== 0){ //immediate shifts
shift = get_bits(ins,6,5);
shift_imm = get_bits(ins,11,7);
}
else if (((ins >> 4)& 1)!= 0) { //register shifts
}
}
}
/* TRAITEMENT INSTRUCTIONS DE TRAITEMENT DE DONNÉES */
int traitement(arm_core p, unint32_t ins){
int Rn, Rd;
uint32_t Rn_val, Rd_val;
int S, I, code_op;
int shifter_carry_out;
S = get_bits(ins,20);
I = get_bits(ins,25);
code_op = get_bits(ins,24,21);
Rn = get_bits(ins,19,16);
Rn_val = read_register(p,Rn);
Rd = get_bits(ins,15,12);
Rd_val = read_register(p,Rd);
Shift_val = shiftval(p, ins, &shifter_carry_out)
if (code_op == AND){
Rd_val = Rn_val & Shift_val;
}
else if (code_op == EOR){
Rd_val = Rn_val ^ Shift_val;
}
else if (code_op == SUB){
Rd_val = Rn_val - Shift_val;
}
else if (code_op == RSB){ //reverse SUB
Rd_val = Shift_val - Rn_val;
}
else if (code_op == ADD){
Rd_val = read_register(p,Rn) + Shift_val;
}
else if (code_op == ADC){ //ADD + Carry
Rd_val = read_register(p,Rn) + Shift_val + get_bits(cpsr, C);
}
else if (code_op == SBC){ //SUB + Carry
Rd_val = read_register(p, Rd) - Shift_val - !(get_bit(cpsr, C));
}
else if (code_op == RSC){ // Reverse SUB + Carry
Rd_val = Shift_val - read_register(p, Rn) - !(get_bit(cpsr, C));
}
else if (code_op == TST){
}
else if (code_op == TEQ){
}
else if (code_op == CMP){
}
else if (code_op == CMN){
}
else if (code_op == ORR){
}
else if (code_op == MOV){
}
else if (code_op == BIC){
}
else if (code_op == MVN){
}
/* Tester si on est dans un cas ou il faut mettre à jour CPSR */
if (S == 1){
cpsr_maj(p,code_op,Rn,Rn_val,Rd,Rd_val,Shift_val);
}
}