void EDDisassembler::initMaps(const MCRegisterInfo ®isterInfo) { unsigned numRegisters = registerInfo.getNumRegs(); unsigned registerIndex; for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) { const char* registerName = registerInfo.get(registerIndex).Name; RegVec.push_back(registerName); RegRMap[registerName] = registerIndex; } switch (Key.Arch) { default: break; case Triple::x86: case Triple::x86_64: stackPointers.insert(registerIDWithName("SP")); stackPointers.insert(registerIDWithName("ESP")); stackPointers.insert(registerIDWithName("RSP")); programCounters.insert(registerIDWithName("IP")); programCounters.insert(registerIDWithName("EIP")); programCounters.insert(registerIDWithName("RIP")); break; case Triple::arm: case Triple::thumb: stackPointers.insert(registerIDWithName("SP")); programCounters.insert(registerIDWithName("PC")); break; } }
bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg, const MCRegisterInfo &RI) const { for (int i = 0, e = NumDefs; i != e; ++i) if (MI.getOperand(i).isReg() && RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) return true; if (variadicOpsAreDefs()) for (int i = NumOperands - 1, e = MI.getNumOperands(); i != e; ++i) if (MI.getOperand(i).isReg() && RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) return true; return hasImplicitDefOfPhysReg(Reg, &RI); }
bool X86MCInstrAnalysis::clearsSuperRegisters(const MCRegisterInfo &MRI, const MCInst &Inst, APInt &Mask) const { const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); unsigned NumDefs = Desc.getNumDefs(); unsigned NumImplicitDefs = Desc.getNumImplicitDefs(); assert(Mask.getBitWidth() == NumDefs + NumImplicitDefs && "Unexpected number of bits in the mask!"); bool HasVEX = (Desc.TSFlags & X86II::EncodingMask) == X86II::VEX; bool HasEVEX = (Desc.TSFlags & X86II::EncodingMask) == X86II::EVEX; bool HasXOP = (Desc.TSFlags & X86II::EncodingMask) == X86II::XOP; const MCRegisterClass &GR32RC = MRI.getRegClass(X86::GR32RegClassID); const MCRegisterClass &VR128XRC = MRI.getRegClass(X86::VR128XRegClassID); const MCRegisterClass &VR256XRC = MRI.getRegClass(X86::VR256XRegClassID); auto ClearsSuperReg = [=](unsigned RegID) { // On X86-64, a general purpose integer register is viewed as a 64-bit // register internal to the processor. // An update to the lower 32 bits of a 64 bit integer register is // architecturally defined to zero extend the upper 32 bits. if (GR32RC.contains(RegID)) return true; // Early exit if this instruction has no vex/evex/xop prefix. if (!HasEVEX && !HasVEX && !HasXOP) return false; // All VEX and EVEX encoded instructions are defined to zero the high bits // of the destination register up to VLMAX (i.e. the maximum vector register // width pertaining to the instruction). // We assume the same behavior for XOP instructions too. return VR128XRC.contains(RegID) || VR256XRC.contains(RegID); }; Mask.clearAllBits(); for (unsigned I = 0, E = NumDefs; I < E; ++I) { const MCOperand &Op = Inst.getOperand(I); if (ClearsSuperReg(Op.getReg())) Mask.setBit(I); } for (unsigned I = 0, E = NumImplicitDefs; I < E; ++I) { const MCPhysReg Reg = Desc.getImplicitDefs()[I]; if (ClearsSuperReg(Reg)) Mask.setBit(NumDefs + I); } return Mask.getBoolValue(); }
bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const { if (isBranch() || isCall() || isReturn() || isIndirectBranch()) return true; unsigned PC = RI.getProgramCounter(); if (PC == 0) return false; if (hasDefOfPhysReg(MI, PC, RI)) return true; return false; }
void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O, const MCRegisterInfo &MRI) { switch (reg) { case AMDGPU::VCC: O << "vcc"; return; case AMDGPU::SCC: O << "scc"; return; case AMDGPU::EXEC: O << "exec"; return; case AMDGPU::M0: O << "m0"; return; case AMDGPU::FLAT_SCR: O << "flat_scratch"; return; case AMDGPU::VCC_LO: O << "vcc_lo"; return; case AMDGPU::VCC_HI: O << "vcc_hi"; return; case AMDGPU::EXEC_LO: O << "exec_lo"; return; case AMDGPU::EXEC_HI: O << "exec_hi"; return; case AMDGPU::FLAT_SCR_LO: O << "flat_scratch_lo"; return; case AMDGPU::FLAT_SCR_HI: O << "flat_scratch_hi"; return; default: break; } char Type; unsigned NumRegs; if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) { Type = 'v'; NumRegs = 1; } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) { Type = 's'; NumRegs = 1; } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) { Type = 'v'; NumRegs = 2; } else if (MRI.getRegClass(AMDGPU::SReg_64RegClassID).contains(reg)) { Type = 's'; NumRegs = 2; } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) { Type = 'v'; NumRegs = 4; } else if (MRI.getRegClass(AMDGPU::SReg_128RegClassID).contains(reg)) { Type = 's'; NumRegs = 4; } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) { Type = 'v'; NumRegs = 3; } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) { Type = 'v'; NumRegs = 8; } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) { Type = 's'; NumRegs = 8; } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) { Type = 'v'; NumRegs = 16; } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) { Type = 's'; NumRegs = 16; } else { O << getRegisterName(reg); return; } // The low 8 bits of the encoding value is the register index, for both VGPRs // and SGPRs. unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1); if (NumRegs == 1) { O << Type << RegIdx; return; } O << Type << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']'; }