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

📄 decoder.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
                  break;               case mfc_op:               case dmfc_op:                  /* Destination of mfc, dmtc is RT, not RD (kind of silly)*/                  thisGrp->no_reg_allocate = 1;                  if( Delayed )                     thisGrp->delay_slot_reg_conflict |=                         ((rt(code)==ctl_reg1) || (rt(code)==ctl_reg2) );                  break;               case cfc_op:                  break;               case bc_op:                  thisGrp->delay_slot_reg_conflict = 1;                  ctl_inst = 1;                  /* Relies on no integer registers */                  break;               default:                  /*arithmetic instruction s*/                  break;               }                  break;         case j_op:         case jal_op:            ctl_inst = 1;            /* No registers */            break;        case beq_op:        case bne_op:        case blez_op:        case bgtz_op:        case beql_op:        case bnel_op:        case blezl_op:        case bgtzl_op:          thisGrp->reg2alloc[rs(code)].num_src++;          thisGrp->reg2alloc[rt(code)].num_src++;          ctl_inst = 1;          ctl_reg1 = rs(code)?rs(code):REG_NONE;          ctl_reg2 = rt(code)?rt(code):REG_NONE;          break;        case addi_op:       /* rs op imm -> rt */        case addiu_op:        case andi_op:        case ori_op:        case slti_op:        case sltiu_op:        case xori_op:        case daddi_op:             case daddiu_op:          thisGrp->reg2alloc[rs(code)].num_src++;          if( Delayed )             thisGrp->delay_slot_reg_conflict |=                 ((rt(code)==ctl_reg1) || (rt(code)==ctl_reg2) );          break;        case lui_op:    /* immed<<16 -> rt */          if( Delayed )             thisGrp->delay_slot_reg_conflict |=                 ((rt(code)==ctl_reg1) || (rt(code)==ctl_reg2) );          break;        case ld_op:#if defined(SIM_MIPS32) && defined(DO_WARNING)           CPUWarning("Hacked LD inst found at 0x%x\n", thisGrp->virt_pc); #endif        case lld_op:        case ldc2_op:        case ll_op:        case lb_op:        case lbu_op:        case lw_op:        case lh_op:        case lhu_op:        case lwl_op:        case lwr_op:        case lwu_op:        case ldl_op:        case ldr_op:          thisGrp->reg2alloc[rs(code)].num_src++;          thisGrp->numDMemoryAcesses++;          if( Delayed )             thisGrp->delay_slot_reg_conflict |=                 ((rt(code)==ctl_reg1) || (rt(code)==ctl_reg2) );          break;        case sc_op:         case scd_op:           /* In page mode, sc calls compare and swap which uses temp regs */           if( embra.emode == EMBRA_PAGE )              thisGrp->no_reg_allocate = 1;           /*FALLTHROUGH */        case sd_op:#if defined(SIM_MIPS32) && defined(DO_WARNING)           CPUWarning("Hacked SD inst found at 0x%x\n", thisGrp->virt_pc); #endif        case sdc2_op:        case sb_op:        case sh_op:        case sw_op:        case swl_op:        case swr_op:        case sdl_op:        case sdr_op:          thisGrp->reg2alloc[rs(code)].num_src++;          thisGrp->reg2alloc[rt(code)].num_src++;          thisGrp->numDMemoryAcesses++;          break;        case lwc1_op:        case ldc1_op:          thisGrp->reg2alloc[rs(code)].num_src++;          thisGrp->numDMemoryAcesses++;          break;        case swc1_op:        case sdc1_op:          thisGrp->reg2alloc[rs(code)].num_src++;          thisGrp->reg2alloc[rt(code)].num_src++;          thisGrp->numDMemoryAcesses++;          break;         case mendel_tns:            thisGrp->no_reg_allocate = 1;            /* This instruction is (and should be) never in the delay slot */            /* but to be safe.. */            /* Because these functions callout & write the register file */            /* we have to treat them as contenders for the ctl_instr               registers */             if( Delayed )               thisGrp->delay_slot_reg_conflict= 1;            break;         case cache_op:            thisGrp->numDMemoryAcesses++;            break;        default:          ; /*nothing*/        }      /* Finished if that was the instruction in the delay slot */      if (Delayed)        break;      /*  Reached the end of group when hit the control flow, or a          page boundary */       if( ctl_inst ) {		 Delayed = 1;		 if( thisGrp->GrpLen == maxInGroup )            {			   /* We have just deocoded an instruction whose delay slot */			   /* will not fit in this instruction group.  Therefore, */			   /* erase the knowledge of this instruction in this */			   /* instruction group, so the decoder sees this as a */			   /* sequential flow */			   thisGrp->GrpLen--;			   break;            }	  }      /* XXX - This is a VERY hairy corner case */      /* When we hit a physical page boundary, we need to see if our */      /* virtual pc is in KSEG0.  If it is not, then we need to translate */      /* the next address because code contiguous in virtual address */      /* space, is not necessarily contiguous in physical address */      /* space (exactly at the page boundary).  So we translate at the */      /* next PC which is calculated by "raising" the virtual PC to */      /* the first entry on the next (virtual) page.  Note that this */      /* wouldn't work if our basic block were over a page, but */      /* maxInGroup insures us that that can't happen. */      /* Also note that we are telling TranslateVirtual that this */      /* request is coming from the virtual address at the start of */      /* the basic block.  That way, we return to the block (which we */      /* want to do because we have not yet translated it).  This */      /* means that exectuting one instruction can cause an exception */      /* fiarly far downstream, even though none of the intervening */      /* instructions have been executed.*/      /*        * To make things even hairier, we now oly straddle pages if       * the last instruction on the first page is a control flow instruction.       * Otherwise, we split the BB at page boundaries. Raising exceptions       * at translation must be avoided whenever possible. In the case where       * this is not possible (branch at end of page and delay slot in next page)       * we DO raise the exception at translation time, but emit the page       * residency check at the same place during the execution of the translated       * BB.       *        * This only applies to user code. Kernel BB may still straddle pages       * as the kernel text is in kseg0.        * (bugnion)       */            if (PAGE_BOUNDARY((unsigned) code_ptr) && !IS_KSEG0(thisGrp->virt_pc)) {                  PA pAddr;          VA next_page_pc;         uint tvRes;         if (!Delayed)             break;         next_page_pc = NEXT_PAGE(thisGrp->virt_pc);         tvRes = Em_TranslateVirtual(cpuNum,                                     next_page_pc,                                     &pAddr,                                     ACT_IREAD);         if( tvRes == EXCEPTION_CODE ) {#if 0            CPUWarning("Embra: decoder exception: 0x%x at %10lld \n",                      thisGrp->virt_pc,                        (uint64)EmbraCpuCycleCount(0)); #endif            ReenterTC(&EMP[cpuNum]);            /* NOT REACHED */         }         code_ptr = (unsigned*) PHYS_TO_MEMADDR(M_FROM_CPU(cpuNum), pAddr);         ASSERT( EMBRA_IS_MEMADDR( M_FROM_CPU(cpuNum), code_ptr ) );         thisGrp->next_maPC = (MA)code_ptr;         thisGrp->next_phys_pc = pAddr;      }    }  /*   * Test for the presence of an 'unusual' number   * of NOPS in the translated BB. Usually a good sign   * fo beign in hyperspace.    */  for(i=0;i<thisGrp->GrpLen-MAX_NOPS;i++) {     int j=0;     while(j < MAX_NOPS && !thisGrp->instrs[j]) {        j++;     }     if (j==MAX_NOPS) {         CPUError("EMBRA translating %d NOPs at cpu=%d PC=%#x mAddr=%#x \n",                 MAX_NOPS,thisGrp->cpuNum,thisGrp->virt_pc,thisGrp->maPC);     }  }  /* Add  Icache references */  thisGrp->numIMemoryAcesses = thisGrp->GrpLen;#ifdef DEBUG_TRANSLATOR  {	 extern unsigned trans_test_num_decoded;	 trans_test_num_decoded = thisGrp->GrpLen;  }#endif}int IsCtlInstr(uint inst){   int ctl = 0;   switch( MAJOR_OPCODE(inst)) {   case bcond_op:    case j_op:    case jal_op:    case beq_op:   case bne_op:   case blez_op:   case bgtz_op:   case beql_op:   case bnel_op:   case blezl_op:   case bgtzl_op:      ctl = 1;      break;   case spec_op:       switch( FUNC(inst)) {      case jr_op:       case jalr_op:          ctl = 1;         break;      }      break;   case cop1_op:       switch (rs(inst)) {      case bc_op:       case eret_op:         ctl = 1;      }      break;   }   return ctl;}/* **************************************************** * EndOfBB returns the last VA of the BB given by * (VA,PA), but does not straddle pages. If the BB  * goes on to the next page, EndOfBB returns the first * word of the second page of the BB * This is only used for an optimization, therefore it's * still ok if we miss a few control instruction. If  * EndOfBB cannot prove that the BB ends on the same * page, Chaining optimization will be disabled. * ***************************************************/  VA EndOfBB(VA vA , MA mA){   VA curVA = vA;   MA curMA = mA;   int ctl = 0;      while( 1 ) {      uint inst = *(uint*)curMA;      switch( MAJOR_OPCODE(inst)) {      case bcond_op:       case j_op:       case jal_op:       case beq_op:      case bne_op:      case blez_op:      case bgtz_op:      case beql_op:      case bnel_op:      case blezl_op:      case bgtzl_op:         ctl = 1;         break;      case spec_op:          switch( FUNC(inst)) {         case jr_op:          case jalr_op:             ctl = 1;            break;         }         break;      case cop1_op:          switch (rs(inst)) {         case bc_op:             ctl = 1;         }         break;      }      if (ctl) {         return curVA + INST_SIZE;      }      curVA += INST_SIZE;      curMA += INST_SIZE;      if( PAGE_NUMBER(curVA) != PAGE_NUMBER(vA)) {         if (!IS_KSEG0(curVA)) {            /*             * The bb was split at translation time not             * to straddle pages.             */            return curVA-INST_SIZE;         }           return curVA;      }   }#if !defined(_COMPILER_VERSION)    return vA; /* Make old compiler happy */#endif}   

⌨️ 快捷键说明

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