<div dir="ltr">Hello.<div><br></div><div style>Sometimes the constraints imposed on an instruction's encoding are too complex to be described in tablegen alone. In such cases a custom decoder method is implemented. This makes sense when the decoding itself is very complex, but it is wasteful to do it only when checking additional constraints. This is because:</div>
<div style><br></div><div style>1. a custom decoder method has to decode operands, set opcodes, etc. - many times the tablegen generated decoder is perfectly capable of doing this job so there is no reason in doing it by hand</div>
<div style>2. when custom decoder methods are implemented for similar-looking instructions there is high chance of code duplication (i.e. reading the fields out of the encoding, setting opcodes using the same logic but with different enums, etc.).</div>
<div style><br></div><div style>Here is a practical example: ARM NEON vector instructions may work in either double word mode (taking d registers) or in quad word mode (taking q registers). The mode is selected by bit 6 (Q bit). When Q == 1, then quad word mode is used.</div>
<div style><br></div><div style>There is an additional constraint: whenever Q == 1, the registers encoded in the instruction need to be even. Otherwise the encoding is undefined. </div><div style><br></div><div style>This constraint is currently unimplemented and triggers incorrect behaviour in the MC disassembler. In order to correct this I would have to create custom decoder methods for a dozen-some instructions which is wasteful. I would much prefer to be able to define a constraint function like:</div>
<div style><br></div><div style><font face="courier new, monospace">static DecodeStatus CheckNEONConstraint(const MCInst &Inst, unsigned Insn)<br></font></div><div style><font face="courier new, monospace">{</font></div>
<div style><font face="courier new, monospace"> Vd = fieldFromInstruction(Insn, 12, 4);</font></div><div style><font face="courier new, monospace"> Vm = fieldFromInstruction(Insn, 0, 4);</font><div><font face="courier new, monospace"> Vn = fieldFromInstruction(Insn, 16, 4);</font></div>
<div><font face="courier new, monospace"> Q = fieldFromInstruction(Insn, 6, 1); <br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> if (Q == 1 && ((Vd & 1) || (Vm & 1) || (Vn & 1)))<br>
</font></div><div><font face="courier new, monospace"> return MCDisassembler::Fail;</font></div><div><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace"> return MCDIsassembler::Success;</font></div>
<font face="courier new, monospace">}</font></div><div style><br></div><div style>Then I'd like to use this in the td file with something along the lines of </div><div style><br></div><div style><font face="courier new, monospace">ConstraintCheckMethod = "CheckNEONConstraint"</font></div>
<div style><br></div><div style>in the superclass of NEON instructions.</div><div style><br></div><div style>I envision this as the very last step in deciding whether an encoding is valid or not. In my example the tablegen generated decoder would "decode" the invalid encoding and create a MCInst but, because this final test returns failure, the encoding is rejected.</div>
<div style><br></div><div style>What do you guys think about this? I feel it'll generally simplify things and could be an opportunity to get rid of some of the custom decoder methods.</div><div style><br></div><div style>
Mihai</div></div>