⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 armia_iacxl10_2004_3_16.cpp

📁 自己编写的ARM处理器的指令集仿真
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "armia_IAcxl10_2004_3_16.h"#include <iostream.h>#include <stdlib.h>#include <stdio.h>#include <assert.h>/*************************************************************************************************************  For IA ISS there is a problem: When a instruct need to read a register and the number is 15(PC),the operand   must be PC+8, because the ARM is a 3_level fluviation struct;but in IA ISS, PC is update after a instruct  being executed completed;So we must keep the PC's vaule while give PC+8 to the instrut which need to read  it;*************************************************************************************************************/void ARMISS_stru::init(){  static int done;  if(!done)    {      for( int i=0;i<=14;i++)          r_gen[i] = 0;      reset();      CPSR.M     = 16;      pc_changed = false;      mas        = 2;      i          = 0;      Emulate    = true;      CPSR.C=CPSR.V=CPSR.Z=CPSR.N=0;      done=1;    }}void ARMISS_stru::reset(){     r_gen[PC]    = 0x0;     nrw          = false;     nirq         = true;     nfiq         = true;     abort        = false;     instruct_reg = (UNL)0;     data_abt     = false;     undef_abt    = false;     irq_ext      = false;     fiq_ext      = false;     prefetch_abt = false;    }void ARMISS_stru::fetch(){     static int i=0;     nrw = false;     (*pmemfun)(r_gen[PC],&data,nrw,2,&abort);     instruct_reg = (unsigned long)data;     if( abort ) instruct_reg = (bool)false;                }//Fetch instructions from memory unit; if abort happend, the instruct is set to be invalid;void ARMISS_stru::decode(){      set_decoder_stru( instruct_reg );      if( instruct_reg.valid )       switch(common_dec.mcoder)     {         case 0: ARM_t0_decode();                 break;         case 1: ARM_t1_decode();                 break;         case 2: ARM_t2_decode();                 break;         case 3: ARM_t3_decode();                 break;         case 4: ARM_t4_decode();                 break;         case 5: ARM_t5_decode();                 break;         case 6: ARM_t6_decode();                 break;         case 7: ARM_t7_decode();                 break;    }    else prefetch_abt = true;  }//First decode - it determine which type the instruct is;int ARMISS_stru::ARM_t0_decode(){     ARM_type0_stru&  tmp = ARM_type0;     if( tmp.b4 == 0 )       {            if( ((tmp.opcode & 0xc) != 0x8) || (tmp.S==1) )                 data_pro_imm_shift_decode();           else               miscell_instr_decode();             return 0;       }     if( (tmp.b4 == 1) && (tmp.b7 == 0) )     {         if( ((tmp.opcode & 0xc) != 0x8) || (tmp.S==1) )             data_pro_reg_shift_decode();          else             miscell_instr_decode();         return 0;     }    if( (tmp.b4 == 1) && (tmp.b7 == 1) )      {         mul_ext_decode();         return 0;      }     }//ARM type 0 - including data-process-immediate shift, miscellaneous instructs,data-process-register shift,//mutiples,extra load/stroe instructs  which can be found from the ARM's reference manual; void ARMISS_stru::data_pro_imm_shift_decode(){        ARM_type0_stru&  tmp   = ARM_type0;         UNL&             r     = getreg(tmp.Rd);        Addressing_mod1( 2 );        oper = getregd( tmp.Rn ) + ( (tmp.Rn==15? 1:0) * 8);//if operand need PC,then return PC+8;        update_flags = ( tmp.S == 1 )? 1:0;        des_reg = tmp.Rd;        if( executable() )         {           switch( tmp.opcode )          {             case  0:  r = AND();                       break;             case  1:  r = EOR();                       break;             case  2:  r = SUB();                       break;             case  3:  r = RSB();                       break;             case  4:  r = ADD();                       break;             case  5:  r = ADC();                       break;             case  6:  r = SBC();                       break;             case  7:  r = RSC();                       break;             case  8:  TST();                       break;             case  9:  TEQ();                       break;             case 10:  CMP();                       break;             case 11:  CMN();                       break;             case 12:  r = ORR();                       break;             case 13:  r = MOV();                       break;             case 14:  r = BIC();                       break;             case 15:  r = MVN();                       break;             default:  break;                                             }   //data process instructs immediate shift;          if( tmp.Rd  == PC ) pc_changed = true;         }}//data-process-immediate shift instructions execute;void ARMISS_stru::data_pro_reg_shift_decode(){        ARM_type0_stru&  tmp   = ARM_type0;         UNL&             r     = getreg(tmp.Rd);        oper = getregd( tmp.Rn ) + ( (tmp.Rn==15? 1:0) * 8);        update_flags = ( tmp.S == 1 )? true:false;        des_reg = tmp.Rd;        Addressing_mod1( 1 );        if( executable() )         {            switch( tmp.opcode )          {             case  0:  r = AND();                       break;             case  1:  r = EOR();                       break;             case  2:  r = SUB();                       break;             case  3:  r = RSB();                       break;             case  4:  r = ADD();                       break;             case  5:  r = ADC();                       break;             case  6:  r = SBC();                       break;             case  7:  r = RSC();                       break;             case  8:  TST();                       break;             case  9:  TEQ();                       break;             case 10:  CMP();                       break;             case 11:  CMN();                       break;             case 12:  r = ORR();                       break;             case 13:  r = MOV();                       break;             case 14:  r = BIC();                       break;             case 15:  r = MVN();                       break;             default:  break;                                             }   //data process instructs immediate shift;          if( tmp.Rd  == PC ) pc_changed = true;        }}void ARMISS_stru::miscell_instr_decode(){       ARM_type0_stru&    tmp = ARM_type0;       UNL&               rd  = getreg( tmp.Rd );       switch( tmp.mis.b7 )     {       case 0 :  if( tmp.mis.b21 == 0 )                   rd = MRS();                 else                  {                    oper = getregd( tmp.mis.Rm);                    MSR();                  }                 break;       case 1 :  if( tmp.mis.op == 1 )                    BX();                 break;       default:  break;     } }void ARMISS_stru::mul_ext_decode(){   ARM_type0_stru&   tmp = ARM_type0;   switch( tmp.mul_ext.b7 )  {     case 9 : switch( tmp.mul_ext.b23 + tmp.mul_ext.b24 )             {               case 0 : if( tmp.mul_ext.A == 1 )                         MLA();                        else                         MUL();                        break;               case 1 : switch( tmp.mul_ext.U1 + tmp.mul_ext.A )                       {                         case 0 : UMULL();                                  break;                         case 1 : UMLAL();                                  break;                         case 2 : SMULL();                                  break;                         case 3 : SMLAL();                                  break;                       }                        break;               case 2 : if( tmp.mul_ext.B == 0 )                              SWP();                        else                              SWPB();                        break;               }               break;     case 11 : if( tmp.mul_ext.L==1)                 LDRH();               else                STRH();               break;      case 15 : if( tmp.mul_ext.S1 == 1 )               LDRSH();               break;   }            }int ARMISS_stru::ARM_t1_decode(){  ARM_type1_stru&  tmp = ARM_type1;  if( (tmp.S==1) || ((tmp.opcode & 0xc)!= 0x8) )        {            data_pro_imm_decode();            return 0;        }  if( tmp.b21 == 2 )        {            oper = rotate_shift(tmp.imm,tmp.rotate*2);            MSR();            return 0;        }  }void ARMISS_stru::data_pro_imm_decode(){      ARM_type1_stru&     tmp = ARM_type1;      UNL&                rd  = getreg( tmp.Rd );          if( executable() )     {      barrel_shifter_rotate_imm(tmp.rotate,tmp.imm);      oper = getregd( tmp.Rn );      if( tmp.Rn == 15 ) oper = oper + 8;      if( tmp.Rd == 15 ) des_reg = 15;      update_flags = (tmp.S == 1)? true:false;      switch( tmp.opcode )      {        case  0:  rd = AND();                  break;        case  1:  rd = EOR();                  break;        case  2:  rd = SUB();                  break;        case  3:  rd = RSB();                  break;        case  4:  rd = ADD();                  break;        case  5:  rd = ADC();                  break;        case  6:  rd = SBC();                  break;        case  7:  rd = RSC();                  break;        case  8:  TST();                  break;        case  9:  TEQ();                  break;        case 10:  CMP();                  break;        case 11:  CMN();                  break;        case 12:  rd = ORR();                  break;        case 13:  rd = MOV();                  break;        case 14:  rd = BIC();                  break;        case 15:  rd = MVN();                  break;        defaults: break;      }      if( tmp.Rd == PC ) pc_changed = true;    }       }int ARMISS_stru::ARM_t2_decode(){   ARM_type2_stru&   tmp = ARM_type2;   UNL               op;   op = (tmp.B << 1) + tmp.L;     switch( op )  {    case 0 : if( (tmp.P==0)&&(tmp.W==1) ) STRT(0);             else                         STR(0);             break;    case 1 : if( (tmp.P==0)&&(tmp.W==1) ) LDRT(0);             else                         LDR(0);             break;    case 2 : STRB(0);             break;    case 3 : if( (tmp.P==0)&&(tmp.W==1) ) LDRBT(0);             else                         LDRB(0);             break;  }   return 0;}int ARMISS_stru::ARM_t3_decode(){    ARM_type3_stru&   tmp = ARM_type3;    UNL               op,code;        code = common_dec.mcoder;    code = (code << 25) + tmp;//用于识别断点指令;  if( common_dec.flags != 0xf )   {     if( tmp.b4 == 0 )     {   op = (tmp.B << 1) + tmp.L;         switch( op )        {          case 0 : STR(1);                   break;          case 1 : LDR(1);                   break;          case 2 : STRB(1);                   break;          case 3 : LDRB(1);                   break;        }             }     else if( code == 0x7ffdefe ) Endcond = 143;          else undef_abt = true;   }  else undef_abt = true;  return 0;}void ARMISS_stru::ARM_t4_decode(){   ARM_type4_stru&  tmp = ARM_type4;   bit32_stru       bit; if( common_dec.flags != 0xf )  {   if( tmp.L == 1 )   {      if( tmp.S==0)  LDM1();       else      {        bit = tmp.reg_list;        if( bit[15] == 0 ) LDM2();         else               LDM3();       }   }   else      {        if( tmp.S == 0 ) STM1();        else             STM2();      }  }  else undef_abt = true;   }void ARMISS_stru::ARM_t5_decode(){    BL();}void ARMISS_stru::ARM_t6_decode(){    ARM_type6_stru&   tmp = ARM_type6;    if( tmp.L == 1 ) LDC();    else             STC();}void ARMISS_stru::ARM_t7_decode(){  ARM_type7_stru&  tmp = ARM_type7;  if( common_dec.flags != 0xf )      {          if( tmp.b24 == 1 )            SWI();         else if( tmp.b4 == 0 )                 CDP();              else                {                  if( tmp.L == 0 ) MCR();                  else             MRC();               }                  }     else       undef_abt = true;}UNL ARMISS_stru::AND(){     long rst;          rst = oper & shifter.operand ;             if( ( update_flags ) && ( des_reg==PC ) )            {              if( getid() != -1 )                 CPSR = SPSR[getid()];            }     else if ( update_flags )         {             CPSR.N = rst >> 31;             CPSR.Z = ( rst == 0 )? 1 : 0;             CPSR.C = shifter.carry_out;        }     return ( rst );}UNL ARMISS_stru::EOR(){     long rst;          rst = oper ^ shifter.operand ;     if( ( update_flags ) && ( des_reg == PC ) )               CPSR = SPSR[getid()];     else if ( update_flags )         {             CPSR.N = rst >> 31;             CPSR.Z = ( rst == 0 )? 1 : 0;             CPSR.C = shifter.carry_out;        }     return ( rst );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -