This is an archive of the discontinued LLVM Phabricator instance.

[ARM] Refactor handling of IT mask operands.
ClosedPublic

Authored by simon_tatham on Jun 12 2019, 9:36 AM.

Details

Summary

During assembly, the mask operand to an IT instruction (storing the
sequence of T/E for 'Then' and 'Else') is parsed out of the mnemonic
into a representation that encodes 'Then' and 'Else' in the same way
regardless of the condition code. At some point during encoding it has
to be converted into the instruction encoding used in the
architecture, in which the mask encodes a sequence of replacement
low-order bits for the condition code, so that which bit value means
'then' and which 'else' depends on whether the original condition code
had its low bit set.

Previously, that transformation was done by processInstruction(), half
way through assembly. So an MCOperand storing an IT mask would
sometimes store it in one format, and sometimes in the other,
depending on where in the assembly pipeline you were. You can see this
in diagnostics from llvm-mc -debug -triple=thumbv8a -show-inst, for
example: if you give it an instruction such as itete eq, you'd see
an <MCOperand Imm:5> in a diagnostic become <MCOperand Imm:11> in
the final output.

Having the same data structure store values with time-dependent
semantics is confusing already, and it will get more confusing when we
introduce the MVE VPT instruction which reuses the Then/Else bitmask
idea in a different context. So I'm refactoring: now, all ARMOperand
and MCOperand representations of an IT mask work exactly the same
way, namely, 0 means 'Then' and 1 means 'Else', regardless of what
original predicate is being referred to. The architectural encoding of
IT that depends on the original condition is now constructed at the
point when we turn the MCOperand into the final instruction bit
pattern, and decoded similarly in the disassembler.

The previous condition-independent parse-time format used 0 for Else
and 1 for Then. I've taken the opportunity to flip the sense of it
while I'm changing all of this anyway, because it seems to me more
natural to use 0 for 'leave the starting condition unchanged' and 1
for 'invert it', as if those bits were an XOR mask.

Diff Detail

Repository
rL LLVM

Event Timeline

simon_tatham created this revision.Jun 12 2019, 9:36 AM
ostannard accepted this revision.Jun 13 2019, 2:23 AM

LGTM, thanks!

This revision is now accepted and ready to land.Jun 13 2019, 2:23 AM
This revision was automatically updated to reflect the committed changes.

(The patch as committed differs from the reviewed one by one trivial change: I spotted a compiler warning that I must have missed yesterday, and removed a no-longer-needed variable initialisation.)