llvm.org GIT mirror llvm / 027e944
[PowerPC] Optimize @ha/@l constructs This patch adds support for having the assembler optimize fixups to constructs like "symbol@ha" or "symbol@l" if "symbol" can be resolved at assembler time. This optimization is already present in the PPCMCExpr.cpp code for handling PPC_HA16/PPC_LO16 target expressions. However, those target expression were used only on Darwin targets. This patch changes target expression code so that they are usable also with the GNU assembler (using the @ha / @l syntax instead of the ha16() / lo16() syntax), and changes the MCInst lowering code to generate those target expressions where appropriate. It also changes the asm parser to generate HA16/LO16 target expressions when parsing assembler source that uses the @ha / @l modifiers. The effect is that now the above- mentioned optimization automatically becomes available for those situations too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184436 91177308-0d34-0410-b5e6-96231b3b80d8 Ulrich Weigand 7 years ago
5 changed file(s) with 163 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
77 //===----------------------------------------------------------------------===//
88
99 #include "MCTargetDesc/PPCMCTargetDesc.h"
10 #include "MCTargetDesc/PPCMCExpr.h"
1011 #include "llvm/MC/MCTargetAsmParser.h"
1112 #include "llvm/MC/MCStreamer.h"
1213 #include "llvm/MC/MCExpr.h"
124125 unsigned &RegNo, int64_t &IntVal);
125126
126127 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
128
129 const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
130 PPCMCExpr::VariantKind &Variant);
131 bool ParseExpression(const MCExpr *&EVal);
127132
128133 bool ParseOperand(SmallVectorImpl &Operands);
129134
539544 return Error(StartLoc, "invalid register name");
540545 }
541546
547 /// Extract @l/@ha modifier from expression. Recursively scan
548 /// the expression and check for VK_PPC_ADDR16_HA/VK_PPC_ADDR16_LO
549 /// symbol variants. If all symbols with modifier use the same
550 /// variant, return the corresponding PPCMCExpr::VariantKind,
551 /// and a modified expression using the default symbol variant.
552 /// Otherwise, return NULL.
553 const MCExpr *PPCAsmParser::
554 ExtractModifierFromExpr(const MCExpr *E,
555 PPCMCExpr::VariantKind &Variant) {
556 MCContext &Context = getParser().getContext();
557 Variant = PPCMCExpr::VK_PPC_None;
558
559 switch (E->getKind()) {
560 case MCExpr::Target:
561 case MCExpr::Constant:
562 return 0;
563
564 case MCExpr::SymbolRef: {
565 const MCSymbolRefExpr *SRE = cast(E);
566
567 switch (SRE->getKind()) {
568 case MCSymbolRefExpr::VK_PPC_ADDR16_HA:
569 Variant = PPCMCExpr::VK_PPC_HA16;
570 break;
571 case MCSymbolRefExpr::VK_PPC_ADDR16_LO:
572 Variant = PPCMCExpr::VK_PPC_LO16;
573 break;
574 default:
575 return 0;
576 }
577
578 return MCSymbolRefExpr::Create(&SRE->getSymbol(), Context);
579 }
580
581 case MCExpr::Unary: {
582 const MCUnaryExpr *UE = cast(E);
583 const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
584 if (!Sub)
585 return 0;
586 return MCUnaryExpr::Create(UE->getOpcode(), Sub, Context);
587 }
588
589 case MCExpr::Binary: {
590 const MCBinaryExpr *BE = cast(E);
591 PPCMCExpr::VariantKind LHSVariant, RHSVariant;
592 const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
593 const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
594
595 if (!LHS && !RHS)
596 return 0;
597
598 if (!LHS) LHS = BE->getLHS();
599 if (!RHS) RHS = BE->getRHS();
600
601 if (LHSVariant == PPCMCExpr::VK_PPC_None)
602 Variant = RHSVariant;
603 else if (RHSVariant == PPCMCExpr::VK_PPC_None)
604 Variant = LHSVariant;
605 else if (LHSVariant == RHSVariant)
606 Variant = LHSVariant;
607 else
608 return 0;
609
610 return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, Context);
611 }
612 }
613
614 llvm_unreachable("Invalid expression kind!");
615 }
616
617 /// Parse an expression. This differs from the default "parseExpression"
618 /// in that it handles complex @l/@ha modifiers.
619 bool PPCAsmParser::
620 ParseExpression(const MCExpr *&EVal) {
621 if (getParser().parseExpression(EVal))
622 return true;
623
624 PPCMCExpr::VariantKind Variant;
625 const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
626 if (E)
627 EVal = PPCMCExpr::Create(Variant, E, getParser().getContext());
628
629 return false;
630 }
631
542632 bool PPCAsmParser::
543633 ParseOperand(SmallVectorImpl &Operands) {
544634 SMLoc S = Parser.getTok().getLoc();
570660 case AsmToken::Identifier:
571661 case AsmToken::Dot:
572662 case AsmToken::Dollar:
573 if (!getParser().parseExpression(EVal))
663 if (!ParseExpression(EVal))
574664 break;
575665 /* fall through */
576666 default:
1010 #include "PPCMCExpr.h"
1111 #include "llvm/MC/MCAssembler.h"
1212 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCAsmInfo.h"
1314
1415 using namespace llvm;
1516
1617 const PPCMCExpr*
1718 PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
1819 MCContext &Ctx) {
19 return new (Ctx) PPCMCExpr(Kind, Expr);
20 int AssemblerDialect = Ctx.getAsmInfo()->getAssemblerDialect();
21 return new (Ctx) PPCMCExpr(Kind, Expr, AssemblerDialect);
2022 }
2123
2224 void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
23 switch (Kind) {
24 default: llvm_unreachable("Invalid kind!");
25 case VK_PPC_HA16: OS << "ha16"; break;
26 case VK_PPC_LO16: OS << "lo16"; break;
25 if (isDarwinSyntax()) {
26 switch (Kind) {
27 default: llvm_unreachable("Invalid kind!");
28 case VK_PPC_HA16: OS << "ha16"; break;
29 case VK_PPC_LO16: OS << "lo16"; break;
30 }
31
32 OS << '(';
33 getSubExpr()->print(OS);
34 OS << ')';
35 } else {
36 getSubExpr()->print(OS);
37
38 switch (Kind) {
39 default: llvm_unreachable("Invalid kind!");
40 case VK_PPC_HA16: OS << "@ha"; break;
41 case VK_PPC_LO16: OS << "@l"; break;
42 }
2743 }
28
29 OS << '(';
30 getSubExpr()->print(OS);
31 OS << ')';
3244 }
3345
3446 bool
2626 private:
2727 const VariantKind Kind;
2828 const MCExpr *Expr;
29 const int AssemblerDialect;
2930
30 explicit PPCMCExpr(VariantKind _Kind, const MCExpr *_Expr)
31 : Kind(_Kind), Expr(_Expr) {}
31 explicit PPCMCExpr(VariantKind _Kind, const MCExpr *_Expr,
32 int _AssemblerDialect)
33 : Kind(_Kind), Expr(_Expr), AssemblerDialect(_AssemblerDialect) {}
3234
3335 public:
3436 /// @name Construction
5557 /// getSubExpr - Get the child of this expression.
5658 const MCExpr *getSubExpr() const { return Expr; }
5759
60 /// isDarwinSyntax - True if expression is to be printed using Darwin syntax.
61 bool isDarwinSyntax() const { return AssemblerDialect == 1; }
62
63
5864 /// @}
5965
6066 void PrintImpl(raw_ostream &OS) const;
110110
111111 unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;
112112
113 if (!isDarwin) {
114 switch (access) {
115 case PPCII::MO_HA16:
116 RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_HA;
117 break;
118 case PPCII::MO_LO16:
119 RefKind = MCSymbolRefExpr::VK_PPC_ADDR16_LO;
120 break;
121 case PPCII::MO_TPREL16_HA:
122 RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
123 break;
124 case PPCII::MO_TPREL16_LO:
125 RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
126 break;
127 case PPCII::MO_DTPREL16_LO:
128 RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
129 break;
130 case PPCII::MO_TLSLD16_LO:
131 RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
132 break;
133 case PPCII::MO_TOC16_LO:
134 RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
135 break;
136 }
113 switch (access) {
114 case PPCII::MO_TPREL16_HA:
115 RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
116 break;
117 case PPCII::MO_TPREL16_LO:
118 RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
119 break;
120 case PPCII::MO_DTPREL16_LO:
121 RefKind = MCSymbolRefExpr::VK_PPC_DTPREL16_LO;
122 break;
123 case PPCII::MO_TLSLD16_LO:
124 RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO;
125 break;
126 case PPCII::MO_TOC16_LO:
127 RefKind = MCSymbolRefExpr::VK_PPC_TOC16_LO;
128 break;
137129 }
138130
139131 const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);
151143 Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx);
152144 }
153145
154 // Add Darwin ha16() / lo16() markers if required.
155 if (isDarwin) {
156 switch (access) {
157 case PPCII::MO_HA16:
158 Expr = PPCMCExpr::CreateHa16(Expr, Ctx);
159 break;
160 case PPCII::MO_LO16:
161 Expr = PPCMCExpr::CreateLo16(Expr, Ctx);
162 break;
163 }
146 // Add ha16() / lo16() markers if required.
147 switch (access) {
148 case PPCII::MO_HA16:
149 Expr = PPCMCExpr::CreateHa16(Expr, Ctx);
150 break;
151 case PPCII::MO_LO16:
152 Expr = PPCMCExpr::CreateLo16(Expr, Ctx);
153 break;
164154 }
165155
166156 return MCOperand::CreateExpr(Expr);
1010 addis 1, 1, target
1111
1212 .set target, 0x1234
13
14 addi 1, 1, target2@l
15 addis 1, 1, target2@ha
16
17 .set target2, 0x12345678
18
19 addi 1, 1, target3-target4@l
20 addis 1, 1, target3-target4@ha
21
22 .set target3, 0x23455678
23 .set target4, 0x12341234
24
25 addi 1, 1, target5+0x8000@l
26 addis 1, 1, target5+0x8000@ha
27
28 .set target5, 0x10000001
1329
1430 .data
1531
3248 # CHECK-NEXT: ]
3349 # CHECK-NEXT: Address: 0x0
3450 # CHECK-NEXT: Offset:
35 # CHECK-NEXT: Size: 8
51 # CHECK-NEXT: Size: 32
3652 # CHECK-NEXT: Link: 0
3753 # CHECK-NEXT: Info: 0
3854 # CHECK-NEXT: AddressAlignment: 4
3955 # CHECK-NEXT: EntrySize: 0
4056 # CHECK-NEXT: SectionData (
41 # CHECK-NEXT: 0000: 38211234 3C211234
57 # CHECK-NEXT: 0000: 38211234 3C211234 38215678 3C211234
58 # CHECK-NEXT: 0010: 38214444 3C211111 38218001 3C211001
4259 # CHECK-NEXT: )
4360 # CHECK-NEXT: }
4461