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

📄 isel.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
ARMAMode2* genGuestArrayOffset ( ISelEnv* env, IRArray* descr, 				 IRExpr* off, Int bias ){   HReg tmp, tmp2, roff;   Int  elemSz = sizeofIRType(descr->elemTy);   Int  nElems = descr->nElems;   ARMImm12A imm12a;   /* throw out any cases not generated by an x86 front end.  In      theory there might be a day where we need to handle them -- if      we ever run non-x86-guest on x86 host. */   if (nElems != 8 || (elemSz != 1 && elemSz != 8))      vpanic("genGuestArrayOffset(arm host)");   /* Compute off into a reg, %off.  Then return:         movl %off, %tmp         addl $bias, %tmp  (if bias != 0)         andl %tmp, 7         ... base(%ebp, %tmp, shift) ...   */   tmp  = newVRegI(env);   roff = iselIntExpr_R(env, off);   addInstr(env, mk_iMOVsd_RR(roff, tmp));   if (bias != 0) {       if ( mk_ARMImm12A( (UInt)bias, &imm12a ) ) {	   addInstr(env, ARMInstr_DPInstr2(ARMalu_ADD, tmp, tmp,					   ARMAMode1_I12A( imm12a )));       } else {	   HReg tmp3 = newVRegI(env);	   addInstr(env, ARMInstr_Literal( tmp, (UInt)bias ));	   addInstr(env, ARMInstr_DPInstr2(ARMalu_ADD, tmp, tmp,					   ARMAMode1_ShlI( tmp3, 0 )));       }   }   mk_ARMImm12A( (UInt)7, &imm12a );   addInstr(env, ARMInstr_DPInstr2(ARMalu_AND, tmp, tmp,				   ARMAMode1_I12A( imm12a )));   vassert(elemSz == 1 || elemSz == 8);// CAB: This anywhere near correct?// X86AMode_IRRS: Immediate + Reg1 + (Reg2 << Shift)// return X86AMode_IRRS( descr->base, hregX86_EBP(), tmp, elemSz==8 ? 3 : 0);   tmp2 = newVRegI(env);  // tmp2 = GET_BP_REG + (tmp << 3|0)   addInstr(env, ARMInstr_DPInstr2(ARMalu_ADD, tmp2, GET_BP_REG(),				   ARMAMode1_ShlI(tmp, elemSz==8 ? 3 : 0)));   return ARMAMode2_RI( tmp2, descr->base );}/*---------------------------------------------------------*//*--- ISEL ...                                           ---*//*---------------------------------------------------------*//* --------------------- AMODEs --------------------- *//* Return an AMode which computes the value of the specified   expression, possibly also adding insns to the code list as a   result.*//* ---------------- Addressing Mode 1 ---------------- */static Bool sane_AMode1 ( ARMAMode1* am ){    switch (am->tag) {    default:	vpanic("sane_AMode1: unknown arm amode tag");    }}static ARMAMode1* iselIntExpr_AMode1 ( ISelEnv* env, IRExpr* e ){    ARMAMode1* am = iselIntExpr_AMode1_wrk(env, e);    vassert(sane_AMode1(am));    return am;}/* DO NOT CALL THIS DIRECTLY ! */static ARMAMode1* iselIntExpr_AMode1_wrk ( ISelEnv* env, IRExpr* e ){    IRType ty = typeOfIRExpr(env->type_env,e);    vassert(ty == Ity_I32);     // ARMam1_I12A,    /* Imm12A: extended (rotated) immedate */    // ARMam1_ShlI,    /* ShlI  reg  Imm5 */    // ARMam1_ShrI,    /* ShrI  reg  Imm5 */    // ARMam1_SarI,    /* SarI  reg  Imm5 */    // ARMam1_ShlR,    /* ShlR  reg  reg */    // ARMam1_ShrR,    /* ShrR  reg  reg */    // ARMam1_SarR,    /* SarR  reg  reg */    // ALU ops:    /*      ARMalu_And, ARMalu_Orr, ARMalu_Eor, ARMalu_Bic, // Logic      ARMalu_Sub, ARMalu_Rsb, ARMalu_Add, ARMalu_Adc, ARMalu_Sbc, ARMalu_Rsc,  // Arith      ARMalu_Tst, ARMalu_Teq, ARMalu_Cmp, ARMalu_Cmn,  // test      ARMalu_Mov, ARMalu_Mvn  // Move    */    return NULL; }/* ---------------- Addressing Mode 2 ---------------- */static Bool sane_AMode2 ( ARMAMode2* am ){   switch (am->tag) {   default:       vpanic("sane_AMode2: unknown arm amode tag");   }}static ARMAMode2* iselIntExpr_AMode2_wrk ( ISelEnv* env, IRExpr* e ){    ARMAMode2* am = iselIntExpr_AMode2_wrk(env, e);    vassert(sane_AMode2(am));    return am;}/* DO NOT CALL THIS DIRECTLY ! */static ARMAMode2* iselIntExpr_AMode2 ( ISelEnv* env, IRExpr* e ){       IRType ty = typeOfIRExpr(env->type_env,e);    vassert(ty == Ity_I32);    // ARMam2_RI,      /* Reg +/- Imm12 */    // ARMam2_RR,       /* Reg +/- Reg */    // ARMam2_RRS,       /* Reg +/- (Reg << Imm5) */    return NULL; }/* ---------------- Addressing Mode 3 ---------------- */static Bool sane_AMode3 ( ARMAMode3* am ){   switch (am->tag) {   default:       vpanic("sane_AMode3: unknown arm amode tag");   }}static ARMAMode3* iselIntExpr_AMode3 ( ISelEnv* env, IRExpr* e ){    ARMAMode3* am = iselIntExpr_AMode3_wrk(env, e);    vassert(sane_AMode3(am));    return am;}/* DO NOT CALL THIS DIRECTLY ! */static ARMAMode3* iselIntExpr_AMode3_wrk ( ISelEnv* env, IRExpr* e ){       IRType ty = typeOfIRExpr(env->type_env,e);    vassert(ty == Ity_I32);    // ARMam3_RI,       /* Reg +/- Imm8 */    // ARMam3_RR,       /* Reg +/- Reg */    return NULL; }/* ---------------- Branch Destination ---------------- */static ARMBranchDest* iselIntExpr_BD ( ISelEnv* env, IRExpr* e ){    ARMBranchDest* bd = iselIntExpr_BD_wrk(env, e);    /* sanity checks ... */    switch (bd->tag) {    case ARMbdImm:	return bd;    case ARMbdReg:	vassert(hregClass(bd->ARMbd.Reg.reg) == HRcInt32);//      vassert(hregIsVirtual(bd->ARMbd.Reg.reg));      // CAB ?	return bd;    default:	vpanic("iselIntExpr_BD: unknown arm BD tag");   }}/* DO NOT CALL THIS DIRECTLY ! */static ARMBranchDest* iselIntExpr_BD_wrk ( ISelEnv* env, IRExpr* e ){    /*      ARMbdImm,      ARMbdReg    */    return NULL;}/* --------------------- CONDCODE --------------------- *//* Generate code to evaluated a bit-typed expression, returning the   condition code which would correspond when the expression would   notionally have returned 1. */static ARMCondCode iselCondCode ( ISelEnv* env, IRExpr* e ){    /* Uh, there's nothing we can sanity check here, unfortunately. */    return iselCondCode_wrk(env, e);}/* DO NOT CALL THIS DIRECTLY ! */static ARMCondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ){#if 0    MatchInfo mi;    DECLARE_PATTERN(p_32to1);    DECLARE_PATTERN(p_1Uto32_then_32to1);#endif    return 0;}static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e ){    return iselIntExpr_R_wrk(env, e);}/* DO NOT CALL THIS DIRECTLY ! */static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ){    return 0;}/*---------------------------------------------------------*//*--- ISEL: Statements                                  ---*//*---------------------------------------------------------*/static void iselStmt ( ISelEnv* env, IRStmt* stmt ){   if (vex_traceflags & VEX_TRACE_VCODE) {      vex_printf("\n-- ");      ppIRStmt(stmt);      vex_printf("\n");   }   switch (stmt->tag) {   /* --------- STORE --------- */   /* little-endian write to memory */   case Ist_Store: {       HReg   reg;       IRType tya = typeOfIRExpr(env->type_env, stmt->Ist.Store.addr);       IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Store.data);       IREndness end = stmt->Ist.Store.end;       if (tya != Ity_I32 || end != Iend_LE)           goto stmt_fail;       reg = iselIntExpr_R(env, stmt->Ist.Store.data);       if (tyd == Ity_I8) {	   ARMAMode2* am2 = iselIntExpr_AMode2(env, stmt->Ist.Store.addr);	   addInstr(env, ARMInstr_StoreB(reg,am2));	   return;       }       if (tyd == Ity_I16) {	   ARMAMode3* am3 = iselIntExpr_AMode3(env, stmt->Ist.Store.addr);	   addInstr(env, ARMInstr_StoreH(reg,am3));	   return;       }       if (tyd == Ity_I32) {	   ARMAMode2* am2 = iselIntExpr_AMode2(env, stmt->Ist.Store.addr);	   addInstr(env, ARMInstr_StoreW(reg,am2));	   return;       }          }   /* --------- PUT --------- */   /* write guest state, fixed offset */   case Ist_Put: {       IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.Put.data);       HReg reg = iselIntExpr_R(env, stmt->Ist.Put.data);       // CAB: This anywhere near right?!       if (tyd == Ity_I32) {	   ARMAMode2* am2 = ARMAMode2_RI(GET_BP_REG(), stmt->Ist.Put.offset);	   addInstr(env, ARMInstr_StoreW(reg, am2));	   return;       }       if (tyd == Ity_I16) {	   ARMAMode3* am3 = ARMAMode3_RI(GET_BP_REG(), stmt->Ist.Put.offset);	   addInstr(env, ARMInstr_StoreH(reg, am3));	   return;       }       if (tyd == Ity_I8) {	   ARMAMode2* am2 = ARMAMode2_RI(GET_BP_REG(), stmt->Ist.Put.offset);	   addInstr(env, ARMInstr_StoreB(reg, am2));	   return;       }// CAB: Ity_I32, Ity_I16 ?       break;   }   /* --------- Indexed PUT --------- */   /* write guest state, run-time offset */   case Ist_PutI: {      ARMAMode2* am2	   = genGuestArrayOffset(	       env, stmt->Ist.PutI.descr, 	       stmt->Ist.PutI.ix, stmt->Ist.PutI.bias );              IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.PutI.data);              if (tyd == Ity_I8) {	   HReg reg = iselIntExpr_R(env, stmt->Ist.PutI.data);	   addInstr(env, ARMInstr_StoreB(reg, am2));	   return;       }// CAB: Ity_I32, Ity_I16 ?       break;   }   /* --------- TMP --------- */   /* assign value to temporary */   case Ist_Tmp: {      IRTemp tmp = stmt->Ist.Tmp.tmp;      IRType ty = typeOfIRTemp(env->type_env, tmp);      if (ty == Ity_I32 || ty == Ity_I16 || ty == Ity_I8) {         ARMAMode1* am = iselIntExpr_AMode1(env, stmt->Ist.Tmp.data);         HReg dst = lookupIRTemp(env, tmp);         addInstr(env, ARMInstr_DPInstr1(ARMalu_MOV,dst,am));         return;      }// CAB: Ity_I1 ?      break;   }   /* --------- Call to DIRTY helper --------- */   /* call complex ("dirty") helper function */   case Ist_Dirty: {     //IRType   retty;       IRDirty* d = stmt->Ist.Dirty.details;       Bool     passBBP = False;      if (d->nFxState == 0)         vassert(!d->needsBBP);      passBBP = toBool(d->nFxState > 0 && d->needsBBP);      /* Marshal args, do the call, clear stack. */      doHelperCall( env, passBBP, d->guard, d->cee, d->args );      /* Now figure out what to do with the returned value, if any. */      if (d->tmp == IRTemp_INVALID)	  /* No return value.  Nothing to do. */	  return;            //retty = typeOfIRTemp(env->type_env, d->tmp);// CAB: ?     if (retty == Ity_I64) {#if 0      if (retty == Ity_I32 || retty == Ity_I16 || retty == Ity_I8) {         /* The returned value is in %eax.  Park it in the register            associated with tmp. */         HReg dst = lookupIRTemp(env, d->tmp);         addInstr(env, mk_iMOVsd_RR(hregX86_EAX(),dst) );         return;      }#endif      break;   }   /* --------- EXIT --------- */   /* conditional exit from BB */   case Ist_Exit: {      ARMBranchDest* dst;      ARMCondCode cc;      if (stmt->Ist.Exit.dst->tag != Ico_U32)         vpanic("isel_arm: Ist_Exit: dst is not a 32-bit value");      // CAB: Where does jumpkind fit in ?      // stmt->Ist.Exit.jk      dst = iselIntExpr_BD(env, IRExpr_Const(stmt->Ist.Exit.dst));      cc  = iselCondCode(env,stmt->Ist.Exit.guard);      addInstr(env, ARMInstr_Branch(cc, dst));      return;   }   default: break;   }  stmt_fail:   ppIRStmt(stmt);   vpanic("iselStmt");}/*---------------------------------------------------------*//*--- ISEL: Basic block terminators (Nexts)             ---*//*---------------------------------------------------------*/static void iselNext ( ISelEnv* env, IRExpr* next, IRJumpKind jk ){    ARMBranchDest* bd;    if (vex_traceflags & VEX_TRACE_VCODE) {	vex_printf("\n-- goto {");	ppIRJumpKind(jk);	vex_printf("} ");	ppIRExpr(next);	vex_printf("\n");    }    bd = iselIntExpr_BD(env, next);        // CAB: jk ?    addInstr( env, ARMInstr_Branch(ARMccAL, bd) );}/*---------------------------------------------------------*//*--- Insn selector top-level                           ---*//*---------------------------------------------------------*//* Translate an entire BB to arm code. */HInstrArray* iselBB_ARM ( IRBB* bb ){    Int     i, j;    /* Make up an initial environment to use. */    ISelEnv* env = LibVEX_Alloc(sizeof(ISelEnv));    env->vreg_ctr = 0;    /* Set up output code array. */    env->code = newHInstrArray();        /* Copy BB's type env. */    env->type_env = bb->tyenv;    /* Make up an IRTemp -> virtual HReg mapping.  This doesn't       change as we go along. */    env->n_vregmap = bb->tyenv->types_used;    env->vregmap   = LibVEX_Alloc(env->n_vregmap * sizeof(HReg));    /* For each IR temporary, allocate a 32bit virtual register. */    j = 0;    for (i = 0; i < env->n_vregmap; i++) {	env->vregmap[i] = mkHReg(j++, HRcInt32, True);    }    env->vreg_ctr = j;    /* Ok, finally we can iterate over the statements. */    for (i = 0; i < bb->stmts_used; i++)	if (bb->stmts[i])	    iselStmt(env,bb->stmts[i]);        iselNext(env,bb->next,bb->jumpkind);    /* record the number of vregs we used. */    env->code->n_vregs = env->vreg_ctr;    return env->code;}/*---------------------------------------------------------------*//*--- end                                     host-x86/isel.c ---*//*---------------------------------------------------------------*/

⌨️ 快捷键说明

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