2012-02-17 16:55:11 +08:00
|
|
|
//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
|
2012-01-11 11:56:41 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-02-05 02:41:57 +08:00
|
|
|
#include "MCTargetDesc/MipsMCExpr.h"
|
2012-01-11 11:56:41 +08:00
|
|
|
#include "MCTargetDesc/MipsMCTargetDesc.h"
|
2012-09-06 07:34:03 +08:00
|
|
|
#include "MipsRegisterInfo.h"
|
2013-10-08 21:08:17 +08:00
|
|
|
#include "MipsTargetStreamer.h"
|
2014-01-07 19:48:04 +08:00
|
|
|
#include "llvm/ADT/APInt.h"
|
2012-09-06 07:34:03 +08:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
|
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
#include "llvm/MC/MCExpr.h"
|
|
|
|
#include "llvm/MC/MCInst.h"
|
2014-03-24 22:05:39 +08:00
|
|
|
#include "llvm/MC/MCInstBuilder.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
|
|
|
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
2012-09-06 07:34:03 +08:00
|
|
|
#include "llvm/MC/MCStreamer.h"
|
|
|
|
#include "llvm/MC/MCSubtargetInfo.h"
|
|
|
|
#include "llvm/MC/MCSymbol.h"
|
2012-08-18 04:16:42 +08:00
|
|
|
#include "llvm/MC/MCTargetAsmParser.h"
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2013-12-13 19:11:02 +08:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2014-01-07 19:48:04 +08:00
|
|
|
#include "llvm/Support/TargetRegistry.h"
|
2012-01-11 11:56:41 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2013-09-12 18:28:05 +08:00
|
|
|
namespace llvm {
|
|
|
|
class MCInstrInfo;
|
|
|
|
}
|
|
|
|
|
2012-01-11 11:56:41 +08:00
|
|
|
namespace {
|
2012-10-04 10:29:46 +08:00
|
|
|
class MipsAssemblerOptions {
|
|
|
|
public:
|
2013-11-06 19:27:05 +08:00
|
|
|
MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
|
2012-10-04 10:29:46 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
unsigned getATRegNum() { return aTReg; }
|
2012-10-04 10:29:46 +08:00
|
|
|
bool setATReg(unsigned Reg);
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
bool isReorder() { return reorder; }
|
|
|
|
void setReorder() { reorder = true; }
|
|
|
|
void setNoreorder() { reorder = false; }
|
2012-10-04 10:29:46 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
bool isMacro() { return macro; }
|
|
|
|
void setMacro() { macro = true; }
|
|
|
|
void setNomacro() { macro = false; }
|
2012-10-04 10:29:46 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
unsigned aTReg;
|
|
|
|
bool reorder;
|
|
|
|
bool macro;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
2012-01-11 11:56:41 +08:00
|
|
|
class MipsAsmParser : public MCTargetAsmParser {
|
2013-10-08 21:08:17 +08:00
|
|
|
MipsTargetStreamer &getTargetStreamer() {
|
2014-01-14 09:21:46 +08:00
|
|
|
MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
|
2013-10-08 21:08:17 +08:00
|
|
|
return static_cast<MipsTargetStreamer &>(TS);
|
|
|
|
}
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
MCSubtargetInfo &STI;
|
|
|
|
MCAsmParser &Parser;
|
2012-10-06 07:55:28 +08:00
|
|
|
MipsAssemblerOptions Options;
|
2012-10-04 10:29:46 +08:00
|
|
|
|
2012-08-18 04:16:42 +08:00
|
|
|
#define GET_ASSEMBLER_HEADER
|
|
|
|
#include "MipsGenAsmMatcher.inc"
|
|
|
|
|
2012-10-13 08:26:04 +08:00
|
|
|
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
2012-10-13 08:26:04 +08:00
|
|
|
MCStreamer &Out, unsigned &ErrorInfo,
|
|
|
|
bool MatchingInlineAsm);
|
2012-01-11 11:56:41 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Parse a register as used in CFI directives
|
2012-01-11 11:56:41 +08:00
|
|
|
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool ParseParenSuffix(StringRef Name,
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
|
|
|
|
|
|
|
bool ParseBracketSuffix(StringRef Name,
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
|
|
|
|
2012-10-26 04:41:34 +08:00
|
|
|
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
|
|
|
SMLoc NameLoc,
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2012-01-11 11:56:41 +08:00
|
|
|
|
|
|
|
bool ParseDirective(AsmToken DirectiveID);
|
|
|
|
|
2013-07-16 18:07:14 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2013-11-06 19:27:05 +08:00
|
|
|
parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-01-12 09:03:14 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
|
|
|
|
SMLoc S);
|
2013-09-26 07:50:44 +08:00
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-04-01 20:35:23 +08:00
|
|
|
MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
SMLoc S);
|
2013-09-26 07:50:44 +08:00
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-09-26 07:50:44 +08:00
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-09-26 07:50:44 +08:00
|
|
|
|
2013-10-21 20:26:50 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-10-21 20:26:50 +08:00
|
|
|
|
2013-10-01 17:48:56 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2013-11-06 19:27:05 +08:00
|
|
|
parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-10-01 17:48:56 +08:00
|
|
|
|
2013-11-18 20:32:49 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-11-18 20:32:49 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
2013-03-22 05:44:16 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
|
2012-09-06 07:34:03 +08:00
|
|
|
StringRef Mnemonic);
|
|
|
|
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
bool needsExpansion(MCInst &Inst);
|
|
|
|
|
|
|
|
void expandInstruction(MCInst &Inst, SMLoc IDLoc,
|
2012-10-06 08:53:28 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
|
2012-10-06 08:53:28 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
|
|
|
void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2013-03-22 08:05:30 +08:00
|
|
|
void expandMemInst(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions, bool isLoad,
|
|
|
|
bool isImmOpnd);
|
2012-10-04 10:29:46 +08:00
|
|
|
bool reportParseError(StringRef ErrorMsg);
|
|
|
|
|
2013-04-17 08:18:04 +08:00
|
|
|
bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
|
2013-01-12 09:03:14 +08:00
|
|
|
bool parseRelocOperand(const MCExpr *&Res);
|
2012-10-04 10:29:46 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
|
2013-04-17 08:18:04 +08:00
|
|
|
|
|
|
|
bool isEvaluated(const MCExpr *Expr);
|
2014-03-26 22:26:27 +08:00
|
|
|
bool parseSetFeature(uint64_t Feature);
|
2014-03-27 21:52:53 +08:00
|
|
|
bool parseDirectiveCPSetup();
|
2012-10-04 10:29:46 +08:00
|
|
|
bool parseDirectiveSet();
|
2014-01-07 07:27:31 +08:00
|
|
|
bool parseDirectiveOption();
|
2012-10-04 10:29:46 +08:00
|
|
|
|
|
|
|
bool parseSetAtDirective();
|
|
|
|
bool parseSetNoAtDirective();
|
|
|
|
bool parseSetMacroDirective();
|
|
|
|
bool parseSetNoMacroDirective();
|
|
|
|
bool parseSetReorderDirective();
|
|
|
|
bool parseSetNoReorderDirective();
|
2014-01-23 07:08:42 +08:00
|
|
|
bool parseSetNoMips16Directive();
|
2012-10-04 10:29:46 +08:00
|
|
|
|
2013-03-22 05:44:16 +08:00
|
|
|
bool parseSetAssignment();
|
|
|
|
|
2014-03-26 23:24:36 +08:00
|
|
|
bool parseDataDirective(unsigned Size, SMLoc L);
|
2013-11-06 19:27:05 +08:00
|
|
|
bool parseDirectiveGpWord();
|
2014-03-31 22:15:07 +08:00
|
|
|
bool parseDirectiveGpDWord();
|
2013-01-25 09:31:34 +08:00
|
|
|
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
|
2012-09-07 08:23:42 +08:00
|
|
|
|
2014-03-28 00:42:17 +08:00
|
|
|
bool isGP64() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
|
2012-09-07 08:23:42 +08:00
|
|
|
bool isFP64() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
|
|
|
|
}
|
|
|
|
|
2014-03-26 19:39:07 +08:00
|
|
|
bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
|
2013-11-06 19:27:05 +08:00
|
|
|
bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
|
2013-08-28 08:55:15 +08:00
|
|
|
|
2013-12-13 19:11:02 +08:00
|
|
|
bool isMicroMips() const {
|
|
|
|
return STI.getFeatureBits() & Mips::FeatureMicroMips;
|
|
|
|
}
|
|
|
|
|
2014-03-27 21:52:53 +08:00
|
|
|
bool parseRegister(unsigned &RegNum);
|
|
|
|
|
|
|
|
bool eatComma(StringRef ErrorStr);
|
|
|
|
|
2013-02-21 07:11:17 +08:00
|
|
|
int matchCPURegisterName(StringRef Symbol);
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
int matchFPURegisterName(StringRef Name);
|
2013-06-20 19:21:49 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
int matchFCCRegisterName(StringRef Name);
|
2012-09-07 08:23:42 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
int matchACRegisterName(StringRef Name);
|
2012-09-07 08:23:42 +08:00
|
|
|
|
2013-09-26 07:50:44 +08:00
|
|
|
int matchMSA128RegisterName(StringRef Name);
|
|
|
|
|
2013-10-21 20:26:50 +08:00
|
|
|
int matchMSA128CtrlRegisterName(StringRef Name);
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
unsigned getReg(int RC, int RegNo);
|
2012-09-04 02:47:45 +08:00
|
|
|
|
2014-03-27 21:52:53 +08:00
|
|
|
unsigned getGPR(int RegNo);
|
|
|
|
|
2013-02-21 07:11:17 +08:00
|
|
|
int getATReg();
|
2013-03-22 08:05:30 +08:00
|
|
|
|
|
|
|
bool processInstruction(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2013-10-14 19:49:30 +08:00
|
|
|
|
|
|
|
// Helper function that checks if the value of a vector index is within the
|
|
|
|
// boundaries of accepted values for each RegisterKind
|
|
|
|
// Example: INSERT.B $w0[n], $1 => 16 > n >= 0
|
|
|
|
bool validateMSAIndex(int Val, int RegKind);
|
|
|
|
|
2014-03-04 17:54:09 +08:00
|
|
|
void setFeatureBits(unsigned Feature, StringRef FeatureString) {
|
|
|
|
if (!(STI.getFeatureBits() & Feature)) {
|
|
|
|
setAvailableFeatures(ComputeAvailableFeatures(
|
|
|
|
STI.ToggleFeature(FeatureString)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
|
|
|
|
if (STI.getFeatureBits() & Feature) {
|
|
|
|
setAvailableFeatures(ComputeAvailableFeatures(
|
|
|
|
STI.ToggleFeature(FeatureString)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-11 11:56:41 +08:00
|
|
|
public:
|
2013-09-12 18:28:05 +08:00
|
|
|
MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
|
|
|
|
const MCInstrInfo &MII)
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
: MCTargetAsmParser(), STI(sti), Parser(parser) {
|
2012-09-06 07:34:03 +08:00
|
|
|
// Initialize the set of available features.
|
|
|
|
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
|
2014-02-20 22:58:19 +08:00
|
|
|
|
|
|
|
// Assert exactly one ABI was chosen.
|
|
|
|
assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
|
|
|
|
((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
|
|
|
|
((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
|
|
|
|
((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
|
2012-01-11 11:56:41 +08:00
|
|
|
}
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
MCAsmParser &getParser() const { return Parser; }
|
|
|
|
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
|
|
|
|
/// Warn if RegNo is the current assembler temporary.
|
|
|
|
void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
|
2012-01-11 11:56:41 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-08-18 04:16:42 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// MipsOperand - Instances of this class represent a parsed Mips machine
|
|
|
|
/// instruction.
|
|
|
|
class MipsOperand : public MCParsedAsmOperand {
|
2013-01-12 09:03:14 +08:00
|
|
|
public:
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Broad categories of register classes
|
|
|
|
/// The exact class is finalized by the render method.
|
|
|
|
enum RegKind {
|
|
|
|
RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
|
|
|
|
RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
|
|
|
|
/// isFP64())
|
|
|
|
RegKind_FCC = 4, /// FCC
|
|
|
|
RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
|
|
|
|
RegKind_MSACtrl = 16, /// MSA control registers
|
|
|
|
RegKind_COP2 = 32, /// COP2
|
|
|
|
RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
|
|
|
|
/// context).
|
|
|
|
RegKind_CCR = 128, /// CCR
|
|
|
|
RegKind_HWRegs = 256, /// HWRegs
|
|
|
|
|
|
|
|
/// Potentially any (e.g. $1)
|
|
|
|
RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
|
|
|
|
RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
|
|
|
|
RegKind_CCR | RegKind_HWRegs
|
2013-01-12 09:03:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
2012-08-18 04:16:42 +08:00
|
|
|
enum KindTy {
|
2014-04-01 20:35:23 +08:00
|
|
|
k_Immediate, /// An immediate (possibly involving symbol references)
|
|
|
|
k_Memory, /// Base + Offset Memory Address
|
|
|
|
k_PhysRegister, /// A physical register from the Mips namespace
|
|
|
|
k_RegisterIndex, /// A register index in one or more RegKind.
|
|
|
|
k_Token /// A simple token
|
2012-08-18 04:16:42 +08:00
|
|
|
} Kind;
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsOperand(KindTy K, MipsAsmParser &Parser)
|
|
|
|
: MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
|
|
|
|
|
|
|
|
/// For diagnostics, and checking the assembler temporary
|
|
|
|
MipsAsmParser &AsmParser;
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2013-03-15 08:42:55 +08:00
|
|
|
struct Token {
|
|
|
|
const char *Data;
|
|
|
|
unsigned Length;
|
|
|
|
};
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
struct PhysRegOp {
|
|
|
|
unsigned Num; /// Register Number
|
|
|
|
};
|
|
|
|
|
|
|
|
struct RegIdxOp {
|
|
|
|
unsigned Index; /// Index into the register class
|
|
|
|
RegKind Kind; /// Bitfield of the kinds it could possibly be
|
|
|
|
const MCRegisterInfo *RegInfo;
|
2013-03-15 08:42:55 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ImmOp {
|
|
|
|
const MCExpr *Val;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MemOp {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsOperand *Base;
|
2013-03-15 08:42:55 +08:00
|
|
|
const MCExpr *Off;
|
|
|
|
};
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
union {
|
2013-03-15 08:42:55 +08:00
|
|
|
struct Token Tok;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
struct PhysRegOp PhysReg;
|
|
|
|
struct RegIdxOp RegIdx;
|
2013-03-15 08:42:55 +08:00
|
|
|
struct ImmOp Imm;
|
|
|
|
struct MemOp Mem;
|
2012-09-06 07:34:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
SMLoc StartLoc, EndLoc;
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Internal constructor for register kinds
|
|
|
|
static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
|
|
|
MipsAsmParser &Parser) {
|
|
|
|
MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
|
|
|
|
Op->RegIdx.Index = Index;
|
|
|
|
Op->RegIdx.RegInfo = RegInfo;
|
|
|
|
Op->RegIdx.Kind = RegKind;
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = E;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
2012-08-18 04:16:42 +08:00
|
|
|
public:
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Coerce the register to GPR32 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getGPR32Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
|
|
|
|
AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
|
|
|
|
unsigned ClassID = Mips::GPR32RegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Coerce the register to GPR64 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getGPR64Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::GPR64RegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
/// Coerce the register to AFGR64 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getAFGR64Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
|
|
|
|
if (RegIdx.Index % 2 != 0)
|
|
|
|
AsmParser.Warning(StartLoc, "Float register should be even.");
|
|
|
|
return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
|
|
|
|
.getRegister(RegIdx.Index / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to FGR64 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getFGR64Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
|
|
|
|
return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
|
|
|
|
.getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to FGR32 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getFGR32Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
|
|
|
|
return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
|
|
|
|
.getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to FGRH32 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getFGRH32Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
|
|
|
|
return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
|
|
|
|
.getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to FCC and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getFCCReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
|
|
|
|
return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
|
|
|
|
.getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to MSA128 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getMSA128Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
|
|
|
|
// It doesn't matter which of the MSA128[BHWD] classes we use. They are all
|
|
|
|
// identical
|
|
|
|
unsigned ClassID = Mips::MSA128BRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to MSACtrl and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getMSACtrlReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::MSACtrlRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to COP2 and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getCOP2Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::COP2RegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to ACC64DSP and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getACC64DSPReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::ACC64DSPRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to HI32DSP and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getHI32DSPReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::HI32DSPRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to LO32DSP and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getLO32DSPReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::LO32DSPRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to CCR and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getCCRReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::CCRRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Coerce the register to HWRegs and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getHWRegsReg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::HWRegsRegClassID;
|
|
|
|
return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
|
2013-08-28 08:55:15 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
public:
|
2013-11-06 19:27:05 +08:00
|
|
|
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
|
2012-09-06 07:34:03 +08:00
|
|
|
// Add as immediate when possible. Null MCExpr = 0.
|
|
|
|
if (Expr == 0)
|
|
|
|
Inst.addOperand(MCOperand::CreateImm(0));
|
|
|
|
else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
|
|
|
|
Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
|
|
|
|
else
|
|
|
|
Inst.addOperand(MCOperand::CreateExpr(Expr));
|
2012-08-18 04:16:42 +08:00
|
|
|
}
|
2012-09-06 07:34:03 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
void addRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
llvm_unreachable("Use a custom parser instead");
|
|
|
|
}
|
|
|
|
|
2014-04-01 20:35:23 +08:00
|
|
|
/// Render the operand to an MCInst as a GPR32
|
|
|
|
/// Asserts if the wrong number of operands are requested, or the operand
|
|
|
|
/// is not a k_RegisterIndex compatible with RegKind_GPR
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
|
|
|
|
}
|
|
|
|
|
2014-04-01 20:35:23 +08:00
|
|
|
/// Render the operand to an MCInst as a GPR64
|
|
|
|
/// Asserts if the wrong number of operands are requested, or the operand
|
|
|
|
/// is not a k_RegisterIndex compatible with RegKind_GPR
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
|
|
|
|
}
|
|
|
|
|
2012-08-18 04:16:42 +08:00
|
|
|
void addImmOperands(MCInst &Inst, unsigned N) const {
|
2012-09-06 07:34:03 +08:00
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
const MCExpr *Expr = getImm();
|
2013-04-18 08:41:53 +08:00
|
|
|
addExpr(Inst, Expr);
|
2012-08-18 04:16:42 +08:00
|
|
|
}
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2012-08-18 04:16:42 +08:00
|
|
|
void addMemOperands(MCInst &Inst, unsigned N) const {
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
assert(N == 2 && "Invalid number of operands!");
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
|
|
|
const MCExpr *Expr = getMemOff();
|
2013-04-18 08:41:53 +08:00
|
|
|
addExpr(Inst, Expr);
|
2012-08-18 04:16:42 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isReg() const {
|
|
|
|
// As a special case until we sort out the definition of div/divu, pretend
|
|
|
|
// that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
|
|
|
|
if (isGPRAsmReg() && RegIdx.Index == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return Kind == k_PhysRegister;
|
|
|
|
}
|
|
|
|
bool isRegIdx() const { return Kind == k_RegisterIndex; }
|
2012-08-18 04:16:42 +08:00
|
|
|
bool isImm() const { return Kind == k_Immediate; }
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isConstantImm() const {
|
|
|
|
return isImm() && dyn_cast<MCConstantExpr>(getImm());
|
|
|
|
}
|
|
|
|
bool isToken() const {
|
|
|
|
// Note: It's not possible to pretend that other operand kinds are tokens.
|
|
|
|
// The matcher emitter checks tokens first.
|
|
|
|
return Kind == k_Token;
|
|
|
|
}
|
2012-08-18 04:16:42 +08:00
|
|
|
bool isMem() const { return Kind == k_Memory; }
|
2013-10-01 17:48:56 +08:00
|
|
|
bool isInvNum() const { return Kind == k_Immediate; }
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isLSAImm() const {
|
|
|
|
if (!isConstantImm())
|
|
|
|
return false;
|
|
|
|
int64_t Val = getConstantImm();
|
|
|
|
return 1 <= Val && Val <= 4;
|
|
|
|
}
|
2012-08-18 04:16:42 +08:00
|
|
|
|
|
|
|
StringRef getToken() const {
|
|
|
|
assert(Kind == k_Token && "Invalid access!");
|
2012-09-06 07:34:03 +08:00
|
|
|
return StringRef(Tok.Data, Tok.Length);
|
2012-08-18 04:16:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getReg() const {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
// As a special case until we sort out the definition of div/divu, pretend
|
|
|
|
// that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
|
|
|
|
if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
|
|
|
|
RegIdx.Kind & RegKind_GPR)
|
|
|
|
return getGPR32Reg(); // FIXME: GPR64 too
|
2013-01-12 09:03:14 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
assert(Kind == k_PhysRegister && "Invalid access!");
|
|
|
|
return PhysReg.Num;
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
|
2014-04-01 02:51:43 +08:00
|
|
|
const MCExpr *getImm() const {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
assert((Kind == k_Immediate) && "Invalid access!");
|
2014-04-01 02:51:43 +08:00
|
|
|
return Imm.Val;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
int64_t getConstantImm() const {
|
|
|
|
const MCExpr *Val = getImm();
|
|
|
|
return static_cast<const MCConstantExpr *>(Val)->getValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
MipsOperand *getMemBase() const {
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
assert((Kind == k_Memory) && "Invalid access!");
|
|
|
|
return Mem.Base;
|
|
|
|
}
|
|
|
|
|
|
|
|
const MCExpr *getMemOff() const {
|
|
|
|
assert((Kind == k_Memory) && "Invalid access!");
|
|
|
|
return Mem.Off;
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
static MipsOperand *CreateToken(StringRef Str, SMLoc S,
|
|
|
|
MipsAsmParser &Parser) {
|
|
|
|
MipsOperand *Op = new MipsOperand(k_Token, Parser);
|
2012-09-06 07:34:03 +08:00
|
|
|
Op->Tok.Data = Str.data();
|
|
|
|
Op->Tok.Length = Str.size();
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = S;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Create a numeric register (e.g. $1). The exact register remains
|
|
|
|
/// unresolved until an instruction successfully matches
|
|
|
|
static MipsOperand *CreateNumericReg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
|
|
|
|
return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
|
2012-08-18 04:16:42 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Create a register that is definitely a GPR.
|
|
|
|
/// This is typically only used for named registers such as $gp.
|
|
|
|
static MipsOperand *CreateGPRReg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Create a register that is definitely a FGR.
|
|
|
|
/// This is typically only used for named registers such as $f0.
|
|
|
|
static MipsOperand *CreateFGRReg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a register that is definitely an FCC.
|
|
|
|
/// This is typically only used for named registers such as $fcc0.
|
|
|
|
static MipsOperand *CreateFCCReg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a register that is definitely an ACC.
|
|
|
|
/// This is typically only used for named registers such as $ac0.
|
|
|
|
static MipsOperand *CreateACCReg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Create a register that is definitely an MSA128.
|
|
|
|
/// This is typically only used for named registers such as $w0.
|
|
|
|
static MipsOperand *CreateMSA128Reg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Create a register that is definitely an MSACtrl.
|
|
|
|
/// This is typically only used for named registers such as $msaaccess.
|
|
|
|
static MipsOperand *CreateMSACtrlReg(unsigned Index,
|
|
|
|
const MCRegisterInfo *RegInfo, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
|
|
|
|
}
|
|
|
|
|
|
|
|
static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
|
|
|
|
MipsAsmParser &Parser) {
|
|
|
|
MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
|
2013-11-18 20:32:49 +08:00
|
|
|
Op->Imm.Val = Val;
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = E;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
MipsOperand *Op = new MipsOperand(k_Memory, Parser);
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
Op->Mem.Base = Base;
|
|
|
|
Op->Mem.Off = Off;
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = E;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isGPRAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
|
2013-07-30 18:12:14 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isFGRAsmReg() const {
|
|
|
|
// AFGR64 is $0-$15 but we handle this in getAFGR64()
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
|
2013-08-07 06:20:40 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isHWRegsAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
|
2013-08-14 09:02:20 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isCCRAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
|
2013-08-14 09:02:20 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isFCCAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
|
2013-09-26 07:50:44 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isACCAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
|
2013-09-26 07:50:44 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isCOP2AsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
|
2013-09-26 07:50:44 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isMSA128AsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
|
2013-09-26 07:50:44 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool isMSACtrlAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
|
2013-10-21 20:26:50 +08:00
|
|
|
}
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
/// getStartLoc - Get the location of the first token of this operand.
|
2013-11-06 19:27:05 +08:00
|
|
|
SMLoc getStartLoc() const { return StartLoc; }
|
2012-09-06 07:34:03 +08:00
|
|
|
/// getEndLoc - Get the location of the last token of this operand.
|
2013-11-06 19:27:05 +08:00
|
|
|
SMLoc getEndLoc() const { return EndLoc; }
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2012-08-18 04:16:42 +08:00
|
|
|
virtual void print(raw_ostream &OS) const {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
switch (Kind) {
|
|
|
|
case k_Immediate:
|
|
|
|
OS << "Imm<";
|
|
|
|
Imm.Val->print(OS);
|
|
|
|
OS << ">";
|
|
|
|
break;
|
|
|
|
case k_Memory:
|
|
|
|
OS << "Mem<";
|
|
|
|
Mem.Base->print(OS);
|
|
|
|
OS << ", ";
|
|
|
|
Mem.Off->print(OS);
|
|
|
|
OS << ">";
|
|
|
|
break;
|
|
|
|
case k_PhysRegister:
|
|
|
|
OS << "PhysReg<" << PhysReg.Num << ">";
|
|
|
|
break;
|
|
|
|
case k_RegisterIndex:
|
|
|
|
OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
|
|
|
|
break;
|
|
|
|
case k_Token:
|
|
|
|
OS << Tok.Data;
|
|
|
|
break;
|
|
|
|
}
|
2012-08-18 04:16:42 +08:00
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
}; // class MipsOperand
|
2013-11-06 19:27:05 +08:00
|
|
|
} // namespace
|
2012-08-18 04:16:42 +08:00
|
|
|
|
2013-03-22 08:05:30 +08:00
|
|
|
namespace llvm {
|
|
|
|
extern const MCInstrDesc MipsInsts[];
|
|
|
|
}
|
|
|
|
static const MCInstrDesc &getInstDesc(unsigned Opcode) {
|
|
|
|
return MipsInsts[Opcode];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
2013-04-17 08:18:04 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
2013-03-22 08:05:30 +08:00
|
|
|
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
|
2014-03-24 22:05:39 +08:00
|
|
|
|
2013-03-22 08:05:30 +08:00
|
|
|
Inst.setLoc(IDLoc);
|
2013-12-13 19:11:02 +08:00
|
|
|
|
|
|
|
if (MCID.isBranch() || MCID.isCall()) {
|
|
|
|
const unsigned Opcode = Inst.getOpcode();
|
|
|
|
MCOperand Offset;
|
|
|
|
|
|
|
|
switch (Opcode) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case Mips::BEQ:
|
|
|
|
case Mips::BNE:
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
case Mips::BEQ_MM:
|
|
|
|
case Mips::BNE_MM:
|
2014-01-23 07:31:38 +08:00
|
|
|
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
|
2013-12-13 19:11:02 +08:00
|
|
|
Offset = Inst.getOperand(2);
|
|
|
|
if (!Offset.isImm())
|
|
|
|
break; // We'll deal with this situation later on when applying fixups.
|
|
|
|
if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
|
|
|
|
return Error(IDLoc, "branch target out of range");
|
2014-01-23 07:31:38 +08:00
|
|
|
if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
|
2013-12-13 19:11:02 +08:00
|
|
|
return Error(IDLoc, "branch to misaligned address");
|
|
|
|
break;
|
|
|
|
case Mips::BGEZ:
|
|
|
|
case Mips::BGTZ:
|
|
|
|
case Mips::BLEZ:
|
|
|
|
case Mips::BLTZ:
|
|
|
|
case Mips::BGEZAL:
|
|
|
|
case Mips::BLTZAL:
|
|
|
|
case Mips::BC1F:
|
|
|
|
case Mips::BC1T:
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
case Mips::BGEZ_MM:
|
|
|
|
case Mips::BGTZ_MM:
|
|
|
|
case Mips::BLEZ_MM:
|
|
|
|
case Mips::BLTZ_MM:
|
|
|
|
case Mips::BGEZAL_MM:
|
|
|
|
case Mips::BLTZAL_MM:
|
|
|
|
case Mips::BC1F_MM:
|
|
|
|
case Mips::BC1T_MM:
|
2014-01-23 07:31:38 +08:00
|
|
|
assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
|
2013-12-13 19:11:02 +08:00
|
|
|
Offset = Inst.getOperand(1);
|
|
|
|
if (!Offset.isImm())
|
|
|
|
break; // We'll deal with this situation later on when applying fixups.
|
|
|
|
if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
|
|
|
|
return Error(IDLoc, "branch target out of range");
|
2014-01-23 07:31:38 +08:00
|
|
|
if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
|
2013-12-13 19:11:02 +08:00
|
|
|
return Error(IDLoc, "branch to misaligned address");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-26 07:31:35 +08:00
|
|
|
if (MCID.hasDelaySlot() && Options.isReorder()) {
|
|
|
|
// If this instruction has a delay slot and .set reorder is active,
|
|
|
|
// emit a NOP after it.
|
|
|
|
Instructions.push_back(Inst);
|
|
|
|
MCInst NopInst;
|
|
|
|
NopInst.setOpcode(Mips::SLL);
|
|
|
|
NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
|
|
|
NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
|
|
|
NopInst.addOperand(MCOperand::CreateImm(0));
|
|
|
|
Instructions.push_back(NopInst);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-03-22 08:05:30 +08:00
|
|
|
if (MCID.mayLoad() || MCID.mayStore()) {
|
|
|
|
// Check the offset of memory operand, if it is a symbol
|
2013-04-18 08:41:53 +08:00
|
|
|
// reference or immediate we may have to expand instructions.
|
|
|
|
for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
|
2013-03-22 08:05:30 +08:00
|
|
|
const MCOperandInfo &OpInfo = MCID.OpInfo[i];
|
2013-11-06 19:27:05 +08:00
|
|
|
if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
|
|
|
|
(OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
|
2013-03-22 08:05:30 +08:00
|
|
|
MCOperand &Op = Inst.getOperand(i);
|
|
|
|
if (Op.isImm()) {
|
|
|
|
int MemOffset = Op.getImm();
|
|
|
|
if (MemOffset < -32768 || MemOffset > 32767) {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Offset can't exceed 16bit value.
|
|
|
|
expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
|
2013-03-22 08:05:30 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (Op.isExpr()) {
|
|
|
|
const MCExpr *Expr = Op.getExpr();
|
2013-04-18 08:41:53 +08:00
|
|
|
if (Expr->getKind() == MCExpr::SymbolRef) {
|
2013-03-22 08:05:30 +08:00
|
|
|
const MCSymbolRefExpr *SR =
|
2013-11-06 19:27:05 +08:00
|
|
|
static_cast<const MCSymbolRefExpr *>(Expr);
|
2013-03-22 08:05:30 +08:00
|
|
|
if (SR->getKind() == MCSymbolRefExpr::VK_None) {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Expand symbol.
|
|
|
|
expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
|
2013-03-22 08:05:30 +08:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-17 08:18:04 +08:00
|
|
|
} else if (!isEvaluated(Expr)) {
|
2013-04-18 08:41:53 +08:00
|
|
|
expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
|
2013-04-17 08:18:04 +08:00
|
|
|
return false;
|
2013-03-22 08:05:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
} // for
|
2013-11-06 19:27:05 +08:00
|
|
|
} // if load/store
|
2013-03-22 08:05:30 +08:00
|
|
|
|
|
|
|
if (needsExpansion(Inst))
|
|
|
|
expandInstruction(Inst, IDLoc, Instructions);
|
|
|
|
else
|
|
|
|
Instructions.push_back(Inst);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
bool MipsAsmParser::needsExpansion(MCInst &Inst) {
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
switch (Inst.getOpcode()) {
|
|
|
|
case Mips::LoadImm32Reg:
|
|
|
|
case Mips::LoadAddr32Imm:
|
|
|
|
case Mips::LoadAddr32Reg:
|
2014-03-24 22:05:39 +08:00
|
|
|
case Mips::SUBi:
|
|
|
|
case Mips::SUBiu:
|
|
|
|
case Mips::DSUBi:
|
|
|
|
case Mips::DSUBiu:
|
2013-04-18 08:41:53 +08:00
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
}
|
|
|
|
}
|
2012-10-06 08:53:28 +08:00
|
|
|
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
2013-04-18 08:41:53 +08:00
|
|
|
switch (Inst.getOpcode()) {
|
|
|
|
case Mips::LoadImm32Reg:
|
|
|
|
return expandLoadImm(Inst, IDLoc, Instructions);
|
|
|
|
case Mips::LoadAddr32Imm:
|
|
|
|
return expandLoadAddressImm(Inst, IDLoc, Instructions);
|
|
|
|
case Mips::LoadAddr32Reg:
|
|
|
|
return expandLoadAddressReg(Inst, IDLoc, Instructions);
|
2014-03-24 22:05:39 +08:00
|
|
|
case Mips::SUBi:
|
|
|
|
Instructions.push_back(MCInstBuilder(Mips::ADDi)
|
|
|
|
.addReg(Inst.getOperand(0).getReg())
|
|
|
|
.addReg(Inst.getOperand(1).getReg())
|
|
|
|
.addImm(-Inst.getOperand(2).getImm()));
|
|
|
|
return;
|
|
|
|
case Mips::SUBiu:
|
|
|
|
Instructions.push_back(MCInstBuilder(Mips::ADDiu)
|
|
|
|
.addReg(Inst.getOperand(0).getReg())
|
|
|
|
.addReg(Inst.getOperand(1).getReg())
|
|
|
|
.addImm(-Inst.getOperand(2).getImm()));
|
|
|
|
return;
|
|
|
|
case Mips::DSUBi:
|
|
|
|
Instructions.push_back(MCInstBuilder(Mips::DADDi)
|
|
|
|
.addReg(Inst.getOperand(0).getReg())
|
|
|
|
.addReg(Inst.getOperand(1).getReg())
|
|
|
|
.addImm(-Inst.getOperand(2).getImm()));
|
|
|
|
return;
|
|
|
|
case Mips::DSUBiu:
|
|
|
|
Instructions.push_back(MCInstBuilder(Mips::DADDiu)
|
|
|
|
.addReg(Inst.getOperand(0).getReg())
|
|
|
|
.addReg(Inst.getOperand(1).getReg())
|
|
|
|
.addImm(-Inst.getOperand(2).getImm()));
|
|
|
|
return;
|
2013-04-18 08:41:53 +08:00
|
|
|
}
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
}
|
2012-10-06 08:53:28 +08:00
|
|
|
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
|
2013-04-18 08:41:53 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
2012-10-06 08:53:28 +08:00
|
|
|
MCInst tmpInst;
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
const MCOperand &ImmOp = Inst.getOperand(1);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
assert(ImmOp.isImm() && "expected immediate operand kind");
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
const MCOperand &RegOp = Inst.getOperand(0);
|
|
|
|
assert(RegOp.isReg() && "expected register operand kind");
|
|
|
|
|
|
|
|
int ImmValue = ImmOp.getImm();
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.setLoc(IDLoc);
|
2013-04-18 08:41:53 +08:00
|
|
|
if (0 <= ImmValue && ImmValue <= 65535) {
|
|
|
|
// For 0 <= j <= 65535.
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
// li d,j => ori d,$zero,j
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::ORi);
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2013-04-18 08:41:53 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
Instructions.push_back(tmpInst);
|
2013-04-18 08:41:53 +08:00
|
|
|
} else if (ImmValue < 0 && ImmValue >= -32768) {
|
|
|
|
// For -32768 <= j < 0.
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
// li d,j => addiu d,$zero,j
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::ADDiu);
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2013-04-18 08:41:53 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
} else {
|
2013-04-18 08:41:53 +08:00
|
|
|
// For any other value of j that is representable as a 32-bit integer.
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
// li d,j => lui d,hi16(j)
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
// ori d,d,lo16(j)
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
Instructions.push_back(tmpInst);
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.clear();
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::ORi);
|
2012-10-06 08:53:28 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
|
|
|
|
tmpInst.setLoc(IDLoc);
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
}
|
|
|
|
}
|
2012-10-06 08:53:28 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
void
|
|
|
|
MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
MCInst tmpInst;
|
|
|
|
const MCOperand &ImmOp = Inst.getOperand(2);
|
|
|
|
assert(ImmOp.isImm() && "expected immediate operand kind");
|
|
|
|
const MCOperand &SrcRegOp = Inst.getOperand(1);
|
|
|
|
assert(SrcRegOp.isReg() && "expected register operand kind");
|
|
|
|
const MCOperand &DstRegOp = Inst.getOperand(0);
|
|
|
|
assert(DstRegOp.isReg() && "expected register operand kind");
|
|
|
|
int ImmValue = ImmOp.getImm();
|
2013-04-18 08:41:53 +08:00
|
|
|
if (-32768 <= ImmValue && ImmValue <= 65535) {
|
|
|
|
// For -32768 <= j <= 65535.
|
|
|
|
// la d,j(s) => addiu d,s,j
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::ADDiu);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
} else {
|
2013-04-18 08:41:53 +08:00
|
|
|
// For any other value of j that is representable as a 32-bit integer.
|
|
|
|
// la d,j(s) => lui d,hi16(j)
|
|
|
|
// ori d,d,lo16(j)
|
|
|
|
// addu d,d,s
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
tmpInst.clear();
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::ORi);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
tmpInst.clear();
|
|
|
|
tmpInst.setOpcode(Mips::ADDu);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
void
|
|
|
|
MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
MCInst tmpInst;
|
|
|
|
const MCOperand &ImmOp = Inst.getOperand(1);
|
|
|
|
assert(ImmOp.isImm() && "expected immediate operand kind");
|
|
|
|
const MCOperand &RegOp = Inst.getOperand(0);
|
|
|
|
assert(RegOp.isReg() && "expected register operand kind");
|
|
|
|
int ImmValue = ImmOp.getImm();
|
2013-04-18 08:41:53 +08:00
|
|
|
if (-32768 <= ImmValue && ImmValue <= 65535) {
|
|
|
|
// For -32768 <= j <= 65535.
|
|
|
|
// la d,j => addiu d,$zero,j
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.setOpcode(Mips::ADDiu);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2013-04-18 08:41:53 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
} else {
|
2013-04-18 08:41:53 +08:00
|
|
|
// For any other value of j that is representable as a 32-bit integer.
|
|
|
|
// la d,j => lui d,hi16(j)
|
|
|
|
// ori d,d,lo16(j)
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
tmpInst.clear();
|
2013-01-12 09:03:14 +08:00
|
|
|
tmpInst.setOpcode(Mips::ORi);
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-22 08:05:30 +08:00
|
|
|
void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCInst> &Instructions,
|
|
|
|
bool isLoad, bool isImmOpnd) {
|
2013-03-22 08:05:30 +08:00
|
|
|
const MCSymbolRefExpr *SR;
|
|
|
|
MCInst TempInst;
|
2013-04-18 08:41:53 +08:00
|
|
|
unsigned ImmOffset, HiOffset, LoOffset;
|
2013-03-22 08:05:30 +08:00
|
|
|
const MCExpr *ExprOffset;
|
|
|
|
unsigned TmpRegNum;
|
2013-11-06 19:27:05 +08:00
|
|
|
unsigned AtRegNum = getReg(
|
2014-03-28 00:42:17 +08:00
|
|
|
(isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
|
2013-04-18 08:41:53 +08:00
|
|
|
// 1st operand is either the source or destination register.
|
2013-03-22 08:05:30 +08:00
|
|
|
assert(Inst.getOperand(0).isReg() && "expected register operand kind");
|
|
|
|
unsigned RegOpNum = Inst.getOperand(0).getReg();
|
2013-04-18 08:41:53 +08:00
|
|
|
// 2nd operand is the base register.
|
2013-03-22 08:05:30 +08:00
|
|
|
assert(Inst.getOperand(1).isReg() && "expected register operand kind");
|
|
|
|
unsigned BaseRegNum = Inst.getOperand(1).getReg();
|
2013-04-18 08:41:53 +08:00
|
|
|
// 3rd operand is either an immediate or expression.
|
2013-03-22 08:05:30 +08:00
|
|
|
if (isImmOpnd) {
|
|
|
|
assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
|
|
|
|
ImmOffset = Inst.getOperand(2).getImm();
|
|
|
|
LoOffset = ImmOffset & 0x0000ffff;
|
|
|
|
HiOffset = (ImmOffset & 0xffff0000) >> 16;
|
2013-04-18 08:41:53 +08:00
|
|
|
// If msb of LoOffset is 1(negative number) we must increment HiOffset.
|
2013-03-22 08:05:30 +08:00
|
|
|
if (LoOffset & 0x8000)
|
|
|
|
HiOffset++;
|
2013-04-18 08:41:53 +08:00
|
|
|
} else
|
2013-03-22 08:05:30 +08:00
|
|
|
ExprOffset = Inst.getOperand(2).getExpr();
|
2013-04-18 08:41:53 +08:00
|
|
|
// All instructions will have the same location.
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.setLoc(IDLoc);
|
|
|
|
// 1st instruction in expansion is LUi. For load instruction we can use
|
|
|
|
// the dst register as a temporary if base and dst are different,
|
2013-04-18 08:41:53 +08:00
|
|
|
// but for stores we must use $at.
|
|
|
|
TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.setOpcode(Mips::LUi);
|
|
|
|
TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
|
|
|
|
if (isImmOpnd)
|
|
|
|
TempInst.addOperand(MCOperand::CreateImm(HiOffset));
|
|
|
|
else {
|
|
|
|
if (ExprOffset->getKind() == MCExpr::SymbolRef) {
|
2013-11-06 19:27:05 +08:00
|
|
|
SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
|
2013-04-18 08:41:53 +08:00
|
|
|
const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
|
|
|
|
SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
|
|
|
|
getContext());
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
|
2013-04-17 08:18:04 +08:00
|
|
|
} else {
|
2013-04-18 08:41:53 +08:00
|
|
|
const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
|
2013-04-17 08:18:04 +08:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
|
2013-03-22 08:05:30 +08:00
|
|
|
}
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
// Add the instruction to the list.
|
2013-03-22 08:05:30 +08:00
|
|
|
Instructions.push_back(TempInst);
|
2013-04-18 08:41:53 +08:00
|
|
|
// Prepare TempInst for next instruction.
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.clear();
|
2013-04-18 08:41:53 +08:00
|
|
|
// Add temp register to base.
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.setOpcode(Mips::ADDu);
|
|
|
|
TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
|
|
|
|
TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
|
|
|
|
TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
|
|
|
|
Instructions.push_back(TempInst);
|
|
|
|
TempInst.clear();
|
2014-01-25 01:20:08 +08:00
|
|
|
// And finally, create original instruction with low part
|
2013-04-18 08:41:53 +08:00
|
|
|
// of offset and new base.
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.setOpcode(Inst.getOpcode());
|
|
|
|
TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
|
|
|
|
TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
|
|
|
|
if (isImmOpnd)
|
|
|
|
TempInst.addOperand(MCOperand::CreateImm(LoOffset));
|
|
|
|
else {
|
|
|
|
if (ExprOffset->getKind() == MCExpr::SymbolRef) {
|
2013-04-18 08:41:53 +08:00
|
|
|
const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
|
|
|
|
SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
|
|
|
|
getContext());
|
2013-03-22 08:05:30 +08:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
|
2013-04-17 08:18:04 +08:00
|
|
|
} else {
|
2013-04-18 08:41:53 +08:00
|
|
|
const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
|
2013-04-17 08:18:04 +08:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
|
2013-03-22 08:05:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Instructions.push_back(TempInst);
|
|
|
|
TempInst.clear();
|
|
|
|
}
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
bool MipsAsmParser::MatchAndEmitInstruction(
|
|
|
|
SMLoc IDLoc, unsigned &Opcode,
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
|
|
|
|
unsigned &ErrorInfo, bool MatchingInlineAsm) {
|
2012-09-06 07:34:03 +08:00
|
|
|
MCInst Inst;
|
2013-03-22 08:05:30 +08:00
|
|
|
SmallVector<MCInst, 8> Instructions;
|
2013-11-06 19:27:05 +08:00
|
|
|
unsigned MatchResult =
|
|
|
|
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
|
2012-09-06 07:34:03 +08:00
|
|
|
|
|
|
|
switch (MatchResult) {
|
2013-04-18 08:41:53 +08:00
|
|
|
default:
|
|
|
|
break;
|
2012-09-06 07:34:03 +08:00
|
|
|
case Match_Success: {
|
2013-04-18 08:41:53 +08:00
|
|
|
if (processInstruction(Inst, IDLoc, Instructions))
|
2013-03-22 08:05:30 +08:00
|
|
|
return true;
|
2013-04-18 08:41:53 +08:00
|
|
|
for (unsigned i = 0; i < Instructions.size(); i++)
|
2014-01-29 07:12:42 +08:00
|
|
|
Out.EmitInstruction(Instructions[i], STI);
|
2012-09-06 07:34:03 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case Match_MissingFeature:
|
|
|
|
Error(IDLoc, "instruction requires a CPU feature not currently enabled");
|
|
|
|
return true;
|
|
|
|
case Match_InvalidOperand: {
|
|
|
|
SMLoc ErrorLoc = IDLoc;
|
|
|
|
if (ErrorInfo != ~0U) {
|
|
|
|
if (ErrorInfo >= Operands.size())
|
|
|
|
return Error(IDLoc, "too few operands for instruction");
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
|
2013-04-18 08:41:53 +08:00
|
|
|
if (ErrorLoc == SMLoc())
|
|
|
|
ErrorLoc = IDLoc;
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Error(ErrorLoc, "invalid operand for instruction");
|
|
|
|
}
|
|
|
|
case Match_MnemonicFail:
|
|
|
|
return Error(IDLoc, "invalid instruction");
|
|
|
|
}
|
2012-01-11 11:56:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
|
|
|
|
if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
|
|
|
|
if (RegIndex == 1)
|
|
|
|
Warning(Loc, "Used $at without \".set noat\"");
|
2014-03-25 19:16:03 +08:00
|
|
|
else
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
|
|
|
|
Twine(RegIndex) + "\"");
|
2014-03-25 18:57:07 +08:00
|
|
|
}
|
2014-03-25 19:16:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int MipsAsmParser::matchCPURegisterName(StringRef Name) {
|
|
|
|
int CC;
|
2013-02-21 07:11:17 +08:00
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
CC = StringSwitch<unsigned>(Name)
|
|
|
|
.Case("zero", 0)
|
2014-03-25 19:16:03 +08:00
|
|
|
.Case("at", 1)
|
2013-11-06 19:27:05 +08:00
|
|
|
.Case("a0", 4)
|
|
|
|
.Case("a1", 5)
|
|
|
|
.Case("a2", 6)
|
|
|
|
.Case("a3", 7)
|
|
|
|
.Case("v0", 2)
|
|
|
|
.Case("v1", 3)
|
|
|
|
.Case("s0", 16)
|
|
|
|
.Case("s1", 17)
|
|
|
|
.Case("s2", 18)
|
|
|
|
.Case("s3", 19)
|
|
|
|
.Case("s4", 20)
|
|
|
|
.Case("s5", 21)
|
|
|
|
.Case("s6", 22)
|
|
|
|
.Case("s7", 23)
|
|
|
|
.Case("k0", 26)
|
|
|
|
.Case("k1", 27)
|
2014-03-26 19:05:24 +08:00
|
|
|
.Case("gp", 28)
|
2013-11-06 19:27:05 +08:00
|
|
|
.Case("sp", 29)
|
|
|
|
.Case("fp", 30)
|
2014-03-26 19:05:24 +08:00
|
|
|
.Case("s8", 30)
|
2013-11-06 19:27:05 +08:00
|
|
|
.Case("ra", 31)
|
|
|
|
.Case("t0", 8)
|
|
|
|
.Case("t1", 9)
|
|
|
|
.Case("t2", 10)
|
|
|
|
.Case("t3", 11)
|
|
|
|
.Case("t4", 12)
|
|
|
|
.Case("t5", 13)
|
|
|
|
.Case("t6", 14)
|
|
|
|
.Case("t7", 15)
|
|
|
|
.Case("t8", 24)
|
|
|
|
.Case("t9", 25)
|
|
|
|
.Default(-1);
|
2013-02-21 07:11:17 +08:00
|
|
|
|
2014-03-26 19:39:07 +08:00
|
|
|
if (isN32() || isN64()) {
|
|
|
|
// Although SGI documentation just cuts out t0-t3 for n32/n64,
|
|
|
|
// GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
|
|
|
|
// We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
|
|
|
|
if (8 <= CC && CC <= 11)
|
|
|
|
CC += 4;
|
|
|
|
|
|
|
|
if (CC == -1)
|
|
|
|
CC = StringSwitch<unsigned>(Name)
|
|
|
|
.Case("a4", 8)
|
|
|
|
.Case("a5", 9)
|
|
|
|
.Case("a6", 10)
|
|
|
|
.Case("a7", 11)
|
|
|
|
.Case("kt0", 26)
|
|
|
|
.Case("kt1", 27)
|
|
|
|
.Default(-1);
|
|
|
|
}
|
2012-10-10 00:27:43 +08:00
|
|
|
|
2013-02-21 07:11:17 +08:00
|
|
|
return CC;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
int MipsAsmParser::matchFPURegisterName(StringRef Name) {
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2012-09-07 08:23:42 +08:00
|
|
|
if (Name[0] == 'f') {
|
|
|
|
StringRef NumString = Name.substr(1);
|
|
|
|
unsigned IntVal;
|
2013-04-18 08:41:53 +08:00
|
|
|
if (NumString.getAsInteger(10, IntVal))
|
2013-11-06 19:27:05 +08:00
|
|
|
return -1; // This is not an integer.
|
2013-08-13 21:07:09 +08:00
|
|
|
if (IntVal > 31) // Maximum index for fpu register.
|
2012-09-07 08:23:42 +08:00
|
|
|
return -1;
|
2013-08-13 21:07:09 +08:00
|
|
|
return IntVal;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2012-09-07 08:23:42 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
|
|
|
|
|
|
|
|
if (Name.startswith("fcc")) {
|
|
|
|
StringRef NumString = Name.substr(3);
|
|
|
|
unsigned IntVal;
|
|
|
|
if (NumString.getAsInteger(10, IntVal))
|
2013-11-06 19:27:05 +08:00
|
|
|
return -1; // This is not an integer.
|
2013-08-13 21:07:09 +08:00
|
|
|
if (IntVal > 7) // There are only 8 fcc registers.
|
|
|
|
return -1;
|
|
|
|
return IntVal;
|
2012-09-07 08:23:42 +08:00
|
|
|
}
|
2012-09-06 07:34:03 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
int MipsAsmParser::matchACRegisterName(StringRef Name) {
|
|
|
|
|
2013-08-14 09:15:52 +08:00
|
|
|
if (Name.startswith("ac")) {
|
|
|
|
StringRef NumString = Name.substr(2);
|
2013-08-13 21:07:09 +08:00
|
|
|
unsigned IntVal;
|
|
|
|
if (NumString.getAsInteger(10, IntVal))
|
2013-11-06 19:27:05 +08:00
|
|
|
return -1; // This is not an integer.
|
2013-08-13 21:07:09 +08:00
|
|
|
if (IntVal > 3) // There are only 3 acc registers.
|
|
|
|
return -1;
|
|
|
|
return IntVal;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2013-06-20 19:21:49 +08:00
|
|
|
|
2013-09-26 07:50:44 +08:00
|
|
|
int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
|
|
|
|
unsigned IntVal;
|
|
|
|
|
|
|
|
if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (IntVal > 31)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return IntVal;
|
|
|
|
}
|
|
|
|
|
2013-10-21 20:26:50 +08:00
|
|
|
int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
|
|
|
|
int CC;
|
|
|
|
|
|
|
|
CC = StringSwitch<unsigned>(Name)
|
2013-11-06 19:27:05 +08:00
|
|
|
.Case("msair", 0)
|
|
|
|
.Case("msacsr", 1)
|
|
|
|
.Case("msaaccess", 2)
|
|
|
|
.Case("msasave", 3)
|
|
|
|
.Case("msamodify", 4)
|
|
|
|
.Case("msarequest", 5)
|
|
|
|
.Case("msamap", 6)
|
|
|
|
.Case("msaunmap", 7)
|
|
|
|
.Default(-1);
|
2013-10-21 20:26:50 +08:00
|
|
|
|
|
|
|
return CC;
|
|
|
|
}
|
|
|
|
|
2012-10-04 10:29:46 +08:00
|
|
|
bool MipsAssemblerOptions::setATReg(unsigned Reg) {
|
|
|
|
if (Reg > 31)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
aTReg = Reg;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-25 00:48:01 +08:00
|
|
|
int MipsAsmParser::getATReg() {
|
|
|
|
int AT = Options.getATRegNum();
|
|
|
|
if (AT == 0)
|
|
|
|
TokError("Pseudo instruction requires $at, which is not available");
|
|
|
|
return AT;
|
|
|
|
}
|
2012-10-04 10:29:46 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
unsigned MipsAsmParser::getReg(int RC, int RegNo) {
|
2013-06-18 15:20:20 +08:00
|
|
|
return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
|
2014-03-27 21:52:53 +08:00
|
|
|
unsigned MipsAsmParser::getGPR(int RegNo) {
|
2014-03-28 00:42:17 +08:00
|
|
|
return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
|
|
|
|
RegNo);
|
2014-03-27 21:52:53 +08:00
|
|
|
}
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
|
2013-08-13 21:07:09 +08:00
|
|
|
if (RegNum >
|
2014-03-27 23:00:44 +08:00
|
|
|
getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
|
2012-09-06 07:34:03 +08:00
|
|
|
return -1;
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
return getReg(RegClass, RegNum);
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
bool
|
|
|
|
MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
|
|
|
StringRef Mnemonic) {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << "ParseOperand\n");
|
|
|
|
|
Implement methods that enable expansion of load immediate
macro instruction (li) in the assembler.
We have identified three possible expansions depending on
the size of immediate operand:
1) for 0 ≤ j ≤ 65535.
li d,j =>
ori d,$zero,j
2) for −32768 ≤ j < 0.
li d,j =>
addiu d,$zero,j
3) for any other value of j that is representable as a 32-bit integer.
li d,j =>
lui d,hi16(j)
ori d,d,lo16(j)
All of the above have been implemented in ths patch.
Contributer: Vladimir Medic
llvm-svn: 165199
2012-10-04 12:03:53 +08:00
|
|
|
// Check if the current operand has a custom associated parser, if so, try to
|
|
|
|
// custom parse the operand, or fallback to the general approach.
|
2012-09-06 07:34:03 +08:00
|
|
|
OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
|
|
|
|
if (ResTy == MatchOperand_Success)
|
|
|
|
return false;
|
|
|
|
// 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)
|
|
|
|
return true;
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << ".. Generic Parser\n");
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
switch (getLexer().getKind()) {
|
|
|
|
default:
|
|
|
|
Error(Parser.getTok().getLoc(), "unexpected token in operand");
|
|
|
|
return true;
|
|
|
|
case AsmToken::Dollar: {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Parse the register.
|
2012-09-06 07:34:03 +08:00
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
// Almost all registers have been parsed by custom parsers. There is only
|
|
|
|
// one exception to this. $zero (and it's alias $0) will reach this point
|
|
|
|
// for div, divu, and similar instructions because it is not an operand
|
|
|
|
// to the instruction definition but an explicit register. Special case
|
|
|
|
// this situation for now.
|
|
|
|
if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
|
2014-04-01 02:51:43 +08:00
|
|
|
return false;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
// Maybe it is a symbol reference.
|
2012-09-06 07:34:03 +08:00
|
|
|
StringRef Identifier;
|
2013-02-21 06:21:35 +08:00
|
|
|
if (Parser.parseIdentifier(Identifier))
|
2012-09-06 07:34:03 +08:00
|
|
|
return true;
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
2012-09-07 17:47:42 +08:00
|
|
|
MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
|
2013-04-18 08:41:53 +08:00
|
|
|
// Otherwise create a symbol reference.
|
2013-11-06 19:27:05 +08:00
|
|
|
const MCExpr *Res =
|
|
|
|
MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
|
2012-09-06 07:34:03 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
|
2012-09-06 07:34:03 +08:00
|
|
|
return false;
|
|
|
|
}
|
2013-11-06 19:27:05 +08:00
|
|
|
// Else drop to expression parsing.
|
2012-09-06 07:34:03 +08:00
|
|
|
case AsmToken::LParen:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Plus:
|
|
|
|
case AsmToken::Integer:
|
|
|
|
case AsmToken::String: {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << ".. generic integer\n");
|
|
|
|
OperandMatchResultTy ResTy = ParseImm(Operands);
|
|
|
|
return ResTy != MatchOperand_Success;
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
case AsmToken::Percent: {
|
2013-04-18 08:41:53 +08:00
|
|
|
// It is a symbol reference or constant expression.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
const MCExpr *IdVal;
|
2013-04-18 08:41:53 +08:00
|
|
|
SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
|
2013-01-12 09:03:14 +08:00
|
|
|
if (parseRelocOperand(IdVal))
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
return true;
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
return false;
|
2012-10-04 10:29:46 +08:00
|
|
|
} // case AsmToken::Percent
|
|
|
|
} // switch(getLexer().getKind())
|
2012-01-11 11:56:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
|
2013-04-17 08:18:04 +08:00
|
|
|
StringRef RelocStr) {
|
|
|
|
const MCExpr *Res;
|
2013-04-18 08:41:53 +08:00
|
|
|
// Check the type of the expression.
|
2013-04-17 08:18:04 +08:00
|
|
|
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
|
2013-04-18 08:41:53 +08:00
|
|
|
// It's a constant, evaluate lo or hi value.
|
2013-04-17 08:18:04 +08:00
|
|
|
if (RelocStr == "lo") {
|
|
|
|
short Val = MCE->getValue();
|
|
|
|
Res = MCConstantExpr::Create(Val, getContext());
|
|
|
|
} else if (RelocStr == "hi") {
|
|
|
|
int Val = MCE->getValue();
|
|
|
|
int LoSign = Val & 0x8000;
|
|
|
|
Val = (Val & 0xffff0000) >> 16;
|
|
|
|
// Lower part is treated as a signed int, so if it is negative
|
2013-04-18 08:41:53 +08:00
|
|
|
// we must add 1 to the hi part to compensate.
|
2013-04-17 08:18:04 +08:00
|
|
|
if (LoSign)
|
|
|
|
Val++;
|
|
|
|
Res = MCConstantExpr::Create(Val, getContext());
|
2013-04-17 14:45:11 +08:00
|
|
|
} else {
|
|
|
|
llvm_unreachable("Invalid RelocStr value");
|
2013-04-17 08:18:04 +08:00
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
return Res;
|
2013-04-17 08:18:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
|
2013-04-18 08:41:53 +08:00
|
|
|
// It's a symbol, create a symbolic expression from the symbol.
|
2013-04-17 08:18:04 +08:00
|
|
|
StringRef Symbol = MSRE->getSymbol().getName();
|
|
|
|
MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
|
2013-04-18 08:41:53 +08:00
|
|
|
Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
|
2013-04-17 08:18:04 +08:00
|
|
|
return Res;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
|
2014-02-05 02:41:57 +08:00
|
|
|
MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
|
|
|
|
|
|
|
|
// Check for %hi(sym1-sym2) and %lo(sym1-sym2) expressions.
|
|
|
|
if (isa<MCSymbolRefExpr>(BE->getLHS()) && isa<MCSymbolRefExpr>(BE->getRHS())
|
|
|
|
&& (VK == MCSymbolRefExpr::VK_Mips_ABS_HI
|
|
|
|
|| VK == MCSymbolRefExpr::VK_Mips_ABS_LO)) {
|
|
|
|
// Create target expression for %hi(sym1-sym2) and %lo(sym1-sym2).
|
|
|
|
if (VK == MCSymbolRefExpr::VK_Mips_ABS_HI)
|
|
|
|
return MipsMCExpr::CreateHi(Expr, getContext());
|
|
|
|
return MipsMCExpr::CreateLo(Expr, getContext());
|
|
|
|
}
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
|
|
|
|
const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
|
2013-04-17 08:18:04 +08:00
|
|
|
Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
|
|
|
|
return Res;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
|
2013-04-18 08:41:53 +08:00
|
|
|
const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
|
|
|
|
Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
|
|
|
|
return Res;
|
2013-04-17 08:18:04 +08:00
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
// Just return the original expression.
|
2013-04-17 08:18:04 +08:00
|
|
|
return Expr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
|
|
|
|
|
|
|
|
switch (Expr->getKind()) {
|
|
|
|
case MCExpr::Constant:
|
|
|
|
return true;
|
|
|
|
case MCExpr::SymbolRef:
|
|
|
|
return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
|
|
|
|
case MCExpr::Binary:
|
|
|
|
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
|
|
|
|
if (!isEvaluated(BE->getLHS()))
|
|
|
|
return false;
|
|
|
|
return isEvaluated(BE->getRHS());
|
|
|
|
}
|
|
|
|
case MCExpr::Unary:
|
|
|
|
return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
|
2014-02-05 02:41:57 +08:00
|
|
|
case MCExpr::Target:
|
|
|
|
return true;
|
2013-04-17 08:18:04 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
|
2013-11-06 19:27:05 +08:00
|
|
|
Parser.Lex(); // Eat the % token.
|
2013-04-18 08:41:53 +08:00
|
|
|
const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
if (Tok.isNot(AsmToken::Identifier))
|
|
|
|
return true;
|
|
|
|
|
2012-09-07 17:47:42 +08:00
|
|
|
std::string Str = Tok.getIdentifier().str();
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the identifier.
|
|
|
|
// Now make an expression from the rest of the operand.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
const MCExpr *IdVal;
|
2013-01-12 09:03:14 +08:00
|
|
|
SMLoc EndLoc;
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
|
|
|
if (getLexer().getKind() == AsmToken::LParen) {
|
|
|
|
while (1) {
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the '(' token.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
if (getLexer().getKind() == AsmToken::Percent) {
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the % token.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
const AsmToken &nextTok = Parser.getTok();
|
|
|
|
if (nextTok.isNot(AsmToken::Identifier))
|
|
|
|
return true;
|
2012-09-07 17:47:42 +08:00
|
|
|
Str += "(%";
|
|
|
|
Str += nextTok.getIdentifier();
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the identifier.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
if (getLexer().getKind() != AsmToken::LParen)
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
if (getParser().parseParenExpression(IdVal, EndLoc))
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
return true;
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
while (getLexer().getKind() == AsmToken::RParen)
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the ')' token.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
|
|
|
} else
|
2013-04-18 08:41:53 +08:00
|
|
|
return true; // Parenthesis must follow the relocation operand.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
Res = evaluateRelocExpr(IdVal, Str);
|
2013-04-17 08:18:04 +08:00
|
|
|
return false;
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
}
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
|
|
|
SMLoc &EndLoc) {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
SmallVector<MCParsedAsmOperand *, 1> Operands;
|
|
|
|
OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
|
|
|
|
if (ResTy == MatchOperand_Success) {
|
|
|
|
assert(Operands.size() == 1);
|
|
|
|
MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
|
|
|
|
StartLoc = Operand.getStartLoc();
|
|
|
|
EndLoc = Operand.getEndLoc();
|
|
|
|
|
|
|
|
// AFAIK, we only support numeric registers and named GPR's in CFI
|
|
|
|
// directives.
|
|
|
|
// Don't worry about eating tokens before failing. Using an unrecognised
|
|
|
|
// register is a parse error.
|
|
|
|
if (Operand.isGPRAsmReg()) {
|
|
|
|
// Resolve to GPR32 or GPR64 appropriately.
|
|
|
|
RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
|
|
|
|
}
|
|
|
|
|
|
|
|
return (RegNo == (unsigned)-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(Operands.size() == 0);
|
2013-11-06 19:27:05 +08:00
|
|
|
return (RegNo == (unsigned)-1);
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
|
2013-04-17 08:18:04 +08:00
|
|
|
bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
|
2013-01-12 09:03:14 +08:00
|
|
|
SMLoc S;
|
2013-04-17 08:18:04 +08:00
|
|
|
bool Result = true;
|
|
|
|
|
|
|
|
while (getLexer().getKind() == AsmToken::LParen)
|
|
|
|
Parser.Lex();
|
2013-01-12 09:03:14 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
switch (getLexer().getKind()) {
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
default:
|
|
|
|
return true;
|
2013-03-22 08:05:30 +08:00
|
|
|
case AsmToken::Identifier:
|
2013-04-17 08:18:04 +08:00
|
|
|
case AsmToken::LParen:
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
case AsmToken::Integer:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Plus:
|
2013-04-17 08:18:04 +08:00
|
|
|
if (isParenExpr)
|
2013-04-18 08:41:53 +08:00
|
|
|
Result = getParser().parseParenExpression(Res, S);
|
2013-04-17 08:18:04 +08:00
|
|
|
else
|
|
|
|
Result = (getParser().parseExpression(Res));
|
2013-04-18 08:41:53 +08:00
|
|
|
while (getLexer().getKind() == AsmToken::RParen)
|
2013-04-17 08:18:04 +08:00
|
|
|
Parser.Lex();
|
2013-04-18 08:41:53 +08:00
|
|
|
break;
|
2013-01-12 09:03:14 +08:00
|
|
|
case AsmToken::Percent:
|
2013-04-17 08:18:04 +08:00
|
|
|
Result = parseRelocOperand(Res);
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
}
|
2013-04-17 08:18:04 +08:00
|
|
|
return Result;
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
}
|
|
|
|
|
2012-09-06 07:34:03 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
|
2013-11-06 19:27:05 +08:00
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << "parseMemOperand\n");
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
const MCExpr *IdVal = 0;
|
2013-01-12 09:03:14 +08:00
|
|
|
SMLoc S;
|
2013-04-17 08:18:04 +08:00
|
|
|
bool isParenExpr = false;
|
2013-08-13 21:07:09 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
|
2013-04-18 08:41:53 +08:00
|
|
|
// First operand is the offset.
|
2013-01-12 09:03:14 +08:00
|
|
|
S = Parser.getTok().getLoc();
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-04-17 08:18:04 +08:00
|
|
|
if (getLexer().getKind() == AsmToken::LParen) {
|
|
|
|
Parser.Lex();
|
|
|
|
isParenExpr = true;
|
|
|
|
}
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-04-17 08:18:04 +08:00
|
|
|
if (getLexer().getKind() != AsmToken::Dollar) {
|
2013-04-18 08:41:53 +08:00
|
|
|
if (parseMemOffset(IdVal, isParenExpr))
|
2013-04-17 08:18:04 +08:00
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
const AsmToken &Tok = Parser.getTok(); // Get the next token.
|
2013-04-17 08:18:04 +08:00
|
|
|
if (Tok.isNot(AsmToken::LParen)) {
|
2013-11-06 19:27:05 +08:00
|
|
|
MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
|
2013-04-17 08:18:04 +08:00
|
|
|
if (Mnemonic->getToken() == "la") {
|
2013-11-06 19:27:05 +08:00
|
|
|
SMLoc E =
|
|
|
|
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
|
2013-04-17 08:18:04 +08:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
if (Tok.is(AsmToken::EndOfStatement)) {
|
2013-11-06 19:27:05 +08:00
|
|
|
SMLoc E =
|
|
|
|
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
2013-04-17 08:18:04 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
// Zero register assumed, add a memory operand with ZERO as its base.
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsOperand *Base = MipsOperand::CreateGPRReg(
|
|
|
|
0, getContext().getRegisterInfo(), S, E, *this);
|
|
|
|
Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
|
2013-04-17 08:18:04 +08:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
Error(Parser.getTok().getLoc(), "'(' expected");
|
|
|
|
return MatchOperand_ParseFail;
|
Initial assembler implementation of Mips load address macro
This patch provides initial implementation of load address
macro instruction for Mips. We have implemented two kinds
of expansions with their variations depending on the size
of immediate operand:
1) load address with immediate value directly:
* la d,j => addiu d,$zero,j (for -32768 <= j <= 65535)
* la d,j => lui d,hi16(j)
ori d,d,lo16(j) (for any other 32 bit value of j)
2) load load address with register offset value
* la d,j(s) => addiu d,s,j (for -32768 <= j <= 65535)
* la d,j(s) => lui d,hi16(j) (for any other 32 bit value of j)
ori d,d,lo16(j)
addu d,d,s
This patch does not cover the case when the address is loaded
from the value of the label or function.
Contributer: Vladimir Medic
llvm-svn: 165561
2012-10-10 07:29:45 +08:00
|
|
|
}
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the '(' token.
|
2013-04-17 08:18:04 +08:00
|
|
|
}
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Res = ParseAnyRegister(Operands);
|
2013-08-13 21:07:09 +08:00
|
|
|
if (Res != MatchOperand_Success)
|
|
|
|
return Res;
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2013-08-13 21:07:09 +08:00
|
|
|
if (Parser.getTok().isNot(AsmToken::RParen)) {
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
Error(Parser.getTok().getLoc(), "')' expected");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
2013-01-12 09:03:14 +08:00
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the ')' token.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
|
|
|
if (IdVal == 0)
|
|
|
|
IdVal = MCConstantExpr::Create(0, getContext());
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
// Replace the register operand with the memory operand.
|
2013-11-06 19:27:05 +08:00
|
|
|
MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
|
2013-04-18 08:41:53 +08:00
|
|
|
// Remove the register from the operands.
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
Operands.pop_back();
|
2013-04-18 08:41:53 +08:00
|
|
|
// Add the memory operand.
|
2013-04-17 08:18:04 +08:00
|
|
|
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
|
|
|
|
int64_t Imm;
|
|
|
|
if (IdVal->EvaluateAsAbsolute(Imm))
|
|
|
|
IdVal = MCConstantExpr::Create(Imm, getContext());
|
|
|
|
else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
|
|
|
|
IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
|
|
|
|
getContext());
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
|
2012-09-06 07:34:03 +08:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
bool MipsAsmParser::searchSymbolAlias(
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
2014-04-01 02:51:43 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
|
|
|
|
if (Sym) {
|
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
|
|
|
const MCExpr *Expr;
|
|
|
|
if (Sym->isVariable())
|
|
|
|
Expr = Sym->getVariableValue();
|
|
|
|
else
|
2014-04-01 02:51:43 +08:00
|
|
|
return false;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
if (Expr->getKind() == MCExpr::SymbolRef) {
|
|
|
|
const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
|
|
|
|
const StringRef DefSymbol = Ref->getSymbol().getName();
|
|
|
|
if (DefSymbol.startswith("$")) {
|
|
|
|
OperandMatchResultTy ResTy =
|
|
|
|
MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
|
2014-04-01 18:37:46 +08:00
|
|
|
if (ResTy == MatchOperand_Success) {
|
|
|
|
Parser.Lex();
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
return true;
|
2014-04-01 18:37:46 +08:00
|
|
|
} else if (ResTy == MatchOperand_ParseFail)
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
llvm_unreachable("Should never ParseFail");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (Expr->getKind() == MCExpr::Constant) {
|
|
|
|
Parser.Lex();
|
|
|
|
const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
|
|
|
|
MipsOperand *op =
|
|
|
|
MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
|
|
|
|
Operands.push_back(op);
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-28 08:55:15 +08:00
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
return false;
|
2013-08-28 08:55:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
|
|
|
|
SMLoc S) {
|
|
|
|
int Index = matchCPURegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::CreateGPRReg(
|
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
2013-08-28 08:55:15 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Index = matchFPURegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::CreateFGRReg(
|
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
2013-01-12 09:03:14 +08:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
2013-07-16 18:07:14 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Index = matchFCCRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::CreateFCCReg(
|
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
|
|
|
return MatchOperand_Success;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
}
|
2013-10-14 19:49:30 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Index = matchACRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::CreateACCReg(
|
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
2013-10-14 19:49:30 +08:00
|
|
|
return MatchOperand_Success;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
}
|
2013-10-14 19:49:30 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Index = matchMSA128RegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::CreateMSA128Reg(
|
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
return MatchOperand_Success;
|
2013-10-14 19:49:30 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Index = matchMSA128CtrlRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::CreateMSACtrlReg(
|
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
|
|
|
return MatchOperand_Success;
|
2014-04-01 02:51:43 +08:00
|
|
|
}
|
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
return MatchOperand_NoMatch;
|
2014-04-01 02:51:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-04-01 20:35:23 +08:00
|
|
|
MipsAsmParser::MatchAnyRegisterWithoutDollar(
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
|
2014-04-01 18:40:14 +08:00
|
|
|
auto Token = Parser.getLexer().peekTok(false);
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
|
|
|
|
if (Token.is(AsmToken::Identifier)) {
|
|
|
|
DEBUG(dbgs() << ".. identifier\n");
|
|
|
|
StringRef Identifier = Token.getIdentifier();
|
2014-04-01 18:37:46 +08:00
|
|
|
OperandMatchResultTy ResTy =
|
|
|
|
MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
|
|
|
|
return ResTy;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
} else if (Token.is(AsmToken::Integer)) {
|
|
|
|
DEBUG(dbgs() << ".. integer\n");
|
|
|
|
Operands.push_back(MipsOperand::CreateNumericReg(
|
|
|
|
Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
|
|
|
|
*this));
|
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
2013-08-14 09:02:20 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
|
2013-08-14 09:02:20 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
return MatchOperand_NoMatch;
|
2014-04-01 02:51:43 +08:00
|
|
|
}
|
2013-08-14 09:02:20 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
|
2014-04-01 02:51:43 +08:00
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << "ParseAnyRegister\n");
|
2013-08-14 09:02:20 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
auto Token = Parser.getTok();
|
2014-04-01 02:51:43 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
SMLoc S = Token.getLoc();
|
2014-04-01 02:51:43 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
if (Token.isNot(AsmToken::Dollar)) {
|
|
|
|
DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
|
|
|
|
if (Token.is(AsmToken::Identifier)) {
|
|
|
|
if (searchSymbolAlias(Operands))
|
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
|
2014-04-01 02:51:43 +08:00
|
|
|
return MatchOperand_NoMatch;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
}
|
|
|
|
DEBUG(dbgs() << ".. $\n");
|
2014-04-01 02:51:43 +08:00
|
|
|
|
2014-04-01 20:35:23 +08:00
|
|
|
OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
|
2014-04-01 18:40:14 +08:00
|
|
|
if (ResTy == MatchOperand_Success) {
|
|
|
|
Parser.Lex(); // $
|
|
|
|
Parser.Lex(); // identifier
|
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
return ResTy;
|
2013-08-14 09:02:20 +08:00
|
|
|
}
|
|
|
|
|
2014-04-01 02:51:43 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
|
|
|
switch (getLexer().getKind()) {
|
|
|
|
default:
|
2014-04-01 02:51:43 +08:00
|
|
|
return MatchOperand_NoMatch;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
case AsmToken::LParen:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Plus:
|
|
|
|
case AsmToken::Integer:
|
|
|
|
case AsmToken::String:
|
|
|
|
break;
|
|
|
|
}
|
2013-09-16 18:29:42 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
const MCExpr *IdVal;
|
2014-04-01 02:51:43 +08:00
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
if (getParser().parseExpression(IdVal))
|
|
|
|
return MatchOperand_ParseFail;
|
2013-04-18 08:41:53 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
|
|
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205229
2014-04-01 01:43:46 +08:00
|
|
|
return MatchOperand_Success;
|
2014-04-01 02:51:43 +08:00
|
|
|
}
|
2013-01-12 09:03:14 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
|
|
|
DEBUG(dbgs() << "ParseJumpTarget\n");
|
2014-04-01 02:51:43 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
SMLoc S = getLexer().getLoc();
|
2014-04-01 02:51:43 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
// Integers and expressions are acceptable
|
|
|
|
OperandMatchResultTy ResTy = ParseImm(Operands);
|
|
|
|
if (ResTy != MatchOperand_NoMatch)
|
|
|
|
return ResTy;
|
2014-04-01 02:51:43 +08:00
|
|
|
|
2014-04-01 18:40:14 +08:00
|
|
|
// Registers are a valid target and have priority over symbols.
|
|
|
|
ResTy = ParseAnyRegister(Operands);
|
|
|
|
if (ResTy != MatchOperand_NoMatch)
|
|
|
|
return ResTy;
|
|
|
|
|
2014-04-01 18:41:48 +08:00
|
|
|
const MCExpr *Expr = nullptr;
|
|
|
|
if (Parser.parseExpression(Expr)) {
|
|
|
|
// We have no way of knowing if a symbol was consumed so we must ParseFail
|
|
|
|
return MatchOperand_ParseFail;
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
}
|
2014-04-01 18:41:48 +08:00
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
return MatchOperand_Success;
|
2013-01-12 09:03:14 +08:00
|
|
|
}
|
|
|
|
|
2013-10-01 17:48:56 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2013-11-06 19:27:05 +08:00
|
|
|
MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
2013-10-01 17:48:56 +08:00
|
|
|
const MCExpr *IdVal;
|
|
|
|
// If the first token is '$' we may have register operand.
|
|
|
|
if (Parser.getTok().is(AsmToken::Dollar))
|
|
|
|
return MatchOperand_NoMatch;
|
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
|
|
|
if (getParser().parseExpression(IdVal))
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
|
2013-11-06 19:27:05 +08:00
|
|
|
assert(MCE && "Unexpected MCExpr type.");
|
2013-10-01 17:48:56 +08:00
|
|
|
int64_t Val = MCE->getValue();
|
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
|
|
Operands.push_back(MipsOperand::CreateImm(
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
|
2013-10-01 17:48:56 +08:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
2013-11-18 20:32:49 +08:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
2013-11-18 20:32:49 +08:00
|
|
|
switch (getLexer().getKind()) {
|
|
|
|
default:
|
|
|
|
return MatchOperand_NoMatch;
|
|
|
|
case AsmToken::LParen:
|
|
|
|
case AsmToken::Plus:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Integer:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
const MCExpr *Expr;
|
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
|
|
|
|
|
|
|
if (getParser().parseExpression(Expr))
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
|
|
|
|
int64_t Val;
|
|
|
|
if (!Expr->EvaluateAsAbsolute(Val)) {
|
|
|
|
Error(S, "expected immediate value");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The LSA instruction allows a 2-bit unsigned immediate. For this reason
|
|
|
|
// and because the CPU always adds one to the immediate field, the allowed
|
|
|
|
// range becomes 1..4. We'll only check the range here and will deal
|
|
|
|
// with the addition/subtraction when actually decoding/encoding
|
|
|
|
// the instruction.
|
|
|
|
if (Val < 1 || Val > 4) {
|
|
|
|
Error(S, "immediate not in range (1..4)");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
2014-01-23 07:31:38 +08:00
|
|
|
Operands.push_back(
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
|
2013-11-18 20:32:49 +08:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
MCSymbolRefExpr::VariantKind VK =
|
|
|
|
StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
|
|
|
|
.Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
|
|
|
|
.Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
|
|
|
|
.Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
|
|
|
|
.Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
|
|
|
|
.Case("got", MCSymbolRefExpr::VK_Mips_GOT)
|
|
|
|
.Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
|
|
|
|
.Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
|
|
|
|
.Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
|
|
|
|
.Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
|
|
|
|
.Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
|
|
|
|
.Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
|
|
|
|
.Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
|
|
|
|
.Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
|
|
|
|
.Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
|
|
|
|
.Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
|
|
|
|
.Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
|
|
|
|
.Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
|
2014-03-31 23:15:02 +08:00
|
|
|
.Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
|
|
|
|
.Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
|
|
|
|
.Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
|
|
|
|
.Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
|
|
|
|
.Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
|
|
|
|
.Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
|
2013-11-06 19:27:05 +08:00
|
|
|
.Default(MCSymbolRefExpr::VK_None);
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
|
2014-03-31 23:15:02 +08:00
|
|
|
assert (VK != MCSymbolRefExpr::VK_None);
|
|
|
|
|
The Mips standalone assembler memory instruction support.
This includes sb,sc,sh,sw,lb,lw,lbu,lh,lhu,ll,lw
Test case included
Contributer: Vladimir Medic
llvm-svn: 163346
2012-09-07 04:00:02 +08:00
|
|
|
return VK;
|
|
|
|
}
|
2012-09-07 08:23:42 +08:00
|
|
|
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
/// Sometimes (i.e. load/stores) the operand may be followed immediately by
|
|
|
|
/// either this.
|
|
|
|
/// ::= '(', register, ')'
|
|
|
|
/// handle it before we iterate so we don't get tripped up by the lack of
|
|
|
|
/// a comma.
|
|
|
|
bool MipsAsmParser::ParseParenSuffix(
|
|
|
|
StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
|
|
|
if (getLexer().is(AsmToken::LParen)) {
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
|
|
|
|
Parser.Lex();
|
|
|
|
if (ParseOperand(Operands, Name)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
|
|
|
if (Parser.getTok().isNot(AsmToken::RParen)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, "unexpected token, expected ')'");
|
|
|
|
}
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
|
|
|
|
Parser.Lex();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sometimes (i.e. in MSA) the operand may be followed immediately by
|
|
|
|
/// either one of these.
|
|
|
|
/// ::= '[', register, ']'
|
|
|
|
/// ::= '[', integer, ']'
|
|
|
|
/// handle it before we iterate so we don't get tripped up by the lack of
|
|
|
|
/// a comma.
|
|
|
|
bool MipsAsmParser::ParseBracketSuffix(
|
|
|
|
StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
|
|
|
if (getLexer().is(AsmToken::LBrac)) {
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
|
|
|
|
Parser.Lex();
|
|
|
|
if (ParseOperand(Operands, Name)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
|
|
|
if (Parser.getTok().isNot(AsmToken::RBrac)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, "unexpected token, expected ']'");
|
|
|
|
}
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
|
|
|
|
Parser.Lex();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
bool MipsAsmParser::ParseInstruction(
|
|
|
|
ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
|
|
|
SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
DEBUG(dbgs() << "ParseInstruction\n");
|
2013-07-17 23:00:42 +08:00
|
|
|
// Check if we have valid mnemonic
|
2013-07-24 15:33:14 +08:00
|
|
|
if (!mnemonicIsValid(Name, 0)) {
|
2013-07-17 23:00:42 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(NameLoc, "Unknown instruction");
|
|
|
|
}
|
2013-07-16 18:07:14 +08:00
|
|
|
// First operand in MCInst is instruction mnemonic.
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
|
2012-09-06 07:34:03 +08:00
|
|
|
|
|
|
|
// Read the remaining operands.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
// Read the first operand.
|
2013-07-16 18:07:14 +08:00
|
|
|
if (ParseOperand(Operands, Name)) {
|
2012-09-06 07:34:03 +08:00
|
|
|
SMLoc Loc = getLexer().getLoc();
|
2013-02-21 06:21:35 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-06 07:34:03 +08:00
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
|
|
|
|
return true;
|
|
|
|
// AFAIK, parenthesis suffixes are never on the first operand
|
2012-09-06 07:34:03 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
while (getLexer().is(AsmToken::Comma)) {
|
|
|
|
Parser.Lex(); // Eat the comma.
|
2012-09-06 07:34:03 +08:00
|
|
|
// Parse and remember the operand.
|
|
|
|
if (ParseOperand(Operands, Name)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
2013-02-21 06:21:35 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-06 07:34:03 +08:00
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
[mips] Rewrite MipsAsmParser and MipsOperand.
Summary:
Highlights:
- Registers are resolved much later (by the render method).
Prior to that point, GPR32's/GPR64's are GPR's regardless of register
size. Similarly FGR32's/FGR64's/AFGR64's are FGR's regardless of register
size or FR mode. Numeric registers can be anything.
- All registers are parsed the same way everywhere (even when handling
symbol aliasing)
- One consequence is that all registers can be specified numerically
almost anywhere (e.g. $fccX, $wX). The exception is symbol aliasing
but that can be easily resolved.
- Removes the need for the hasConsumedDollar hack
- Parenthesis and Bracket suffixes are handled generically
- Micromips instructions are parsed directly instead of going through the
standard encodings first.
- rdhwr accepts all 32 registers, and the following instructions that previously
xfailed now work:
ddiv, ddivu, div, divu, cvt.l.[ds], se[bh], wsbh, floor.w.[ds], c.ngl.d,
c.sf.s, dsbh, dshd, madd.s, msub.s, nmadd.s, nmsub.s, swxc1
- Diagnostics involving registers point at the correct character (the $)
- There's only one kind of immediate in MipsOperand. LSA immediates are handled
by the predicate and renderer.
Lowlights:
- Hardcoded '$zero' in the div patterns is handled with a hack.
MipsOperand::isReg() will return true for a k_RegisterIndex token
with Index == 0 and getReg() will return ZERO for this case. Note that it
doesn't return ZERO_64 on isGP64() targets.
- I haven't cleaned up all of the now-unused functions.
Some more of the generic parser could be removed too (integers and relocs
for example).
- insve.df needed a custom decoder to handle the implicit fourth operand that
was needed to make it parse correctly. The difficulty was that the matcher
expected a Token<'0'> but gets an Imm<0>. Adding an implicit zero solved this.
Reviewers: matheusalmeida, vmedic
Reviewed By: matheusalmeida
Differential Revision: http://llvm-reviews.chandlerc.com/D3222
llvm-svn: 205292
2014-04-01 18:35:28 +08:00
|
|
|
// Parse bracket and parenthesis suffixes before we iterate
|
|
|
|
if (getLexer().is(AsmToken::LBrac)) {
|
|
|
|
if (ParseBracketSuffix(Name, Operands))
|
|
|
|
return true;
|
|
|
|
} else if (getLexer().is(AsmToken::LParen) &&
|
|
|
|
ParseParenSuffix(Name, Operands))
|
|
|
|
return true;
|
2012-09-06 07:34:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
2013-02-21 06:21:35 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-06 07:34:03 +08:00
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-09-06 07:34:03 +08:00
|
|
|
return false;
|
2012-01-11 11:56:41 +08:00
|
|
|
}
|
|
|
|
|
2012-10-04 10:29:46 +08:00
|
|
|
bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
|
2013-04-18 08:41:53 +08:00
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, ErrorMsg);
|
2012-10-04 10:29:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetNoAtDirective() {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Line should look like: ".set noat".
|
|
|
|
// set at reg to 0.
|
2012-10-06 07:55:28 +08:00
|
|
|
Options.setATReg(0);
|
2012-10-04 10:29:46 +08:00
|
|
|
// eat noat
|
|
|
|
Parser.Lex();
|
2013-04-18 08:41:53 +08:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 10:29:46 +08:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
|
2012-10-04 10:29:46 +08:00
|
|
|
bool MipsAsmParser::parseSetAtDirective() {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Line can be .set at - defaults to $1
|
2012-10-04 10:29:46 +08:00
|
|
|
// or .set at=$reg
|
2013-02-21 07:11:17 +08:00
|
|
|
int AtRegNo;
|
2012-10-04 10:29:46 +08:00
|
|
|
getParser().Lex();
|
|
|
|
if (getLexer().is(AsmToken::EndOfStatement)) {
|
2012-10-06 07:55:28 +08:00
|
|
|
Options.setATReg(1);
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
|
|
|
} else if (getLexer().is(AsmToken::Equal)) {
|
2013-04-18 08:41:53 +08:00
|
|
|
getParser().Lex(); // Eat the '='.
|
2012-10-04 10:29:46 +08:00
|
|
|
if (getLexer().isNot(AsmToken::Dollar)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Eat the '$'.
|
2013-02-21 07:11:17 +08:00
|
|
|
const AsmToken &Reg = Parser.getTok();
|
|
|
|
if (Reg.is(AsmToken::Identifier)) {
|
|
|
|
AtRegNo = matchCPURegisterName(Reg.getIdentifier());
|
|
|
|
} else if (Reg.is(AsmToken::Integer)) {
|
|
|
|
AtRegNo = Reg.getIntVal();
|
|
|
|
} else {
|
2012-10-04 10:29:46 +08:00
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
2013-02-21 07:11:17 +08:00
|
|
|
|
2014-03-25 21:01:06 +08:00
|
|
|
if (AtRegNo < 0 || AtRegNo > 31) {
|
2013-02-21 07:11:17 +08:00
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Options.setATReg(AtRegNo)) {
|
2012-10-04 10:29:46 +08:00
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
getParser().Lex(); // Eat the register.
|
2012-10-04 10:29:46 +08:00
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
2013-04-18 08:41:53 +08:00
|
|
|
}
|
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetReorderDirective() {
|
|
|
|
Parser.Lex();
|
2013-04-18 08:41:53 +08:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 10:29:46 +08:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
2012-10-06 07:55:28 +08:00
|
|
|
Options.setReorder();
|
2014-03-10 21:21:10 +08:00
|
|
|
getTargetStreamer().emitDirectiveSetReorder();
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetNoReorderDirective() {
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex();
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
2013-04-18 08:41:53 +08:00
|
|
|
}
|
|
|
|
Options.setNoreorder();
|
2014-01-26 14:57:13 +08:00
|
|
|
getTargetStreamer().emitDirectiveSetNoReorder();
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
|
|
|
return false;
|
2012-10-04 10:29:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetMacroDirective() {
|
|
|
|
Parser.Lex();
|
2013-04-18 08:41:53 +08:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 10:29:46 +08:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
2012-10-06 07:55:28 +08:00
|
|
|
Options.setMacro();
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetNoMacroDirective() {
|
|
|
|
Parser.Lex();
|
2013-04-18 08:41:53 +08:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 10:29:46 +08:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("`noreorder' must be set before `nomacro'");
|
|
|
|
return false;
|
|
|
|
}
|
2012-10-06 07:55:28 +08:00
|
|
|
if (Options.isReorder()) {
|
2012-10-04 10:29:46 +08:00
|
|
|
reportParseError("`noreorder' must be set before `nomacro'");
|
|
|
|
return false;
|
|
|
|
}
|
2012-10-06 07:55:28 +08:00
|
|
|
Options.setNomacro();
|
2013-04-18 08:41:53 +08:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 10:29:46 +08:00
|
|
|
return false;
|
|
|
|
}
|
2013-03-22 05:44:16 +08:00
|
|
|
|
2014-01-23 07:08:42 +08:00
|
|
|
bool MipsAsmParser::parseSetNoMips16Directive() {
|
|
|
|
Parser.Lex();
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// For now do nothing.
|
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-03-22 05:44:16 +08:00
|
|
|
bool MipsAsmParser::parseSetAssignment() {
|
|
|
|
StringRef Name;
|
|
|
|
const MCExpr *Value;
|
|
|
|
|
|
|
|
if (Parser.parseIdentifier(Name))
|
|
|
|
reportParseError("expected identifier after .set");
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::Comma))
|
|
|
|
return reportParseError("unexpected token in .set directive");
|
2013-04-17 08:18:04 +08:00
|
|
|
Lex(); // Eat comma
|
2013-03-22 05:44:16 +08:00
|
|
|
|
2014-01-23 07:31:38 +08:00
|
|
|
if (Parser.parseExpression(Value))
|
2013-05-29 06:21:05 +08:00
|
|
|
return reportParseError("expected valid expression after comma");
|
2013-03-22 05:44:16 +08:00
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
// Check if the Name already exists as a symbol.
|
2013-03-22 05:44:16 +08:00
|
|
|
MCSymbol *Sym = getContext().LookupSymbol(Name);
|
2013-04-18 08:41:53 +08:00
|
|
|
if (Sym)
|
2013-03-22 05:44:16 +08:00
|
|
|
return reportParseError("symbol already defined");
|
|
|
|
Sym = getContext().GetOrCreateSymbol(Name);
|
|
|
|
Sym->setVariableValue(Value);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 08:41:53 +08:00
|
|
|
|
2014-03-26 22:26:27 +08:00
|
|
|
bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
|
|
|
|
Parser.Lex();
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
|
|
|
return reportParseError("unexpected token in .set directive");
|
|
|
|
|
|
|
|
switch(Feature) {
|
|
|
|
default: llvm_unreachable("Unimplemented feature");
|
|
|
|
case Mips::FeatureDSP:
|
|
|
|
setFeatureBits(Mips::FeatureDSP, "dsp");
|
|
|
|
getTargetStreamer().emitDirectiveSetDsp();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMicroMips:
|
|
|
|
getTargetStreamer().emitDirectiveSetMicroMips();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips16:
|
|
|
|
getTargetStreamer().emitDirectiveSetMips16();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips32r2:
|
|
|
|
setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips32R2();
|
|
|
|
break;
|
2014-03-26 23:14:32 +08:00
|
|
|
case Mips::FeatureMips64:
|
|
|
|
setFeatureBits(Mips::FeatureMips64, "mips64");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips64();
|
|
|
|
break;
|
2014-03-26 22:52:22 +08:00
|
|
|
case Mips::FeatureMips64r2:
|
|
|
|
setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips64R2();
|
|
|
|
break;
|
2014-03-26 22:26:27 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-27 21:52:53 +08:00
|
|
|
bool MipsAsmParser::parseRegister(unsigned &RegNum) {
|
|
|
|
if (!getLexer().is(AsmToken::Dollar))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Parser.Lex();
|
|
|
|
|
|
|
|
const AsmToken &Reg = Parser.getTok();
|
|
|
|
if (Reg.is(AsmToken::Identifier)) {
|
|
|
|
RegNum = matchCPURegisterName(Reg.getIdentifier());
|
|
|
|
} else if (Reg.is(AsmToken::Integer)) {
|
|
|
|
RegNum = Reg.getIntVal();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Parser.Lex();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::eatComma(StringRef ErrorStr) {
|
|
|
|
if (getLexer().isNot(AsmToken::Comma)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, ErrorStr);
|
|
|
|
}
|
|
|
|
|
|
|
|
Parser.Lex(); // Eat the comma.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseDirectiveCPSetup() {
|
|
|
|
unsigned FuncReg;
|
|
|
|
unsigned Save;
|
|
|
|
bool SaveIsReg = true;
|
|
|
|
|
|
|
|
if (!parseRegister(FuncReg))
|
|
|
|
return reportParseError("expected register containing function address");
|
|
|
|
FuncReg = getGPR(FuncReg);
|
|
|
|
|
|
|
|
if (!eatComma("expected comma parsing directive"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!parseRegister(Save)) {
|
|
|
|
const AsmToken &Tok = Parser.getTok();
|
|
|
|
if (Tok.is(AsmToken::Integer)) {
|
|
|
|
Save = Tok.getIntVal();
|
|
|
|
SaveIsReg = false;
|
|
|
|
Parser.Lex();
|
|
|
|
} else
|
|
|
|
return reportParseError("expected save register or stack offset");
|
|
|
|
} else
|
|
|
|
Save = getGPR(Save);
|
|
|
|
|
|
|
|
if (!eatComma("expected comma parsing directive"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
StringRef Name;
|
|
|
|
if (Parser.parseIdentifier(Name))
|
|
|
|
reportParseError("expected identifier");
|
|
|
|
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
|
|
|
|
unsigned GPReg = getGPR(matchCPURegisterName("gp"));
|
|
|
|
|
|
|
|
// FIXME: The code below this point should be in the TargetStreamers.
|
|
|
|
// Only N32 and N64 emit anything for .cpsetup
|
|
|
|
// FIXME: We should only emit something for PIC mode too.
|
|
|
|
if (!isN32() && !isN64())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
MCStreamer &TS = getStreamer();
|
|
|
|
MCInst Inst;
|
|
|
|
// Either store the old $gp in a register or on the stack
|
|
|
|
if (SaveIsReg) {
|
|
|
|
// move $save, $gpreg
|
|
|
|
Inst.setOpcode(Mips::DADDu);
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(Save));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPR(0)));
|
|
|
|
} else {
|
|
|
|
// sd $gpreg, offset($sp)
|
|
|
|
Inst.setOpcode(Mips::SD);
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPR(matchCPURegisterName("sp"))));
|
|
|
|
Inst.addOperand(MCOperand::CreateImm(Save));
|
|
|
|
}
|
|
|
|
TS.EmitInstruction(Inst, STI);
|
|
|
|
Inst.clear();
|
|
|
|
|
|
|
|
const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
|
|
|
|
Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_HI,
|
|
|
|
getContext());
|
|
|
|
const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
|
|
|
|
Sym->getName(), MCSymbolRefExpr::VK_Mips_GPOFF_LO,
|
|
|
|
getContext());
|
|
|
|
// lui $gp, %hi(%neg(%gp_rel(funcSym)))
|
|
|
|
Inst.setOpcode(Mips::LUi);
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateExpr(HiExpr));
|
|
|
|
TS.EmitInstruction(Inst, STI);
|
|
|
|
Inst.clear();
|
|
|
|
|
|
|
|
// addiu $gp, $gp, %lo(%neg(%gp_rel(funcSym)))
|
|
|
|
Inst.setOpcode(Mips::ADDiu);
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateExpr(LoExpr));
|
|
|
|
TS.EmitInstruction(Inst, STI);
|
|
|
|
Inst.clear();
|
|
|
|
|
|
|
|
// daddu $gp, $gp, $funcreg
|
|
|
|
Inst.setOpcode(Mips::DADDu);
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(GPReg));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(FuncReg));
|
|
|
|
TS.EmitInstruction(Inst, STI);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-10-04 10:29:46 +08:00
|
|
|
bool MipsAsmParser::parseDirectiveSet() {
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
// Get the next token.
|
2012-10-04 10:29:46 +08:00
|
|
|
const AsmToken &Tok = Parser.getTok();
|
|
|
|
|
|
|
|
if (Tok.getString() == "noat") {
|
|
|
|
return parseSetNoAtDirective();
|
|
|
|
} else if (Tok.getString() == "at") {
|
|
|
|
return parseSetAtDirective();
|
|
|
|
} else if (Tok.getString() == "reorder") {
|
|
|
|
return parseSetReorderDirective();
|
|
|
|
} else if (Tok.getString() == "noreorder") {
|
|
|
|
return parseSetNoReorderDirective();
|
|
|
|
} else if (Tok.getString() == "macro") {
|
|
|
|
return parseSetMacroDirective();
|
|
|
|
} else if (Tok.getString() == "nomacro") {
|
|
|
|
return parseSetNoMacroDirective();
|
2014-01-23 07:08:42 +08:00
|
|
|
} else if (Tok.getString() == "mips16") {
|
2014-03-26 22:26:27 +08:00
|
|
|
return parseSetFeature(Mips::FeatureMips16);
|
2012-10-04 10:29:46 +08:00
|
|
|
} else if (Tok.getString() == "nomips16") {
|
2014-01-23 07:08:42 +08:00
|
|
|
return parseSetNoMips16Directive();
|
2012-10-04 10:29:46 +08:00
|
|
|
} else if (Tok.getString() == "nomicromips") {
|
2014-01-14 12:25:13 +08:00
|
|
|
getTargetStreamer().emitDirectiveSetNoMicroMips();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
} else if (Tok.getString() == "micromips") {
|
2014-03-26 22:26:27 +08:00
|
|
|
return parseSetFeature(Mips::FeatureMicroMips);
|
2014-03-04 17:54:09 +08:00
|
|
|
} else if (Tok.getString() == "mips32r2") {
|
2014-03-26 22:26:27 +08:00
|
|
|
return parseSetFeature(Mips::FeatureMips32r2);
|
2014-03-26 23:14:32 +08:00
|
|
|
} else if (Tok.getString() == "mips64") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips64);
|
2014-03-26 22:52:22 +08:00
|
|
|
} else if (Tok.getString() == "mips64r2") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips64r2);
|
2014-03-05 19:05:09 +08:00
|
|
|
} else if (Tok.getString() == "dsp") {
|
2014-03-26 22:26:27 +08:00
|
|
|
return parseSetFeature(Mips::FeatureDSP);
|
2013-03-22 05:44:16 +08:00
|
|
|
} else {
|
2013-04-18 08:41:53 +08:00
|
|
|
// It is just an identifier, look for an assignment.
|
2013-03-22 05:44:16 +08:00
|
|
|
parseSetAssignment();
|
|
|
|
return false;
|
2012-10-04 10:29:46 +08:00
|
|
|
}
|
2013-01-25 09:31:34 +08:00
|
|
|
|
2012-10-04 10:29:46 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-26 23:24:36 +08:00
|
|
|
/// parseDataDirective
|
2013-01-25 09:31:34 +08:00
|
|
|
/// ::= .word [ expression (, expression)* ]
|
2014-03-26 23:24:36 +08:00
|
|
|
bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
|
2013-01-25 09:31:34 +08:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
for (;;) {
|
|
|
|
const MCExpr *Value;
|
2013-02-21 06:21:35 +08:00
|
|
|
if (getParser().parseExpression(Value))
|
2013-01-25 09:31:34 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
getParser().getStreamer().EmitValue(Value, Size);
|
|
|
|
|
|
|
|
if (getLexer().is(AsmToken::EndOfStatement))
|
|
|
|
break;
|
|
|
|
|
|
|
|
// FIXME: Improve diagnostic.
|
|
|
|
if (getLexer().isNot(AsmToken::Comma))
|
|
|
|
return Error(L, "unexpected token in directive");
|
|
|
|
Parser.Lex();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Parser.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-06 19:27:05 +08:00
|
|
|
/// parseDirectiveGpWord
|
|
|
|
/// ::= .gpword local_sym
|
|
|
|
bool MipsAsmParser::parseDirectiveGpWord() {
|
|
|
|
const MCExpr *Value;
|
|
|
|
// EmitGPRel32Value requires an expression, so we are using base class
|
|
|
|
// method to evaluate the expression.
|
|
|
|
if (getParser().parseExpression(Value))
|
|
|
|
return true;
|
|
|
|
getParser().getStreamer().EmitGPRel32Value(Value);
|
|
|
|
|
2013-11-13 21:18:04 +08:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
2013-11-06 19:27:05 +08:00
|
|
|
return Error(getLexer().getLoc(), "unexpected token in directive");
|
2013-11-13 21:18:04 +08:00
|
|
|
Parser.Lex(); // Eat EndOfStatement token.
|
2013-11-06 19:27:05 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-31 22:15:07 +08:00
|
|
|
/// parseDirectiveGpDWord
|
2014-03-29 02:50:26 +08:00
|
|
|
/// ::= .gpdword local_sym
|
2014-03-31 22:15:07 +08:00
|
|
|
bool MipsAsmParser::parseDirectiveGpDWord() {
|
2014-03-29 02:50:26 +08:00
|
|
|
const MCExpr *Value;
|
|
|
|
// EmitGPRel64Value requires an expression, so we are using base class
|
|
|
|
// method to evaluate the expression.
|
|
|
|
if (getParser().parseExpression(Value))
|
|
|
|
return true;
|
|
|
|
getParser().getStreamer().EmitGPRel64Value(Value);
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
|
|
|
return Error(getLexer().getLoc(), "unexpected token in directive");
|
|
|
|
Parser.Lex(); // Eat EndOfStatement token.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-07 07:27:31 +08:00
|
|
|
bool MipsAsmParser::parseDirectiveOption() {
|
|
|
|
// Get the option token.
|
|
|
|
AsmToken Tok = Parser.getTok();
|
|
|
|
// At the moment only identifiers are supported.
|
|
|
|
if (Tok.isNot(AsmToken::Identifier)) {
|
|
|
|
Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef Option = Tok.getIdentifier();
|
|
|
|
|
|
|
|
if (Option == "pic0") {
|
|
|
|
getTargetStreamer().emitDirectiveOptionPic0();
|
|
|
|
Parser.Lex();
|
|
|
|
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
Error(Parser.getTok().getLoc(),
|
|
|
|
"unexpected token in .option pic0 directive");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-26 21:40:29 +08:00
|
|
|
if (Option == "pic2") {
|
|
|
|
getTargetStreamer().emitDirectiveOptionPic2();
|
|
|
|
Parser.Lex();
|
|
|
|
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
Error(Parser.getTok().getLoc(),
|
|
|
|
"unexpected token in .option pic2 directive");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-07 07:27:31 +08:00
|
|
|
// Unknown option.
|
|
|
|
Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-10-04 10:29:46 +08:00
|
|
|
bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
|
2013-01-25 09:31:34 +08:00
|
|
|
StringRef IDVal = DirectiveID.getString();
|
|
|
|
|
2014-03-26 23:44:18 +08:00
|
|
|
if (IDVal == ".dword") {
|
|
|
|
parseDataDirective(8, DirectiveID.getLoc());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-04-18 08:41:53 +08:00
|
|
|
if (IDVal == ".ent") {
|
|
|
|
// Ignore this directive for now.
|
2012-09-07 08:48:02 +08:00
|
|
|
Parser.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".end") {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Ignore this directive for now.
|
2012-09-07 08:48:02 +08:00
|
|
|
Parser.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".frame") {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Ignore this directive for now.
|
2013-02-21 06:21:35 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-07 08:48:02 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".set") {
|
2012-10-04 10:29:46 +08:00
|
|
|
return parseDirectiveSet();
|
2012-09-07 08:48:02 +08:00
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".fmask") {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Ignore this directive for now.
|
2013-02-21 06:21:35 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-07 08:48:02 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".mask") {
|
2013-04-18 08:41:53 +08:00
|
|
|
// Ignore this directive for now.
|
2013-02-21 06:21:35 +08:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-07 08:48:02 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".gpword") {
|
2013-11-06 19:27:05 +08:00
|
|
|
parseDirectiveGpWord();
|
2012-09-07 08:48:02 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-29 02:50:26 +08:00
|
|
|
if (IDVal == ".gpdword") {
|
2014-03-31 22:15:07 +08:00
|
|
|
parseDirectiveGpDWord();
|
2014-03-29 02:50:26 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 09:31:34 +08:00
|
|
|
if (IDVal == ".word") {
|
2014-03-26 23:24:36 +08:00
|
|
|
parseDataDirective(4, DirectiveID.getLoc());
|
2013-01-25 09:31:34 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-07 07:27:31 +08:00
|
|
|
if (IDVal == ".option")
|
|
|
|
return parseDirectiveOption();
|
|
|
|
|
|
|
|
if (IDVal == ".abicalls") {
|
|
|
|
getTargetStreamer().emitDirectiveAbiCalls();
|
|
|
|
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
Error(Parser.getTok().getLoc(), "unexpected token in directive");
|
|
|
|
// Clear line
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-27 21:52:53 +08:00
|
|
|
if (IDVal == ".cpsetup")
|
|
|
|
return parseDirectiveCPSetup();
|
|
|
|
|
2012-01-11 11:56:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void LLVMInitializeMipsAsmParser() {
|
|
|
|
RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
|
|
|
|
RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
|
|
|
|
RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
|
|
|
|
RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
|
|
|
|
}
|
2012-09-06 07:34:03 +08:00
|
|
|
|
|
|
|
#define GET_REGISTER_MATCHER
|
|
|
|
#define GET_MATCHER_IMPLEMENTATION
|
|
|
|
#include "MipsGenAsmMatcher.inc"
|