1263320SdimPull in r198658 from upstream llvm trunk: 2263320Sdim 3263320Sdim [Sparc] Add support for parsing memory operands in sparc AsmParser. 4263320Sdim 5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261 6263320Sdim 7263320SdimIndex: test/MC/Sparc/sparc-ctrl-instructions.s 8263320Sdim=================================================================== 9263320Sdim--- test/MC/Sparc/sparc-ctrl-instructions.s 10263320Sdim+++ test/MC/Sparc/sparc-ctrl-instructions.s 11263320Sdim@@ -0,0 +1,23 @@ 12263320Sdim+! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s 13263320Sdim+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s 14263320Sdim+ 15263320Sdim+ ! CHECK: call foo 16263320Sdim+ call foo 17263320Sdim+ 18263320Sdim+ ! CHECK: call %g1+%i2 19263320Sdim+ call %g1 + %i2 20263320Sdim+ 21263320Sdim+ ! CHECK: call %o1+8 22263320Sdim+ call %o1 + 8 23263320Sdim+ 24263320Sdim+ ! CHECK: call %g1 25263320Sdim+ call %g1 26263320Sdim+ 27263320Sdim+ ! CHECK: jmp %g1+%i2 28263320Sdim+ jmp %g1 + %i2 29263320Sdim+ 30263320Sdim+ ! CHECK: jmp %o1+8 31263320Sdim+ jmp %o1 + 8 32263320Sdim+ 33263320Sdim+ ! CHECK: jmp %g1 34263320Sdim+ jmp %g1 35263320SdimIndex: test/MC/Sparc/sparc-mem-instructions.s 36263320Sdim=================================================================== 37263320Sdim--- test/MC/Sparc/sparc-mem-instructions.s 38263320Sdim+++ test/MC/Sparc/sparc-mem-instructions.s 39263320Sdim@@ -0,0 +1,58 @@ 40263320Sdim+! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s 41263320Sdim+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s 42263320Sdim+ 43263320Sdim+ ! CHECK: ldsb [%i0+%l6], %o2 ! encoding: [0xd4,0x4e,0x00,0x16] 44263320Sdim+ ldsb [%i0 + %l6], %o2 45263320Sdim+ ! CHECK: ldsb [%i0+32], %o2 ! encoding: [0xd4,0x4e,0x20,0x20] 46263320Sdim+ ldsb [%i0 + 32], %o2 47263320Sdim+ ! CHECK: ldsb [%g1], %o4 ! encoding: [0xd8,0x48,0x60,0x00] 48263320Sdim+ ldsb [%g1], %o4 49263320Sdim+ 50263320Sdim+ ! CHECK: ldsh [%i0+%l6], %o2 ! encoding: [0xd4,0x56,0x00,0x16] 51263320Sdim+ ldsh [%i0 + %l6], %o2 52263320Sdim+ ! CHECK: ldsh [%i0+32], %o2 ! encoding: [0xd4,0x56,0x20,0x20] 53263320Sdim+ ldsh [%i0 + 32], %o2 54263320Sdim+ ! CHECK: ldsh [%g1], %o4 ! encoding: [0xd8,0x50,0x60,0x00] 55263320Sdim+ ldsh [%g1], %o4 56263320Sdim+ 57263320Sdim+ ! CHECK: ldub [%i0+%l6], %o2 ! encoding: [0xd4,0x0e,0x00,0x16] 58263320Sdim+ ldub [%i0 + %l6], %o2 59263320Sdim+ ! CHECK: ldub [%i0+32], %o2 ! encoding: [0xd4,0x0e,0x20,0x20] 60263320Sdim+ ldub [%i0 + 32], %o2 61263320Sdim+ ! CHECK: ldub [%g1], %o2 ! encoding: [0xd4,0x08,0x60,0x00] 62263320Sdim+ ldub [%g1], %o2 63263320Sdim+ 64263320Sdim+ ! CHECK: lduh [%i0+%l6], %o2 ! encoding: [0xd4,0x16,0x00,0x16] 65263320Sdim+ lduh [%i0 + %l6], %o2 66263320Sdim+ ! CHECK: lduh [%i0+32], %o2 ! encoding: [0xd4,0x16,0x20,0x20] 67263320Sdim+ lduh [%i0 + 32], %o2 68263320Sdim+ ! CHECK: lduh [%g1], %o2 ! encoding: [0xd4,0x10,0x60,0x00] 69263320Sdim+ lduh [%g1], %o2 70263320Sdim+ 71263320Sdim+ ! CHECK: ld [%i0+%l6], %o2 ! encoding: [0xd4,0x06,0x00,0x16] 72263320Sdim+ ld [%i0 + %l6], %o2 73263320Sdim+ ! CHECK: ld [%i0+32], %o2 ! encoding: [0xd4,0x06,0x20,0x20] 74263320Sdim+ ld [%i0 + 32], %o2 75263320Sdim+ ! CHECK: ld [%g1], %o2 ! encoding: [0xd4,0x00,0x60,0x00] 76263320Sdim+ ld [%g1], %o2 77263320Sdim+ 78263320Sdim+ ! CHECK: stb %o2, [%i0+%l6] ! encoding: [0xd4,0x2e,0x00,0x16] 79263320Sdim+ stb %o2, [%i0 + %l6] 80263320Sdim+ ! CHECK: stb %o2, [%i0+32] ! encoding: [0xd4,0x2e,0x20,0x20] 81263320Sdim+ stb %o2, [%i0 + 32] 82263320Sdim+ ! CHECK: stb %o2, [%g1] ! encoding: [0xd4,0x28,0x60,0x00] 83263320Sdim+ stb %o2, [%g1] 84263320Sdim+ 85263320Sdim+ ! CHECK: sth %o2, [%i0+%l6] ! encoding: [0xd4,0x36,0x00,0x16] 86263320Sdim+ sth %o2, [%i0 + %l6] 87263320Sdim+ ! CHECK: sth %o2, [%i0+32] ! encoding: [0xd4,0x36,0x20,0x20] 88263320Sdim+ sth %o2, [%i0 + 32] 89263320Sdim+ ! CHECK: sth %o2, [%g1] ! encoding: [0xd4,0x30,0x60,0x00] 90263320Sdim+ sth %o2, [%g1] 91263320Sdim+ 92263320Sdim+ ! CHECK: st %o2, [%i0+%l6] ! encoding: [0xd4,0x26,0x00,0x16] 93263320Sdim+ st %o2, [%i0 + %l6] 94263320Sdim+ ! CHECK: st %o2, [%i0+32] ! encoding: [0xd4,0x26,0x20,0x20] 95263320Sdim+ st %o2, [%i0 + 32] 96263320Sdim+ ! CHECK: st %o2, [%g1] ! encoding: [0xd4,0x20,0x60,0x00] 97263320Sdim+ st %o2, [%g1] 98263320SdimIndex: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp 99263320Sdim=================================================================== 100263320Sdim--- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp 101263320Sdim+++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp 102263320Sdim@@ -28,6 +28,7 @@ namespace llvm { 103263320Sdim } 104263320Sdim 105263320Sdim namespace { 106263320Sdim+class SparcOperand; 107263320Sdim class SparcAsmParser : public MCTargetAsmParser { 108263320Sdim 109263320Sdim MCSubtargetInfo &STI; 110263320Sdim@@ -55,18 +56,15 @@ class SparcAsmParser : public MCTargetAsmParser { 111263320Sdim 112263320Sdim // Custom parse functions for Sparc specific operands. 113263320Sdim OperandMatchResultTy 114263320Sdim- parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 115263320Sdim- OperandMatchResultTy 116263320Sdim- parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 117263320Sdim+ parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 118263320Sdim 119263320Sdim OperandMatchResultTy 120263320Sdim- parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 121263320Sdim- int ImmOffsetOrReg); 122263320Sdim- 123263320Sdim- OperandMatchResultTy 124263320Sdim parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 125263320Sdim StringRef Name); 126263320Sdim 127263320Sdim+ OperandMatchResultTy 128263320Sdim+ parseSparcAsmOperand(SparcOperand *&Operand); 129263320Sdim+ 130263320Sdim // returns true if Tok is matched to a register and returns register in RegNo. 131263320Sdim bool matchRegisterName(const AsmToken &Tok, unsigned &RegNo, bool isDFP, 132263320Sdim bool isQFP); 133263320Sdim@@ -298,7 +296,35 @@ class SparcOperand : public MCParsedAsmOperand { 134263320Sdim return Op; 135263320Sdim } 136263320Sdim 137263320Sdim+ static SparcOperand *MorphToMEMrr(unsigned Base, SparcOperand *Op) { 138263320Sdim+ unsigned offsetReg = Op->getReg(); 139263320Sdim+ Op->Kind = k_MemoryReg; 140263320Sdim+ Op->Mem.Base = Base; 141263320Sdim+ Op->Mem.OffsetReg = offsetReg; 142263320Sdim+ Op->Mem.Off = 0; 143263320Sdim+ return Op; 144263320Sdim+ } 145263320Sdim 146263320Sdim+ static SparcOperand *CreateMEMri(unsigned Base, 147263320Sdim+ const MCExpr *Off, 148263320Sdim+ SMLoc S, SMLoc E) { 149263320Sdim+ SparcOperand *Op = new SparcOperand(k_MemoryImm); 150263320Sdim+ Op->Mem.Base = Base; 151263320Sdim+ Op->Mem.OffsetReg = 0; 152263320Sdim+ Op->Mem.Off = Off; 153263320Sdim+ Op->StartLoc = S; 154263320Sdim+ Op->EndLoc = E; 155263320Sdim+ return Op; 156263320Sdim+ } 157263320Sdim+ 158263320Sdim+ static SparcOperand *MorphToMEMri(unsigned Base, SparcOperand *Op) { 159263320Sdim+ const MCExpr *Imm = Op->getImm(); 160263320Sdim+ Op->Kind = k_MemoryImm; 161263320Sdim+ Op->Mem.Base = Base; 162263320Sdim+ Op->Mem.OffsetReg = 0; 163263320Sdim+ Op->Mem.Off = Imm; 164263320Sdim+ return Op; 165263320Sdim+ } 166263320Sdim }; 167263320Sdim 168263320Sdim } // end namespace 169263320Sdim@@ -412,23 +438,42 @@ ParseDirective(AsmToken DirectiveID) 170263320Sdim } 171263320Sdim 172263320Sdim SparcAsmParser::OperandMatchResultTy SparcAsmParser:: 173263320Sdim-parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 174263320Sdim- int ImmOffsetOrReg) 175263320Sdim+parseMEMOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) 176263320Sdim { 177263320Sdim- // FIXME: Implement memory operand parsing here. 178263320Sdim- return MatchOperand_NoMatch; 179263320Sdim-} 180263320Sdim 181263320Sdim-SparcAsmParser::OperandMatchResultTy SparcAsmParser:: 182263320Sdim-parseMEMrrOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) 183263320Sdim-{ 184263320Sdim- return parseMEMOperand(Operands, 2); 185263320Sdim-} 186263320Sdim+ SMLoc S, E; 187263320Sdim+ unsigned BaseReg = 0; 188263320Sdim 189263320Sdim-SparcAsmParser::OperandMatchResultTy SparcAsmParser:: 190263320Sdim-parseMEMriOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) 191263320Sdim-{ 192263320Sdim- return parseMEMOperand(Operands, 1); 193263320Sdim+ if (ParseRegister(BaseReg, S, E)) { 194263320Sdim+ return MatchOperand_NoMatch; 195263320Sdim+ } 196263320Sdim+ 197263320Sdim+ switch (getLexer().getKind()) { 198263320Sdim+ default: return MatchOperand_NoMatch; 199263320Sdim+ 200263320Sdim+ case AsmToken::RBrac: 201263320Sdim+ case AsmToken::EndOfStatement: 202263320Sdim+ Operands.push_back(SparcOperand::CreateMEMri(BaseReg, 0, S, E)); 203263320Sdim+ return MatchOperand_Success; 204263320Sdim+ 205263320Sdim+ case AsmToken:: Plus: 206263320Sdim+ Parser.Lex(); // Eat the '+' 207263320Sdim+ break; 208263320Sdim+ case AsmToken::Minus: 209263320Sdim+ break; 210263320Sdim+ } 211263320Sdim+ 212263320Sdim+ SparcOperand *Offset = 0; 213263320Sdim+ OperandMatchResultTy ResTy = parseSparcAsmOperand(Offset); 214263320Sdim+ if (ResTy != MatchOperand_Success || !Offset) 215263320Sdim+ return MatchOperand_NoMatch; 216263320Sdim+ 217263320Sdim+ Offset = (Offset->isImm() 218263320Sdim+ ? SparcOperand::MorphToMEMri(BaseReg, Offset) 219263320Sdim+ : SparcOperand::MorphToMEMrr(BaseReg, Offset)); 220263320Sdim+ 221263320Sdim+ Operands.push_back(Offset); 222263320Sdim+ return MatchOperand_Success; 223263320Sdim } 224263320Sdim 225263320Sdim SparcAsmParser::OperandMatchResultTy SparcAsmParser:: 226263320Sdim@@ -435,20 +480,57 @@ SparcAsmParser::OperandMatchResultTy SparcAsmParse 227263320Sdim parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 228263320Sdim StringRef Mnemonic) 229263320Sdim { 230263320Sdim+ 231263320Sdim OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 232263320Sdim- if (ResTy == MatchOperand_Success) 233263320Sdim- return ResTy; 234263320Sdim+ 235263320Sdim // If there wasn't a custom match, try the generic matcher below. Otherwise, 236263320Sdim // there was a match, but an error occurred, in which case, just return that 237263320Sdim // the operand parsing failed. 238263320Sdim- if (ResTy == MatchOperand_ParseFail) 239263320Sdim+ if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail) 240263320Sdim return ResTy; 241263320Sdim 242263320Sdim+ if (getLexer().is(AsmToken::LBrac)) { 243263320Sdim+ // Memory operand 244263320Sdim+ Operands.push_back(SparcOperand::CreateToken("[", 245263320Sdim+ Parser.getTok().getLoc())); 246263320Sdim+ Parser.Lex(); // Eat the [ 247263320Sdim+ 248263320Sdim+ ResTy = parseMEMOperand(Operands); 249263320Sdim+ if (ResTy != MatchOperand_Success) 250263320Sdim+ return ResTy; 251263320Sdim+ 252263320Sdim+ if (!getLexer().is(AsmToken::RBrac)) 253263320Sdim+ return MatchOperand_ParseFail; 254263320Sdim+ 255263320Sdim+ Operands.push_back(SparcOperand::CreateToken("]", 256263320Sdim+ Parser.getTok().getLoc())); 257263320Sdim+ Parser.Lex(); // Eat the ] 258263320Sdim+ return MatchOperand_Success; 259263320Sdim+ } 260263320Sdim+ 261263320Sdim+ SparcOperand *Op = 0; 262263320Sdim+ ResTy = parseSparcAsmOperand(Op); 263263320Sdim+ if (ResTy != MatchOperand_Success || !Op) 264263320Sdim+ return MatchOperand_ParseFail; 265263320Sdim+ 266263320Sdim+ // Push the parsed operand into the list of operands 267263320Sdim+ Operands.push_back(Op); 268263320Sdim+ 269263320Sdim+ return MatchOperand_Success; 270263320Sdim+} 271263320Sdim+ 272263320Sdim+SparcAsmParser::OperandMatchResultTy 273263320Sdim+SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op) 274263320Sdim+{ 275263320Sdim+ 276263320Sdim SMLoc S = Parser.getTok().getLoc(); 277263320Sdim SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 278263320Sdim const MCExpr *EVal; 279263320Sdim- SparcOperand *Op; 280263320Sdim+ 281263320Sdim+ Op = 0; 282263320Sdim switch (getLexer().getKind()) { 283263320Sdim+ default: break; 284263320Sdim+ 285263320Sdim case AsmToken::Percent: 286263320Sdim Parser.Lex(); // Eat the '%'. 287263320Sdim unsigned RegNo; 288263320Sdim@@ -458,40 +540,30 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> 289263320Sdim break; 290263320Sdim } 291263320Sdim // FIXME: Handle modifiers like %hi, %lo etc., 292263320Sdim- return MatchOperand_ParseFail; 293263320Sdim+ break; 294263320Sdim 295263320Sdim case AsmToken::Minus: 296263320Sdim case AsmToken::Integer: 297263320Sdim- if (getParser().parseExpression(EVal)) 298263320Sdim- return MatchOperand_ParseFail; 299263320Sdim- 300263320Sdim- Op = SparcOperand::CreateImm(EVal, S, E); 301263320Sdim+ if (!getParser().parseExpression(EVal)) 302263320Sdim+ Op = SparcOperand::CreateImm(EVal, S, E); 303263320Sdim break; 304263320Sdim 305263320Sdim case AsmToken::Identifier: { 306263320Sdim StringRef Identifier; 307263320Sdim- if (getParser().parseIdentifier(Identifier)) 308263320Sdim- return MatchOperand_ParseFail; 309263320Sdim- SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 310263320Sdim- MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); 311263320Sdim+ if (!getParser().parseIdentifier(Identifier)) { 312263320Sdim+ SMLoc E = SMLoc::getFromPointer(Parser.getTok(). 313263320Sdim+ getLoc().getPointer() - 1); 314263320Sdim+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Identifier); 315263320Sdim 316263320Sdim- // Otherwise create a symbol reference. 317263320Sdim- const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 318263320Sdim- getContext()); 319263320Sdim+ const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 320263320Sdim+ getContext()); 321263320Sdim 322263320Sdim- Op = SparcOperand::CreateImm(Res, S, E); 323263320Sdim+ Op = SparcOperand::CreateImm(Res, S, E); 324263320Sdim+ } 325263320Sdim break; 326263320Sdim } 327263320Sdim- 328263320Sdim- case AsmToken::LBrac: // handle [ 329263320Sdim- return parseMEMOperand(Operands, 0); 330263320Sdim- 331263320Sdim- default: 332263320Sdim- return MatchOperand_ParseFail; 333263320Sdim } 334263320Sdim- // Push the parsed operand into the list of operands 335263320Sdim- Operands.push_back(Op); 336263320Sdim- return MatchOperand_Success; 337263320Sdim+ return (Op) ? MatchOperand_Success : MatchOperand_ParseFail; 338263320Sdim } 339263320Sdim 340263320Sdim bool SparcAsmParser::matchRegisterName(const AsmToken &Tok, 341263320SdimIndex: lib/Target/Sparc/SparcInstrInfo.td 342263320Sdim=================================================================== 343263320Sdim--- lib/Target/Sparc/SparcInstrInfo.td 344263320Sdim+++ lib/Target/Sparc/SparcInstrInfo.td 345263320Sdim@@ -78,12 +78,12 @@ def ADDRri : ComplexPattern<iPTR, 2, "SelectADDRri 346263320Sdim // Address operands 347263320Sdim def SparcMEMrrAsmOperand : AsmOperandClass { 348263320Sdim let Name = "MEMrr"; 349263320Sdim- let ParserMethod = "parseMEMrrOperand"; 350263320Sdim+ let ParserMethod = "parseMEMOperand"; 351263320Sdim } 352263320Sdim 353263320Sdim def SparcMEMriAsmOperand : AsmOperandClass { 354263320Sdim let Name = "MEMri"; 355263320Sdim- let ParserMethod = "parseMEMriOperand"; 356263320Sdim+ let ParserMethod = "parseMEMOperand"; 357263320Sdim } 358263320Sdim 359263320Sdim def MEMrr : Operand<iPTR> { 360