llvm.org GIT mirror llvm / 7eaa421
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363244 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Tatham 1 year, 1 month ago
6 changed file(s) with 88 addition(s) and 64 deletion(s). Raw diff Collapse all Expand all
2424 def it_mask : Operand {
2525 let PrintMethod = "printThumbITMask";
2626 let ParserMatchClass = it_mask_asmoperand;
27 let EncoderMethod = "getITMaskOpValue";
2728 }
2829
2930 // t2_shift_imm: An integer that encodes a shift amount and the type of shift
8989
9090 enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
9191
92 static inline unsigned extractITMaskBit(unsigned Mask, unsigned Position) {
93 // Position==0 means we're not in an IT block at all. Position==1
94 // means we want the first state bit, which is always 0 (Then).
95 // Position==2 means we want the second state bit, stored at bit 3
96 // of Mask, and so on downwards. So (5 - Position) will shift the
97 // right bit down to bit 0, including the always-0 bit at bit 4 for
98 // the mandatory initial Then.
99 return (Mask >> (5 - Position) & 1);
100 }
101
92102 class UnwindContext {
93103 using Locs = SmallVector;
94104
225235 }
226236
227237 // Emit the IT instruction
228 unsigned Mask = getITMaskEncoding();
229238 MCInst ITInst;
230239 ITInst.setOpcode(ARM::t2IT);
231240 ITInst.addOperand(MCOperand::createImm(ITState.Cond));
232 ITInst.addOperand(MCOperand::createImm(Mask));
241 ITInst.addOperand(MCOperand::createImm(ITState.Mask));
233242 Out.EmitInstruction(ITInst, getSTI());
234243
235244 // Emit the conditonal instructions
287296 return MRI->getSubReg(QReg, ARM::dsub_0);
288297 }
289298
290 // Get the encoding of the IT mask, as it will appear in an IT instruction.
291 unsigned getITMaskEncoding() {
292 assert(inITBlock());
293 unsigned Mask = ITState.Mask;
294 unsigned TZ = countTrailingZeros(Mask);
295 if ((ITState.Cond & 1) == 0) {
296 assert(Mask && TZ <= 3 && "illegal IT mask value!");
297 Mask ^= (0xE << TZ) & 0xF;
298 }
299 return Mask;
300 }
301
302299 // Get the condition code corresponding to the current IT block slot.
303300 ARMCC::CondCodes currentITCond() {
304 unsigned MaskBit;
305 if (ITState.CurPosition == 1)
306 MaskBit = 1;
307 else
308 MaskBit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
309
310 return MaskBit ? ITState.Cond : ARMCC::getOppositeCondition(ITState.Cond);
301 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
302 return MaskBit ? ARMCC::getOppositeCondition(ITState.Cond) : ITState.Cond;
311303 }
312304
313305 // Invert the condition of the current IT block slot without changing any
337329 // Keep any existing condition bits.
338330 NewMask |= ITState.Mask & (0xE << TZ);
339331 // Insert the new condition bit.
340 NewMask |= (Cond == ITState.Cond) << TZ;
332 NewMask |= (Cond != ITState.Cond) << TZ;
341333 // Move the trailing 1 down one bit.
342334 NewMask |= 1 << (TZ - 1);
343335 ITState.Mask = NewMask;
352344 ITState.IsExplicit = false;
353345 }
354346
355 // Create a new explicit IT block with the given condition and mask. The mask
356 // should be in the parsed format, with a 1 implying 't', regardless of the
357 // low bit of the condition.
347 // Create a new explicit IT block with the given condition and mask.
348 // The mask should be in the format used in ARMOperand and
349 // MCOperand, with a 1 implying 'e', regardless of the low bit of
350 // the condition.
358351 void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
359352 assert(!inITBlock());
360353 ITState.Cond = Cond;
33543347 break;
33553348 case k_ITCondMask: {
33563349 static const char *const MaskStr[] = {
3357 "(invalid)", "(teee)", "(tee)", "(teet)",
3358 "(te)", "(tete)", "(tet)", "(tett)",
3359 "(t)", "(ttee)", "(tte)", "(ttet)",
3360 "(tt)", "(ttte)", "(ttt)", "(tttt)"
3350 "(invalid)", "(tttt)", "(ttt)", "(ttte)",
3351 "(tt)", "(ttet)", "(tte)", "(ttee)",
3352 "(t)", "(tett)", "(tet)", "(tete)",
3353 "(te)", "(teet)", "(tee)", "(teee)",
33613354 };
33623355 assert((ITMask.Mask & 0xf) == ITMask.Mask);
33633356 OS << "";
62716264
62726265 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
62736266
6274 // Handle the IT instruction ITMask. Convert it to a bitmask. This
6275 // is the mask as it will be for the IT encoding if the conditional
6276 // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
6277 // where the conditional bit0 is zero, the instruction post-processing
6278 // will adjust the mask accordingly.
6267 // Handle the mask for IT instructions. In ARMOperand and MCOperand,
6268 // this is stored in a format independent of the condition code: the
6269 // lowest set bit indicates the end of the encoding, and above that,
6270 // a 1 bit indicates 'else', and an 0 indicates 'then'. E.g.
6271 // IT -> 1000
6272 // ITx -> x100 (ITT -> 0100, ITE -> 1100)
6273 // ITxy -> xy10 (e.g. ITET -> 1010)
6274 // ITxyz -> xyz1 (e.g. ITEET -> 1101)
62796275 if (Mnemonic == "it") {
62806276 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
62816277 if (ITMask.size() > 3) {
62886284 return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
62896285 }
62906286 Mask >>= 1;
6291 if (ITMask[i - 1] == 't')
6287 if (ITMask[i - 1] == 'e')
62926288 Mask |= 8;
62936289 }
62946290 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
66806676 unsigned Cond = Inst.getOperand(0).getImm();
66816677 unsigned Mask = Inst.getOperand(1).getImm();
66826678
6683 // Mask hasn't been modified to the IT instruction encoding yet so
6684 // conditions only allowing a 't' are a block of 1s starting at bit 3
6685 // followed by all 0s. Easiest way is to just list the 4 possibilities.
6686 if (Cond == ARMCC::AL && Mask != 8 && Mask != 12 && Mask != 14 &&
6687 Mask != 15)
6679 // Conditions only allowing a 't' are those with no set bit except
6680 // the lowest-order one that indicates the end of the sequence. In
6681 // other words, powers of 2.
6682 if (Cond == ARMCC::AL && countPopulation(Mask) != 1)
66886683 return Error(Loc, "unpredictable IT predicate sequence");
66896684 break;
66906685 }
92599254 }
92609255 case ARM::ITasm:
92619256 case ARM::t2IT: {
9262 MCOperand &MO = Inst.getOperand(1);
9263 unsigned Mask = MO.getImm();
9264 ARMCC::CondCodes Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
9265
92669257 // Set up the IT block state according to the IT instruction we just
92679258 // matched.
92689259 assert(!inITBlock() && "nested IT blocks?!");
9269 startExplicitITBlock(Cond, Mask);
9270 MO.setImm(getITMaskEncoding());
9260 startExplicitITBlock(ARMCC::CondCodes(Inst.getOperand(0).getImm()),
9261 Inst.getOperand(1).getImm());
92719262 break;
92729263 }
92739264 case ARM::t2LSLrr:
6262 return ITStates.size() == 1;
6363 }
6464
65 // Called when decoding an IT instruction. Sets the IT state for the following
66 // instructions that for the IT block. Firstcond and Mask correspond to the
67 // fields in the IT instruction encoding.
65 // Called when decoding an IT instruction. Sets the IT state for
66 // the following instructions that for the IT block. Firstcond
67 // corresponds to the field in the IT instruction encoding; Mask
68 // is in the MCOperand format in which 1 means 'else' and 0 'then'.
6869 void setITState(char Firstcond, char Mask) {
6970 // (3 - the number of trailing zeros) is the number of then / else.
70 unsigned CondBit0 = Firstcond & 1;
7171 unsigned NumTZ = countTrailingZeros(Mask);
7272 unsigned char CCBits = static_cast(Firstcond & 0xf);
7373 assert(NumTZ <= 3 && "Invalid IT mask!");
7474 // push condition codes onto the stack the correct order for the pops
7575 for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
76 bool T = ((Mask >> Pos) & 1) == CondBit0;
77 if (T)
78 ITStates.push_back(CCBits);
79 else
80 ITStates.push_back(CCBits ^ 1);
76 unsigned Else = (Mask >> Pos) & 1;
77 ITStates.push_back(CCBits ^ Else);
8178 }
8279 ITStates.push_back(CCBits);
8380 }
51755172 if (mask == 0x0)
51765173 return MCDisassembler::Fail;
51775174
5175 // IT masks are encoded as a sequence of replacement low-order bits
5176 // for the condition code. So if the low bit of the starting
5177 // condition code is 1, then we have to flip all the bits above the
5178 // terminating bit (which is the lowest 1 bit).
5179 if (pred & 1) {
5180 unsigned LowBit = mask & -mask;
5181 unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
5182 mask ^= BitsAboveLowBit;
5183 }
5184
51785185 Inst.addOperand(MCOperand::createImm(pred));
51795186 Inst.addOperand(MCOperand::createImm(mask));
51805187 return S;
10381038 raw_ostream &O) {
10391039 // (3 - the number of trailing zeros) is the number of then / else.
10401040 unsigned Mask = MI->getOperand(OpNum).getImm();
1041 unsigned Firstcond = MI->getOperand(OpNum - 1).getImm();
1042 unsigned CondBit0 = Firstcond & 1;
10431041 unsigned NumTZ = countTrailingZeros(Mask);
10441042 assert(NumTZ <= 3 && "Invalid IT mask!");
10451043 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1046 bool T = ((Mask >> Pos) & 1) == CondBit0;
1047 if (T)
1044 if ((Mask >> Pos) & 1)
1045 O << 'e';
1046 else
10481047 O << 't';
1049 else
1050 O << 'e';
10511048 }
10521049 }
10531050
161161 SmallVectorImpl &Fixups,
162162 const MCSubtargetInfo &STI) const;
163163
164 uint32_t getITMaskOpValue(const MCInst &MI, unsigned OpIdx,
165 SmallVectorImpl &Fixups,
166 const MCSubtargetInfo &STI) const;
164167
165168 /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
166169 /// operand.
828831 return Val;
829832 }
830833
834 /// getITMaskOpValue - Return the architectural encoding of an IT
835 /// predication mask, given the MCOperand format.
836 uint32_t ARMMCCodeEmitter::
837 getITMaskOpValue(const MCInst &MI, unsigned OpIdx,
838 SmallVectorImpl &Fixups,
839 const MCSubtargetInfo &STI) const {
840 const MCOperand MaskMO = MI.getOperand(OpIdx);
841 assert(MaskMO.isImm() && "Unexpected operand type!");
842
843 unsigned Mask = MaskMO.getImm();
844
845 // IT masks are encoded as a sequence of replacement low-order bits
846 // for the condition code. So if the low bit of the starting
847 // condition code is 1, then we have to flip all the bits above the
848 // terminating bit (which is the lowest 1 bit).
849 assert(OpIdx > 0 && "IT mask appears first!");
850 const MCOperand CondMO = MI.getOperand(OpIdx-1);
851 assert(CondMO.isImm() && "Unexpected operand type!");
852 if (CondMO.getImm() & 1) {
853 unsigned LowBit = Mask & -Mask;
854 unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
855 Mask ^= BitsAboveLowBit;
856 }
857
858 return Mask;
859 }
860
831861 /// getThumbAdrLabelOpValue - Return encoding info for 8-bit immediate ADR label
832862 /// target.
833863 uint32_t ARMMCCodeEmitter::
244244 unsigned NPredReg = 0;
245245 ARMCC::CondCodes NCC = getITInstrPredicate(*NMI, NPredReg);
246246 if (NCC == CC || NCC == OCC) {
247 Mask |= (NCC & 1) << Pos;
247 Mask |= ((NCC ^ CC) & 1) << Pos;
248248 // Add implicit use of ITSTATE.
249249 NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
250250 true/*isImp*/, false/*isKill*/));
268268
269269 // Finalize IT mask.
270270 Mask |= (1 << Pos);
271 // Tag along (firstcond[0] << 4) with the mask.
272 Mask |= (CC & 1) << 4;
273271 MIB.addImm(Mask);
274272
275273 // Last instruction in IT block kills ITSTATE.