freebsd-dev/contrib/llvm/patches/patch-r262261-llvm-r198658-sparc.diff
Dimitry Andric a1f8ad145e Add separate patch files for all the customizations we have currently
applied to our copy of llvm/clang.  These can be applied in alphabetical
order to a pristine llvm/clang 3.4 release source tree, to result in the
same version used in FreeBSD.

This is intended to clearly document all the changes until now, which
mostly consist of cherry pickings from the respective upstream trunks,
plus a number of hand-written FreeBSD-specific ones.  Hopefully those
can eventually be cleaned up and sent upstream too.

MFC after:	1 week
X-MFC-With:	r263313
2014-03-18 22:07:45 +00:00

360 lines
12 KiB
Diff

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> {