llvm.org GIT mirror llvm / 53e3fc4
Use TableGen'erated pseudo lowering for ARM. Hook up the TableGen lowering for simple pseudo instructions for ARM and use it for a subset of the many pseudos the backend has as proof of concept. More conversions to come. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134705 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 9 years ago
8 changed file(s) with 196 addition(s) and 216 deletion(s). Raw diff Collapse all Expand all
10681068
10691069 extern cl::opt EnableARMEHABI;
10701070
1071 // Simple pseudo-instructions have their lowering (with expansion to real
1072 // instructions) auto-generated.
1073 #include "ARMGenMCPseudoLowering.inc"
1074
10711075 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1076 // Do any auto-generated pseudo lowerings.
1077 if (emitPseudoExpansionLowering(OutStreamer, MI))
1078 return;
1079
1080 // Check for manual lowerings.
10721081 unsigned Opc = MI->getOpcode();
10731082 switch (Opc) {
1074 default: break;
1075 case ARM::B: {
1076 // B is just a Bcc with an 'always' predicate.
1077 MCInst TmpInst;
1078 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1079 TmpInst.setOpcode(ARM::Bcc);
1080 // Add predicate operands.
1081 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1082 TmpInst.addOperand(MCOperand::CreateReg(0));
1083 OutStreamer.EmitInstruction(TmpInst);
1084 return;
1085 }
1086 case ARM::LDMIA_RET: {
1087 // LDMIA_RET is just a normal LDMIA_UPD instruction that targets PC and as
1088 // such has additional code-gen properties and scheduling information.
1089 // To emit it, we just construct as normal and set the opcode to LDMIA_UPD.
1090 MCInst TmpInst;
1091 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1092 TmpInst.setOpcode(ARM::LDMIA_UPD);
1093 OutStreamer.EmitInstruction(TmpInst);
1094 return;
1095 }
1096 case ARM::t2LDMIA_RET: {
1097 // As above for LDMIA_RET. Map to the tPOP instruction.
1098 MCInst TmpInst;
1099 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1100 TmpInst.setOpcode(ARM::t2LDMIA_UPD);
1101 OutStreamer.EmitInstruction(TmpInst);
1102 return;
1103 }
1104 case ARM::tPOP_RET: {
1105 // As above for LDMIA_RET. Map to the tPOP instruction.
1106 MCInst TmpInst;
1107 LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
1108 TmpInst.setOpcode(ARM::tPOP);
1109 OutStreamer.EmitInstruction(TmpInst);
1110 return;
1111 }
1112
11131083 case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
11141084 case ARM::DBG_VALUE: {
11151085 if (isVerbose() && OutStreamer.hasRawTextSupport()) {
11181088 PrintDebugValueComment(MI, OS);
11191089 OutStreamer.EmitRawText(StringRef(OS.str()));
11201090 }
1121 return;
1122 }
1123 case ARM::tBfar: {
1124 MCInst TmpInst;
1125 TmpInst.setOpcode(ARM::tBL);
1126 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(
1127 MI->getOperand(0).getMBB()->getSymbol(), OutContext)));
1128 OutStreamer.EmitInstruction(TmpInst);
11291091 return;
11301092 }
11311093 case ARM::LEApcrel:
11551117 MI->getOperand(2).getImm()),
11561118 MI->getOperand(3).getImm(), MI->getOperand(4).getReg(),
11571119 OutContext);
1158 OutStreamer.EmitInstruction(TmpInst);
1159 return;
1160 }
1161 case ARM::MOVPCRX: {
1162 MCInst TmpInst;
1163 TmpInst.setOpcode(ARM::MOVr);
1164 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1165 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1166 // Add predicate operands.
1167 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1168 TmpInst.addOperand(MCOperand::CreateReg(0));
1169 // Add 's' bit operand (always reg0 for this)
1170 TmpInst.addOperand(MCOperand::CreateReg(0));
11711120 OutStreamer.EmitInstruction(TmpInst);
11721121 return;
11731122 }
19111860 OutStreamer.EmitInstruction(TmpInst);
19121861 return;
19131862 }
1914
1915 // These are the pseudos created to comply with stricter operand restrictions
1916 // on ARMv5. Lower them now to "normal" instructions, since all the
1917 // restrictions are already satisfied.
1918 case ARM::MULv5:
1919 EmitPatchedInstruction(MI, ARM::MUL);
1920 return;
1921 case ARM::MLAv5:
1922 EmitPatchedInstruction(MI, ARM::MLA);
1923 return;
1924 case ARM::SMULLv5:
1925 EmitPatchedInstruction(MI, ARM::SMULL);
1926 return;
1927 case ARM::UMULLv5:
1928 EmitPatchedInstruction(MI, ARM::UMULL);
1929 return;
1930 case ARM::SMLALv5:
1931 EmitPatchedInstruction(MI, ARM::SMLAL);
1932 return;
1933 case ARM::UMLALv5:
1934 EmitPatchedInstruction(MI, ARM::UMLAL);
1935 return;
1936 case ARM::UMAALv5:
1937 EmitPatchedInstruction(MI, ARM::UMAAL);
1938 return;
19391863 }
19401864
19411865 MCInst TmpInst;
1919 #include "llvm/Support/Compiler.h"
2020
2121 namespace llvm {
22
23 class MCOperand;
2224
2325 namespace ARM {
2426 enum DW_ISA {
7173 void EmitStartOfAsmFile(Module &M);
7274 void EmitEndOfAsmFile(Module &M);
7375
76 // lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
77 bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
78
7479 private:
7580 // Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
7681 void emitAttributes();
8287 void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
8388
8489 void EmitUnwindingInstruction(const MachineInstr *MI);
90
91 // emitPseudoExpansionLowering - tblgen'erated.
92 bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
93 const MachineInstr *MI);
8594
8695 public:
8796 void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
99108 llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
100109 }
101110
111 MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
102112 MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
103113 const MachineBasicBlock *MBB) const;
104114 MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
106116 MCSymbol *GetARMSJLJEHLabel(void) const;
107117
108118 MCSymbol *GetARMGVSymbol(const GlobalValue *GV);
109
119
110120 /// EmitMachineConstantPoolValue - Print a machine constantpool value to
111121 /// the .s file.
112122 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
313313 let SZ = sz;
314314 list Predicates = [IsThumb2];
315315 }
316
317 class ARMPseudoExpand
318 InstrItinClass itin, list pattern,
319 dag Result>
320 : ARMPseudoInst,
321 PseudoInstExpansion;
322
323 class tPseudoExpand
324 InstrItinClass itin, list pattern,
325 dag Result>
326 : tPseudoInst,
327 PseudoInstExpansion;
328
329 class t2PseudoExpand
330 InstrItinClass itin, list pattern,
331 dag Result>
332 : t2PseudoInst,
333 PseudoInstExpansion;
334
316335 // Almost all ARM instructions are predicable.
317336 class I
318337 IndexMode im, Format f, InstrItinClass itin,
13621362 let Inst{27-4} = 0b000100101111111111110001;
13631363 let Inst{3-0} = dst;
13641364 }
1365
1366 // ARMV4 only
1367 // FIXME: We would really like to define this as a vanilla ARMPat like:
1368 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
1369 // With that, however, we can't set isBranch, isTerminator, etc..
1370 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
1371 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
1372 Requires<[IsARM, NoV4T]>;
13731365 }
13741366
13751367 // All calls clobber the non-callee saved registers. SP is marked as
15251517 }
15261518
15271519 let isBranch = 1, isTerminator = 1 in {
1528 // B is "predicable" since it's just a Bcc with an 'always' condition.
1520 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1521 // a two-value operand where a dag node expects two operands. :(
1522 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1523 IIC_Br, "b", "\t$target",
1524 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1525 bits<24> target;
1526 let Inst{23-0} = target;
1527 }
1528
15291529 let isBarrier = 1 in {
1530 // B is "predicable" since it's just a Bcc with an 'always' condition.
15301531 let isPredicable = 1 in
15311532 // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
15321533 // should be sufficient.
1533 def B : ARMPseudoInst<(outs), (ins brtarget:$target), Size4Bytes, IIC_Br,
1534 [(br bb:$target)]>;
1534 // FIXME: Is B really a Barrier? That doesn't seem right.
1535 def B : ARMPseudoExpand<(outs), (ins br_target:$target), Size4Bytes, IIC_Br,
1536 [(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>;
15351537
15361538 let isNotDuplicable = 1, isIndirectBranch = 1 in {
15371539 def BR_JTr : ARMPseudoInst<(outs),
15531555 } // isNotDuplicable = 1, isIndirectBranch = 1
15541556 } // isBarrier = 1
15551557
1556 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
1557 // a two-value operand where a dag node expects two operands. :(
1558 def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
1559 IIC_Br, "b", "\t$target",
1560 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
1561 bits<24> target;
1562 let Inst{23-0} = target;
1563 }
15641558 }
15651559
15661560 // BLX (immediate) -- for disassembly only
20292023 // FIXME: Should pc be an implicit operand like PICADD, etc?
20302024 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
20312025 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2032 def LDMIA_RET : ARMPseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2033 reglist:$regs, variable_ops),
2034 Size4Bytes, IIC_iLoad_mBr, []>,
2026 def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2027 reglist:$regs, variable_ops),
2028 Size4Bytes, IIC_iLoad_mBr, [],
2029 (LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
20352030 RegConstraint<"$Rn = $wb">;
20362031
20372032 //===----------------------------------------------------------------------===//
26892684 let Inst{3-0} = Rn;
26902685 }
26912686
2687 // FIXME: The v5 pseudos are only necessary for the additional Constraint
2688 // property. Remove them when it's possible to add those properties
2689 // on an individual MachineInstr, not just an instuction description.
26922690 let isCommutable = 1 in {
2693 let Constraints = "@earlyclobber $Rd" in
2694 def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2695 pred:$p, cc_out:$s),
2696 Size4Bytes, IIC_iMUL32,
2697 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
2698 Requires<[IsARM, NoV6]>;
2699
27002691 def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
27012692 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
27022693 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
27032694 Requires<[IsARM, HasV6]> {
27042695 let Inst{15-12} = 0b0000;
27052696 }
2706 }
27072697
27082698 let Constraints = "@earlyclobber $Rd" in
2709 def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
2710 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2711 Size4Bytes, IIC_iMAC32,
2712 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
2699 def MULv5: ARMPseudoExpand<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
2700 pred:$p, cc_out:$s),
2701 Size4Bytes, IIC_iMUL32,
2702 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))],
2703 (MUL GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
27132704 Requires<[IsARM, NoV6]>;
2705 }
2706
27142707 def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
27152708 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
27162709 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
27182711 bits<4> Ra;
27192712 let Inst{15-12} = Ra;
27202713 }
2714
2715 let Constraints = "@earlyclobber $Rd" in
2716 def MLAv5: ARMPseudoExpand<(outs GPR:$Rd),
2717 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
2718 Size4Bytes, IIC_iMAC32,
2719 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))],
2720 (MLA GPR:$Rd, GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s)>,
2721 Requires<[IsARM, NoV6]>;
27212722
27222723 def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
27232724 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
27342735 }
27352736
27362737 // Extra precision multiplies with low / high results
2737
27382738 let neverHasSideEffects = 1 in {
27392739 let isCommutable = 1 in {
2740 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2741 def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2742 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2743 Size4Bytes, IIC_iMUL64, []>,
2744 Requires<[IsARM, NoV6]>;
2745
2746 def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2747 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2748 Size4Bytes, IIC_iMUL64, []>,
2749 Requires<[IsARM, NoV6]>;
2750 }
2751
27522740 def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
2753 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2741 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
27542742 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
27552743 Requires<[IsARM, HasV6]>;
27562744
27572745 def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
2758 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
2746 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
27592747 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
27602748 Requires<[IsARM, HasV6]>;
2749
2750 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2751 def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
2752 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2753 Size4Bytes, IIC_iMUL64, [],
2754 (SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
2755 Requires<[IsARM, NoV6]>;
2756
2757 def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
2758 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2759 Size4Bytes, IIC_iMUL64, [],
2760 (UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
2761 Requires<[IsARM, NoV6]>;
2762 }
27612763 }
27622764
27632765 // Multiply + accumulate
2764 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2765 def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2766 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2767 Size4Bytes, IIC_iMAC64, []>,
2768 Requires<[IsARM, NoV6]>;
2769 def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2770 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2771 Size4Bytes, IIC_iMAC64, []>,
2772 Requires<[IsARM, NoV6]>;
2773 def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
2774 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2775 Size4Bytes, IIC_iMAC64, []>,
2776 Requires<[IsARM, NoV6]>;
2777
2778 }
2779
27802766 def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
27812767 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
27822768 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
27992785 let Inst{11-8} = Rm;
28002786 let Inst{3-0} = Rn;
28012787 }
2788
2789 let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
2790 def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
2791 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2792 Size4Bytes, IIC_iMAC64, [],
2793 (SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
2794 Requires<[IsARM, NoV6]>;
2795 def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
2796 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
2797 Size4Bytes, IIC_iMAC64, [],
2798 (UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
2799 Requires<[IsARM, NoV6]>;
2800 def UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
2801 (ins GPR:$Rn, GPR:$Rm, pred:$p),
2802 Size4Bytes, IIC_iMAC64, [],
2803 (UMAAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p)>,
2804 Requires<[IsARM, NoV6]>;
2805 }
2806
28022807 } // neverHasSideEffects
28032808
28042809 // Most significant word multiply
38373842 // Non-Instruction Patterns
38383843 //
38393844
3845 // ARMv4 indirect branch using (MOVr PC, dst)
3846 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
3847 def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst),
3848 Size4Bytes, IIC_Br, [(brind GPR:$dst)],
3849 (MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
3850 Requires<[IsARM, NoV4T]>;
3851
38403852 // Large immediate handling.
38413853
38423854 // 32-bit immediate using two piece so_imms or movw + movt.
403403 let Inst{2-0} = 0b111;
404404 }
405405 }
406
407 // FIXME: remove when we have a way to marking a MI with these properties.
408 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
409 hasExtraDefRegAllocReq = 1 in
410 def tPOP_RET : tPseudoInst<(outs), (ins pred:$p, reglist:$regs, variable_ops),
411 Size2Bytes, IIC_iPop_Br, []>;
412406
413407 // All calls clobber the non-callee saved registers. SP is marked as a use to
414408 // prevent stack-pointer assignments that appear immediately before calls from
527521 // Just a pseudo for a tBL instruction. Needed to let regalloc know about
528522 // the clobber of LR.
529523 let Defs = [LR] in
530 def tBfar : tPseudoInst<(outs), (ins t_bltarget:$target),
531 Size4Bytes, IIC_Br, []>;
524 def tBfar : tPseudoExpand<(outs), (ins t_bltarget:$target),
525 Size4Bytes, IIC_Br, [], (tBL t_bltarget:$target)>;
532526
533527 def tBR_JTr : tPseudoInst<(outs),
534528 (ins tGPR:$target, i32imm:$jt, i32imm:$id),
14761470 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
14771471 imm:$cp))]>,
14781472 Requires<[IsThumb, IsThumb1Only]>;
1473
1474 // Pseudo-instruction for merged POP and return.
1475 // FIXME: remove when we have a way to marking a MI with these properties.
1476 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1477 hasExtraDefRegAllocReq = 1 in
1478 def tPOP_RET : tPseudoExpand<(outs), (ins pred:$p, reglist:$regs, variable_ops),
1479 Size2Bytes, IIC_iPop_Br, [],
1480 (tPOP pred:$p, reglist:$regs)>;
1481
29772977 // FIXME: Should pc be an implicit operand like PICADD, etc?
29782978 let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
29792979 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
2980 def t2LDMIA_RET: t2PseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
2980 def t2LDMIA_RET: t2PseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
29812981 reglist:$regs, variable_ops),
2982 Size4Bytes, IIC_iLoad_mBr, []>,
2982 Size4Bytes, IIC_iLoad_mBr, [],
2983 (t2LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
29832984 RegConstraint<"$Rn = $wb">;
29842985
29852986 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
2222 using namespace llvm;
2323
2424
25 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
26 ARMAsmPrinter &Printer) {
27 MCContext &Ctx = Printer.OutContext;
25 MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
26 const MCSymbol *Symbol) {
2827 const MCExpr *Expr;
2928 switch (MO.getTargetFlags()) {
3029 default: {
31 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
30 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
31 OutContext);
3232 switch (MO.getTargetFlags()) {
3333 default:
3434 assert(0 && "Unknown target flag on symbol operand");
3535 case 0:
3636 break;
3737 case ARMII::MO_LO16:
38 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
39 Expr = ARMMCExpr::CreateLower16(Expr, Ctx);
38 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
39 OutContext);
40 Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
4041 break;
4142 case ARMII::MO_HI16:
42 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
43 Expr = ARMMCExpr::CreateUpper16(Expr, Ctx);
43 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
44 OutContext);
45 Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
4446 break;
4547 }
4648 break;
4749 }
4850
4951 case ARMII::MO_PLT:
50 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx);
52 Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT,
53 OutContext);
5154 break;
5255 }
5356
5457 if (!MO.isJTI() && MO.getOffset())
5558 Expr = MCBinaryExpr::CreateAdd(Expr,
56 MCConstantExpr::Create(MO.getOffset(), Ctx),
57 Ctx);
59 MCConstantExpr::Create(MO.getOffset(),
60 OutContext),
61 OutContext);
5862 return MCOperand::CreateExpr(Expr);
5963
64 }
65
66 bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
67 MCOperand &MCOp) {
68 switch (MO.getType()) {
69 default:
70 assert(0 && "unknown operand type");
71 return false;
72 case MachineOperand::MO_Register:
73 // Ignore all non-CPSR implicit register operands.
74 if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
75 return false;
76 assert(!MO.getSubReg() && "Subregs should be eliminated!");
77 MCOp = MCOperand::CreateReg(MO.getReg());
78 break;
79 case MachineOperand::MO_Immediate:
80 MCOp = MCOperand::CreateImm(MO.getImm());
81 break;
82 case MachineOperand::MO_MachineBasicBlock:
83 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
84 MO.getMBB()->getSymbol(), OutContext));
85 break;
86 case MachineOperand::MO_GlobalAddress:
87 MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal()));
88 break;
89 case MachineOperand::MO_ExternalSymbol:
90 MCOp = GetSymbolRef(MO,
91 GetExternalSymbolSymbol(MO.getSymbolName()));
92 break;
93 case MachineOperand::MO_JumpTableIndex:
94 MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
95 break;
96 case MachineOperand::MO_ConstantPoolIndex:
97 MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
98 break;
99 case MachineOperand::MO_BlockAddress:
100 MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
101 break;
102 case MachineOperand::MO_FPImmediate: {
103 APFloat Val = MO.getFPImm()->getValueAPF();
104 bool ignored;
105 Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
106 MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
107 break;
108 }
109 }
110 return true;
60111 }
61112
62113 void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
67118 const MachineOperand &MO = MI->getOperand(i);
68119
69120 MCOperand MCOp;
70 switch (MO.getType()) {
71 default:
72 MI->dump();
73 assert(0 && "unknown operand type");
74 case MachineOperand::MO_Register:
75 // Ignore all non-CPSR implicit register operands.
76 if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue;
77 assert(!MO.getSubReg() && "Subregs should be eliminated!");
78 MCOp = MCOperand::CreateReg(MO.getReg());
79 break;
80 case MachineOperand::MO_Immediate:
81 MCOp = MCOperand::CreateImm(MO.getImm());
82 break;
83 case MachineOperand::MO_MachineBasicBlock:
84 MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
85 MO.getMBB()->getSymbol(), AP.OutContext));
86 break;
87 case MachineOperand::MO_GlobalAddress:
88 MCOp = GetSymbolRef(MO, AP.Mang->getSymbol(MO.getGlobal()), AP);
89 break;
90 case MachineOperand::MO_ExternalSymbol:
91 MCOp = GetSymbolRef(MO,
92 AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
93 break;
94 case MachineOperand::MO_JumpTableIndex:
95 MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);
96 break;
97 case MachineOperand::MO_ConstantPoolIndex:
98 MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP);
99 break;
100 case MachineOperand::MO_BlockAddress:
101 MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP);
102 break;
103 case MachineOperand::MO_FPImmediate: {
104 APFloat Val = MO.getFPImm()->getValueAPF();
105 bool ignored;
106 Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
107 MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
108 break;
109 }
110 }
111
112 OutMI.addOperand(MCOp);
121 if (AP.lowerOperand(MO, MCOp))
122 OutMI.addOperand(MCOp);
113123 }
114124 }
1616 ARMGenDAGISel.inc ARMGenSubtargetInfo.inc \
1717 ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
1818 ARMGenDecoderTables.inc ARMGenEDInfo.inc \
19 ARMGenFastISel.inc ARMGenMCCodeEmitter.inc
19 ARMGenFastISel.inc ARMGenMCCodeEmitter.inc \
20 ARMGenMCPseudoLowering.inc
2021
2122 DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
2223