12
12
#include " llvm/ADT/STLExtras.h"
13
13
#include " llvm/MC/MCContext.h"
14
14
#include " llvm/MC/MCInst.h"
15
+ #include " llvm/MC/MCObjectFileInfo.h"
15
16
#include " llvm/MC/MCParser/MCParsedAsmOperand.h"
16
17
#include " llvm/MC/MCStreamer.h"
17
18
#include " llvm/MC/MCSubtargetInfo.h"
19
+ #include " llvm/MC/MCSymbol.h"
18
20
#include " llvm/MC/MCTargetAsmParser.h"
19
21
#include " llvm/Support/TargetRegistry.h"
20
22
@@ -66,7 +68,7 @@ class SparcAsmParser : public MCTargetAsmParser {
66
68
StringRef Name);
67
69
68
70
OperandMatchResultTy
69
- parseSparcAsmOperand (SparcOperand *&Operand);
71
+ parseSparcAsmOperand (SparcOperand *&Operand, bool isCall = false );
70
72
71
73
// returns true if Tok is matched to a register and returns register in RegNo.
72
74
bool matchRegisterName (const AsmToken &Tok, unsigned &RegNo,
@@ -623,7 +625,7 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
623
625
}
624
626
625
627
SparcOperand *Op = 0 ;
626
- ResTy = parseSparcAsmOperand (Op);
628
+ ResTy = parseSparcAsmOperand (Op, (Mnemonic == " call " ) );
627
629
if (ResTy != MatchOperand_Success || !Op)
628
630
return MatchOperand_ParseFail;
629
631
@@ -634,7 +636,7 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
634
636
}
635
637
636
638
SparcAsmParser::OperandMatchResultTy
637
- SparcAsmParser::parseSparcAsmOperand (SparcOperand *&Op)
639
+ SparcAsmParser::parseSparcAsmOperand (SparcOperand *&Op, bool isCall )
638
640
{
639
641
640
642
SMLoc S = Parser.getTok ().getLoc ();
@@ -695,6 +697,10 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
695
697
696
698
const MCExpr *Res = MCSymbolRefExpr::Create (Sym, MCSymbolRefExpr::VK_None,
697
699
getContext ());
700
+ if (isCall &&
701
+ getContext ().getObjectFileInfo ()->getRelocM () == Reloc::PIC_)
702
+ Res = SparcMCExpr::Create (SparcMCExpr::VK_Sparc_WPLT30, Res,
703
+ getContext ());
698
704
Op = SparcOperand::CreateImm (Res, S, E);
699
705
}
700
706
break ;
@@ -813,6 +819,31 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
813
819
return false ;
814
820
}
815
821
822
+ static bool hasGOTReference (const MCExpr *Expr) {
823
+ switch (Expr->getKind ()) {
824
+ case MCExpr::Target:
825
+ if (const SparcMCExpr *SE = dyn_cast<SparcMCExpr>(Expr))
826
+ return hasGOTReference (SE->getSubExpr ());
827
+ break ;
828
+
829
+ case MCExpr::Constant:
830
+ break ;
831
+
832
+ case MCExpr::Binary: {
833
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
834
+ return hasGOTReference (BE->getLHS ()) || hasGOTReference (BE->getRHS ());
835
+ }
836
+
837
+ case MCExpr::SymbolRef: {
838
+ const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
839
+ return (SymRef.getSymbol ().getName () == " _GLOBAL_OFFSET_TABLE_" );
840
+ }
841
+
842
+ case MCExpr::Unary:
843
+ return hasGOTReference (cast<MCUnaryExpr>(Expr)->getSubExpr ());
844
+ }
845
+ return false ;
846
+ }
816
847
817
848
bool SparcAsmParser::matchSparcAsmModifiers (const MCExpr *&EVal,
818
849
SMLoc &EndLoc)
@@ -836,6 +867,23 @@ bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
836
867
const MCExpr *subExpr;
837
868
if (Parser.parseParenExpression (subExpr, EndLoc))
838
869
return false ;
870
+
871
+ bool isPIC = getContext ().getObjectFileInfo ()->getRelocM () == Reloc::PIC_;
872
+
873
+ switch (VK) {
874
+ default : break ;
875
+ case SparcMCExpr::VK_Sparc_LO:
876
+ VK = (hasGOTReference (subExpr)
877
+ ? SparcMCExpr::VK_Sparc_PC10
878
+ : (isPIC ? SparcMCExpr::VK_Sparc_GOT10 : VK));
879
+ break ;
880
+ case SparcMCExpr::VK_Sparc_HI:
881
+ VK = (hasGOTReference (subExpr)
882
+ ? SparcMCExpr::VK_Sparc_PC22
883
+ : (isPIC ? SparcMCExpr::VK_Sparc_GOT22 : VK));
884
+ break ;
885
+ }
886
+
839
887
EVal = SparcMCExpr::Create (VK, subExpr, getContext ());
840
888
return true ;
841
889
}
0 commit comments