mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 21:10:42 +00:00
Handle switch opcode
This commit is contained in:
@@ -1616,14 +1616,12 @@ Program::Program(const byte *bytes, size_t length)
|
||||
|
||||
// true destination
|
||||
inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[0]));
|
||||
|
||||
f.blocks[op.ops[0]].preds.insert(0, &f.blocks[curBlock]);
|
||||
|
||||
if(op.ops.size() > 1)
|
||||
{
|
||||
// false destination
|
||||
inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[1]));
|
||||
|
||||
f.blocks[op.ops[1]].preds.insert(0, &f.blocks[curBlock]);
|
||||
|
||||
// predicate
|
||||
@@ -1634,6 +1632,62 @@ Program::Program(const byte *bytes, size_t length)
|
||||
|
||||
f.instructions.push_back(inst);
|
||||
}
|
||||
else if(IS_KNOWN(op.id, FunctionRecord::INST_SWITCH))
|
||||
{
|
||||
Instruction inst;
|
||||
|
||||
inst.op = Instruction::Switch;
|
||||
|
||||
inst.type = GetVoidType();
|
||||
|
||||
uint64_t typeIdx = op.ops[0];
|
||||
|
||||
static const uint64_t SWITCH_INST_MAGIC = 0x4B5;
|
||||
if((typeIdx >> 16) == SWITCH_INST_MAGIC)
|
||||
{
|
||||
// type of condition
|
||||
const Type *condType = &m_Types[op.ops[1]];
|
||||
|
||||
RDCASSERT(condType->bitWidth <= 64);
|
||||
|
||||
// condition
|
||||
inst.args.push_back(getSymbol(op.ops[2]));
|
||||
|
||||
// default block
|
||||
inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[3]));
|
||||
f.blocks[op.ops[3]].preds.insert(0, &f.blocks[curBlock]);
|
||||
|
||||
RDCERR("Unsupported switch instruction version");
|
||||
}
|
||||
else
|
||||
{
|
||||
// type of condition, ignored
|
||||
// op.ops[0]
|
||||
|
||||
// condition
|
||||
inst.args.push_back(getSymbol(op.ops[1]));
|
||||
|
||||
// default block
|
||||
inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[2]));
|
||||
f.blocks[op.ops[2]].preds.insert(0, &f.blocks[curBlock]);
|
||||
|
||||
uint64_t numCases = (op.ops.size() - 3) / 2;
|
||||
|
||||
for(uint64_t c = 0; c < numCases; c++)
|
||||
{
|
||||
// case value, absolute not relative
|
||||
inst.args.push_back(m_Symbols[op.ops[3 + c * 2 + 0]]);
|
||||
|
||||
// case block
|
||||
inst.args.push_back(Symbol(SymbolType::BasicBlock, op.ops[3 + c * 2 + 1]));
|
||||
f.blocks[op.ops[3 + c * 2 + 1]].preds.insert(0, &f.blocks[curBlock]);
|
||||
}
|
||||
}
|
||||
|
||||
curBlock++;
|
||||
|
||||
f.instructions.push_back(inst);
|
||||
}
|
||||
else if(IS_KNOWN(op.id, FunctionRecord::INST_PHI))
|
||||
{
|
||||
Instruction inst;
|
||||
@@ -1802,7 +1856,8 @@ Program::Program(const byte *bytes, size_t length)
|
||||
for(size_t i = 0, resultID = 1; i < f.instructions.size(); i++)
|
||||
{
|
||||
if(f.instructions[i].op == Instruction::Branch ||
|
||||
f.instructions[i].op == Instruction::Unreachable)
|
||||
f.instructions[i].op == Instruction::Unreachable ||
|
||||
f.instructions[i].op == Instruction::Switch)
|
||||
{
|
||||
curBlock++;
|
||||
if(f.blocks[curBlock].name.empty())
|
||||
|
||||
@@ -388,6 +388,7 @@ struct Instruction
|
||||
InsertValue,
|
||||
Branch,
|
||||
Phi,
|
||||
Switch,
|
||||
} op = Unknown;
|
||||
|
||||
InstructionFlags opFlags = InstructionFlags::NoFlags;
|
||||
|
||||
@@ -395,8 +395,12 @@ void Program::MakeDisassemblyString()
|
||||
switch(s.type)
|
||||
{
|
||||
case SymbolType::Unknown:
|
||||
case SymbolType::Alias:
|
||||
case SymbolType::Literal: ret = "???"; break;
|
||||
case SymbolType::Alias: ret = "???"; break;
|
||||
case SymbolType::Literal:
|
||||
if(withTypes)
|
||||
ret += "i32 ";
|
||||
ret += StringFormat::Fmt("%lld", s.idx);
|
||||
break;
|
||||
case SymbolType::Metadata:
|
||||
if(withTypes)
|
||||
ret += "metadata ";
|
||||
@@ -835,6 +839,25 @@ void Program::MakeDisassemblyString()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Switch:
|
||||
{
|
||||
m_Disassembly += "switch ";
|
||||
m_Disassembly += argToString(inst.args[0], true);
|
||||
m_Disassembly += ", ";
|
||||
m_Disassembly += argToString(inst.args[1], true);
|
||||
m_Disassembly += " [";
|
||||
m_Disassembly += "\n";
|
||||
instructionLine++;
|
||||
for(size_t a = 2; a < inst.args.size(); a += 2)
|
||||
{
|
||||
m_Disassembly +=
|
||||
StringFormat::Fmt(" %s, %s\n", argToString(inst.args[a], true).c_str(),
|
||||
argToString(inst.args[a + 1], true).c_str());
|
||||
instructionLine++;
|
||||
}
|
||||
m_Disassembly += " ]";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(inst.debugLoc != ~0U)
|
||||
@@ -905,7 +928,8 @@ void Program::MakeDisassemblyString()
|
||||
m_Disassembly += "\n";
|
||||
instructionLine++;
|
||||
|
||||
if(inst.op == Instruction::Branch || inst.op == Instruction::Unreachable)
|
||||
if(inst.op == Instruction::Branch || inst.op == Instruction::Unreachable ||
|
||||
inst.op == Instruction::Switch)
|
||||
{
|
||||
m_Disassembly += "\n";
|
||||
instructionLine++;
|
||||
@@ -939,6 +963,7 @@ void Program::MakeDisassemblyString()
|
||||
|
||||
m_Disassembly += labelName;
|
||||
m_Disassembly += "\n";
|
||||
instructionLine++;
|
||||
}
|
||||
}
|
||||
m_Disassembly += "}\n\n";
|
||||
|
||||
Reference in New Issue
Block a user