llvm.org GIT mirror llvm / f043afb
[ARM] Add <saturate> operand to SQRSHRL and UQRSHLL Summary: According to the new Armv8-M specification https://static.docs.arm.com/ddi0553/bh/DDI0553B_h_armv8m_arm.pdf the instructions SQRSHRL and UQRSHLL now have an additional immediate operand <saturate>. The new assembly syntax is: SQRSHRL<c> RdaLo, RdaHi, #<saturate>, Rm UQRSHLL<c> RdaLo, RdaHi, #<saturate>, Rm where <saturate> can be either 64 (the existing behavior) or 48, in that case the result is saturated to 48 bits. The new operand is encoded as follows: #64 Encoded as sat = 0 #48 Encoded as sat = 1 sat is bit 7 of the instruction bit pattern. This patch adds a new assembler operand class MveSaturateOperand which implements parsing and encoding. Decoding is implemented in DecodeMVEOverlappingLongShift. Reviewers: ostannard, simon_tatham, t.p.northover, samparker, dmgreen, SjoerdMeijer Reviewed By: simon_tatham Subscribers: javed.absar, kristof.beyls, hiraditya, pbarrio, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64810 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366555 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Maltsev 1 year, 17 days ago
8 changed file(s) with 91 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
27232723 let PrintMethod = "printComplexRotationOp<180, 90>";
27242724 }
27252725
2726 def MveSaturateOperand : AsmOperandClass {
2727 let PredicateMethod = "isMveSaturateOp";
2728 let DiagnosticString = "saturate operand must be 48 or 64";
2729 let Name = "MveSaturate";
2730 }
2731 def saturateop : Operand {
2732 let ParserMatchClass = MveSaturateOperand;
2733 let PrintMethod = "printMveSaturateOp";
2734 }
2735
27262736 // Data type suffix token aliases. Implements Table A7-3 in the ARM ARM.
27272737 def : TokenAlias<".s8", ".i8">;
27282738 def : TokenAlias<".u8", ".i8">;
402402 let Inst{3-0} = 0b1111;
403403 }
404404
405 class MVE_ScalarShiftDRegReg
406 list pattern=[]>
405 class MVE_ScalarShiftDRegRegBase
406 bit op5, bit op16, list pattern=[]>
407407 : MVE_ScalarShiftDoubleReg<
408 iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm),
409 "$RdaLo, $RdaHi, $Rm", "@earlyclobber $RdaHi,@earlyclobber $RdaLo,"
410 "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
408 iname, iops, asm, "@earlyclobber $RdaHi,@earlyclobber $RdaLo,"
409 "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
411410 pattern> {
412411 bits<4> Rm;
413412
414413 let Inst{16} = op16;
415414 let Inst{15-12} = Rm{3-0};
416 let Inst{7-6} = 0b00;
415 let Inst{6} = 0b0;
417416 let Inst{5} = op5;
418417 let Inst{4} = 0b0;
419418 let Inst{3-0} = 0b1101;
426425 let DecoderMethod = "DecodeMVEOverlappingLongShift";
427426 }
428427
429 def MVE_ASRLr : MVE_ScalarShiftDRegReg<"asrl", 0b1, 0b0, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
428 class MVE_ScalarShiftDRegReg pattern=[]>
429 : MVE_ScalarShiftDRegRegBase<
430 iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm),
431 "$RdaLo, $RdaHi, $Rm", op5, 0b0, pattern> {
432
433 let Inst{7} = 0b0;
434 }
435
436 class MVE_ScalarShiftDRegRegWithSat pattern=[]>
437 : MVE_ScalarShiftDRegRegBase<
438 iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm, saturateop:$sat),
439 "$RdaLo, $RdaHi, $sat, $Rm", op5, 0b1, pattern> {
440 bit sat;
441
442 let Inst{7} = sat;
443 }
444
445 def MVE_ASRLr : MVE_ScalarShiftDRegReg<"asrl", 0b1, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
430446 (ARMasrl tGPREven:$RdaLo_src,
431447 tGPROdd:$RdaHi_src, rGPR:$Rm))]>;
432448 def MVE_ASRLi : MVE_ScalarShiftDRegImm<"asrl", 0b10, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
433449 (ARMasrl tGPREven:$RdaLo_src,
434450 tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>;
435 def MVE_LSLLr : MVE_ScalarShiftDRegReg<"lsll", 0b0, 0b0, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
451 def MVE_LSLLr : MVE_ScalarShiftDRegReg<"lsll", 0b0, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
436452 (ARMlsll tGPREven:$RdaLo_src,
437453 tGPROdd:$RdaHi_src, rGPR:$Rm))]>;
438454 def MVE_LSLLi : MVE_ScalarShiftDRegImm<"lsll", 0b00, ?, [(set tGPREven:$RdaLo, tGPROdd:$RdaHi,
442458 (ARMlsrl tGPREven:$RdaLo_src,
443459 tGPROdd:$RdaHi_src, (i32 imm:$imm)))]>;
444460
445 def MVE_SQRSHRL : MVE_ScalarShiftDRegReg<"sqrshrl", 0b1, 0b1>;
461 def MVE_SQRSHRL : MVE_ScalarShiftDRegRegWithSat<"sqrshrl", 0b1>;
446462 def MVE_SQSHLL : MVE_ScalarShiftDRegImm<"sqshll", 0b11, 0b1>;
447463 def MVE_SRSHRL : MVE_ScalarShiftDRegImm<"srshrl", 0b10, 0b1>;
448464
449 def MVE_UQRSHLL : MVE_ScalarShiftDRegReg<"uqrshll", 0b0, 0b1>;
465 def MVE_UQRSHLL : MVE_ScalarShiftDRegRegWithSat<"uqrshll", 0b0>;
450466 def MVE_UQSHLL : MVE_ScalarShiftDRegImm<"uqshll", 0b00, 0b1>;
451467 def MVE_URSHRL : MVE_ScalarShiftDRegImm<"urshrl", 0b01, 0b1>;
452468
22742274 return Value >= 1 && Value <= 32;
22752275 }
22762276
2277 bool isMveSaturateOp() const {
2278 if (!isImm()) return false;
2279 const MCConstantExpr *CE = dyn_cast(getImm());
2280 if (!CE) return false;
2281 uint64_t Value = CE->getValue();
2282 return Value == 48 || Value == 64;
2283 }
2284
22772285 bool isITCondCodeNoAL() const {
22782286 if (!isITCondCode()) return false;
22792287 ARMCC::CondCodes CC = getCondCode();
33673375 assert(N == 1 && "Invalid number of operands!");
33683376 const MCConstantExpr *CE = dyn_cast(getImm());
33693377 Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
3378 }
3379
3380 void addMveSaturateOperands(MCInst &Inst, unsigned N) const {
3381 assert(N == 1 && "Invalid number of operands!");
3382 const MCConstantExpr *CE = dyn_cast(getImm());
3383 unsigned Imm = CE->getValue();
3384 assert((Imm == 48 || Imm == 64) && "Invalid saturate operand");
3385 Inst.addOperand(MCOperand::createImm(Imm == 48 ? 1 : 0));
33703386 }
33713387
33723388 void print(raw_ostream &OS) const override;
65026502 if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
65036503 return MCDisassembler::Fail;
65046504
6505 if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
6506 Inst.getOpcode() == ARM::MVE_UQRSHLL) {
6507 unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
6508 // Saturate, the bit position for saturation
6509 Inst.addOperand(MCOperand::createImm(Saturate));
6510 }
6511
65056512 return S;
65066513 }
65076514
16751675 O.write_hex(Val);
16761676 O << markup(">");
16771677 }
1678
1679 void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum,
1680 const MCSubtargetInfo &STI,
1681 raw_ostream &O) {
1682 uint32_t Val = MI->getOperand(OpNum).getImm();
1683 assert(Val <= 1 && "Invalid MVE saturate operand");
1684 O << "#" << (Val == 1 ? 48 : 64);
1685 }
261261 const MCSubtargetInfo &STI, raw_ostream &O);
262262 void printExpandedImmOperand(const MCInst *MI, unsigned OpNum,
263263 const MCSubtargetInfo &STI, raw_ostream &O);
264
264 void printMveSaturateOp(const MCInst *MI, unsigned OpNum,
265 const MCSubtargetInfo &STI, raw_ostream &O);
265266 private:
266267 unsigned DefaultAltIdx = ARM::NoRegAltName;
267268 };
110110 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
111111 sqrshr r11, r12
112112
113 # CHECK: sqrshrl lr, r3, r8 @ encoding: [0x5f,0xea,0x2d,0x83]
113 # CHECK: sqrshrl lr, r3, #64, r8 @ encoding: [0x5f,0xea,0x2d,0x83]
114114 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
115 sqrshrl lr, r3, r8
115 sqrshrl lr, r3, #64, r8
116
117 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: saturate operand must be 48 or 64
118 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
119 sqrshrl lr, r3, #32, r8
116120
117121 # CHECK: sqshl lr, #17 @ encoding: [0x5e,0xea,0x7f,0x4f]
118122 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
134138 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
135139 uqrshl lr, r1
136140
137 # CHECK: uqrshll lr, r1, r4 @ encoding: [0x5f,0xea,0x0d,0x41]
141 # CHECK: uqrshll lr, r1, #48, r4 @ encoding: [0x5f,0xea,0x8d,0x41]
138142 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
139 uqrshll lr, r1, r4
143 uqrshll lr, r1, #48, r4
144
145 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: saturate operand must be 48 or 64
146 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
147 uqrshll lr, r1, #0, r4
140148
141149 # CHECK: uqshl r0, #1 @ encoding: [0x50,0xea,0x4f,0x0f]
142150 # ERROR-NOMVE: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
2626 # CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding
2727
2828 [0x5f 0xea 0x2d 0x83]
29 # CHECK: sqrshrl lr, r3, r8 @ encoding: [0x5f,0xea,0x2d,0x83]
29 # CHECK: sqrshrl lr, r3, #64, r8 @ encoding: [0x5f,0xea,0x2d,0x83]
30 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
31
32 [0x5f 0xea 0xad 0x83]
33 # CHECK: sqrshrl lr, r3, #48, r8 @ encoding: [0x5f,0xea,0xad,0x83]
3034 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
3135
3236 [0x5e 0xea 0x7f 0x4f]
6266 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
6367
6468 [0x5f 0xea 0x0d 0x41]
65 # CHECK: uqrshll lr, r1, r4 @ encoding: [0x5f,0xea,0x0d,0x41]
69 # CHECK: uqrshll lr, r1, #64, r4 @ encoding: [0x5f,0xea,0x0d,0x41]
70 # CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding
71
72 [0x5f 0xea 0x8d 0x41]
73 # CHECK: uqrshll lr, r1, #48, r4 @ encoding: [0x5f,0xea,0x8d,0x41]
6674 # CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding
6775
6876 [0x50 0xea 0x4f 0x0f]