llvm.org GIT mirror llvm / 0819555
[ARM][FIX] Fix vfmal.f16 and vfmsl.f16 operand The indexed variant of vfmal.f16 and vfmsl.f16 instructions use the uppser bits of the indexed operand to store the index (1 bit for the double variant, 2 bits for the quad). This limits the usable registers to d0 - d7 or s0 - s15. This patch enforces this limitation. Differential Revision: https://reviews.llvm.org/D59021 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355707 91177308-0d34-0410-b5e6-96231b3b80d8 Diogo N. Sampaio 1 year, 5 months ago
3 changed file(s) with 61 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
51205120 : N3VCP8Q0
51215121 asm, "f16", "$Vd, $Vn, $Vm", "", []>;
51225122
5123 class VFMQ0 S>
5123 // Vd, Vs, Vs[0-15], Idx[0-1]
5124 class VFMD S>
51245125 : N3VLaneCP8<0, S, 0, 1, (outs DPR:$Vd),
5125 (ins SPR:$Vn, SPR:$Vm, VectorIndex32:$idx),
5126 IIC_VMACD, opc, "f16", "$Vd, $Vn, $Vm$idx", "", []> {
5126 (ins SPR:$Vn, SPR_8:$Vm, VectorIndex32:$idx),
5127 IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {
51275128 bit idx;
51285129 let Inst{3} = idx;
51295130 let Inst{19-16} = Vn{4-1};
51325133 let Inst{2-0} = Vm{3-1};
51335134 }
51345135
5135 class VFMQ1 S>
5136 // Vq, Vd, Vd[0-7], Idx[0-3]
5137 class VFMQ S>
51365138 : N3VLaneCP8<0, S, 1, 1, (outs QPR:$Vd),
5137 (ins DPR:$Vn, DPR:$Vm, VectorIndex16:$idx),
5138 IIC_VMACD, opc, "f16", "$Vd, $Vn, $Vm$idx", "", []> {
5139 (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx),
5140 IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {
51395141 bits<2> idx;
51405142 let Inst{5} = idx{1};
51415143 let Inst{3} = idx{0};
51475149 def VFMSLD : N3VCP8F16Q0<"vfmsl", DPR, SPR, SPR, 0b01, 0b10, 1>;
51485150 def VFMALQ : N3VCP8F16Q1<"vfmal", QPR, DPR, DPR, 0b00, 0b10, 1>;
51495151 def VFMSLQ : N3VCP8F16Q1<"vfmsl", QPR, DPR, DPR, 0b01, 0b10, 1>;
5150 def VFMALDI : VFMQ0<"vfmal", 0b00>;
5151 def VFMSLDI : VFMQ0<"vfmsl", 0b01>;
5152 def VFMALQI : VFMQ1<"vfmal", 0b00>;
5153 def VFMSLQI : VFMQ1<"vfmsl", 0b01>;
5152 def VFMALDI : VFMD<"vfmal", "f16", 0b00>;
5153 def VFMSLDI : VFMD<"vfmsl", "f16", 0b01>;
5154 def VFMALQI : VFMQ<"vfmal", "f16", 0b00>;
5155 def VFMSLQI : VFMQ<"vfmsl", "f16", 0b01>;
51545156 }
51555157 } // HasNEON, HasFP16FML
51565158
164164 uint64_t Address, const void *Decoder);
165165 static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
166166 uint64_t Address, const void *Decoder);
167 static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
168 uint64_t Address, const void *Decoder);
167169 static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
168170 unsigned RegNo,
169171 uint64_t Address,
10421044 if (RegNo > 7)
10431045 return MCDisassembler::Fail;
10441046 return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1047 }
1048
1049 static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1050 uint64_t Address, const void *Decoder) {
1051 if (RegNo > 15)
1052 return MCDisassembler::Fail;
1053 return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
10451054 }
10461055
10471056 static DecodeStatus
55 vfmal.f16 q0, d1, d2[4]
66 VFMSL.F16 Q0, D1, D2[4]
77 vfmal.f16 q0, d1, d2[-1]
8 VFMSL.F16 D0, S1, S16[0]
9 vfmal.f16 d0, s1, s16[0]
10 VFMSL.F16 Q0, D1, D8[0]
11 vfmal.f16 q0, d1, d8[0]
812
913 //CHECK-ERROR: error: invalid operand for instruction
1014 //CHECK-ERROR-NEXT: VFMAL.F16 D0, S1, S2[2]
2428 //CHECK-ERROR-NEXT: error: invalid operand for instruction
2529 //CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d2[-1]
2630 //CHECK-ERROR-NEXT: ^
31 //CHECK-ERROR-NEXT: error: invalid instruction, any one of the following would fix this:
32 //CHECK-ERROR-NEXT: VFMSL.F16 D0, S1, S16[0]
33 //CHECK-ERROR-NEXT: ^
34 //CHECK-ERROR-NEXT: note: operand must be a register in range [s0, s15]
35 //CHECK-ERROR-NEXT: VFMSL.F16 D0, S1, S16[0]
36 //CHECK-ERROR-NEXT: ^
37 //CHECK-ERROR-NEXT: note: too many operands for instruction
38 //CHECK-ERROR-NEXT: VFMSL.F16 D0, S1, S16[0]
39 //CHECK-ERROR-NEXT: ^
40 //CHECK-ERROR-NEXT: error: invalid instruction, any one of the following would fix this:
41 //CHECK-ERROR-NEXT: vfmal.f16 d0, s1, s16[0]
42 //CHECK-ERROR-NEXT: ^
43 //CHECK-ERROR-NEXT: note: operand must be a register in range [s0, s15]
44 //CHECK-ERROR-NEXT: vfmal.f16 d0, s1, s16[0]
45 //CHECK-ERROR-NEXT: ^
46 //CHECK-ERROR-NEXT: note: too many operands for instruction
47 //CHECK-ERROR-NEXT: vfmal.f16 d0, s1, s16[0]
48 //CHECK-ERROR-NEXT: ^
49 //CHECK-ERROR-NEXT: : error: invalid instruction, any one of the following would fix this:
50 //CHECK-ERROR-NEXT: VFMSL.F16 Q0, D1, D8[0]
51 //CHECK-ERROR-NEXT: ^
52 //CHECK-ERROR-NEXT: : note: operand must be a register in range [d0, d7]
53 //CHECK-ERROR-NEXT: VFMSL.F16 Q0, D1, D8[0]
54 //CHECK-ERROR-NEXT: ^
55 //CHECK-ERROR-NEXT: : note: too many operands for instruction
56 //CHECK-ERROR-NEXT: VFMSL.F16 Q0, D1, D8[0]
57 //CHECK-ERROR-NEXT: ^
58 //CHECK-ERROR-NEXT: : error: invalid instruction, any one of the following would fix this:
59 //CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d8[0]
60 //CHECK-ERROR-NEXT: ^
61 //CHECK-ERROR-NEXT: : note: operand must be a register in range [d0, d7]
62 //CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d8[0]
63 //CHECK-ERROR-NEXT: ^
64 //CHECK-ERROR-NEXT: 1: note: too many operands for instruction
65 //CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d8[0]
66 //CHECK-ERROR-NEXT: ^