diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp index 5182dadc2..ba2d9de00 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.cpp @@ -89,6 +89,7 @@ enum class ConstantsRecord : uint32_t AGGREGATE = 7, STRING = 8, CSTRING = 9, + EVAL_CAST = 11, EVAL_GEP = 20, DATA = 22, }; @@ -223,6 +224,27 @@ enum class TypeRecord : uint32_t #define IS_KNOWN(val, KnownID) (decltype(KnownID)(val) == KnownID) +static Operation DecodeCast(uint64_t opcode) +{ + switch(opcode) + { + case 0: return Operation::Trunc; break; + case 1: return Operation::ZExt; break; + case 2: return Operation::SExt; break; + case 3: return Operation::FToU; break; + case 4: return Operation::FToS; break; + case 5: return Operation::UToF; break; + case 6: return Operation::SToF; break; + case 7: return Operation::FPTrunc; break; + case 8: return Operation::FPExt; break; + case 9: return Operation::PtrToI; break; + case 10: return Operation::IToPtr; break; + case 11: return Operation::Bitcast; break; + case 12: return Operation::AddrSpaceCast; break; + default: RDCERR("Unhandled cast type %llu", opcode); return Operation::Bitcast; + } +} + void ParseConstant(const LLVMBC::BlockOrRecord &constant, const Type *&curType, std::function getType, std::function getPtrType, @@ -269,11 +291,20 @@ void ParseConstant(const LLVMBC::BlockOrRecord &constant, const Type *&curType, v.str = constant.getString(0); addConstant(v); } + else if(IS_KNOWN(constant.id, ConstantsRecord::EVAL_CAST)) + { + Constant v; + v.op = DecodeCast(constant.ops[0]); + v.type = curType; + // getType(constant.ops[1]); type of the constant, which we ignore + v.inner = getConstant(constant.ops[2]); + addConstant(v); + } else if(IS_KNOWN(constant.id, ConstantsRecord::EVAL_GEP)) { Constant v; - v.op = Constant::GEP; + v.op = Operation::GetElementPtr; size_t idx = 0; if(constant.ops.size() & 1) @@ -1288,7 +1319,7 @@ Program::Program(const byte *bytes, size_t length) else if(op.type == FunctionRecord::INST_CALL) { Instruction inst; - inst.op = Instruction::Call; + inst.op = Operation::Call; inst.paramAttrs = &m_Attributes[op.get()]; uint64_t callingFlags = op.get(); @@ -1339,26 +1370,7 @@ Program::Program(const byte *bytes, size_t length) inst.type = op.getType(); uint64_t opcode = op.get(); - switch(opcode) - { - case 0: inst.op = Instruction::Trunc; break; - case 1: inst.op = Instruction::ZExt; break; - case 2: inst.op = Instruction::SExt; break; - case 3: inst.op = Instruction::FToU; break; - case 4: inst.op = Instruction::FToS; break; - case 5: inst.op = Instruction::UToF; break; - case 6: inst.op = Instruction::SToF; break; - case 7: inst.op = Instruction::FPTrunc; break; - case 8: inst.op = Instruction::FPExt; break; - case 9: inst.op = Instruction::PtrToI; break; - case 10: inst.op = Instruction::IToPtr; break; - case 11: inst.op = Instruction::Bitcast; break; - case 12: inst.op = Instruction::AddrSpaceCast; break; - default: - inst.op = Instruction::Bitcast; - RDCERR("Unhandled cast type %llu", opcode); - break; - } + inst.op = DecodeCast(opcode); m_Symbols.push_back({SymbolType::Instruction, f.instructions.size()}); @@ -1368,7 +1380,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::ExtractVal; + inst.op = Operation::ExtractVal; inst.args.push_back(op.getSymbol()); inst.type = op.getType(f, inst.args.back()); @@ -1390,7 +1402,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Ret; + inst.op = Operation::Ret; if(op.remaining() == 0) { @@ -1423,21 +1435,21 @@ Program::Program(const byte *bytes, size_t length) uint64_t opcode = op.get(); switch(opcode) { - case 0: inst.op = isFloatOp ? Instruction::FAdd : Instruction::Add; break; - case 1: inst.op = isFloatOp ? Instruction::FSub : Instruction::Sub; break; - case 2: inst.op = isFloatOp ? Instruction::FMul : Instruction::Mul; break; - case 3: inst.op = Instruction::UDiv; break; - case 4: inst.op = isFloatOp ? Instruction::FDiv : Instruction::SDiv; break; - case 5: inst.op = Instruction::URem; break; - case 6: inst.op = isFloatOp ? Instruction::FRem : Instruction::SRem; break; - case 7: inst.op = Instruction::ShiftLeft; break; - case 8: inst.op = Instruction::LogicalShiftRight; break; - case 9: inst.op = Instruction::ArithShiftRight; break; - case 10: inst.op = Instruction::And; break; - case 11: inst.op = Instruction::Or; break; - case 12: inst.op = Instruction::Xor; break; + case 0: inst.op = isFloatOp ? Operation::FAdd : Operation::Add; break; + case 1: inst.op = isFloatOp ? Operation::FSub : Operation::Sub; break; + case 2: inst.op = isFloatOp ? Operation::FMul : Operation::Mul; break; + case 3: inst.op = Operation::UDiv; break; + case 4: inst.op = isFloatOp ? Operation::FDiv : Operation::SDiv; break; + case 5: inst.op = Operation::URem; break; + case 6: inst.op = isFloatOp ? Operation::FRem : Operation::SRem; break; + case 7: inst.op = Operation::ShiftLeft; break; + case 8: inst.op = Operation::LogicalShiftRight; break; + case 9: inst.op = Operation::ArithShiftRight; break; + case 10: inst.op = Operation::And; break; + case 11: inst.op = Operation::Or; break; + case 12: inst.op = Operation::Xor; break; default: - inst.op = Instruction::And; + inst.op = Operation::And; RDCERR("Unhandled binop type %llu", opcode); break; } @@ -1445,17 +1457,17 @@ Program::Program(const byte *bytes, size_t length) if(op.remaining() > 0) { uint64_t flags = op.get(); - if(inst.op == Instruction::Add || inst.op == Instruction::Sub || - inst.op == Instruction::Mul || inst.op == Instruction::ShiftLeft) + if(inst.op == Operation::Add || inst.op == Operation::Sub || + inst.op == Operation::Mul || inst.op == Operation::ShiftLeft) { if(flags & 0x2) inst.opFlags |= InstructionFlags::NoSignedWrap; if(flags & 0x1) inst.opFlags |= InstructionFlags::NoUnsignedWrap; } - else if(inst.op == Instruction::SDiv || inst.op == Instruction::UDiv || - inst.op == Instruction::LogicalShiftRight || - inst.op == Instruction::ArithShiftRight) + else if(inst.op == Operation::SDiv || inst.op == Operation::UDiv || + inst.op == Operation::LogicalShiftRight || + inst.op == Operation::ArithShiftRight) { if(flags & 0x1) inst.opFlags |= InstructionFlags::Exact; @@ -1475,13 +1487,13 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Unreachable; + inst.op = Operation::Unreachable; } else if(op.type == FunctionRecord::INST_ALLOCA) { Instruction inst; - inst.op = Instruction::Alloca; + inst.op = Operation::Alloca; inst.type = op.getType(); @@ -1521,7 +1533,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::GetElementPtr; + inst.op = Operation::GetElementPtr; if(op.type == FunctionRecord::INST_INBOUNDS_GEP_OLD) inst.opFlags |= InstructionFlags::InBounds; @@ -1574,7 +1586,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Load; + inst.op = Operation::Load; inst.args.push_back(op.getSymbol()); @@ -1601,7 +1613,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Store; + inst.op = Operation::Store; inst.type = GetVoidType(); @@ -1633,36 +1645,36 @@ Program::Program(const byte *bytes, size_t length) uint64_t opcode = op.get(); switch(opcode) { - case 0: inst.op = Instruction::FOrdFalse; break; - case 1: inst.op = Instruction::FOrdEqual; break; - case 2: inst.op = Instruction::FOrdGreater; break; - case 3: inst.op = Instruction::FOrdGreaterEqual; break; - case 4: inst.op = Instruction::FOrdLess; break; - case 5: inst.op = Instruction::FOrdLessEqual; break; - case 6: inst.op = Instruction::FOrdNotEqual; break; - case 7: inst.op = Instruction::FOrd; break; - case 8: inst.op = Instruction::FUnord; break; - case 9: inst.op = Instruction::FUnordEqual; break; - case 10: inst.op = Instruction::FUnordGreater; break; - case 11: inst.op = Instruction::FUnordGreaterEqual; break; - case 12: inst.op = Instruction::FUnordLess; break; - case 13: inst.op = Instruction::FUnordLessEqual; break; - case 14: inst.op = Instruction::FUnordNotEqual; break; - case 15: inst.op = Instruction::FOrdTrue; break; + case 0: inst.op = Operation::FOrdFalse; break; + case 1: inst.op = Operation::FOrdEqual; break; + case 2: inst.op = Operation::FOrdGreater; break; + case 3: inst.op = Operation::FOrdGreaterEqual; break; + case 4: inst.op = Operation::FOrdLess; break; + case 5: inst.op = Operation::FOrdLessEqual; break; + case 6: inst.op = Operation::FOrdNotEqual; break; + case 7: inst.op = Operation::FOrd; break; + case 8: inst.op = Operation::FUnord; break; + case 9: inst.op = Operation::FUnordEqual; break; + case 10: inst.op = Operation::FUnordGreater; break; + case 11: inst.op = Operation::FUnordGreaterEqual; break; + case 12: inst.op = Operation::FUnordLess; break; + case 13: inst.op = Operation::FUnordLessEqual; break; + case 14: inst.op = Operation::FUnordNotEqual; break; + case 15: inst.op = Operation::FOrdTrue; break; - case 32: inst.op = Instruction::IEqual; break; - case 33: inst.op = Instruction::INotEqual; break; - case 34: inst.op = Instruction::UGreater; break; - case 35: inst.op = Instruction::UGreaterEqual; break; - case 36: inst.op = Instruction::ULess; break; - case 37: inst.op = Instruction::ULessEqual; break; - case 38: inst.op = Instruction::SGreater; break; - case 39: inst.op = Instruction::SGreaterEqual; break; - case 40: inst.op = Instruction::SLess; break; - case 41: inst.op = Instruction::SLessEqual; break; + case 32: inst.op = Operation::IEqual; break; + case 33: inst.op = Operation::INotEqual; break; + case 34: inst.op = Operation::UGreater; break; + case 35: inst.op = Operation::UGreaterEqual; break; + case 36: inst.op = Operation::ULess; break; + case 37: inst.op = Operation::ULessEqual; break; + case 38: inst.op = Operation::SGreater; break; + case 39: inst.op = Operation::SGreaterEqual; break; + case 40: inst.op = Operation::SLess; break; + case 41: inst.op = Operation::SLessEqual; break; default: - inst.op = Instruction::FOrdFalse; + inst.op = Operation::FOrdFalse; RDCERR("Unexpected comparison %llu", opcode); break; } @@ -1698,7 +1710,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Select; + inst.op = Operation::Select; // if true inst.args.push_back(op.getSymbol()); @@ -1721,7 +1733,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Branch; + inst.op = Operation::Branch; inst.type = GetVoidType(); @@ -1749,7 +1761,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Switch; + inst.op = Operation::Switch; inst.type = GetVoidType(); @@ -1805,7 +1817,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Phi; + inst.op = Operation::Phi; inst.type = op.getType(); @@ -1833,7 +1845,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::LoadAtomic; + inst.op = Operation::LoadAtomic; inst.args.push_back(op.getSymbol()); @@ -1887,7 +1899,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::StoreAtomic; + inst.op = Operation::StoreAtomic; inst.type = GetVoidType(); @@ -1947,20 +1959,20 @@ Program::Program(const byte *bytes, size_t length) uint64_t opcode = op.get(); switch(opcode) { - case 0: inst.op = Instruction::AtomicExchange; break; - case 1: inst.op = Instruction::AtomicAdd; break; - case 2: inst.op = Instruction::AtomicSub; break; - case 3: inst.op = Instruction::AtomicAnd; break; - case 4: inst.op = Instruction::AtomicNand; break; - case 5: inst.op = Instruction::AtomicOr; break; - case 6: inst.op = Instruction::AtomicXor; break; - case 7: inst.op = Instruction::AtomicMax; break; - case 8: inst.op = Instruction::AtomicMin; break; - case 9: inst.op = Instruction::AtomicUMax; break; - case 10: inst.op = Instruction::AtomicUMin; break; + case 0: inst.op = Operation::AtomicExchange; break; + case 1: inst.op = Operation::AtomicAdd; break; + case 2: inst.op = Operation::AtomicSub; break; + case 3: inst.op = Operation::AtomicAnd; break; + case 4: inst.op = Operation::AtomicNand; break; + case 5: inst.op = Operation::AtomicOr; break; + case 6: inst.op = Operation::AtomicXor; break; + case 7: inst.op = Operation::AtomicMax; break; + case 8: inst.op = Operation::AtomicMin; break; + case 9: inst.op = Operation::AtomicUMax; break; + case 10: inst.op = Operation::AtomicUMin; break; default: RDCERR("Unhandled atomicrmw op %llu", opcode); - inst.op = Instruction::AtomicExchange; + inst.op = Operation::AtomicExchange; break; } @@ -2002,7 +2014,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::CompareExchange; + inst.op = Operation::CompareExchange; // pointer to atomically modify inst.args.push_back(op.getSymbol()); @@ -2096,7 +2108,7 @@ Program::Program(const byte *bytes, size_t length) { Instruction inst; - inst.op = Instruction::Fence; + inst.op = Operation::Fence; inst.type = GetVoidType(); @@ -2135,7 +2147,7 @@ Program::Program(const byte *bytes, size_t length) Instruction inst; - inst.op = Instruction::ExtractElement; + inst.op = Operation::ExtractElement; // vector inst.args.push_back(op.getSymbol()); @@ -2157,7 +2169,7 @@ Program::Program(const byte *bytes, size_t length) Instruction inst; - inst.op = Instruction::InsertElement; + inst.op = Operation::InsertElement; // vector inst.args.push_back(op.getSymbol()); @@ -2181,7 +2193,7 @@ Program::Program(const byte *bytes, size_t length) Instruction inst; - inst.op = Instruction::ShuffleVector; + inst.op = Operation::ShuffleVector; // vector 1 inst.args.push_back(op.getSymbol()); @@ -2220,7 +2232,7 @@ Program::Program(const byte *bytes, size_t length) Instruction inst; - inst.op = Instruction::InsertValue; + inst.op = Operation::InsertValue; // aggregate inst.args.push_back(op.getSymbol()); @@ -2279,9 +2291,9 @@ Program::Program(const byte *bytes, size_t length) } } - if(f.instructions[i].op == Instruction::Branch || - f.instructions[i].op == Instruction::Unreachable || - f.instructions[i].op == Instruction::Switch || f.instructions[i].op == Instruction::Ret) + if(f.instructions[i].op == Operation::Branch || + f.instructions[i].op == Operation::Unreachable || + f.instructions[i].op == Operation::Switch || f.instructions[i].op == Operation::Ret) { curBlock++; diff --git a/renderdoc/driver/shaders/dxil/dxil_bytecode.h b/renderdoc/driver/shaders/dxil/dxil_bytecode.h index 340fde037..e54e1a95d 100644 --- a/renderdoc/driver/shaders/dxil/dxil_bytecode.h +++ b/renderdoc/driver/shaders/dxil/dxil_bytecode.h @@ -204,18 +204,108 @@ struct Attributes rdcstr toString() const; }; +enum class Operation : uint8_t +{ + NoOp, + Call, + Trunc, + ZExt, + SExt, + FToU, + FToS, + UToF, + SToF, + FPTrunc, + FPExt, + PtrToI, + IToPtr, + Bitcast, + AddrSpaceCast, + ExtractVal, + Ret, + FAdd, + FSub, + FMul, + FDiv, + FRem, + Add, + Sub, + Mul, + UDiv, + SDiv, + URem, + SRem, + ShiftLeft, + LogicalShiftRight, + ArithShiftRight, + And, + Or, + Xor, + Unreachable, + Alloca, + GetElementPtr, + Load, + Store, + FOrdFalse, + FOrdEqual, + FOrdGreater, + FOrdGreaterEqual, + FOrdLess, + FOrdLessEqual, + FOrdNotEqual, + FOrd, + FUnord, + FUnordEqual, + FUnordGreater, + FUnordGreaterEqual, + FUnordLess, + FUnordLessEqual, + FUnordNotEqual, + FOrdTrue, + IEqual, + INotEqual, + UGreater, + UGreaterEqual, + ULess, + ULessEqual, + SGreater, + SGreaterEqual, + SLess, + SLessEqual, + Select, + ExtractElement, + InsertElement, + ShuffleVector, + InsertValue, + Branch, + Phi, + Switch, + Fence, + CompareExchange, + LoadAtomic, + StoreAtomic, + AtomicExchange, + AtomicAdd, + AtomicSub, + AtomicAnd, + AtomicNand, + AtomicOr, + AtomicXor, + AtomicMax, + AtomicMin, + AtomicUMax, + AtomicUMin, +}; + struct Constant { const Type *type = NULL; ShaderValue val = {}; rdcarray members; + const Constant *inner = NULL; rdcstr str; bool undef = false, nullconst = false, symbol = false; - enum ConstantOp : uint8_t - { - NoOp = 0, - GEP, - } op = NoOp; + Operation op = Operation::NoOp; rdcstr toString(bool withType = false) const; }; @@ -358,99 +448,7 @@ struct Block; struct Instruction { - enum - { - Unknown, - Call, - Trunc, - ZExt, - SExt, - FToU, - FToS, - UToF, - SToF, - FPTrunc, - FPExt, - PtrToI, - IToPtr, - Bitcast, - AddrSpaceCast, - ExtractVal, - Ret, - FAdd, - FSub, - FMul, - FDiv, - FRem, - Add, - Sub, - Mul, - UDiv, - SDiv, - URem, - SRem, - ShiftLeft, - LogicalShiftRight, - ArithShiftRight, - And, - Or, - Xor, - Unreachable, - Alloca, - GetElementPtr, - Load, - Store, - FOrdFalse, - FOrdEqual, - FOrdGreater, - FOrdGreaterEqual, - FOrdLess, - FOrdLessEqual, - FOrdNotEqual, - FOrd, - FUnord, - FUnordEqual, - FUnordGreater, - FUnordGreaterEqual, - FUnordLess, - FUnordLessEqual, - FUnordNotEqual, - FOrdTrue, - IEqual, - INotEqual, - UGreater, - UGreaterEqual, - ULess, - ULessEqual, - SGreater, - SGreaterEqual, - SLess, - SLessEqual, - Select, - ExtractElement, - InsertElement, - ShuffleVector, - InsertValue, - Branch, - Phi, - Switch, - Fence, - CompareExchange, - LoadAtomic, - StoreAtomic, - AtomicExchange, - AtomicAdd, - AtomicSub, - AtomicAnd, - AtomicNand, - AtomicOr, - AtomicXor, - AtomicMax, - AtomicMin, - AtomicUMax, - AtomicUMin, - } op = Unknown; - + Operation op = Operation::NoOp; InstructionFlags opFlags = InstructionFlags::NoFlags; // common to all instructions diff --git a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp index 2115f3d40..03c62e661 100644 --- a/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_disassemble.cpp @@ -613,8 +613,8 @@ void Program::MakeDisassemblyString() switch(inst.op) { - case Instruction::Unknown: m_Disassembly += "??? "; break; - case Instruction::Call: + case Operation::NoOp: m_Disassembly += "??? "; break; + case Operation::Call: { m_Disassembly += "call " + inst.type->toString(); m_Disassembly += " @" + escapeStringIfNeeded(inst.funcCall->name); @@ -632,35 +632,35 @@ void Program::MakeDisassemblyString() debugCall = inst.funcCall->name.beginsWith("llvm.dbg."); break; } - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FToU: - case Instruction::FToS: - case Instruction::UToF: - case Instruction::SToF: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::PtrToI: - case Instruction::IToPtr: - case Instruction::Bitcast: - case Instruction::AddrSpaceCast: + case Operation::Trunc: + case Operation::ZExt: + case Operation::SExt: + case Operation::FToU: + case Operation::FToS: + case Operation::UToF: + case Operation::SToF: + case Operation::FPTrunc: + case Operation::FPExt: + case Operation::PtrToI: + case Operation::IToPtr: + case Operation::Bitcast: + case Operation::AddrSpaceCast: { switch(inst.op) { - case Instruction::Trunc: m_Disassembly += "trunc "; break; - case Instruction::ZExt: m_Disassembly += "zext "; break; - case Instruction::SExt: m_Disassembly += "sext "; break; - case Instruction::FToU: m_Disassembly += "fptoui "; break; - case Instruction::FToS: m_Disassembly += "fptosi "; break; - case Instruction::UToF: m_Disassembly += "uitofp "; break; - case Instruction::SToF: m_Disassembly += "sitofp "; break; - case Instruction::FPTrunc: m_Disassembly += "fptrunc "; break; - case Instruction::FPExt: m_Disassembly += "fpext "; break; - case Instruction::PtrToI: m_Disassembly += "ptrtoi "; break; - case Instruction::IToPtr: m_Disassembly += "itoptr "; break; - case Instruction::Bitcast: m_Disassembly += "bitcast "; break; - case Instruction::AddrSpaceCast: m_Disassembly += "addrspacecast "; break; + case Operation::Trunc: m_Disassembly += "trunc "; break; + case Operation::ZExt: m_Disassembly += "zext "; break; + case Operation::SExt: m_Disassembly += "sext "; break; + case Operation::FToU: m_Disassembly += "fptoui "; break; + case Operation::FToS: m_Disassembly += "fptosi "; break; + case Operation::UToF: m_Disassembly += "uitofp "; break; + case Operation::SToF: m_Disassembly += "sitofp "; break; + case Operation::FPTrunc: m_Disassembly += "fptrunc "; break; + case Operation::FPExt: m_Disassembly += "fpext "; break; + case Operation::PtrToI: m_Disassembly += "ptrtoi "; break; + case Operation::IToPtr: m_Disassembly += "itoptr "; break; + case Operation::Bitcast: m_Disassembly += "bitcast "; break; + case Operation::AddrSpaceCast: m_Disassembly += "addrspacecast "; break; default: break; } @@ -669,7 +669,7 @@ void Program::MakeDisassemblyString() m_Disassembly += inst.type->toString(); break; } - case Instruction::ExtractVal: + case Operation::ExtractVal: { m_Disassembly += "extractvalue "; m_Disassembly += argToString(inst.args[0], true); @@ -677,45 +677,45 @@ void Program::MakeDisassemblyString() m_Disassembly += StringFormat::Fmt(", %llu", inst.args[n].idx); break; } - case Instruction::FAdd: - case Instruction::FSub: - case Instruction::FMul: - case Instruction::FDiv: - case Instruction::FRem: - case Instruction::Add: - case Instruction::Sub: - case Instruction::Mul: - case Instruction::UDiv: - case Instruction::SDiv: - case Instruction::URem: - case Instruction::SRem: - case Instruction::ShiftLeft: - case Instruction::LogicalShiftRight: - case Instruction::ArithShiftRight: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: + case Operation::FAdd: + case Operation::FSub: + case Operation::FMul: + case Operation::FDiv: + case Operation::FRem: + case Operation::Add: + case Operation::Sub: + case Operation::Mul: + case Operation::UDiv: + case Operation::SDiv: + case Operation::URem: + case Operation::SRem: + case Operation::ShiftLeft: + case Operation::LogicalShiftRight: + case Operation::ArithShiftRight: + case Operation::And: + case Operation::Or: + case Operation::Xor: { switch(inst.op) { - case Instruction::FAdd: m_Disassembly += "fadd "; break; - case Instruction::FSub: m_Disassembly += "fsub "; break; - case Instruction::FMul: m_Disassembly += "fmul "; break; - case Instruction::FDiv: m_Disassembly += "fdiv "; break; - case Instruction::FRem: m_Disassembly += "frem "; break; - case Instruction::Add: m_Disassembly += "add "; break; - case Instruction::Sub: m_Disassembly += "sub "; break; - case Instruction::Mul: m_Disassembly += "mul "; break; - case Instruction::UDiv: m_Disassembly += "udiv "; break; - case Instruction::SDiv: m_Disassembly += "sdiv "; break; - case Instruction::URem: m_Disassembly += "urem "; break; - case Instruction::SRem: m_Disassembly += "srem "; break; - case Instruction::ShiftLeft: m_Disassembly += "shl "; break; - case Instruction::LogicalShiftRight: m_Disassembly += "lshr "; break; - case Instruction::ArithShiftRight: m_Disassembly += "ashr "; break; - case Instruction::And: m_Disassembly += "and "; break; - case Instruction::Or: m_Disassembly += "or "; break; - case Instruction::Xor: m_Disassembly += "xor "; break; + case Operation::FAdd: m_Disassembly += "fadd "; break; + case Operation::FSub: m_Disassembly += "fsub "; break; + case Operation::FMul: m_Disassembly += "fmul "; break; + case Operation::FDiv: m_Disassembly += "fdiv "; break; + case Operation::FRem: m_Disassembly += "frem "; break; + case Operation::Add: m_Disassembly += "add "; break; + case Operation::Sub: m_Disassembly += "sub "; break; + case Operation::Mul: m_Disassembly += "mul "; break; + case Operation::UDiv: m_Disassembly += "udiv "; break; + case Operation::SDiv: m_Disassembly += "sdiv "; break; + case Operation::URem: m_Disassembly += "urem "; break; + case Operation::SRem: m_Disassembly += "srem "; break; + case Operation::ShiftLeft: m_Disassembly += "shl "; break; + case Operation::LogicalShiftRight: m_Disassembly += "lshr "; break; + case Operation::ArithShiftRight: m_Disassembly += "ashr "; break; + case Operation::And: m_Disassembly += "and "; break; + case Operation::Or: m_Disassembly += "or "; break; + case Operation::Xor: m_Disassembly += "xor "; break; default: break; } @@ -744,9 +744,9 @@ void Program::MakeDisassemblyString() break; } - case Instruction::Ret: m_Disassembly += "ret " + inst.type->toString(); break; - case Instruction::Unreachable: m_Disassembly += "unreachable"; break; - case Instruction::Alloca: + case Operation::Ret: m_Disassembly += "ret " + inst.type->toString(); break; + case Operation::Unreachable: m_Disassembly += "unreachable"; break; + case Operation::Alloca: { m_Disassembly += "alloca "; m_Disassembly += inst.type->inner->toString(); @@ -754,7 +754,7 @@ void Program::MakeDisassemblyString() m_Disassembly += StringFormat::Fmt(", align %u", inst.align); break; } - case Instruction::GetElementPtr: + case Operation::GetElementPtr: { m_Disassembly += "getelementptr "; if(inst.opFlags & InstructionFlags::InBounds) @@ -772,7 +772,7 @@ void Program::MakeDisassemblyString() } break; } - case Instruction::Load: + case Operation::Load: { m_Disassembly += "load "; if(inst.opFlags & InstructionFlags::Volatile) @@ -792,7 +792,7 @@ void Program::MakeDisassemblyString() m_Disassembly += StringFormat::Fmt(", align %u", inst.align); break; } - case Instruction::Store: + case Operation::Store: { m_Disassembly += "store "; if(inst.opFlags & InstructionFlags::Volatile) @@ -804,22 +804,22 @@ void Program::MakeDisassemblyString() m_Disassembly += StringFormat::Fmt(", align %u", inst.align); break; } - case Instruction::FOrdFalse: - case Instruction::FOrdEqual: - case Instruction::FOrdGreater: - case Instruction::FOrdGreaterEqual: - case Instruction::FOrdLess: - case Instruction::FOrdLessEqual: - case Instruction::FOrdNotEqual: - case Instruction::FOrd: - case Instruction::FUnord: - case Instruction::FUnordEqual: - case Instruction::FUnordGreater: - case Instruction::FUnordGreaterEqual: - case Instruction::FUnordLess: - case Instruction::FUnordLessEqual: - case Instruction::FUnordNotEqual: - case Instruction::FOrdTrue: + case Operation::FOrdFalse: + case Operation::FOrdEqual: + case Operation::FOrdGreater: + case Operation::FOrdGreaterEqual: + case Operation::FOrdLess: + case Operation::FOrdLessEqual: + case Operation::FOrdNotEqual: + case Operation::FOrd: + case Operation::FUnord: + case Operation::FUnordEqual: + case Operation::FUnordGreater: + case Operation::FUnordGreaterEqual: + case Operation::FUnordLess: + case Operation::FUnordLessEqual: + case Operation::FUnordNotEqual: + case Operation::FOrdTrue: { m_Disassembly += "fcmp "; rdcstr opFlagsStr = ToStr(inst.opFlags); @@ -836,22 +836,22 @@ void Program::MakeDisassemblyString() m_Disassembly += " "; switch(inst.op) { - case Instruction::FOrdFalse: m_Disassembly += "false "; break; - case Instruction::FOrdEqual: m_Disassembly += "oeq "; break; - case Instruction::FOrdGreater: m_Disassembly += "ogt "; break; - case Instruction::FOrdGreaterEqual: m_Disassembly += "oge "; break; - case Instruction::FOrdLess: m_Disassembly += "olt "; break; - case Instruction::FOrdLessEqual: m_Disassembly += "ole "; break; - case Instruction::FOrdNotEqual: m_Disassembly += "one "; break; - case Instruction::FOrd: m_Disassembly += "ord "; break; - case Instruction::FUnord: m_Disassembly += "uno "; break; - case Instruction::FUnordEqual: m_Disassembly += "ueq "; break; - case Instruction::FUnordGreater: m_Disassembly += "ugt "; break; - case Instruction::FUnordGreaterEqual: m_Disassembly += "uge "; break; - case Instruction::FUnordLess: m_Disassembly += "ult "; break; - case Instruction::FUnordLessEqual: m_Disassembly += "ule "; break; - case Instruction::FUnordNotEqual: m_Disassembly += "une "; break; - case Instruction::FOrdTrue: m_Disassembly += "true "; break; + case Operation::FOrdFalse: m_Disassembly += "false "; break; + case Operation::FOrdEqual: m_Disassembly += "oeq "; break; + case Operation::FOrdGreater: m_Disassembly += "ogt "; break; + case Operation::FOrdGreaterEqual: m_Disassembly += "oge "; break; + case Operation::FOrdLess: m_Disassembly += "olt "; break; + case Operation::FOrdLessEqual: m_Disassembly += "ole "; break; + case Operation::FOrdNotEqual: m_Disassembly += "one "; break; + case Operation::FOrd: m_Disassembly += "ord "; break; + case Operation::FUnord: m_Disassembly += "uno "; break; + case Operation::FUnordEqual: m_Disassembly += "ueq "; break; + case Operation::FUnordGreater: m_Disassembly += "ugt "; break; + case Operation::FUnordGreaterEqual: m_Disassembly += "uge "; break; + case Operation::FUnordLess: m_Disassembly += "ult "; break; + case Operation::FUnordLessEqual: m_Disassembly += "ule "; break; + case Operation::FUnordNotEqual: m_Disassembly += "une "; break; + case Operation::FOrdTrue: m_Disassembly += "true "; break; default: break; } m_Disassembly += argToString(inst.args[0], true); @@ -859,30 +859,30 @@ void Program::MakeDisassemblyString() m_Disassembly += argToString(inst.args[1], false); break; } - case Instruction::IEqual: - case Instruction::INotEqual: - case Instruction::UGreater: - case Instruction::UGreaterEqual: - case Instruction::ULess: - case Instruction::ULessEqual: - case Instruction::SGreater: - case Instruction::SGreaterEqual: - case Instruction::SLess: - case Instruction::SLessEqual: + case Operation::IEqual: + case Operation::INotEqual: + case Operation::UGreater: + case Operation::UGreaterEqual: + case Operation::ULess: + case Operation::ULessEqual: + case Operation::SGreater: + case Operation::SGreaterEqual: + case Operation::SLess: + case Operation::SLessEqual: { m_Disassembly += "icmp "; switch(inst.op) { - case Instruction::IEqual: m_Disassembly += "eq "; break; - case Instruction::INotEqual: m_Disassembly += "ne "; break; - case Instruction::UGreater: m_Disassembly += "ugt "; break; - case Instruction::UGreaterEqual: m_Disassembly += "uge "; break; - case Instruction::ULess: m_Disassembly += "ult "; break; - case Instruction::ULessEqual: m_Disassembly += "ule "; break; - case Instruction::SGreater: m_Disassembly += "sgt "; break; - case Instruction::SGreaterEqual: m_Disassembly += "sge "; break; - case Instruction::SLess: m_Disassembly += "slt "; break; - case Instruction::SLessEqual: m_Disassembly += "sle "; break; + case Operation::IEqual: m_Disassembly += "eq "; break; + case Operation::INotEqual: m_Disassembly += "ne "; break; + case Operation::UGreater: m_Disassembly += "ugt "; break; + case Operation::UGreaterEqual: m_Disassembly += "uge "; break; + case Operation::ULess: m_Disassembly += "ult "; break; + case Operation::ULessEqual: m_Disassembly += "ule "; break; + case Operation::SGreater: m_Disassembly += "sgt "; break; + case Operation::SGreaterEqual: m_Disassembly += "sge "; break; + case Operation::SLess: m_Disassembly += "slt "; break; + case Operation::SLessEqual: m_Disassembly += "sle "; break; default: break; } m_Disassembly += argToString(inst.args[0], true); @@ -890,7 +890,7 @@ void Program::MakeDisassemblyString() m_Disassembly += argToString(inst.args[1], false); break; } - case Instruction::Select: + case Operation::Select: { m_Disassembly += "select "; m_Disassembly += argToString(inst.args[2], true); @@ -900,7 +900,7 @@ void Program::MakeDisassemblyString() m_Disassembly += argToString(inst.args[1], true); break; } - case Instruction::ExtractElement: + case Operation::ExtractElement: { m_Disassembly += "extractelement "; m_Disassembly += argToString(inst.args[0], true); @@ -908,7 +908,7 @@ void Program::MakeDisassemblyString() m_Disassembly += argToString(inst.args[1], true); break; } - case Instruction::InsertElement: + case Operation::InsertElement: { m_Disassembly += "insertelement "; m_Disassembly += argToString(inst.args[0], true); @@ -918,7 +918,7 @@ void Program::MakeDisassemblyString() m_Disassembly += argToString(inst.args[2], true); break; } - case Instruction::ShuffleVector: + case Operation::ShuffleVector: { m_Disassembly += "shufflevector "; m_Disassembly += argToString(inst.args[0], true); @@ -928,7 +928,7 @@ void Program::MakeDisassemblyString() m_Disassembly += argToString(inst.args[2], true); break; } - case Instruction::InsertValue: + case Operation::InsertValue: { m_Disassembly += "insertvalue "; m_Disassembly += argToString(inst.args[0], true); @@ -940,7 +940,7 @@ void Program::MakeDisassemblyString() } break; } - case Instruction::Branch: + case Operation::Branch: { m_Disassembly += "br "; if(inst.args.size() > 1) @@ -955,7 +955,7 @@ void Program::MakeDisassemblyString() } break; } - case Instruction::Phi: + case Operation::Phi: { m_Disassembly += "phi "; m_Disassembly += inst.type->toString(); @@ -971,7 +971,7 @@ void Program::MakeDisassemblyString() } break; } - case Instruction::Switch: + case Operation::Switch: { m_Disassembly += "switch "; m_Disassembly += argToString(inst.args[0], true); @@ -990,7 +990,7 @@ void Program::MakeDisassemblyString() m_Disassembly += " ]"; break; } - case Instruction::Fence: + case Operation::Fence: { m_Disassembly += "fence "; if(inst.opFlags & InstructionFlags::SingleThread) @@ -1008,7 +1008,7 @@ void Program::MakeDisassemblyString() default: break; } } - case Instruction::LoadAtomic: + case Operation::LoadAtomic: { m_Disassembly += "load atomic "; if(inst.opFlags & InstructionFlags::Volatile) @@ -1027,7 +1027,7 @@ void Program::MakeDisassemblyString() m_Disassembly += StringFormat::Fmt(", align %u", inst.align); break; } - case Instruction::StoreAtomic: + case Operation::StoreAtomic: { m_Disassembly += "store atomic "; if(inst.opFlags & InstructionFlags::Volatile) @@ -1038,7 +1038,7 @@ void Program::MakeDisassemblyString() m_Disassembly += StringFormat::Fmt(", align %u", inst.align); break; } - case Instruction::CompareExchange: + case Operation::CompareExchange: { m_Disassembly += "cmpxchg "; if(inst.opFlags & InstructionFlags::Weak) @@ -1086,34 +1086,34 @@ void Program::MakeDisassemblyString() } break; } - case Instruction::AtomicExchange: - case Instruction::AtomicAdd: - case Instruction::AtomicSub: - case Instruction::AtomicAnd: - case Instruction::AtomicNand: - case Instruction::AtomicOr: - case Instruction::AtomicXor: - case Instruction::AtomicMax: - case Instruction::AtomicMin: - case Instruction::AtomicUMax: - case Instruction::AtomicUMin: + case Operation::AtomicExchange: + case Operation::AtomicAdd: + case Operation::AtomicSub: + case Operation::AtomicAnd: + case Operation::AtomicNand: + case Operation::AtomicOr: + case Operation::AtomicXor: + case Operation::AtomicMax: + case Operation::AtomicMin: + case Operation::AtomicUMax: + case Operation::AtomicUMin: { m_Disassembly += "atomicrmw "; if(inst.opFlags & InstructionFlags::Volatile) m_Disassembly += "volatile "; switch(inst.op) { - case Instruction::AtomicExchange: m_Disassembly += "xchg "; break; - case Instruction::AtomicAdd: m_Disassembly += "add "; break; - case Instruction::AtomicSub: m_Disassembly += "sub "; break; - case Instruction::AtomicAnd: m_Disassembly += "and "; break; - case Instruction::AtomicNand: m_Disassembly += "nand "; break; - case Instruction::AtomicOr: m_Disassembly += "or "; break; - case Instruction::AtomicXor: m_Disassembly += "xor "; break; - case Instruction::AtomicMax: m_Disassembly += "max "; break; - case Instruction::AtomicMin: m_Disassembly += "min "; break; - case Instruction::AtomicUMax: m_Disassembly += "umax "; break; - case Instruction::AtomicUMin: m_Disassembly += "umin "; break; + case Operation::AtomicExchange: m_Disassembly += "xchg "; break; + case Operation::AtomicAdd: m_Disassembly += "add "; break; + case Operation::AtomicSub: m_Disassembly += "sub "; break; + case Operation::AtomicAnd: m_Disassembly += "and "; break; + case Operation::AtomicNand: m_Disassembly += "nand "; break; + case Operation::AtomicOr: m_Disassembly += "or "; break; + case Operation::AtomicXor: m_Disassembly += "xor "; break; + case Operation::AtomicMax: m_Disassembly += "max "; break; + case Operation::AtomicMin: m_Disassembly += "min "; break; + case Operation::AtomicUMax: m_Disassembly += "umax "; break; + case Operation::AtomicUMin: m_Disassembly += "umin "; break; default: break; } @@ -1335,8 +1335,8 @@ void Program::MakeDisassemblyString() if(funcIdx == func.instructions.size() - 1) break; - if(inst.op == Instruction::Branch || inst.op == Instruction::Unreachable || - inst.op == Instruction::Switch || inst.op == Instruction::Ret) + if(inst.op == Operation::Branch || inst.op == Operation::Unreachable || + inst.op == Operation::Switch || inst.op == Operation::Ret) { m_Disassembly += "\n"; instructionLine++; @@ -1645,12 +1645,12 @@ rdcstr Constant::toString(bool withType) const { ret += StringFormat::Fmt("@%s", escapeStringIfNeeded(str).c_str()); } - else if(op != Constant::NoOp) + else if(op != Operation::NoOp) { switch(op) { - case Constant::NoOp: break; - case Constant::GEP: + default: break; + case Operation::GetElementPtr: { ret += "getelementptr inbounds ("; @@ -1664,6 +1664,46 @@ rdcstr Constant::toString(bool withType) const ret += members[i].toString(withType); } ret += ")"; + break; + } + case Operation::Trunc: + case Operation::ZExt: + case Operation::SExt: + case Operation::FToU: + case Operation::FToS: + case Operation::UToF: + case Operation::SToF: + case Operation::FPTrunc: + case Operation::FPExt: + case Operation::PtrToI: + case Operation::IToPtr: + case Operation::Bitcast: + case Operation::AddrSpaceCast: + { + switch(op) + { + case Operation::Trunc: ret += "trunc "; break; + case Operation::ZExt: ret += "zext "; break; + case Operation::SExt: ret += "sext "; break; + case Operation::FToU: ret += "fptoui "; break; + case Operation::FToS: ret += "fptosi "; break; + case Operation::UToF: ret += "uitofp "; break; + case Operation::SToF: ret += "sitofp "; break; + case Operation::FPTrunc: ret += "fptrunc "; break; + case Operation::FPExt: ret += "fpext "; break; + case Operation::PtrToI: ret += "ptrtoi "; break; + case Operation::IToPtr: ret += "itoptr "; break; + case Operation::Bitcast: ret += "bitcast "; break; + case Operation::AddrSpaceCast: ret += "addrspacecast "; break; + default: break; + } + + ret += "("; + ret += inner->toString(withType); + ret += " to "; + ret += type->toString(); + ret += ")"; + break; } } }