///
/// Statepoint operands take the form:
/// <id>, <num patch bytes >, <num call arguments>, <call target>,
-/// [call arguments], <StackMaps::ConstantOp>, <calling convention>,
+/// [call arguments...],
+/// <StackMaps::ConstantOp>, <calling convention>,
/// <StackMaps::ConstantOp>, <statepoint flags>,
-/// <StackMaps::ConstantOp>, <num other args>, [other args],
-/// [gc values]
+/// <StackMaps::ConstantOp>, <num deopt args>, [deopt args...],
+/// <gc base/derived pairs...> <gc allocas...>
+/// Note that the last two sets of arguments are not currently length
+/// prefixed.
class StatepointOpers {
+ // TODO:: we should change the STATEPOINT representation so that CC and
+ // Flags should be part of meta operands, with args and deopt operands, and
+ // gc operands all prefixed by their length and a type code. This would be
+ // much more consistent.
public:
// These values are aboolute offsets into the operands of the statepoint
// instruction.
// These values are relative offests from the start of the statepoint meta
// arguments (i.e. the end of the call arguments).
- enum { CCOffset = 1, FlagsOffset = 3, NumVMSArgsOffset = 5 };
+ enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
!MI->getOperand(StatepointOpers::NCallArgsPos).isImm())
report("meta operands to STATEPOINT not constant!", MI);
break;
+
+ auto VerifyStackMapConstant = [&](unsigned Offset) {
+ if (!MI->getOperand(Offset).isImm() ||
+ MI->getOperand(Offset).getImm() != StackMaps::ConstantOp ||
+ !MI->getOperand(Offset + 1).isImm())
+ report("stack map constant to STATEPOINT not well formed!", MI);
+ };
+ const unsigned VarStart = StatepointOpers(MI).getVarIdx();
+ VerifyStackMapConstant(VarStart + StatepointOpers::CCOffset);
+ VerifyStackMapConstant(VarStart + StatepointOpers::FlagsOffset);
+ VerifyStackMapConstant(VarStart + StatepointOpers::NumDeoptOperandsOffset);
+
+ // TODO: verify we have properly encoded deopt arguments
+
};
}