llvm.org GIT mirror llvm / e5b666f
[ARM] Add support for mrrc/mrrc2 intrinsics. Reapplying patch as it was reverted when it was first committed because of an assertion failure when the mrrc2 intrinsic was called in ARM mode. The failure was happening because the instruction was being built in ARMISelDAGToDAG.cpp and the tablegen description for mrrc2 instruction doesn't allow you to use a predicate. The ARM architecture manuals do say that mrrc2 in ARM mode can be predicated with AL in assembly but this has no effect on the encoding of the instruction as the top 4 bits will always be 1111 not 1110 which is the encoding for the condition AL. Differential Revision: http://reviews.llvm.org/D21408 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272982 91177308-0d34-0410-b5e6-96231b3b80d8 Ranjeet Singh 4 years ago
5 changed file(s) with 88 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
122122 llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
123123
124124 // Move from two registers to coprocessor
125 def int_arm_mcrr : GCCBuiltin<"__builtin_arm_mcrr">,
126 Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
127 llvm_i32_ty, llvm_i32_ty], []>;
128 def int_arm_mcrr2 : GCCBuiltin<"__builtin_arm_mcrr2">,
129 Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
130 llvm_i32_ty, llvm_i32_ty], []>;
125 def int_arm_mcrr : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
126 llvm_i32_ty, llvm_i32_ty], []>;
127 def int_arm_mcrr2 : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
128 llvm_i32_ty, llvm_i32_ty], []>;
129
130 def int_arm_mrrc : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty,
131 llvm_i32_ty, llvm_i32_ty], []>;
132 def int_arm_mrrc2 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty,
133 llvm_i32_ty, llvm_i32_ty], []>;
131134
132135 //===----------------------------------------------------------------------===//
133136 // CRC32
33343334 default:
33353335 break;
33363336
3337 case Intrinsic::arm_mrrc:
3338 case Intrinsic::arm_mrrc2: {
3339 SDLoc dl(N);
3340 SDValue Chain = N->getOperand(0);
3341 unsigned Opc;
3342
3343 if (Subtarget->isThumb())
3344 Opc = (IntNo == Intrinsic::arm_mrrc ? ARM::t2MRRC : ARM::t2MRRC2);
3345 else
3346 Opc = (IntNo == Intrinsic::arm_mrrc ? ARM::MRRC : ARM::MRRC2);
3347
3348 SmallVector Ops;
3349 Ops.push_back(getI32Imm(cast(N->getOperand(2))->getZExtValue(), dl)); /* coproc */
3350 Ops.push_back(getI32Imm(cast(N->getOperand(3))->getZExtValue(), dl)); /* opc */
3351 Ops.push_back(getI32Imm(cast(N->getOperand(4))->getZExtValue(), dl)); /* CRm */
3352
3353 // The mrrc2 instruction in ARM doesn't allow predicates, the top 4 bits of the encoded
3354 // instruction will always be '1111' but it is possible in assembly language to specify
3355 // AL as a predicate to mrrc2 but it doesn't make any difference to the encoded instruction.
3356 if (Opc != ARM::MRRC2) {
3357 Ops.push_back(getAL(CurDAG, dl));
3358 Ops.push_back(CurDAG->getRegister(0, MVT::i32));
3359 }
3360
3361 Ops.push_back(Chain);
3362
3363 // Writes to two registers.
3364 std::vector RetType;
3365 RetType.push_back(MVT::i32);
3366 RetType.push_back(MVT::i32);
3367 RetType.push_back(MVT::Other);
3368
3369 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, RetType, Ops));
3370 return;
3371 }
33373372 case Intrinsic::arm_ldaexd:
33383373 case Intrinsic::arm_ldrexd: {
33393374 SDLoc dl(N);
51445144 (outs GPRnopc:$Rt, GPRnopc:$Rt2),
51455145 (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>;
51465146
5147 class MovRRCopro2 pattern = []>
5148 : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1,
5149 GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), NoItinerary,
5147 class MovRRCopro2,
5148 list pattern = []>
5149 : ABXI<0b1100, oops, iops, NoItinerary,
51505150 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern>,
51515151 Requires<[PreV8]> {
51525152 let Inst{31-28} = 0b1111;
51655165 let Inst{7-4} = opc1;
51665166 let Inst{3-0} = CRm;
51675167
5168 let DecoderMethod = "DecodeMRRC2";
5168 let DecoderMethod = "DecoderForMRRC2AndMCRR2";
51695169 }
51705170
51715171 def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */,
5172 (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt,
5173 GPRnopc:$Rt2, c_imm:$CRm),
51725174 [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPRnopc:$Rt,
51735175 GPRnopc:$Rt2, imm:$CRm)]>;
5174 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>;
5176
5177 def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */,
5178 (outs GPRnopc:$Rt, GPRnopc:$Rt2),
5179 (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>;
51755180
51765181 //===----------------------------------------------------------------------===//
51775182 // Move between special register and ARM core register
394394
395395 static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
396396 uint64_t Address, const void *Decoder);
397 static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
398 uint64_t Address, const void *Decoder);
397 static DecodeStatus DecoderForMRRC2AndMCRR2(llvm::MCInst &Inst, unsigned Val,
398 uint64_t Address, const void *Decoder);
399399 #include "ARMGenDisassemblerTables.inc"
400400
401401 static MCDisassembler *createARMDisassembler(const Target &T,
52645264 return S;
52655265 }
52665266
5267 static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
5268 uint64_t Address, const void *Decoder) {
5267 static DecodeStatus DecoderForMRRC2AndMCRR2(llvm::MCInst &Inst, unsigned Val,
5268 uint64_t Address, const void *Decoder) {
52695269
52705270 DecodeStatus S = MCDisassembler::Success;
52715271
52815281 if (Rt == Rt2)
52825282 S = MCDisassembler::SoftFail;
52835283
5284 // We have to check if the instruction is MRRC2
5285 // or MCRR2 when constructing the operands for
5286 // Inst. Reason is because MRRC2 stores to two
5287 // registers so it's tablegen desc has has two
5288 // outputs whereas MCRR doesn't store to any
5289 // registers so all of it's operands are listed
5290 // as inputs, therefore the operand order for
5291 // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
5292 // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
5293
5294 if (Inst.getOpcode() == ARM::MRRC2) {
5295 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5296 return MCDisassembler::Fail;
5297 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5298 return MCDisassembler::Fail;
5299 }
52845300 Inst.addOperand(MCOperand::createImm(cop));
52855301 Inst.addOperand(MCOperand::createImm(opc1));
5286 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5287 return MCDisassembler::Fail;
5288 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5289 return MCDisassembler::Fail;
5302 if (Inst.getOpcode() == ARM::MCRR2) {
5303 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5304 return MCDisassembler::Fail;
5305 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5306 return MCDisassembler::Fail;
5307 }
52905308 Inst.addOperand(MCOperand::createImm(CRm));
52915309
52925310 return S;
3434 tail call void @llvm.arm.stc2(i32 7, i32 3, i8* %i) nounwind
3535 ; CHECK: stc2l p7, c3, [r{{[0-9]+}}]
3636 tail call void @llvm.arm.stc2l(i32 7, i32 3, i8* %i) nounwind
37 ; CHECK: mrrc p1, #2, r{{[0-9]+}}, r{{[0-9]+}}, c3
38 %2 = tail call { i32, i32 } @llvm.arm.mrrc(i32 1, i32 2, i32 3) nounwind
39 ; CHECK: mrrc2 p1, #2, r{{[0-9]+}}, r{{[0-9]+}}, c3
40 %3 = tail call { i32, i32 } @llvm.arm.mrrc2(i32 1, i32 2, i32 3) nounwind
3741 ret void
3842 }
3943
6872 declare void @llvm.arm.mcr(i32, i32, i32, i32, i32, i32) nounwind
6973
7074 declare i32 @llvm.arm.mrc(i32, i32, i32, i32, i32) nounwind
75
76 declare { i32, i32 } @llvm.arm.mrrc(i32, i32, i32) nounwind
77
78 declare { i32, i32 } @llvm.arm.mrrc2(i32, i32, i32) nounwind