Support cast constant operations

This commit is contained in:
baldurk
2020-06-19 17:43:08 +01:00
parent 2c998ffbb2
commit f2ff54dcea
3 changed files with 412 additions and 362 deletions
+114 -102
View File
@@ -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<const Type *(uint64_t)> getType,
std::function<const Type *(const Type *)> 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<size_t>()];
uint64_t callingFlags = op.get<uint64_t>();
@@ -1339,26 +1370,7 @@ Program::Program(const byte *bytes, size_t length)
inst.type = op.getType();
uint64_t opcode = op.get<uint64_t>();
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<uint64_t>();
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<uint64_t>();
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<uint64_t>();
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<uint64_t>();
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++;
+96 -98
View File
@@ -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<Constant> 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
+202 -162
View File
@@ -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;
}
}
}