llvm.org GIT mirror llvm / 19c14ab
[ARMv8] Add support for the NEON instructions vmaxnm/vminnm. This adds a new class for non-predicable NEON instructions and a new DecoderNamespace for v8 NEON instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186504 91177308-0d34-0410-b5e6-96231b3b80d8 Joey Gouly 7 years ago
6 changed file(s) with 122 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
179179 // Vector Maximum.
180180 def int_arm_neon_vmaxs : Neon_2Arg_Intrinsic;
181181 def int_arm_neon_vmaxu : Neon_2Arg_Intrinsic;
182 def int_arm_neon_vmaxnm : Neon_2Arg_Intrinsic;
182183
183184 // Vector Minimum.
184185 def int_arm_neon_vmins : Neon_2Arg_Intrinsic;
185186 def int_arm_neon_vminu : Neon_2Arg_Intrinsic;
187 def int_arm_neon_vminnm : Neon_2Arg_Intrinsic;
186188
187189 // Vector Reciprocal Step.
188190 def int_arm_neon_vrecps : Neon_2Arg_Intrinsic;
165165 unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val)
166166 const { return 0; }
167167 unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val)
168 const { return 0; }
169 unsigned NEONThumb2V8PostEncoder(const MachineInstr &MI,unsigned Val)
168170 const { return 0; }
169171 unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val)
170172 const { return 0; }
18291829 let DecoderNamespace = "NEON";
18301830 }
18311831
1832 // Same as NeonI except it is not predicated
1833 class NeonInp
1834 InstrItinClass itin, string opc, string dt, string asm, string cstr,
1835 list pattern>
1836 : InstARM {
1837 let OutOperandList = oops;
1838 let InOperandList = iops;
1839 let AsmString = !strconcat(opc, ".", dt, "\t", asm);
1840 let Pattern = pattern;
1841 list Predicates = [HasNEON];
1842 let DecoderNamespace = "NEON";
1843
1844 let Inst{31-28} = 0b1111;
1845 }
1846
18321847 class NLdSt op21_20, bits<4> op11_8, bits<4> op7_4,
18331848 dag oops, dag iops, InstrItinClass itin,
18341849 string opc, string dt, string asm, string cstr, list pattern>
20272042 let Inst{7} = Vn{4};
20282043 let Inst{3-0} = Vm{3-0};
20292044 let Inst{5} = Vm{4};
2045 }
2046
2047 class N3Vnp op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2048 bit op4, dag oops, dag iops,Format f, InstrItinClass itin,
2049 string OpcodeStr, string Dt, ValueType ResTy, ValueType OpTy,
2050 SDPatternOperator IntOp, bit Commutable, list pattern>
2051 : NeonInp
2052 Dt, "$Vd, $Vn, $Vm", "", pattern> {
2053 bits<5> Vd;
2054 bits<5> Vn;
2055 bits<5> Vm;
2056
2057 // Encode instruction operands
2058 let Inst{22} = Vd{4};
2059 let Inst{15-12} = Vd{3-0};
2060 let Inst{19-16} = Vn{3-0};
2061 let Inst{7} = Vn{4};
2062 let Inst{5} = Vm{4};
2063 let Inst{3-0} = Vm{3-0};
2064
2065 // Encode constant bits
2066 let Inst{27-23} = op27_23;
2067 let Inst{21-20} = op21_20;
2068 let Inst{11-8} = op11_8;
2069 let Inst{6} = op6;
2070 let Inst{4} = op4;
20302071 }
20312072
20322073 class N3VLane32 op21_20, bits<4> op11_8, bit op6,
25402540 let TwoOperandAliasConstraint = "$Vn = $Vd";
25412541 let isCommutable = Commutable;
25422542 }
2543
2544 class N3VDIntnp op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2545 bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2546 string Dt, ValueType ResTy, ValueType OpTy,
2547 SDPatternOperator IntOp, bit Commutable>
2548 : N3Vnp
2549 (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), f, itin, OpcodeStr, Dt,
2550 ResTy, OpTy, IntOp, Commutable,
2551 [(set DPR:$Vd, (ResTy (IntOp (OpTy DPR:$Vn), (OpTy DPR:$Vm))))]>;
2552
25432553 class N3VDIntSL op21_20, bits<4> op11_8, InstrItinClass itin,
25442554 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
25452555 : N3VLane32<0, 1, op21_20, op11_8, 1, 0,
25512561 imm:$lane)))))]> {
25522562 let isCommutable = 0;
25532563 }
2564
25542565 class N3VDIntSL16 op21_20, bits<4> op11_8, InstrItinClass itin,
25552566 string OpcodeStr, string Dt, ValueType Ty, SDPatternOperator IntOp>
25562567 : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
25832594 let TwoOperandAliasConstraint = "$Vn = $Vd";
25842595 let isCommutable = Commutable;
25852596 }
2597
2598 class N3VQIntnp op27_23, bits<2> op21_20, bits<4> op11_8, bit op6,
2599 bit op4, Format f, InstrItinClass itin, string OpcodeStr,
2600 string Dt, ValueType ResTy, ValueType OpTy,
2601 SDPatternOperator IntOp, bit Commutable>
2602 : N3Vnp
2603 (outs QPR:$Vd), (ins QPR:$Vn, QPR:$Vm), f, itin, OpcodeStr, Dt,
2604 ResTy, OpTy, IntOp, Commutable,
2605 [(set QPR:$Vd, (ResTy (IntOp (OpTy QPR:$Vn), (OpTy QPR:$Vm))))]>;
2606
25862607 class N3VQIntSL op21_20, bits<4> op11_8, InstrItinClass itin,
25872608 string OpcodeStr, string Dt,
25882609 ValueType ResTy, ValueType OpTy, SDPatternOperator IntOp>
46584679 "vmax", "f32",
46594680 v4f32, v4f32, int_arm_neon_vmaxs, 1>;
46604681
4682 // VMAXNM
4683 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
4684 def VMAXNMND : N3VDIntnp<0b000110, 0b00, 0b1111, 0, 1,
4685 N3RegFrm, NoItinerary, "vmaxnm", "f32",
4686 v2f32, v2f32, int_arm_neon_vmaxnm, 1>,
4687 Requires<[HasV8, HasNEON]>;
4688 def VMAXNMNQ : N3VQIntnp<0b00110, 0b00, 0b1111, 1, 1,
4689 N3RegFrm, NoItinerary, "vmaxnm", "f32",
4690 v4f32, v4f32, int_arm_neon_vmaxnm, 1>,
4691 Requires<[HasV8, HasNEON]>;
4692 }
4693
46614694 // VMIN : Vector Minimum
46624695 defm VMINs : N3VInt_QHS<0, 0, 0b0110, 1, N3RegFrm,
46634696 IIC_VSUBi4D, IIC_VSUBi4D, IIC_VSUBi4Q, IIC_VSUBi4Q,
46714704 def VMINfq : N3VQInt<0, 0, 0b10, 0b1111, 0, N3RegFrm, IIC_VBINQ,
46724705 "vmin", "f32",
46734706 v4f32, v4f32, int_arm_neon_vmins, 1>;
4707
4708 // VMINNM
4709 let PostEncoderMethod = "NEONThumb2V8PostEncoder", DecoderNamespace = "v8NEON" in {
4710 def VMINNMND : N3VDIntnp<0b00110, 0b10, 0b1111, 0, 1,
4711 N3RegFrm, NoItinerary, "vminnm", "f32",
4712 v2f32, v2f32, int_arm_neon_vminnm, 1>,
4713 Requires<[HasV8, HasNEON]>;
4714 def VMINNMNQ : N3VQIntnp<0b00110, 0b10, 0b1111, 1, 1,
4715 N3RegFrm, NoItinerary, "vminnm", "f32",
4716 v4f32, v4f32, int_arm_neon_vminnm, 1>,
4717 Requires<[HasV8, HasNEON]>;
4718 }
46744719
46754720 // Vector Pairwise Operations.
46764721
498498 }
499499
500500 MI.clear();
501
501 result = decodeInstruction(DecoderTablev8NEON32, MI, insn, Address,
502 this, STI);
503 if (result != MCDisassembler::Fail) {
504 Size = 4;
505 return result;
506 }
507
508 MI.clear();
502509 Size = 0;
503510 return MCDisassembler::Fail;
504511 }
817824 }
818825 }
819826
827 MI.clear();
828 uint32_t NEONv8Insn = insn32;
829 NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
830 result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
831 this, STI);
832 if (result != MCDisassembler::Fail) {
833 Size = 4;
834 return result;
835 }
836
837 MI.clear();
820838 Size = 0;
821839 return MCDisassembler::Fail;
822840 }
314314 unsigned EncodedValue) const;
315315 unsigned NEONThumb2DupPostEncoder(const MCInst &MI,
316316 unsigned EncodedValue) const;
317 unsigned NEONThumb2V8PostEncoder(const MCInst &MI,
318 unsigned EncodedValue) const;
317319
318320 unsigned VFPThumb2PostEncoder(const MCInst &MI,
319321 unsigned EncodedValue) const;
383385 if (isThumb2()) {
384386 EncodedValue &= 0x00FFFFFF;
385387 EncodedValue |= 0xEE000000;
388 }
389
390 return EncodedValue;
391 }
392
393 /// Post-process encoded NEON v8 instructions, and rewrite them to Thumb2 form
394 /// if we are in Thumb2.
395 unsigned ARMMCCodeEmitter::NEONThumb2V8PostEncoder(const MCInst &MI,
396 unsigned EncodedValue) const {
397 if (isThumb2()) {
398 EncodedValue |= 0xC000000; // Set bits 27-26
386399 }
387400
388401 return EncodedValue;