AccueilAccueil  Dernières imagesDernières images  RechercherRechercher  S'enregistrerS'enregistrer  ConnexionConnexion  
Le Deal du moment :
Jeux, jouets et Lego : le deuxième à ...
Voir le deal

 

 [JOUR 6] Suite du codage des fonctions Data-Processing etc...

Aller en bas 
2 participants
AuteurMessage
Manael
Lama Impérial
Manael



[JOUR 6] Suite du codage des fonctions Data-Processing etc... Empty
MessageSujet: [JOUR 6] Suite du codage des fonctions Data-Processing etc...   [JOUR 6] Suite du codage des fonctions Data-Processing etc... EmptyLun 8 Jan - 16:19

Yo !

On a vu avant les fonctions de data processing, d'autres fonctions annexes ont été implémentés pour factoriser les calculs :

set_ZNCV_CPSR(arm_core p, uint32_t Zbit, uint32_t Nbit, uint32_t Cbit, uint32_t Vbit) :
Permet de modifier les Flags du CPSR par les flags donnés en paramètre. ON EST PAS OBLIGE DE CHANGER TOUS LES FLAGS ! Mettez une valeur au pif (je choisis toujours 9 moi.) si vous voulez pas changer le flag.
Exemple : set_ZNCV_CPSR(p, 0, 1, 9, 9) permet d'ignorer C et V.


int carry_from(uint32_t op1, uint32_t op2) : Prend 2 opérandes en paramètre et retourne 1 si il y a une retenue sortante (utile pour le C flag), 0 sinon.

borrow_from(uint32_t op1, uint32_t op2) : (A CONFIRMER) Utile pour le C flag.

overflow_from(uint32_t op1, uint32_t op2, uint8_t operation) : Permet de voir si l'opération (avec des opérandes SIGNES) émet un dépassement. Utile pour le V flag.Il retourne 1 si il y a un dépassement, 0 sinon.

void Is_S(arm_core p, uint32_t ins, int Cbit, int Vbit) : Regarde la valeur de S et modifie les flags si celui-ci est à 1. Il n'est important QUE dans les opérateurs qui modifient les flags de façon facultatif (ADD, AND, ORR, MOV etc...).
Les opérateurs de test (TST, TEQ, CMP, CMN) ignorent cette fonction car ils modifient obligatoirement les flags.

uint32_t shiftval(arm_core p, uint32_t ins, int *shifter_carry_out) : Permet d'extraire la valeur du shifter_operand, en prenant en compte si c'est un registre ou une valeur immédiate, les rotations etc... Voir la suite.

--------------------------------------------------------------------------------------------------------------------------


Dernière édition par Manael le Mar 9 Jan - 16:10, édité 2 fois
Revenir en haut Aller en bas
Elisagh
Petit Lama de la Cambrousse




[JOUR 6] Suite du codage des fonctions Data-Processing etc... Empty
MessageSujet: Re: [JOUR 6] Suite du codage des fonctions Data-Processing etc...   [JOUR 6] Suite du codage des fonctions Data-Processing etc... EmptyLun 8 Jan - 19:05

Code:

#include "arm_data_processing.h"
#include "arm_exception.h"
#include "arm_constants.h"
#include "arm_branch_other.h"
#include "arm_load_store.h"
#include "util.h"
#include "debug.h"

#define AND 0x00
#define EOR 0x01
#define SUB 0x02
#define RSB 0x03
#define ADD 0x04
#define ADC 0x05
#define SBC 0x06
#define RSC 0x07
#define TST 0x08
#define TEQ 0x09
#define CMP 0x0A
#define CMN 0x0B
#define ORR 0x0C
#define MOV 0x0D
#define BIC 0x0E
#define MVN 0x0F


int traitement(arm_core p, uint32_t ins);
uint8_t overflow_from(uint32_t op1, uint32_t op2, uint8_t operation);
uint8_t carry_from(uint32_t op1, uint32_t op2);
uint8_t borrow(uint32_t op1, uint32_t op2);

//----------------------------------------------------------------------------------------------------//
/* 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_op : cas valeur immédiate / cas registre */
uint32_t shiftval(arm_core p, uint32_t ins, int *shifter_carry_out)

   uint32_t rotate_imm, shifter_operand, immed_8;
   uint32_t I;
   uint32_t shift,shift_imm,Rs;
   uint32_t Rm,Rm_val;
   uint32_t Rs_val8, Rs_val5;
   uint32_t Cflag = 0;
   uint32_t CPSRflag = 0;

   if (shifter_carry_out != NULL) {
   CPSRflag = arm_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);
   immed_8 = get_bits(ins,7,0);
   I = get_bit(ins,25);
   Rm = get_bits(ins,3,0);
   Rm_val = arm_read_usr_register(p,Rm);

   //[Valeur immédiate]//
   if (I == 1){
      shifter_operand = ror(immed_8, (rotate_imm * 2));
      if (shifter_carry_out != NULL) {
         if (rotate_imm == 0){
            *shifter_carry_out = Cflag;
         }
         else {
            *shifter_carry_out = get_bit(shifter_operand,31);   
         }
      }      
      return shifter_operand;
   }
   //[Registre]//
   else if (I == 0){
      //immediate shifts <=> bit 4 à 0
      if(((ins >> 4)& 1)== 0){
         shift = get_bits(ins,6,5);
         shift_imm = get_bits(ins,11,7);         

         if (shift == 00){ //LSL
            if (shift_imm == 0){
               shifter_operand = Rm;
               *shifter_carry_out = Cflag;
            }
            else if (shift_imm > 0){
               shifter_operand = Rm << shift_imm;
               *shifter_carry_out = get_bit(Rm_val,(32 - shift_imm));
            }
         }

         else if (shift == 01){ //LSR
            if (shift_imm == 0){
               shifter_operand = 0;
               *shifter_carry_out = get_bit(Rm_val,31);
            }
            else if (shift_imm > 0){
               shifter_operand = Rm_val >> shift_imm;
               *shifter_carry_out = get_bit(Rm_val,(shift_imm - 1));
            }
         }

         else if (shift == 10){ //ASR
            if (shift_imm == 0){
               if (get_bit(Rm_val,31) == 0){
                  shifter_operand = 0;
                  *shifter_carry_out = get_bit(Rm_val,31);
               }
               else if (get_bit(Rm_val,31) == 1){
                  shifter_operand = 0xFFFFFFFF;
                  *shifter_carry_out = get_bit(Rm_val,31);
               }
            }
            else if (shift_imm > 0){
               shifter_operand = asr(Rm_val,(uint8_t)shift_imm);
               *shifter_carry_out = get_bit(Rm_val,(shift_imm - 1));
            }
         }

         else if (shift == 11){ //ROR
            if (shift_imm == 0){
               shifter_operand = (Cflag << 31) | (Rm_val >> 1);
               *shifter_carry_out = get_bit(Rm_val,0);
            }
            else {
               shifter_operand = ror(Rm_val,shift_imm);
               *shifter_carry_out = get_bit(Rm_val,(shift_imm - 1));
            }
         }

      return shifter_operand;   
      
      }
      
      
      //register shifts <=> bit 4 à 1
      else if (((ins >> 4)& 1)!= 0) {
         shift = get_bits(ins,7,5);
         Rs = get_bits(ins,11,8);
         Rs_val8 = arm_read_usr_register(p,Rs) & 0xFF; // récupérer les 8 premiers bits de Rs
         Rs_val5 = arm_read_usr_register(p,Rs) & 0x1F; // récupérer les 5 premiers bits de Rs

         if (shift == 000){ //LSL
            if (Rs_val8 == 0){
               shifter_operand = Rm_val;
               *shifter_carry_out = Cflag;
            }
            else if (Rs_val8 < 32){
               shifter_operand = Rm_val << Rs_val8;
               *shifter_carry_out = get_bit(Rm_val,(32 - Rs_val8));
            }
            else if (Rs_val8 == 32){
               shifter_operand = 0;
               *shifter_carry_out = get_bit(Rm_val,0);
            }
            else if (Rs_val8 > 32){
               shifter_operand = 0;
               *shifter_carry_out = 0;
            }            
         }
         
         else if (shift == 001){ //LSR
            if (Rs_val8 == 0){
               shifter_operand = Rm_val;
               *shifter_carry_out = Cflag;
            }
            else if (Rs_val8 < 32){
               shifter_operand = Rm_val >> Rs_val8;
               *shifter_carry_out = get_bit(Rm_val,(Rs_val8 - 1));
            }
            else if (Rs_val8 == 32){
               shifter_operand = 0;
               *shifter_carry_out = get_bit(Rm_val,31);
            }
            else if (Rs_val8 > 32){
               shifter_operand = 0;
               *shifter_carry_out = 0;
            }
         }
         
         
         else if (shift == 010){ //ASR
            if (Rs_val8 == 0){
               shifter_operand = Rm_val;
               *shifter_carry_out = Cflag;
            }
            else if (Rs_val8 < 32){
               shifter_operand = asr(Rm_val, (uint8_t)Rs_val8);
               *shifter_carry_out = get_bit(Rm_val,(Rs_val8 - 1));
            }
            else if (Rs_val8 >= 32){
               if (get_bit(Rm_val,31) == 0){
                  shifter_operand = 0;
                  *shifter_carry_out = get_bit(Rm_val,31);
               }
               else if(get_bit(Rm_val,31) == 1){
                  shifter_operand = 0xFFFFFFFF;
                  *shifter_carry_out = get_bit(Rm_val,31);
               }
            }
         }
         
         
         
         else if (shift == 011){ //ROR
            if (Rs_val8 == 0){
               shifter_operand = Rm_val;
               *shifter_carry_out = Cflag;
            }
            else if (Rs_val5 == 0){
               shifter_operand = Rm_val;
               *shifter_carry_out = get_bit(Rm_val,31);
            }
            else if (Rs_val5 > 0){
               shifter_operand = ror(Rm_val, Rs_val5);
               *shifter_carry_out = get_bit(Rm_val,(Rs_val5 - 1));
            }
         }
         return shifter_operand;   
      }
      
   }
   return 0; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
//----------------------------------------------------------------------------------------------------//
/*  TRAITEMENT INSTRUCTIONS DE TRAITEMENT DE DONNÉES  */
int traitement(arm_core p, uint32_t ins){
   int Rn, Rd;
   uint32_t Rn_val, Rd_val,Shift_op;
   int S, code_op;
   int shifter_carry_out;
   uint32_t CPSRflag = 0;

   S = get_bit(ins,20);
   //I = get_bit(ins,25);
   code_op = get_bits(ins,24,21);

   Rn = get_bits(ins,19,16); //La 1ère opérande (un registre)
   Rn_val = arm_read_register(p,Rn);

   Rd = get_bits(ins,15,12); //Le registre résultat
   Rd_val = arm_read_register(p,Rd);

   Shift_op = shiftval(p, ins, &shifter_carry_out);

   CPSRflag = arm_read_cpsr(p); // On récupère CPSR


   if (code_op == AND){
      Rd_val = Rn_val & Shift_op;
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | ((get_bit(Rd_val,31)) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         CPSRflag = (CPSRflag & ~(1 << C)) | ((shifter_carry_out) << C);
         // flag V (UNAFFECTED)
      }
   }

   else if (code_op == EOR){
      Rd_val = Rn_val ^ Shift_op;
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | (get_bit(Rd_val,31) << N);
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         CPSRflag = (CPSRflag & ~(1 << C)) | ((shifter_carry_out) << C);
         // flag V (UNAFFECTED)
      }
   }

   else if (code_op == SUB){
      Rd_val = Rn_val - Shift_op;
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }   
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | ((get_bit(Rd_val,31)) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         if (!(borrow(Rn_val, Shift_op))) {
            arm_write_cpsr(p, set_bit(CPSRflag, C));            
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, C));
         }
         // flag V
         if (overflow_from (Rn_val, Shift_op, 0)){
            arm_write_cpsr(p, set_bit(CPSRflag, V));
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, V));
         }
         
      }
   }

   else if (code_op == RSB){ //(reverse SUB)
      Rd_val = Shift_op - Rn_val;
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }   
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | ((get_bit(Rd_val,31)) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         if (!(borrow(Shift_op, Rn_val))){
            arm_write_cpsr(p, set_bit(CPSRflag, C));            
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, C));
         }
         // flag V
         if (overflow_from (Shift_op,Rn_val,0)){
            arm_write_cpsr(p, set_bit(CPSRflag, V));
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, V));
         }
         
      }
   }

   else if (code_op == ADD){
      Rd_val = Rn_val + Shift_op;
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }   
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | ((get_bit(Rd_val,31)) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         if (carry_from(Rn_val, Shift_op)){
            arm_write_cpsr(p, set_bit(CPSRflag, C));            
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, C));
         }
         // flag V
         if (overflow_from (Rn_val, Shift_op, 1)){
            arm_write_cpsr(p, set_bit(CPSRflag, V));
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, V));
         }
         
      }   
   }

   else if (code_op == ADC){ //(ADD + Carry)
      Rd_val = Rn_val + Shift_op + get_bit(CPSRflag, C);
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | ((get_bit(Rd_val,31)) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         if (carry_from(Rn_val, (Shift_op + get_bit(CPSRflag, C)))){
            arm_write_cpsr(p, set_bit(CPSRflag, C));            
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, C));
         }
         // flag V
         if (overflow_from (Rn_val, (Shift_op + get_bit(CPSRflag, C)), 1)){
            arm_write_cpsr(p, set_bit(CPSRflag, V));
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, V));
         }
      }
   }

   else if (code_op == SBC){ //(SUB + Carry)
      Rd_val = Rn_val - Shift_op - !(get_bit(CPSRflag, C));
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }   
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | (get_bit(Rd_val,31) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         if (!borrow(Rn_val, (Shift_op +(!get_bit(CPSRflag, C))))){
            arm_write_cpsr(p, set_bit(CPSRflag, C));            
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, C));
         }
         // flag V
         if (overflow_from (Rn_val, (Shift_op +(!get_bit(CPSRflag, C))), 0)){
            arm_write_cpsr(p, set_bit(CPSRflag, V));
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, V));
         }
         
      }
   }

   else if (code_op == RSC){ //(Reverse SUB + Carry)
      Rd_val = Shift_op - Rn_val - !(get_bit(CPSRflag, C));
      if ((S == 1) && (Rd == 15)){
         if (arm_current_mode_has_spsr(p)){
            arm_write_cpsr(p, arm_read_spsr(p));
         }
         else{
            //UNPREDICTABLE
         }
      }   
      else if (S==1){
         // flag N   
         CPSRflag = (CPSRflag & ~(1 << N)) | ((get_bit(Rd_val,31)) << N );
         // flag Z
         if (Rd_val == 0){
            arm_write_cpsr(p, set_bit(CPSRflag, Z));   
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, Z));
         }
         // flag C
         if (!borrow(Shift_op, (Rn_val +(!get_bit(CPSRflag, C))))){
            arm_write_cpsr(p, set_bit(CPSRflag, C));            
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, C));
         }
         // flag V
         if (overflow_from (Shift_op, (Rn_val +(!get_bit(CPSRflag, C))), 0)){
            arm_write_cpsr(p, set_bit(CPSRflag, V));
         }
         else {
            arm_write_cpsr(p, clr_bit(CPSRflag, V));
         }
         
      }
   }

   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){
   }

   else {
      return UNDEFINED_INSTRUCTION;
   }
   return 0; /////////////////////////////////////////////////////////////////;
}
   
   
//----------------------------------------------------------------------------------------------------//
/* GESTION DE CARRY */
   uint8_t carry_from(uint32_t op1, uint32_t op2){ 
      uint64_t resultat;
      resultat = op1 + op2;
      return get_bit(resultat,32);      
   }
   
   uint8_t borrow(uint32_t op1, uint32_t op2){
      if(op1-op2 < 0)
         return 1;
      return 0;
   }
   
//----------------------------------------------------------------------------------------------------//
/*GESTION DE OVERFLOW, operation = 1 si c'est une addition, 0 si c'est une soustraction */
/* cas d'une addition : overflow si les 2 opérandes sont de même signe, mais le resultat de signe différent */
/* cas d'un soustraction : overflow si les 2 opérandes sont de signes différents et le résultat de signe différent de l'opérande de gauche */
   uint8_t overflow_from(uint32_t op1, uint32_t op2, uint8_t operation){
      uint32_t resultat;
      if (operation == 1){
         resultat = op1 + op2;
         if (get_bit(op1,N) == get_bit(op2,N)){
            if (get_bit(op1,N) != get_bit(resultat,N)){
               return 1;
            }
            else {
               return 0;
            }
         }
         else {
            return 0;
         }
      }
      else {
         resultat = op1 - op2;
         if (get_bit(op1,N) != get_bit(op2,N)){
            if (get_bit(op1,N) != get_bit(resultat,N)){
               return 1;
            }
            else {
               return 0;
            }
         }
         else {
            return 0;
         }
      }
      
   }
Revenir en haut Aller en bas
 
[JOUR 6] Suite du codage des fonctions Data-Processing etc...
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» [JOUR 5] Suite de Data-Processing etc...
» [JOUR 4] Réalisation des fonctions (Data-Processing, Branchement et Load/store)
» [JOUR 3] Traitement d'une instruction (SUITE)
» [JOUR 7] Débuggage
» [JOUR 2] Traitement d'une instruction

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
GP-12 :: Organisation :: Planning-
Sauter vers: