mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	[Hexagon] Use A2_tfrsi for constant pool and jump table addresses
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235535 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -116,12 +116,14 @@ static bool isCombinableInstType(MachineInstr *MI, | |||||||
|   switch(MI->getOpcode()) { |   switch(MI->getOpcode()) { | ||||||
|   case Hexagon::A2_tfr: { |   case Hexagon::A2_tfr: { | ||||||
|     // A COPY instruction can be combined if its arguments are IntRegs (32bit). |     // A COPY instruction can be combined if its arguments are IntRegs (32bit). | ||||||
|     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg()); |     const MachineOperand &Op0 = MI->getOperand(0); | ||||||
|  |     const MachineOperand &Op1 = MI->getOperand(1); | ||||||
|  |     assert(Op0.isReg() && Op1.isReg()); | ||||||
|  |  | ||||||
|     unsigned DestReg = MI->getOperand(0).getReg(); |     unsigned DestReg = Op0.getReg(); | ||||||
|     unsigned SrcReg = MI->getOperand(1).getReg(); |     unsigned SrcReg = Op1.getReg(); | ||||||
|     return Hexagon::IntRegsRegClass.contains(DestReg) && |     return Hexagon::IntRegsRegClass.contains(DestReg) && | ||||||
|       Hexagon::IntRegsRegClass.contains(SrcReg); |            Hexagon::IntRegsRegClass.contains(SrcReg); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   case Hexagon::A2_tfrsi: { |   case Hexagon::A2_tfrsi: { | ||||||
| @@ -144,21 +146,6 @@ static bool isCombinableInstType(MachineInstr *MI, | |||||||
|            (ShouldCombineAggressively || NotExt); |            (ShouldCombineAggressively || NotExt); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   case Hexagon::TFRI_V4: { |  | ||||||
|     if (!ShouldCombineAggressively) |  | ||||||
|       return false; |  | ||||||
|     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal()); |  | ||||||
|  |  | ||||||
|     // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a |  | ||||||
|     // workaround for an ABI bug that prevents GOT relocations on combine |  | ||||||
|     // instructions |  | ||||||
|     if (MI->getOperand(1).getTargetFlags() != HexagonII::MO_NO_FLAG) |  | ||||||
|       return false; |  | ||||||
|  |  | ||||||
|     unsigned DestReg = MI->getOperand(0).getReg(); |  | ||||||
|     return Hexagon::IntRegsRegClass.contains(DestReg); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   default: |   default: | ||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
| @@ -166,13 +153,14 @@ static bool isCombinableInstType(MachineInstr *MI, | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool isGreaterThan8BitTFRI(MachineInstr *I) { | template <unsigned N> | ||||||
|   return I->getOpcode() == Hexagon::A2_tfrsi && | static bool isGreaterThanNBitTFRI(const MachineInstr *I) { | ||||||
|     !isInt<8>(I->getOperand(1).getImm()); |   if (I->getOpcode() == Hexagon::TFRI64_V4 || | ||||||
| } |       I->getOpcode() == Hexagon::A2_tfrsi) { | ||||||
| static bool isGreaterThan6BitTFRI(MachineInstr *I) { |     const MachineOperand &Op = I->getOperand(1); | ||||||
|   return I->getOpcode() == Hexagon::A2_tfrsi && |     return !Op.isImm() || !isInt<N>(Op.getImm()); | ||||||
|     !isUInt<6>(I->getOperand(1).getImm()); |   } | ||||||
|  |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// areCombinableOperations - Returns true if the two instruction can be merge | /// areCombinableOperations - Returns true if the two instruction can be merge | ||||||
| @@ -180,19 +168,15 @@ static bool isGreaterThan6BitTFRI(MachineInstr *I) { | |||||||
| static bool areCombinableOperations(const TargetRegisterInfo *TRI, | static bool areCombinableOperations(const TargetRegisterInfo *TRI, | ||||||
|                                     MachineInstr *HighRegInst, |                                     MachineInstr *HighRegInst, | ||||||
|                                     MachineInstr *LowRegInst) { |                                     MachineInstr *LowRegInst) { | ||||||
|   assert((HighRegInst->getOpcode() == Hexagon::A2_tfr || |   unsigned HiOpc = HighRegInst->getOpcode(); | ||||||
|           HighRegInst->getOpcode() == Hexagon::A2_tfrsi || |   unsigned LoOpc = LowRegInst->getOpcode(); | ||||||
|           HighRegInst->getOpcode() == Hexagon::TFRI_V4) && |   assert((HiOpc == Hexagon::A2_tfr || HiOpc == Hexagon::A2_tfrsi) && | ||||||
|          (LowRegInst->getOpcode() == Hexagon::A2_tfr || |          (LoOpc == Hexagon::A2_tfr || LoOpc == Hexagon::A2_tfrsi) && | ||||||
|           LowRegInst->getOpcode() == Hexagon::A2_tfrsi || |  | ||||||
|           LowRegInst->getOpcode() == Hexagon::TFRI_V4) && |  | ||||||
|          "Assume individual instructions are of a combinable type"); |          "Assume individual instructions are of a combinable type"); | ||||||
|  |  | ||||||
|   // There is no combine of two constant extended values. |   // There is no combine of two constant extended values. | ||||||
|   if ((HighRegInst->getOpcode() == Hexagon::TFRI_V4 || |   if (isGreaterThanNBitTFRI<8>(HighRegInst) && | ||||||
|        isGreaterThan8BitTFRI(HighRegInst)) && |       isGreaterThanNBitTFRI<6>(LowRegInst)) | ||||||
|       (LowRegInst->getOpcode() == Hexagon::TFRI_V4 || |  | ||||||
|        isGreaterThan6BitTFRI(LowRegInst))) |  | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   return true; |   return true; | ||||||
| @@ -219,10 +203,14 @@ static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg, | |||||||
|                                   unsigned DestReg, |                                   unsigned DestReg, | ||||||
|                                   const TargetRegisterInfo *TRI) { |                                   const TargetRegisterInfo *TRI) { | ||||||
|   return (UseReg && (I->modifiesRegister(UseReg, TRI))) || |   return (UseReg && (I->modifiesRegister(UseReg, TRI))) || | ||||||
|           I->modifiesRegister(DestReg, TRI) || |          I->modifiesRegister(DestReg, TRI) || | ||||||
|           I->readsRegister(DestReg, TRI) || |          I->readsRegister(DestReg, TRI) || | ||||||
|           I->hasUnmodeledSideEffects() || |          I->hasUnmodeledSideEffects() || | ||||||
|           I->isInlineAsm() || I->isDebugValue(); |          I->isInlineAsm() || I->isDebugValue(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static unsigned UseReg(const MachineOperand& MO) { | ||||||
|  |   return MO.isReg() ? MO.getReg() : 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such | /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such | ||||||
| @@ -232,9 +220,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, | |||||||
|                                                 unsigned I1DestReg, |                                                 unsigned I1DestReg, | ||||||
|                                                 unsigned I2DestReg, |                                                 unsigned I2DestReg, | ||||||
|                                                 bool &DoInsertAtI1) { |                                                 bool &DoInsertAtI1) { | ||||||
|  |   unsigned I2UseReg = UseReg(I2->getOperand(1)); | ||||||
|   bool IsImmUseReg = I2->getOperand(1).isImm() || I2->getOperand(1).isGlobal(); |  | ||||||
|   unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg(); |  | ||||||
|  |  | ||||||
|   // It is not safe to move I1 and I2 into one combine if I2 has a true |   // It is not safe to move I1 and I2 into one combine if I2 has a true | ||||||
|   // dependence on I1. |   // dependence on I1. | ||||||
| @@ -298,8 +284,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, | |||||||
|     // At O3 we got better results (dhrystone) by being more conservative here. |     // At O3 we got better results (dhrystone) by being more conservative here. | ||||||
|     if (!ShouldCombineAggressively) |     if (!ShouldCombineAggressively) | ||||||
|       End = std::next(MachineBasicBlock::iterator(I2)); |       End = std::next(MachineBasicBlock::iterator(I2)); | ||||||
|     IsImmUseReg = I1->getOperand(1).isImm() || I1->getOperand(1).isGlobal(); |     unsigned I1UseReg = UseReg(I1->getOperand(1)); | ||||||
|     unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg(); |  | ||||||
|     // Track killed operands. If we move across an instruction that kills our |     // Track killed operands. If we move across an instruction that kills our | ||||||
|     // operand, we need to update the kill information on the moved I1. It kills |     // operand, we need to update the kill information on the moved I1. It kills | ||||||
|     // the operand now. |     // the operand now. | ||||||
| @@ -558,7 +543,7 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, | |||||||
|   DebugLoc DL = InsertPt->getDebugLoc(); |   DebugLoc DL = InsertPt->getDebugLoc(); | ||||||
|   MachineBasicBlock *BB = InsertPt->getParent(); |   MachineBasicBlock *BB = InsertPt->getParent(); | ||||||
|  |  | ||||||
|   // Handle  globals. |   // Handle globals. | ||||||
|   if (HiOperand.isGlobal()) { |   if (HiOperand.isGlobal()) { | ||||||
|     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) | ||||||
|       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), |       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), | ||||||
| @@ -574,17 +559,64 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, | |||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Handle constant extended immediates. |   // Handle block addresses. | ||||||
|   if (!isInt<8>(HiOperand.getImm())) { |   if (HiOperand.isBlockAddress()) { | ||||||
|     assert(isInt<8>(LoOperand.getImm())); |  | ||||||
|     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) | ||||||
|       .addImm(HiOperand.getImm()) |       .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), | ||||||
|  |                        HiOperand.getTargetFlags()) | ||||||
|       .addImm(LoOperand.getImm()); |       .addImm(LoOperand.getImm()); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |   if (LoOperand.isBlockAddress()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) | ||||||
|  |       .addImm(HiOperand.getImm()) | ||||||
|  |       .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), | ||||||
|  |                        LoOperand.getTargetFlags()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if (!isUInt<6>(LoOperand.getImm())) { |   // Handle jump tables. | ||||||
|     assert(isInt<8>(HiOperand.getImm())); |   if (HiOperand.isJTI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) | ||||||
|  |       .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) | ||||||
|  |       .addImm(LoOperand.getImm()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (LoOperand.isJTI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) | ||||||
|  |       .addImm(HiOperand.getImm()) | ||||||
|  |       .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Handle constant pools. | ||||||
|  |   if (HiOperand.isCPI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) | ||||||
|  |       .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), | ||||||
|  |                             HiOperand.getTargetFlags()) | ||||||
|  |       .addImm(LoOperand.getImm()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (LoOperand.isCPI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) | ||||||
|  |       .addImm(HiOperand.getImm()) | ||||||
|  |       .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), | ||||||
|  |                             LoOperand.getTargetFlags()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // First preference should be given to Hexagon::A2_combineii instruction | ||||||
|  |   // as it can include U6 (in Hexagon::A4_combineii) as well. | ||||||
|  |   // In this instruction, HiOperand is const extended, if required. | ||||||
|  |   if (isInt<8>(LoOperand.getImm())) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) | ||||||
|  |       .addImm(HiOperand.getImm()) | ||||||
|  |       .addImm(LoOperand.getImm()); | ||||||
|  |       return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // In this instruction, LoOperand is const extended, if required. | ||||||
|  |   if (isInt<8>(HiOperand.getImm())) { | ||||||
|     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) | ||||||
|       .addImm(HiOperand.getImm()) |       .addImm(HiOperand.getImm()) | ||||||
|       .addImm(LoOperand.getImm()); |       .addImm(LoOperand.getImm()); | ||||||
| @@ -608,7 +640,7 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, | |||||||
|   DebugLoc DL = InsertPt->getDebugLoc(); |   DebugLoc DL = InsertPt->getDebugLoc(); | ||||||
|   MachineBasicBlock *BB = InsertPt->getParent(); |   MachineBasicBlock *BB = InsertPt->getParent(); | ||||||
|  |  | ||||||
|   // Handle global. |   // Handle globals. | ||||||
|   if (HiOperand.isGlobal()) { |   if (HiOperand.isGlobal()) { | ||||||
|     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) | ||||||
|       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), |       .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), | ||||||
| @@ -616,6 +648,29 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, | |||||||
|       .addReg(LoReg, LoRegKillFlag); |       .addReg(LoReg, LoRegKillFlag); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |   // Handle block addresses. | ||||||
|  |   if (HiOperand.isBlockAddress()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) | ||||||
|  |       .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), | ||||||
|  |                        HiOperand.getTargetFlags()) | ||||||
|  |       .addReg(LoReg, LoRegKillFlag); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   // Handle jump tables. | ||||||
|  |   if (HiOperand.isJTI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) | ||||||
|  |       .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) | ||||||
|  |       .addReg(LoReg, LoRegKillFlag); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   // Handle constant pools. | ||||||
|  |   if (HiOperand.isCPI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) | ||||||
|  |       .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), | ||||||
|  |                             HiOperand.getTargetFlags()) | ||||||
|  |       .addReg(LoReg, LoRegKillFlag); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|   // Insert new combine instruction. |   // Insert new combine instruction. | ||||||
|   //  DoubleRegDest = combine #HiImm, LoReg |   //  DoubleRegDest = combine #HiImm, LoReg | ||||||
|   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) |   BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) | ||||||
| @@ -641,6 +696,29 @@ void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, | |||||||
|                         LoOperand.getTargetFlags()); |                         LoOperand.getTargetFlags()); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |   // Handle block addresses. | ||||||
|  |   if (LoOperand.isBlockAddress()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) | ||||||
|  |       .addReg(HiReg, HiRegKillFlag) | ||||||
|  |       .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), | ||||||
|  |                        LoOperand.getTargetFlags()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   // Handle jump tables. | ||||||
|  |   if (LoOperand.isJTI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) | ||||||
|  |       .addReg(HiOperand.getReg(), HiRegKillFlag) | ||||||
|  |       .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   // Handle constant pools. | ||||||
|  |   if (LoOperand.isCPI()) { | ||||||
|  |     BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) | ||||||
|  |       .addReg(HiOperand.getReg(), HiRegKillFlag) | ||||||
|  |       .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), | ||||||
|  |                             LoOperand.getTargetFlags()); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Insert new combine instruction. |   // Insert new combine instruction. | ||||||
|   //  DoubleRegDest = combine HiReg, #LoImm |   //  DoubleRegDest = combine HiReg, #LoImm | ||||||
|   | |||||||
| @@ -1770,7 +1770,8 @@ bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const { | |||||||
|   // We currently only handle isGlobal() because it is the only kind of |   // We currently only handle isGlobal() because it is the only kind of | ||||||
|   // object we are going to end up with here for now. |   // object we are going to end up with here for now. | ||||||
|   // In the future we probably should add isSymbol(), etc. |   // In the future we probably should add isSymbol(), etc. | ||||||
|   if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress()) |   if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() || | ||||||
|  |       MO.isJTI() || MO.isCPI()) | ||||||
|     return true; |     return true; | ||||||
|  |  | ||||||
|   // If the extendable operand is not 'Immediate' type, the instruction should |   // If the extendable operand is not 'Immediate' type, the instruction should | ||||||
|   | |||||||
| @@ -4823,12 +4823,6 @@ def CONST32 : CONSTLDInst<(outs IntRegs:$dst), (ins globaladdress:$global), | |||||||
|               [(set (i32 IntRegs:$dst), |               [(set (i32 IntRegs:$dst), | ||||||
|                     (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; |                     (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; | ||||||
|  |  | ||||||
| let isReMaterializable = 1, isMoveImm = 1 in |  | ||||||
| def CONST32_set_jt : CONSTLDInst<(outs IntRegs:$dst), (ins jumptablebase:$jt), |  | ||||||
|                      "$dst = CONST32(#$jt)", |  | ||||||
|                      [(set (i32 IntRegs:$dst), |  | ||||||
|                            (HexagonCONST32 tjumptable:$jt))]>; |  | ||||||
|  |  | ||||||
| let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in | let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in | ||||||
| def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), | def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), | ||||||
|                        "$dst = CONST32(#$global)", |                        "$dst = CONST32(#$global)", | ||||||
| @@ -4836,7 +4830,7 @@ def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), | |||||||
|  |  | ||||||
| // Map TLS addressses to a CONST32 instruction | // Map TLS addressses to a CONST32 instruction | ||||||
| def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s16Ext:$addr)>; | def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s16Ext:$addr)>; | ||||||
| def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s16Ext:$label)>; | def: Pat<(HexagonCONST32 bbl:$label),           (A2_tfrsi s16Ext:$label)>; | ||||||
|  |  | ||||||
| let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in | let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in | ||||||
| def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label), | def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label), | ||||||
| @@ -5145,10 +5139,8 @@ def: Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)), | |||||||
| def HexagonJT:     SDNode<"HexagonISD::JT", SDTIntUnaryOp>; | def HexagonJT:     SDNode<"HexagonISD::JT", SDTIntUnaryOp>; | ||||||
| def HexagonCP:     SDNode<"HexagonISD::CP", SDTIntUnaryOp>; | def HexagonCP:     SDNode<"HexagonISD::CP", SDTIntUnaryOp>; | ||||||
|  |  | ||||||
| def: Pat<(HexagonJT tjumptable:$dst), | def: Pat<(HexagonJT tjumptable:$dst), (A2_tfrsi s16Ext:$dst)>; | ||||||
|          (CONST32_set_jt tjumptable:$dst)>; | def: Pat<(HexagonCP tconstpool:$dst), (A2_tfrsi s16Ext:$dst)>; | ||||||
| def: Pat<(HexagonCP tconstpool :$dst), |  | ||||||
|          (CONST32_set_jt tconstpool:$dst)>; |  | ||||||
|  |  | ||||||
| // XTYPE/SHIFT | // XTYPE/SHIFT | ||||||
| // | // | ||||||
|   | |||||||
| @@ -499,10 +499,23 @@ multiclass T_LoadAbsReg_Pat <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> { | |||||||
|   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), |   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), | ||||||
|                              (HexagonCONST32 tglobaladdr:$src3)))), |                              (HexagonCONST32 tglobaladdr:$src3)))), | ||||||
|               (MI IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3)>; |               (MI IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3)>; | ||||||
|  |  | ||||||
|   def  : Pat <(VT (ldOp (add IntRegs:$src1, |   def  : Pat <(VT (ldOp (add IntRegs:$src1, | ||||||
|                              (HexagonCONST32 tglobaladdr:$src2)))), |                              (HexagonCONST32 tglobaladdr:$src2)))), | ||||||
|               (MI IntRegs:$src1, 0, tglobaladdr:$src2)>; |               (MI IntRegs:$src1, 0, tglobaladdr:$src2)>; | ||||||
|  |  | ||||||
|  |   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), | ||||||
|  |                              (HexagonCONST32 tconstpool:$src3)))), | ||||||
|  |               (MI IntRegs:$src1, u2ImmPred:$src2, tconstpool:$src3)>; | ||||||
|  |   def  : Pat <(VT (ldOp (add IntRegs:$src1, | ||||||
|  |                              (HexagonCONST32 tconstpool:$src2)))), | ||||||
|  |               (MI IntRegs:$src1, 0, tconstpool:$src2)>; | ||||||
|  |  | ||||||
|  |   def  : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2ImmPred:$src2), | ||||||
|  |                              (HexagonCONST32 tjumptable:$src3)))), | ||||||
|  |               (MI IntRegs:$src1, u2ImmPred:$src2, tjumptable:$src3)>; | ||||||
|  |   def  : Pat <(VT (ldOp (add IntRegs:$src1, | ||||||
|  |                              (HexagonCONST32 tjumptable:$src2)))), | ||||||
|  |               (MI IntRegs:$src1, 0, tjumptable:$src2)>; | ||||||
| } | } | ||||||
|  |  | ||||||
| let AddedComplexity  = 60 in { | let AddedComplexity  = 60 in { | ||||||
|   | |||||||
| @@ -83,19 +83,8 @@ bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { | |||||||
|     while (MII != MIE) { |     while (MII != MIE) { | ||||||
|       MachineInstr *MI = MII; |       MachineInstr *MI = MII; | ||||||
|       int Opc = MI->getOpcode(); |       int Opc = MI->getOpcode(); | ||||||
|       if (Opc == Hexagon::CONST32_set_jt) { |       if (Opc == Hexagon::CONST32_Int_Real && | ||||||
|         int DestReg = MI->getOperand(0).getReg(); |           MI->getOperand(1).isBlockAddress()) { | ||||||
|         MachineOperand &Symbol = MI->getOperand (1); |  | ||||||
|         BuildMI (*MBB, MII, MI->getDebugLoc(), |  | ||||||
|                  TII->get(Hexagon::A2_tfrsi), DestReg).addOperand(Symbol); |  | ||||||
|  |  | ||||||
|         // MBB->erase returns the iterator to the next instruction, which is the |  | ||||||
|         // one we want to process next |  | ||||||
|         MII = MBB->erase (MI); |  | ||||||
|         continue; |  | ||||||
|       } |  | ||||||
|       else if (Opc == Hexagon::CONST32_Int_Real && |  | ||||||
|                MI->getOperand(1).isBlockAddress()) { |  | ||||||
|         int DestReg = MI->getOperand(0).getReg(); |         int DestReg = MI->getOperand(0).getReg(); | ||||||
|         MachineOperand &Symbol = MI->getOperand (1); |         MachineOperand &Symbol = MI->getOperand (1); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| ; RUN: llc -march=hexagon < %s | FileCheck %s | ; RUN: llc -march=hexagon < %s | FileCheck %s | ||||||
|  |  | ||||||
| ; CHECK: r{{[0-9]+}} = CONST32(#.LJTI{{[0-9]+_[0-9]+}}) | ; Allow combine(..##JTI..): | ||||||
| ; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}} + r{{[0-9]+<<#[0-9]+}}) | ; CHECK: r{{[0-9]+}}{{.*}} = {{.*}}#.LJTI | ||||||
|  | ; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}{{ *}}+{{ *}}r{{[0-9]+<<#[0-9]+}}) | ||||||
| ; CHECK: jumpr r{{[0-9]+}} | ; CHECK: jumpr r{{[0-9]+}} | ||||||
|  |  | ||||||
| define void @main() #0 { | define void @main() #0 { | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ entry: | |||||||
|  |  | ||||||
| ; Function Attrs: nounwind | ; Function Attrs: nounwind | ||||||
| define i64 @test4() #0 { | define i64 @test4() #0 { | ||||||
| ; CHECK: combine(#0, ##100) | ; CHECK: combine(#0, #100) | ||||||
| entry: | entry: | ||||||
|   store i16 100, i16* @b, align 2 |   store i16 100, i16* @b, align 2 | ||||||
|   store i16 0, i16* @a, align 2 |   store i16 0, i16* @a, align 2 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user