summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
diff options
context:
space:
mode:
authorSimon Tatham <simon.tatham@arm.com>2019-06-13 10:01:52 +0000
committerSimon Tatham <simon.tatham@arm.com>2019-06-13 10:01:52 +0000
commit848d3d0d2c45334f090dbf315501ebafe75f4b4d (patch)
tree700c0b3ea3e387cf9fe50ad511e239f96768b260 /llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
parent86b7f865ac5750777fd925a23226538ff17c50bc (diff)
downloadbcm5719-llvm-848d3d0d2c45334f090dbf315501ebafe75f4b4d.tar.gz
bcm5719-llvm-848d3d0d2c45334f090dbf315501ebafe75f4b4d.zip
[ARM] Refactor handling of IT mask operands.
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. Reviewers: ostannard Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63219 llvm-svn: 363244
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp25
1 files changed, 16 insertions, 9 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index ef71cacfa92..bc9d5a0913f 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -63,22 +63,19 @@ namespace {
return ITStates.size() == 1;
}
- // Called when decoding an IT instruction. Sets the IT state for the following
- // instructions that for the IT block. Firstcond and Mask correspond to the
- // fields in the IT instruction encoding.
+ // Called when decoding an IT instruction. Sets the IT state for
+ // the following instructions that for the IT block. Firstcond
+ // corresponds to the field in the IT instruction encoding; Mask
+ // is in the MCOperand format in which 1 means 'else' and 0 'then'.
void setITState(char Firstcond, char Mask) {
// (3 - the number of trailing zeros) is the number of then / else.
- unsigned CondBit0 = Firstcond & 1;
unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
assert(NumTZ <= 3 && "Invalid IT mask!");
// push condition codes onto the stack the correct order for the pops
for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
- bool T = ((Mask >> Pos) & 1) == CondBit0;
- if (T)
- ITStates.push_back(CCBits);
- else
- ITStates.push_back(CCBits ^ 1);
+ unsigned Else = (Mask >> Pos) & 1;
+ ITStates.push_back(CCBits ^ Else);
}
ITStates.push_back(CCBits);
}
@@ -5176,6 +5173,16 @@ static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
if (mask == 0x0)
return MCDisassembler::Fail;
+ // IT masks are encoded as a sequence of replacement low-order bits
+ // for the condition code. So if the low bit of the starting
+ // condition code is 1, then we have to flip all the bits above the
+ // terminating bit (which is the lowest 1 bit).
+ if (pred & 1) {
+ unsigned LowBit = mask & -mask;
+ unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
+ mask ^= BitsAboveLowBit;
+ }
+
Inst.addOperand(MCOperand::createImm(pred));
Inst.addOperand(MCOperand::createImm(mask));
return S;
OpenPOWER on IntegriCloud