diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff new file mode 100644 index 0000000..b7eb2a2 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff @@ -0,0 +1,359 @@ +Pull in r198658 from upstream llvm trunk: + + [Sparc] Add support for parsing memory operands in sparc AsmParser. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: test/MC/Sparc/sparc-ctrl-instructions.s +=================================================================== +--- test/MC/Sparc/sparc-ctrl-instructions.s ++++ test/MC/Sparc/sparc-ctrl-instructions.s +@@ -0,0 +1,23 @@ ++! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s ++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s ++ ++ ! CHECK: call foo ++ call foo ++ ++ ! CHECK: call %g1+%i2 ++ call %g1 + %i2 ++ ++ ! CHECK: call %o1+8 ++ call %o1 + 8 ++ ++ ! CHECK: call %g1 ++ call %g1 ++ ++ ! CHECK: jmp %g1+%i2 ++ jmp %g1 + %i2 ++ ++ ! CHECK: jmp %o1+8 ++ jmp %o1 + 8 ++ ++ ! CHECK: jmp %g1 ++ jmp %g1 +Index: test/MC/Sparc/sparc-mem-instructions.s +=================================================================== +--- test/MC/Sparc/sparc-mem-instructions.s ++++ test/MC/Sparc/sparc-mem-instructions.s +@@ -0,0 +1,58 @@ ++! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s ++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s ++ ++ ! CHECK: ldsb [%i0+%l6], %o2 ! encoding: [0xd4,0x4e,0x00,0x16] ++ ldsb [%i0 + %l6], %o2 ++ ! CHECK: ldsb [%i0+32], %o2 ! encoding: [0xd4,0x4e,0x20,0x20] ++ ldsb [%i0 + 32], %o2 ++ ! CHECK: ldsb [%g1], %o4 ! encoding: [0xd8,0x48,0x60,0x00] ++ ldsb [%g1], %o4 ++ ++ ! CHECK: ldsh [%i0+%l6], %o2 ! encoding: [0xd4,0x56,0x00,0x16] ++ ldsh [%i0 + %l6], %o2 ++ ! CHECK: ldsh [%i0+32], %o2 ! encoding: [0xd4,0x56,0x20,0x20] ++ ldsh [%i0 + 32], %o2 ++ ! CHECK: ldsh [%g1], %o4 ! encoding: [0xd8,0x50,0x60,0x00] ++ ldsh [%g1], %o4 ++ ++ ! CHECK: ldub [%i0+%l6], %o2 ! encoding: [0xd4,0x0e,0x00,0x16] ++ ldub [%i0 + %l6], %o2 ++ ! CHECK: ldub [%i0+32], %o2 ! encoding: [0xd4,0x0e,0x20,0x20] ++ ldub [%i0 + 32], %o2 ++ ! CHECK: ldub [%g1], %o2 ! encoding: [0xd4,0x08,0x60,0x00] ++ ldub [%g1], %o2 ++ ++ ! CHECK: lduh [%i0+%l6], %o2 ! encoding: [0xd4,0x16,0x00,0x16] ++ lduh [%i0 + %l6], %o2 ++ ! CHECK: lduh [%i0+32], %o2 ! encoding: [0xd4,0x16,0x20,0x20] ++ lduh [%i0 + 32], %o2 ++ ! CHECK: lduh [%g1], %o2 ! encoding: [0xd4,0x10,0x60,0x00] ++ lduh [%g1], %o2 ++ ++ ! CHECK: ld [%i0+%l6], %o2 ! encoding: [0xd4,0x06,0x00,0x16] ++ ld [%i0 + %l6], %o2 ++ ! CHECK: ld [%i0+32], %o2 ! encoding: [0xd4,0x06,0x20,0x20] ++ ld [%i0 + 32], %o2 ++ ! CHECK: ld [%g1], %o2 ! encoding: [0xd4,0x00,0x60,0x00] ++ ld [%g1], %o2 ++ ++ ! CHECK: stb %o2, [%i0+%l6] ! encoding: [0xd4,0x2e,0x00,0x16] ++ stb %o2, [%i0 + %l6] ++ ! CHECK: stb %o2, [%i0+32] ! encoding: [0xd4,0x2e,0x20,0x20] ++ stb %o2, [%i0 + 32] ++ ! CHECK: stb %o2, [%g1] ! encoding: [0xd4,0x28,0x60,0x00] ++ stb %o2, [%g1] ++ ++ ! CHECK: sth %o2, [%i0+%l6] ! encoding: [0xd4,0x36,0x00,0x16] ++ sth %o2, [%i0 + %l6] ++ ! CHECK: sth %o2, [%i0+32] ! encoding: [0xd4,0x36,0x20,0x20] ++ sth %o2, [%i0 + 32] ++ ! CHECK: sth %o2, [%g1] ! encoding: [0xd4,0x30,0x60,0x00] ++ sth %o2, [%g1] ++ ++ ! CHECK: st %o2, [%i0+%l6] ! encoding: [0xd4,0x26,0x00,0x16] ++ st %o2, [%i0 + %l6] ++ ! CHECK: st %o2, [%i0+32] ! encoding: [0xd4,0x26,0x20,0x20] ++ st %o2, [%i0 + 32] ++ ! CHECK: st %o2, [%g1] ! encoding: [0xd4,0x20,0x60,0x00] ++ st %o2, [%g1] +Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +=================================================================== +--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp ++++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +@@ -28,6 +28,7 @@ namespace llvm { + } + + namespace { ++class SparcOperand; + class SparcAsmParser : public MCTargetAsmParser { + + MCSubtargetInfo &STI; +@@ -55,18 +56,15 @@ class SparcAsmParser : public MCTargetAsmParser { + + // Custom parse functions for Sparc specific operands. + OperandMatchResultTy +- parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); +- OperandMatchResultTy +- parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); ++ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); + + OperandMatchResultTy +- parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, +- int ImmOffsetOrReg); +- +- OperandMatchResultTy + parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, + StringRef Name); + ++ OperandMatchResultTy ++ parseSparcAsmOperand(SparcOperand *&Operand); ++ + // returns true if Tok is matched to a register and returns register in RegNo. + bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP, + bool isQFP); +@@ -298,7 +296,35 @@ class SparcOperand : public MCParsedAsmOperand { + return Op; + } + ++ static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) { ++ unsigned offsetReg = Op->getReg(); ++ Op->Kind = k_MemoryReg; ++ Op->Mem.Base = Base; ++ Op->Mem.OffsetReg = offsetReg; ++ Op->Mem.Off = 0; ++ return Op; ++ } + ++ static SparcOperand *CreateMEMri(unsigned Base, ++ const MCExpr *Off, ++ SMLoc S, SMLoc E) { ++ SparcOperand *Op = new SparcOperand(k_MemoryImm); ++ Op->Mem.Base = Base; ++ Op->Mem.OffsetReg = 0; ++ Op->Mem.Off = Off; ++ Op->StartLoc = S; ++ Op->EndLoc = E; ++ return Op; ++ } ++ ++ static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) { ++ const MCExpr *Imm = Op->getImm(); ++ Op->Kind = k_MemoryImm; ++ Op->Mem.Base = Base; ++ Op->Mem.OffsetReg = 0; ++ Op->Mem.Off = Imm; ++ return Op; ++ } + }; + + } // end namespace +@@ -412,23 +438,42 @@ ParseDirective(AsmToken DirectiveID) + } + + SparcAsmParser::OperandMatchResultTy SparcAsmParser:: +-parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, +- int ImmOffsetOrReg) ++parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) + { +- // FIXME: Implement memory operand parsing here. +- return MatchOperand_NoMatch; +-} + +-SparcAsmParser::OperandMatchResultTy SparcAsmParser:: +-parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) +-{ +- return parseMEMOperand(Operands, 2); +-} ++ SMLoc S, E; ++ unsigned BaseReg = 0; + +-SparcAsmParser::OperandMatchResultTy SparcAsmParser:: +-parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) +-{ +- return parseMEMOperand(Operands, 1); ++ if (ParseRegister(BaseReg, S, E)) { ++ return MatchOperand_NoMatch; ++ } ++ ++ switch (getLexer().getKind()) { ++ default: return MatchOperand_NoMatch; ++ ++ case AsmToken::RBrac: ++ case AsmToken::EndOfStatement: ++ Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E)); ++ return MatchOperand_Success; ++ ++ case AsmToken:: Plus: ++ Parser.Lex(); // Eat the '+' ++ break; ++ case AsmToken::Minus: ++ break; ++ } ++ ++ SparcOperand *Offset = 0; ++ OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset); ++ if (ResTy != MatchOperand_Success || !Offset) ++ return MatchOperand_NoMatch; ++ ++ Offset = (Offset->isImm() ++ ? SparcOperand::MorphToMEMri(BaseReg, Offset) ++ : SparcOperand::MorphToMEMrr(BaseReg, Offset)); ++ ++ Operands.push_back(Offset); ++ return MatchOperand_Success; + } + + SparcAsmParser::OperandMatchResultTy SparcAsmParser:: +@@ -435,20 +480,57 @@ SparcAsmParser::OperandMatchResultTy SparcAsmParse + parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, + StringRef Mnemonic) + { ++ + OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); +- if (ResTy == MatchOperand_Success) +- return ResTy; ++ + // If there wasn't a custom match, try the generic matcher below. Otherwise, + // there was a match, but an error occurred, in which case, just return that + // the operand parsing failed. +- if (ResTy == MatchOperand_ParseFail) ++ if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) + return ResTy; + ++ if (getLexer().is(AsmToken::LBrac)) { ++ // Memory operand ++ Operands.push_back(SparcOperand::CreateToken("[", ++ Parser.getTok().getLoc())); ++ Parser.Lex(); // Eat the [ ++ ++ ResTy = parseMEMOperand(Operands); ++ if (ResTy != MatchOperand_Success) ++ return ResTy; ++ ++ if (!getLexer().is(AsmToken::RBrac)) ++ return MatchOperand_ParseFail; ++ ++ Operands.push_back(SparcOperand::CreateToken("]", ++ Parser.getTok().getLoc())); ++ Parser.Lex(); // Eat the ] ++ return MatchOperand_Success; ++ } ++ ++ SparcOperand *Op = 0; ++ ResTy = parseSparcAsmOperand(Op); ++ if (ResTy != MatchOperand_Success || !Op) ++ return MatchOperand_ParseFail; ++ ++ // Push the parsed operand into the list of operands ++ Operands.push_back(Op); ++ ++ return MatchOperand_Success; ++} ++ ++SparcAsmParser::OperandMatchResultTy ++SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op) ++{ ++ + SMLoc S = Parser.getTok().getLoc(); + SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + const MCExpr *EVal; +- SparcOperand *Op; ++ ++ Op = 0; + switch (getLexer().getKind()) { ++ default: break; ++ + case AsmToken::Percent: + Parser.Lex(); // Eat the '%'. + unsigned RegNo; +@@ -458,40 +540,30 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> + break; + } + // FIXME: Handle modifiers like %hi, %lo etc., +- return MatchOperand_ParseFail; ++ break; + + case AsmToken::Minus: + case AsmToken::Integer: +- if (getParser().parseExpression(EVal)) +- return MatchOperand_ParseFail; +- +- Op = SparcOperand::CreateImm(EVal, S, E); ++ if (!getParser().parseExpression(EVal)) ++ Op = SparcOperand::CreateImm(EVal, S, E); + break; + + case AsmToken::Identifier: { + StringRef Identifier; +- if (getParser().parseIdentifier(Identifier)) +- return MatchOperand_ParseFail; +- SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); +- MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); ++ if (!getParser().parseIdentifier(Identifier)) { ++ SMLoc E = SMLoc::getFromPointer(Parser.getTok(). ++ getLoc().getPointer() - 1); ++ MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); + +- // Otherwise create a symbol reference. +- const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, +- getContext()); ++ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, ++ getContext()); + +- Op = SparcOperand::CreateImm(Res, S, E); ++ Op = SparcOperand::CreateImm(Res, S, E); ++ } + break; + } +- +- case AsmToken::LBrac: // handle [ +- return parseMEMOperand(Operands, 0); +- +- default: +- return MatchOperand_ParseFail; + } +- // Push the parsed operand into the list of operands +- Operands.push_back(Op); +- return MatchOperand_Success; ++ return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; + } + + bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, +Index: lib/Target/Sparc/SparcInstrInfo.td +=================================================================== +--- lib/Target/Sparc/SparcInstrInfo.td ++++ lib/Target/Sparc/SparcInstrInfo.td +@@ -78,12 +78,12 @@ def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri + // Address operands + def SparcMEMrrAsmOperand : AsmOperandClass { + let Name = "MEMrr"; +- let ParserMethod = "parseMEMrrOperand"; ++ let ParserMethod = "parseMEMOperand"; + } + + def SparcMEMriAsmOperand : AsmOperandClass { + let Name = "MEMri"; +- let ParserMethod = "parseMEMriOperand"; ++ let ParserMethod = "parseMEMOperand"; + } + + def MEMrr : Operand<iPTR> { |