summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff359
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> {
OpenPOWER on IntegriCloud