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

📄 hdefs.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
            default: vpanic("getRegUsage_X86Instr:Call:regparms");         }         /* Finally, there is the issue that the insn trashes a            register because the literal target address has to be            loaded into a register.  Fortunately, for the 0/1/2            regparm case, we can use EAX, EDX and ECX respectively, so            this does not cause any further damage.  For the 3-regparm            case, we'll have to choose another register arbitrarily --            since A, D and C are used for parameters -- and so we might            as well choose EDI. */         if (i->Xin.Call.regparms == 3)            addHRegUse(u, HRmWrite, hregX86_EDI());         /* Upshot of this is that the assembler really must observe            the here-stated convention of which register to use as an            address temporary, depending on the regparmness: 0==EAX,            1==EDX, 2==ECX, 3==EDI. */         return;      case Xin_Goto:         addRegUsage_X86RI(u, i->Xin.Goto.dst);         addHRegUse(u, HRmWrite, hregX86_EAX()); /* used for next guest addr */         addHRegUse(u, HRmWrite, hregX86_EDX()); /* used for dispatcher addr */         if (i->Xin.Goto.jk != Ijk_Boring             && i->Xin.Goto.jk != Ijk_Call             && i->Xin.Goto.jk != Ijk_Ret)            /* note, this is irrelevant since ebp is not actually               available to the allocator.  But still .. */            addHRegUse(u, HRmWrite, hregX86_EBP());         return;      case Xin_CMov32:         addRegUsage_X86RM(u, i->Xin.CMov32.src, HRmRead);         addHRegUse(u, HRmModify, i->Xin.CMov32.dst);         return;      case Xin_LoadEX:         addRegUsage_X86AMode(u, i->Xin.LoadEX.src);         addHRegUse(u, HRmWrite, i->Xin.LoadEX.dst);         return;      case Xin_Store:         addHRegUse(u, HRmRead, i->Xin.Store.src);         addRegUsage_X86AMode(u, i->Xin.Store.dst);         return;      case Xin_Set32:         addHRegUse(u, HRmWrite, i->Xin.Set32.dst);         return;      case Xin_Bsfr32:         addHRegUse(u, HRmRead, i->Xin.Bsfr32.src);         addHRegUse(u, HRmWrite, i->Xin.Bsfr32.dst);         return;      case Xin_MFence:         return;      case Xin_FpUnary:         addHRegUse(u, HRmRead, i->Xin.FpUnary.src);         addHRegUse(u, HRmWrite, i->Xin.FpUnary.dst);         return;      case Xin_FpBinary:         addHRegUse(u, HRmRead, i->Xin.FpBinary.srcL);         addHRegUse(u, HRmRead, i->Xin.FpBinary.srcR);         addHRegUse(u, HRmWrite, i->Xin.FpBinary.dst);         return;      case Xin_FpLdSt:         addRegUsage_X86AMode(u, i->Xin.FpLdSt.addr);         addHRegUse(u, i->Xin.FpLdSt.isLoad ? HRmWrite : HRmRead,                       i->Xin.FpLdSt.reg);         return;      case Xin_FpLdStI:         addRegUsage_X86AMode(u, i->Xin.FpLdStI.addr);         addHRegUse(u, i->Xin.FpLdStI.isLoad ? HRmWrite : HRmRead,                       i->Xin.FpLdStI.reg);         return;      case Xin_Fp64to32:         addHRegUse(u, HRmRead,  i->Xin.Fp64to32.src);         addHRegUse(u, HRmWrite, i->Xin.Fp64to32.dst);         return;      case Xin_FpCMov:         addHRegUse(u, HRmRead,   i->Xin.FpCMov.src);         addHRegUse(u, HRmModify, i->Xin.FpCMov.dst);         return;      case Xin_FpLdCW:         addRegUsage_X86AMode(u, i->Xin.FpLdCW.addr);         return;      case Xin_FpStSW_AX:         addHRegUse(u, HRmWrite, hregX86_EAX());         return;      case Xin_FpCmp:         addHRegUse(u, HRmRead, i->Xin.FpCmp.srcL);         addHRegUse(u, HRmRead, i->Xin.FpCmp.srcR);         addHRegUse(u, HRmWrite, i->Xin.FpCmp.dst);         addHRegUse(u, HRmWrite, hregX86_EAX());         return;      case Xin_SseLdSt:         addRegUsage_X86AMode(u, i->Xin.SseLdSt.addr);         addHRegUse(u, i->Xin.SseLdSt.isLoad ? HRmWrite : HRmRead,                       i->Xin.SseLdSt.reg);         return;      case Xin_SseLdzLO:         addRegUsage_X86AMode(u, i->Xin.SseLdzLO.addr);         addHRegUse(u, HRmWrite, i->Xin.SseLdzLO.reg);         return;      case Xin_SseConst:         addHRegUse(u, HRmWrite, i->Xin.SseConst.dst);         return;      case Xin_Sse32Fx4:         vassert(i->Xin.Sse32Fx4.op != Xsse_MOV);         unary = toBool( i->Xin.Sse32Fx4.op == Xsse_RCPF                         || i->Xin.Sse32Fx4.op == Xsse_RSQRTF                         || i->Xin.Sse32Fx4.op == Xsse_SQRTF );         addHRegUse(u, HRmRead, i->Xin.Sse32Fx4.src);         addHRegUse(u, unary ? HRmWrite : HRmModify,                        i->Xin.Sse32Fx4.dst);         return;      case Xin_Sse32FLo:         vassert(i->Xin.Sse32FLo.op != Xsse_MOV);         unary = toBool( i->Xin.Sse32FLo.op == Xsse_RCPF                         || i->Xin.Sse32FLo.op == Xsse_RSQRTF                         || i->Xin.Sse32FLo.op == Xsse_SQRTF );         addHRegUse(u, HRmRead, i->Xin.Sse32FLo.src);         addHRegUse(u, unary ? HRmWrite : HRmModify,                        i->Xin.Sse32FLo.dst);         return;      case Xin_Sse64Fx2:         vassert(i->Xin.Sse64Fx2.op != Xsse_MOV);         unary = toBool( i->Xin.Sse64Fx2.op == Xsse_RCPF                         || i->Xin.Sse64Fx2.op == Xsse_RSQRTF                         || i->Xin.Sse64Fx2.op == Xsse_SQRTF );         addHRegUse(u, HRmRead, i->Xin.Sse64Fx2.src);         addHRegUse(u, unary ? HRmWrite : HRmModify,                        i->Xin.Sse64Fx2.dst);         return;      case Xin_Sse64FLo:         vassert(i->Xin.Sse64FLo.op != Xsse_MOV);         unary = toBool( i->Xin.Sse64FLo.op == Xsse_RCPF                         || i->Xin.Sse64FLo.op == Xsse_RSQRTF                         || i->Xin.Sse64FLo.op == Xsse_SQRTF );         addHRegUse(u, HRmRead, i->Xin.Sse64FLo.src);         addHRegUse(u, unary ? HRmWrite : HRmModify,                        i->Xin.Sse64FLo.dst);         return;      case Xin_SseReRg:         if (i->Xin.SseReRg.op == Xsse_XOR             && i->Xin.SseReRg.src == i->Xin.SseReRg.dst) {            /* reg-alloc needs to understand 'xor r,r' as a write of r */            /* (as opposed to a rite of passage :-) */            addHRegUse(u, HRmWrite, i->Xin.SseReRg.dst);         } else {            addHRegUse(u, HRmRead, i->Xin.SseReRg.src);            addHRegUse(u, i->Xin.SseReRg.op == Xsse_MOV                              ? HRmWrite : HRmModify,                           i->Xin.SseReRg.dst);         }         return;      case Xin_SseCMov:         addHRegUse(u, HRmRead,   i->Xin.SseCMov.src);         addHRegUse(u, HRmModify, i->Xin.SseCMov.dst);         return;      case Xin_SseShuf:         addHRegUse(u, HRmRead,  i->Xin.SseShuf.src);         addHRegUse(u, HRmWrite, i->Xin.SseShuf.dst);         return;      default:         ppX86Instr(i, False);         vpanic("getRegUsage_X86Instr");   }}/* local helper */static void mapReg( HRegRemap* m, HReg* r ){   *r = lookupHRegRemap(m, *r);}void mapRegs_X86Instr ( HRegRemap* m, X86Instr* i, Bool mode64 ){   vassert(mode64 == False);   switch (i->tag) {      case Xin_Alu32R:         mapRegs_X86RMI(m, i->Xin.Alu32R.src);         mapReg(m, &i->Xin.Alu32R.dst);         return;      case Xin_Alu32M:         mapRegs_X86RI(m, i->Xin.Alu32M.src);         mapRegs_X86AMode(m, i->Xin.Alu32M.dst);         return;      case Xin_Sh32:         mapReg(m, &i->Xin.Sh32.dst);         return;      case Xin_Test32:         mapReg(m, &i->Xin.Test32.dst);         return;      case Xin_Unary32:         mapReg(m, &i->Xin.Unary32.dst);         return;      case Xin_MulL:         mapRegs_X86RM(m, i->Xin.MulL.src);         return;      case Xin_Div:         mapRegs_X86RM(m, i->Xin.Div.src);         return;      case Xin_Sh3232:         mapReg(m, &i->Xin.Sh3232.src);         mapReg(m, &i->Xin.Sh3232.dst);         return;      case Xin_Push:         mapRegs_X86RMI(m, i->Xin.Push.src);         return;      case Xin_Call:         return;      case Xin_Goto:         mapRegs_X86RI(m, i->Xin.Goto.dst);         return;      case Xin_CMov32:         mapRegs_X86RM(m, i->Xin.CMov32.src);         mapReg(m, &i->Xin.CMov32.dst);         return;      case Xin_LoadEX:         mapRegs_X86AMode(m, i->Xin.LoadEX.src);         mapReg(m, &i->Xin.LoadEX.dst);         return;      case Xin_Store:         mapReg(m, &i->Xin.Store.src);         mapRegs_X86AMode(m, i->Xin.Store.dst);         return;      case Xin_Set32:         mapReg(m, &i->Xin.Set32.dst);         return;      case Xin_Bsfr32:         mapReg(m, &i->Xin.Bsfr32.src);         mapReg(m, &i->Xin.Bsfr32.dst);         return;      case Xin_MFence:         return;      case Xin_FpUnary:         mapReg(m, &i->Xin.FpUnary.src);         mapReg(m, &i->Xin.FpUnary.dst);         return;      case Xin_FpBinary:         mapReg(m, &i->Xin.FpBinary.srcL);         mapReg(m, &i->Xin.FpBinary.srcR);         mapReg(m, &i->Xin.FpBinary.dst);         return;      case Xin_FpLdSt:         mapRegs_X86AMode(m, i->Xin.FpLdSt.addr);         mapReg(m, &i->Xin.FpLdSt.reg);         return;      case Xin_FpLdStI:         mapRegs_X86AMode(m, i->Xin.FpLdStI.addr);         mapReg(m, &i->Xin.FpLdStI.reg);         return;      case Xin_Fp64to32:         mapReg(m, &i->Xin.Fp64to32.src);         mapReg(m, &i->Xin.Fp64to32.dst);         return;      case Xin_FpCMov:         mapReg(m, &i->Xin.FpCMov.src);         mapReg(m, &i->Xin.FpCMov.dst);         return;      case Xin_FpLdCW:         mapRegs_X86AMode(m, i->Xin.FpLdCW.addr);         return;      case Xin_FpStSW_AX:         return;      case Xin_FpCmp:         mapReg(m, &i->Xin.FpCmp.srcL);         mapReg(m, &i->Xin.FpCmp.srcR);         mapReg(m, &i->Xin.FpCmp.dst);         return;      case Xin_SseConst:         mapReg(m, &i->Xin.SseConst.dst);         return;      case Xin_SseLdSt:         mapReg(m, &i->Xin.SseLdSt.reg);         mapRegs_X86AMode(m, i->Xin.SseLdSt.addr);         break;      case Xin_SseLdzLO:         mapReg(m, &i->Xin.SseLdzLO.reg);         mapRegs_X86AMode(m, i->Xin.SseLdzLO.addr);         break;      case Xin_Sse32Fx4:         mapReg(m, &i->Xin.Sse32Fx4.src);         mapReg(m, &i->Xin.Sse32Fx4.dst);         return;      case Xin_Sse32FLo:         mapReg(m, &i->Xin.Sse32FLo.src);         mapReg(m, &i->Xin.Sse32FLo.dst);         return;      case Xin_Sse64Fx2:         mapReg(m, &i->Xin.Sse64Fx2.src);         mapReg(m, &i->Xin.Sse64Fx2.dst);         return;      case Xin_Sse64FLo:         mapReg(m, &i->Xin.Sse64FLo.src);         mapReg(m, &i->Xin.Sse64FLo.dst);         return;      case Xin_SseReRg:         mapReg(m, &i->Xin.SseReRg.src);         mapReg(m, &i->Xin.SseReRg.dst);         return;      case Xin_SseCMov:         mapReg(m, &i->Xin.SseCMov.src);         mapReg(m, &i->Xin.SseCMov.dst);         return;      case Xin_SseShuf:         mapReg(m, &i->Xin.SseShuf.src);         mapReg(m, &i->Xin.SseShuf.dst);         return;      default:         ppX86Instr(i, mode64);         vpanic("mapRegs_X86Instr");   }}/* Figure out if i represents a reg-reg move, and if so assign the   source and destination to *src and *dst.  If in doubt say No.  Used   by the register allocator to do move coalescing. */Bool isMove_X86Instr ( X86Instr* i, HReg* src, HReg* dst ){   /* Moves between integer regs */   if (i->tag == Xin_Alu32R) {      if (i->Xin.Alu32R.op != Xalu_MOV)         return False;      if (i->Xin.Alu32R.src->tag != Xrmi_Reg)         return False;      *src = i->Xin.Alu32R.src->Xrmi.Reg.reg;      *dst = i->Xin.Alu32R.dst;      return True;   }   /* Moves between FP regs */   if (i->tag == Xin_FpUnary) {      if (i->Xin.FpUnary.op != Xfp_MOV)         return False;      *src = i->Xin.FpUnary.src;      *dst = i->Xin.FpUnary.dst;      return True;   }   if (i->tag == Xin_SseReRg) {      if (i->Xin.SseReRg.op != Xsse_MOV)         return False;      *src = i->Xin.SseReRg.src;      *dst = i->Xin.SseReRg.dst;      return True;   }   return False;}/* Generate x86 spill/reload instructions under the direction of the   register allocator.  Note it's critical these don't write the   condition codes. */X86Instr* genSpill_X86 ( HReg rreg, Int offsetB, Bool mode64 ){   X86AMode* am;   vassert(offsetB >= 0);   vassert(!hregIsVirtual(rreg));   vassert(mode64 == False);   am = X86AMode_IR(offsetB, hregX86_EBP());   switch (hregClass(rreg)) {      case HRcInt32:         return X86Instr_Alu32M ( Xalu_MOV, X86RI_Reg(rreg), am );      case HRcFlt64:         return X86Instr_FpLdSt ( False/*store*/, 8, rreg, am );      case HRcVec128:         return X86Instr_SseLdSt ( False/*store*/, rreg, am );      default:          ppHRegClass(hregClass(rreg));         vpanic("genSpill_X86: unimplemented regclass");   }}X86Instr* genReload_X86 ( HReg rreg, Int offsetB, Bool mode64 ){   X86AMode* am;   vassert(offsetB >= 0);   vassert(!hregIsVirtual(rreg));   vassert(mode64 == False);   am = X86AMode_IR(offsetB, hregX86_EBP());   switch (hregClass(rreg)) {      case HRcInt32:         return X86Instr_Alu32R ( Xalu_MOV, X86RMI_Mem(am), rreg );      case HRcFlt64:         return X86Instr_FpLdSt ( True/*load*/, 8, rreg, am );      case HRcVec128:         return X86Instr_SseLdSt ( True/*load*/, rreg, am );      default:          ppHRegClass(hregClass(rreg));         vpanic("genReload_X86: unimplemented regclass");   }}/* --------- The x86 assembler (bleh.) --------- */static UChar iregNo ( HReg r ){   UInt n;   vassert(hregClass(r) == HRcInt32);   vassert(!hregIsVirtual(r));   n = hregNumber(r);   vassert(n <= 7);   return toUChar(n);

⌨️ 快捷键说明

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