Add brackets around nested math operations for precedence clarity

This commit is contained in:
baldurk
2016-02-07 18:41:40 +01:00
parent 2a230ecc00
commit 6642685069
@@ -275,7 +275,7 @@ struct SPVTypeData
struct SPVOperation
{
SPVOperation() : type(NULL), complexity(0), inlineArgs(0) {}
SPVOperation() : type(NULL), access(spv::MemoryAccessMaskNone), funcCall(0), complexity(0), mathop(false), inlineArgs(0) {}
SPVTypeData *type;
@@ -293,6 +293,11 @@ struct SPVOperation
// disassembly.
int complexity;
// if this operation will be of the form 'a + b', we need to be sure
// to bracket any arguments that are mathops in nested expressions,
// to make order of operations clear.
bool mathop;
// bitfield indicating which arguments should be inlined
uint32_t inlineArgs;
@@ -822,40 +827,76 @@ struct SPVInstruction
return ret;
}
case spv::OpIAdd:
case spv::OpIMul:
case spv::OpFAdd:
case spv::OpFMul:
case spv::OpVectorTimesScalar:
case spv::OpMatrixTimesVector:
case spv::OpSLessThan:
case spv::OpFNegate:
{
// unary math operation
RDCASSERT(op);
char c = '?';
switch(opcode)
{
case spv::OpIAdd:
case spv::OpFAdd:
c = '+';
break;
case spv::OpIMul:
case spv::OpFMul:
case spv::OpVectorTimesScalar:
case spv::OpMatrixTimesVector:
c = '*';
break;
case spv::OpSLessThan:
c = '<';
break;
default:
break;
case spv::OpFNegate:
c = '-';
break;
default:
break;
}
string a;
op->GetArg(ids, 0, a);
if(op->arguments[0]->op && op->arguments[0]->op->mathop)
a = "(" + a + ")";
if(inlineOp)
return StringFormat::Fmt("%c%s", c, a.c_str());
return StringFormat::Fmt("%s %s = %c%s", op->type->GetName().c_str(), GetIDName().c_str(), c, a.c_str());
}
case spv::OpIAdd:
case spv::OpIMul:
case spv::OpFAdd:
case spv::OpFMul:
case spv::OpFDiv:
case spv::OpVectorTimesScalar:
case spv::OpMatrixTimesVector:
case spv::OpSLessThan:
{
// binary math operation
RDCASSERT(op);
char c = '?';
switch(opcode)
{
case spv::OpIAdd:
case spv::OpFAdd:
c = '+';
break;
case spv::OpIMul:
case spv::OpFMul:
case spv::OpVectorTimesScalar:
case spv::OpMatrixTimesVector:
c = '*';
break;
case spv::OpSLessThan:
c = '<';
break;
case spv::OpFDiv:
c = '/';
break;
default:
break;
}
string a, b;
op->GetArg(ids, 0, a);
op->GetArg(ids, 1, b);
if(op->arguments[0]->op && op->arguments[0]->op->mathop)
a = "(" + a + ")";
if(op->arguments[1]->op && op->arguments[1]->op->mathop)
b = "(" + b + ")";
if(inlineOp)
return StringFormat::Fmt("%s %c %s", a.c_str(), c, b.c_str());
@@ -1561,6 +1602,8 @@ void DisassembleSPIRV(SPIRVShaderStage shadType, uint32_t *spirv, size_t spirvLe
op.opcode = spv::Op(spirv[it]&0xffff);
bool mathop = false;
switch(op.opcode)
{
//////////////////////////////////////////////////////////////////////
@@ -2147,20 +2190,24 @@ void DisassembleSPIRV(SPIRVShaderStage shadType, uint32_t *spirv, size_t spirvLe
}
//////////////////////////////////////////////////////////////////////
// Easy to handle opcodes with just some number of ID parameters
case spv::OpAccessChain:
case spv::OpIAdd:
case spv::OpIMul:
case spv::OpFAdd:
case spv::OpFMul:
case spv::OpFDiv:
case spv::OpVectorTimesScalar:
case spv::OpMatrixTimesVector:
case spv::OpSLessThan:
case spv::OpFNegate:
mathop = true; // deliberate fallthrough
case spv::OpAccessChain:
{
SPVInstruction *typeInst = module.GetByID(spirv[it+1]);
RDCASSERT(typeInst && typeInst->type);
op.op = new SPVOperation();
op.op->type = typeInst->type;
op.op->mathop = mathop;
for(int i=3; i < WordCount; i++)
{