2012-02-17 08:55:11 +00:00
|
|
|
//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
|
2012-01-11 03:56:41 +00:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-02-04 18:41:57 +00:00
|
|
|
#include "MCTargetDesc/MipsMCExpr.h"
|
2012-01-11 03:56:41 +00:00
|
|
|
#include "MCTargetDesc/MipsMCTargetDesc.h"
|
2012-09-05 23:34:03 +00:00
|
|
|
#include "MipsRegisterInfo.h"
|
2013-10-08 13:08:17 +00:00
|
|
|
#include "MipsTargetStreamer.h"
|
2014-01-07 11:48:04 +00:00
|
|
|
#include "llvm/ADT/APInt.h"
|
2012-09-05 23:34:03 +00:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2014-09-09 10:15:38 +00:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2012-09-05 23:34:03 +00:00
|
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
#include "llvm/MC/MCExpr.h"
|
|
|
|
#include "llvm/MC/MCInst.h"
|
2014-03-24 14:05:39 +00:00
|
|
|
#include "llvm/MC/MCInstBuilder.h"
|
2012-12-03 16:50:05 +00:00
|
|
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
|
|
|
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
2012-09-05 23:34:03 +00:00
|
|
|
#include "llvm/MC/MCStreamer.h"
|
|
|
|
#include "llvm/MC/MCSubtargetInfo.h"
|
|
|
|
#include "llvm/MC/MCSymbol.h"
|
2012-08-17 20:16:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
#include "llvm/Support/Debug.h"
|
2013-12-13 11:11:02 +00:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2014-01-07 11:48:04 +00:00
|
|
|
#include "llvm/Support/TargetRegistry.h"
|
2014-10-03 15:37:37 +00:00
|
|
|
#include "llvm/Support/SourceMgr.h"
|
2014-09-09 10:15:38 +00:00
|
|
|
#include <memory>
|
2012-01-11 03:56:41 +00:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-21 22:55:11 +00:00
|
|
|
#define DEBUG_TYPE "mips-asm-parser"
|
|
|
|
|
2013-09-12 10:28:05 +00:00
|
|
|
namespace llvm {
|
|
|
|
class MCInstrInfo;
|
|
|
|
}
|
|
|
|
|
2012-01-11 03:56:41 +00:00
|
|
|
namespace {
|
2012-10-04 02:29:46 +00:00
|
|
|
class MipsAssemblerOptions {
|
|
|
|
public:
|
2014-09-09 10:15:38 +00:00
|
|
|
MipsAssemblerOptions(uint64_t Features_) :
|
|
|
|
ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
|
|
|
|
ATReg = Opts->getATRegNum();
|
|
|
|
Reorder = Opts->isReorder();
|
|
|
|
Macro = Opts->isMacro();
|
|
|
|
Features = Opts->getFeatures();
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getATRegNum() const { return ATReg; }
|
2012-10-04 02:29:46 +00:00
|
|
|
bool setATReg(unsigned Reg);
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
bool isReorder() const { return Reorder; }
|
2014-09-05 15:43:21 +00:00
|
|
|
void setReorder() { Reorder = true; }
|
|
|
|
void setNoReorder() { Reorder = false; }
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
bool isMacro() const { return Macro; }
|
2014-09-05 15:43:21 +00:00
|
|
|
void setMacro() { Macro = true; }
|
|
|
|
void setNoMacro() { Macro = false; }
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
uint64_t getFeatures() const { return Features; }
|
|
|
|
void setFeatures(uint64_t Features_) { Features = Features_; }
|
|
|
|
|
2014-08-04 12:20:00 +00:00
|
|
|
// Set of features that are either architecture features or referenced
|
|
|
|
// by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
|
|
|
|
// The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
|
|
|
|
// The reason we need this mask is explained in the selectArch function.
|
|
|
|
// FIXME: Ideally we would like TableGen to generate this information.
|
|
|
|
static const uint64_t AllArchRelatedMask =
|
|
|
|
Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
|
|
|
|
Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
|
|
|
|
Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
|
|
|
|
Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
|
|
|
|
Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
|
|
|
|
Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
|
|
|
|
Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
|
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
private:
|
2014-09-05 15:43:21 +00:00
|
|
|
unsigned ATReg;
|
|
|
|
bool Reorder;
|
|
|
|
bool Macro;
|
2014-09-09 10:15:38 +00:00
|
|
|
uint64_t Features;
|
2012-10-04 02:29:46 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
2012-01-11 03:56:41 +00:00
|
|
|
class MipsAsmParser : public MCTargetAsmParser {
|
2013-10-08 13:08:17 +00:00
|
|
|
MipsTargetStreamer &getTargetStreamer() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
|
2013-10-08 13:08:17 +00:00
|
|
|
return static_cast<MipsTargetStreamer &>(TS);
|
|
|
|
}
|
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
MCSubtargetInfo &STI;
|
2014-09-09 10:15:38 +00:00
|
|
|
SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
|
2014-08-13 10:07:34 +00:00
|
|
|
MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
|
|
|
|
// nullptr, which indicates that no function is currently
|
|
|
|
// selected. This usually happens after an '.end func'
|
|
|
|
// directive.
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2014-10-03 15:37:37 +00:00
|
|
|
// Print a warning along with its fix-it message at the given range.
|
|
|
|
void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
|
|
|
|
SMRange Range, bool ShowColors = true);
|
|
|
|
|
2012-08-17 20:16:42 +00:00
|
|
|
#define GET_ASSEMBLER_HEADER
|
|
|
|
#include "MipsGenAsmMatcher.inc"
|
|
|
|
|
2014-06-11 15:05:56 +00:00
|
|
|
unsigned checkTargetMatchPredicate(MCInst &Inst) override;
|
|
|
|
|
2012-10-13 00:26:04 +00:00
|
|
|
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
2014-06-08 16:18:35 +00:00
|
|
|
OperandVector &Operands, MCStreamer &Out,
|
2014-08-18 11:49:42 +00:00
|
|
|
uint64_t &ErrorInfo,
|
2014-04-29 07:58:02 +00:00
|
|
|
bool MatchingInlineAsm) override;
|
2012-01-11 03:56:41 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Parse a register as used in CFI directives
|
2014-04-29 07:58:02 +00:00
|
|
|
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
|
2012-01-11 03:56:41 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
bool parseParenSuffix(StringRef Name, OperandVector &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
bool parseBracketSuffix(StringRef Name, OperandVector &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
|
|
|
SMLoc NameLoc, OperandVector &Operands) override;
|
2012-01-11 03:56:41 +00:00
|
|
|
|
2014-04-29 07:58:02 +00:00
|
|
|
bool ParseDirective(AsmToken DirectiveID) override;
|
2012-01-11 03:56:41 +00:00
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
|
2013-09-25 23:50:44 +00:00
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
|
2014-06-08 16:18:35 +00:00
|
|
|
StringRef Identifier, SMLoc S);
|
2013-09-25 23:50:44 +00:00
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
|
2013-09-25 23:50:44 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
|
2013-09-25 23:50:44 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
|
2013-10-21 12:26:50 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
|
2013-10-01 09:48:56 +00:00
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
|
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
|
2013-11-18 12:32:49 +00:00
|
|
|
|
2014-12-16 14:59:10 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
|
|
|
parseRegisterPair (OperandVector &Operands);
|
|
|
|
|
2014-11-19 16:44:02 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
|
|
|
parseRegisterList (OperandVector &Operands);
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
bool searchSymbolAlias(OperandVector &Operands);
|
2013-03-21 21:44:16 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
bool parseOperand(OperandVector &, StringRef Mnemonic);
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
bool needsExpansion(MCInst &Inst);
|
|
|
|
|
2014-06-19 14:39:14 +00:00
|
|
|
// Expands assembly pseudo instructions.
|
|
|
|
// Returns false on success, true otherwise.
|
|
|
|
bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
|
2012-10-06 00:53:28 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2014-06-19 14:39:14 +00:00
|
|
|
|
|
|
|
bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
|
2012-10-06 00:53:28 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2014-06-19 14:39:14 +00:00
|
|
|
|
|
|
|
bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2014-06-19 14:39:14 +00:00
|
|
|
|
|
|
|
bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2014-06-19 14:39:14 +00:00
|
|
|
|
2014-08-14 10:29:17 +00:00
|
|
|
void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
void expandMemInst(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 11:27:05 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions, bool isLoad,
|
|
|
|
bool isImmOpnd);
|
2014-07-08 10:11:38 +00:00
|
|
|
bool reportParseError(Twine ErrorMsg);
|
|
|
|
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2013-04-17 00:18:04 +00:00
|
|
|
bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
|
2013-01-12 01:03:14 +00:00
|
|
|
bool parseRelocOperand(const MCExpr *&Res);
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2013-11-06 11:27:05 +00:00
|
|
|
const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
|
2013-04-17 00:18:04 +00:00
|
|
|
|
|
|
|
bool isEvaluated(const MCExpr *Expr);
|
2014-09-09 12:52:14 +00:00
|
|
|
bool parseSetMips0Directive();
|
2014-08-19 14:22:52 +00:00
|
|
|
bool parseSetArchDirective();
|
2014-03-26 14:26:27 +00:00
|
|
|
bool parseSetFeature(uint64_t Feature);
|
2014-10-01 14:53:19 +00:00
|
|
|
bool parseDirectiveCpLoad(SMLoc Loc);
|
2014-03-27 13:52:53 +00:00
|
|
|
bool parseDirectiveCPSetup();
|
2014-04-16 15:48:55 +00:00
|
|
|
bool parseDirectiveNaN();
|
2012-10-04 02:29:46 +00:00
|
|
|
bool parseDirectiveSet();
|
2014-01-06 23:27:31 +00:00
|
|
|
bool parseDirectiveOption();
|
2012-10-04 02:29:46 +00:00
|
|
|
|
|
|
|
bool parseSetAtDirective();
|
|
|
|
bool parseSetNoAtDirective();
|
|
|
|
bool parseSetMacroDirective();
|
|
|
|
bool parseSetNoMacroDirective();
|
2014-08-07 12:03:36 +00:00
|
|
|
bool parseSetMsaDirective();
|
|
|
|
bool parseSetNoMsaDirective();
|
2014-09-17 09:01:54 +00:00
|
|
|
bool parseSetNoDspDirective();
|
2012-10-04 02:29:46 +00:00
|
|
|
bool parseSetReorderDirective();
|
|
|
|
bool parseSetNoReorderDirective();
|
2014-11-04 17:18:07 +00:00
|
|
|
bool parseSetMips16Directive();
|
2014-01-22 23:08:42 +00:00
|
|
|
bool parseSetNoMips16Directive();
|
2014-07-08 08:59:22 +00:00
|
|
|
bool parseSetFpDirective();
|
2014-09-09 10:15:38 +00:00
|
|
|
bool parseSetPopDirective();
|
|
|
|
bool parseSetPushDirective();
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2013-03-21 21:44:16 +00:00
|
|
|
bool parseSetAssignment();
|
|
|
|
|
2014-03-26 15:24:36 +00:00
|
|
|
bool parseDataDirective(unsigned Size, SMLoc L);
|
2013-11-06 11:27:05 +00:00
|
|
|
bool parseDirectiveGpWord();
|
2014-03-31 14:15:07 +00:00
|
|
|
bool parseDirectiveGpDWord();
|
2014-07-08 08:59:22 +00:00
|
|
|
bool parseDirectiveModule();
|
2014-07-08 10:11:38 +00:00
|
|
|
bool parseDirectiveModuleFP();
|
2014-07-10 13:38:23 +00:00
|
|
|
bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
|
|
|
|
StringRef Directive);
|
2013-01-25 01:31:34 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
|
2012-09-07 00:23:42 +00:00
|
|
|
|
2014-03-27 13:52:53 +00:00
|
|
|
bool eatComma(StringRef ErrorStr);
|
|
|
|
|
2013-02-20 23:11:17 +00:00
|
|
|
int matchCPURegisterName(StringRef Symbol);
|
|
|
|
|
2014-11-11 10:31:31 +00:00
|
|
|
int matchHWRegsRegisterName(StringRef Symbol);
|
|
|
|
|
2013-01-12 01:03:14 +00:00
|
|
|
int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2013-08-13 13:07:09 +00:00
|
|
|
int matchFPURegisterName(StringRef Name);
|
2013-06-20 11:21:49 +00:00
|
|
|
|
2013-08-13 13:07:09 +00:00
|
|
|
int matchFCCRegisterName(StringRef Name);
|
2012-09-07 00:23:42 +00:00
|
|
|
|
2013-08-13 13:07:09 +00:00
|
|
|
int matchACRegisterName(StringRef Name);
|
2012-09-07 00:23:42 +00:00
|
|
|
|
2013-09-25 23:50:44 +00:00
|
|
|
int matchMSA128RegisterName(StringRef Name);
|
|
|
|
|
2013-10-21 12:26:50 +00:00
|
|
|
int matchMSA128CtrlRegisterName(StringRef Name);
|
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
unsigned getReg(int RC, int RegNo);
|
2012-09-03 18:47:45 +00:00
|
|
|
|
2014-03-27 13:52:53 +00:00
|
|
|
unsigned getGPR(int RegNo);
|
|
|
|
|
2014-06-18 14:46:05 +00:00
|
|
|
int getATReg(SMLoc Loc);
|
2013-03-22 00:05:30 +00:00
|
|
|
|
|
|
|
bool processInstruction(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 11:27:05 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions);
|
2013-10-14 11:49:30 +00: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-08-04 12:20:00 +00:00
|
|
|
// Selects a new architecture by updating the FeatureBits with the necessary
|
|
|
|
// info including implied dependencies.
|
|
|
|
// Internally, it clears all the feature bits related to *any* architecture
|
|
|
|
// and selects the new one using the ToggleFeature functionality of the
|
|
|
|
// MCSubtargetInfo object that handles implied dependencies. The reason we
|
|
|
|
// clear all the arch related bits manually is because ToggleFeature only
|
|
|
|
// clears the features that imply the feature being cleared and not the
|
|
|
|
// features implied by the feature being cleared. This is easier to see
|
|
|
|
// with an example:
|
|
|
|
// --------------------------------------------------
|
|
|
|
// | Feature | Implies |
|
|
|
|
// | -------------------------------------------------|
|
|
|
|
// | FeatureMips1 | None |
|
|
|
|
// | FeatureMips2 | FeatureMips1 |
|
|
|
|
// | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
|
|
|
|
// | FeatureMips4 | FeatureMips3 |
|
|
|
|
// | ... | |
|
|
|
|
// --------------------------------------------------
|
|
|
|
//
|
|
|
|
// Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
|
|
|
|
// FeatureMipsGP64 | FeatureMips1)
|
|
|
|
// Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
|
|
|
|
void selectArch(StringRef ArchFeature) {
|
|
|
|
uint64_t FeatureBits = STI.getFeatureBits();
|
|
|
|
FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
|
|
|
|
STI.setFeatureBits(FeatureBits);
|
|
|
|
setAvailableFeatures(
|
|
|
|
ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setFeatures(getAvailableFeatures());
|
2014-08-04 12:20:00 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 16:32:09 +00:00
|
|
|
void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
|
2014-03-04 09:54:09 +00:00
|
|
|
if (!(STI.getFeatureBits() & Feature)) {
|
2014-04-22 10:15:54 +00:00
|
|
|
setAvailableFeatures(
|
|
|
|
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
|
2014-03-04 09:54:09 +00:00
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setFeatures(getAvailableFeatures());
|
2014-03-04 09:54:09 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 16:32:09 +00:00
|
|
|
void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
|
2014-03-04 09:54:09 +00:00
|
|
|
if (STI.getFeatureBits() & Feature) {
|
2014-04-22 10:15:54 +00:00
|
|
|
setAvailableFeatures(
|
|
|
|
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
|
2014-03-04 09:54:09 +00:00
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setFeatures(getAvailableFeatures());
|
2014-03-04 09:54:09 +00:00
|
|
|
}
|
|
|
|
|
2012-01-11 03:56:41 +00:00
|
|
|
public:
|
2014-06-11 15:05:56 +00:00
|
|
|
enum MipsMatchResultTy {
|
|
|
|
Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
|
|
|
|
#define GET_OPERAND_DIAGNOSTIC_TYPES
|
|
|
|
#include "MipsGenAsmMatcher.inc"
|
|
|
|
#undef GET_OPERAND_DIAGNOSTIC_TYPES
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2013-09-12 10:28:05 +00:00
|
|
|
MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
|
2014-07-08 08:59:22 +00:00
|
|
|
const MCInstrInfo &MII, const MCTargetOptions &Options)
|
2014-11-11 05:18:41 +00:00
|
|
|
: MCTargetAsmParser(), STI(sti) {
|
|
|
|
MCAsmParserExtension::Initialize(parser);
|
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
// Initialize the set of available features.
|
|
|
|
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
|
2014-09-09 10:15:38 +00:00
|
|
|
|
|
|
|
// Remember the initial assembler options. The user can not modify these.
|
2014-09-12 05:17:20 +00:00
|
|
|
AssemblerOptions.push_back(
|
|
|
|
make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
|
2014-09-09 10:15:38 +00:00
|
|
|
|
|
|
|
// Create an assembler options environment for the user to modify.
|
2014-09-12 05:17:20 +00:00
|
|
|
AssemblerOptions.push_back(
|
|
|
|
make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
|
2014-02-20 14:58:19 +00:00
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
getTargetStreamer().updateABIInfo(*this);
|
|
|
|
|
2014-02-20 14:58:19 +00: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);
|
2014-07-10 13:38:23 +00:00
|
|
|
|
2014-07-14 10:26:15 +00:00
|
|
|
if (!isABI_O32() && !useOddSPReg() != 0)
|
2014-07-10 13:38:23 +00:00
|
|
|
report_fatal_error("-mno-odd-spreg requires the O32 ABI");
|
2014-08-13 10:07:34 +00:00
|
|
|
|
|
|
|
CurrentFn = nullptr;
|
2012-01-11 03:56:41 +00:00
|
|
|
}
|
|
|
|
|
2014-06-12 15:00:17 +00:00
|
|
|
/// True if all of $fcc0 - $fcc7 exist for the current ISA.
|
|
|
|
bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
|
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
|
|
|
|
bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
|
|
|
|
bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
|
|
|
|
bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
|
|
|
|
bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
|
2014-07-15 15:31:39 +00:00
|
|
|
bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
|
2014-07-08 08:59:22 +00:00
|
|
|
|
2014-07-14 10:26:15 +00:00
|
|
|
bool useOddSPReg() const {
|
2014-07-10 13:38:23 +00:00
|
|
|
return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
|
|
|
|
}
|
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
bool inMicroMipsMode() const {
|
|
|
|
return STI.getFeatureBits() & Mips::FeatureMicroMips;
|
|
|
|
}
|
|
|
|
bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
|
|
|
|
bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
|
|
|
|
bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
|
|
|
|
bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
|
|
|
|
bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
|
|
|
|
bool hasMips32() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureMips32);
|
|
|
|
}
|
|
|
|
bool hasMips64() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureMips64);
|
|
|
|
}
|
|
|
|
bool hasMips32r2() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureMips32r2);
|
|
|
|
}
|
|
|
|
bool hasMips64r2() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureMips64r2);
|
|
|
|
}
|
|
|
|
bool hasMips32r6() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureMips32r6);
|
|
|
|
}
|
|
|
|
bool hasMips64r6() const {
|
|
|
|
return (STI.getFeatureBits() & Mips::FeatureMips64r6);
|
|
|
|
}
|
|
|
|
bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
|
|
|
|
bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
|
|
|
|
bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
|
|
|
|
|
|
|
|
bool inMips16Mode() const {
|
|
|
|
return STI.getFeatureBits() & Mips::FeatureMips16;
|
|
|
|
}
|
|
|
|
// TODO: see how can we get this info.
|
2014-07-18 00:08:50 +00:00
|
|
|
bool abiUsesSoftFloat() const { return false; }
|
2014-07-08 08:59:22 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Warn if RegNo is the current assembler temporary.
|
2014-09-04 13:23:44 +00:00
|
|
|
void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
|
2012-01-11 03:56:41 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-08-17 20:16:42 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// MipsOperand - Instances of this class represent a parsed Mips machine
|
|
|
|
/// instruction.
|
|
|
|
class MipsOperand : public MCParsedAsmOperand {
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Broad categories of register classes
|
|
|
|
/// The exact class is finalized by the render method.
|
|
|
|
enum RegKind {
|
2014-07-08 08:59:22 +00:00
|
|
|
RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
|
2014-07-08 08:59:22 +00:00
|
|
|
/// isFP64bit())
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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
|
2014-05-08 13:02:11 +00:00
|
|
|
RegKind_COP3 = 512, /// COP3
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
|
|
|
|
/// Potentially any (e.g. $1)
|
|
|
|
RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
|
|
|
|
RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
|
2014-05-08 13:02:11 +00:00
|
|
|
RegKind_CCR | RegKind_HWRegs | RegKind_COP3
|
2013-01-12 01:03:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
2012-08-17 20:16:42 +00:00
|
|
|
enum KindTy {
|
2014-04-01 12:35:23 +00: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.
|
2014-11-19 16:44:02 +00:00
|
|
|
k_Token, /// A simple token
|
2014-12-16 14:59:10 +00:00
|
|
|
k_RegList, /// A physical register list
|
|
|
|
k_RegPair /// A pair of physical register
|
2012-08-17 20:16:42 +00:00
|
|
|
} Kind;
|
|
|
|
|
2014-06-08 16:18:35 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
MipsOperand(KindTy K, MipsAsmParser &Parser)
|
|
|
|
: MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
private:
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// For diagnostics, and checking the assembler temporary
|
|
|
|
MipsAsmParser &AsmParser;
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2013-03-15 00:42:55 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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 00:42:55 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
MipsOperand *Base;
|
2013-03-15 00:42:55 +00:00
|
|
|
const MCExpr *Off;
|
|
|
|
};
|
|
|
|
|
2014-11-19 16:44:02 +00:00
|
|
|
struct RegListOp {
|
|
|
|
SmallVector<unsigned, 10> *List;
|
|
|
|
};
|
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
union {
|
2013-03-15 00:42:55 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
struct PhysRegOp PhysReg;
|
|
|
|
struct RegIdxOp RegIdx;
|
2013-03-15 00:42:55 +00:00
|
|
|
struct ImmOp Imm;
|
|
|
|
struct MemOp Mem;
|
2014-11-19 16:44:02 +00:00
|
|
|
struct RegListOp RegList;
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Internal constructor for register kinds
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
|
|
|
|
const MCRegisterInfo *RegInfo,
|
|
|
|
SMLoc S, SMLoc E,
|
|
|
|
MipsAsmParser &Parser) {
|
|
|
|
auto Op = make_unique<MipsOperand>(k_RegisterIndex, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Op->RegIdx.Index = Index;
|
|
|
|
Op->RegIdx.RegInfo = RegInfo;
|
|
|
|
Op->RegIdx.Kind = RegKind;
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = E;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
2012-08-17 20:16:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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!");
|
2014-09-04 13:23:44 +00:00
|
|
|
AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00:00
|
|
|
}
|
|
|
|
|
2014-10-21 08:23:11 +00:00
|
|
|
/// Coerce the register to GPR32 and return the real register for the current
|
|
|
|
/// target.
|
|
|
|
unsigned getGPRMM16Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
|
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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);
|
|
|
|
}
|
|
|
|
|
2014-05-08 13:02:11 +00:00
|
|
|
/// Coerce the register to COP3 and return the real register for the
|
|
|
|
/// current target.
|
|
|
|
unsigned getCOP3Reg() const {
|
|
|
|
assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
|
|
|
|
unsigned ClassID = Mips::COP3RegClassID;
|
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// 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 00:55:15 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
public:
|
2013-11-06 11:27:05 +00:00
|
|
|
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
|
2012-09-05 23:34:03 +00:00
|
|
|
// Add as immediate when possible. Null MCExpr = 0.
|
2014-04-25 05:30:21 +00:00
|
|
|
if (!Expr)
|
2012-09-05 23:34:03 +00:00
|
|
|
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-17 20:16:42 +00:00
|
|
|
}
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
void addRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
llvm_unreachable("Use a custom parser instead");
|
|
|
|
}
|
|
|
|
|
2014-04-01 12:35:23 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
|
|
|
|
}
|
|
|
|
|
2014-10-21 08:23:11 +00:00
|
|
|
void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
|
|
|
|
}
|
|
|
|
|
2014-11-24 14:25:53 +00:00
|
|
|
void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
|
|
|
|
}
|
|
|
|
|
2014-04-01 12:35:23 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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()));
|
2014-07-10 13:38:23 +00:00
|
|
|
// FIXME: We ought to do this for -integrated-as without -via-file-asm too.
|
2014-07-14 10:26:15 +00:00
|
|
|
if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
|
2014-07-10 13:38:23 +00:00
|
|
|
AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
|
|
|
|
"registers");
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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()));
|
|
|
|
}
|
|
|
|
|
2014-05-08 13:02:11 +00:00
|
|
|
void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
|
|
|
|
}
|
|
|
|
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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-17 20:16:42 +00:00
|
|
|
void addImmOperands(MCInst &Inst, unsigned N) const {
|
2012-09-05 23:34:03 +00:00
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
const MCExpr *Expr = getImm();
|
2013-04-18 00:41:53 +00:00
|
|
|
addExpr(Inst, Expr);
|
2012-08-17 20:16:42 +00:00
|
|
|
}
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2012-08-17 20:16:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
|
|
|
const MCExpr *Expr = getMemOff();
|
2013-04-18 00:41:53 +00:00
|
|
|
addExpr(Inst, Expr);
|
2012-08-17 20:16:42 +00:00
|
|
|
}
|
|
|
|
|
2014-11-24 14:39:13 +00:00
|
|
|
void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 2 && "Invalid number of operands!");
|
|
|
|
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
|
|
|
|
|
|
|
|
const MCExpr *Expr = getMemOff();
|
|
|
|
addExpr(Inst, Expr);
|
|
|
|
}
|
|
|
|
|
2014-11-19 16:44:02 +00:00
|
|
|
void addRegListOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 1 && "Invalid number of operands!");
|
|
|
|
|
|
|
|
for (auto RegNo : getRegList())
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
}
|
|
|
|
|
2014-12-16 14:59:10 +00:00
|
|
|
void addRegPairOperands(MCInst &Inst, unsigned N) const {
|
|
|
|
assert(N == 2 && "Invalid number of operands!");
|
|
|
|
unsigned RegNo = getRegPair();
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(RegNo++));
|
|
|
|
Inst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
}
|
|
|
|
|
2014-04-29 07:58:02 +00:00
|
|
|
bool isReg() const override {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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 (isGPRAsmReg() && RegIdx.Index == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return Kind == k_PhysRegister;
|
|
|
|
}
|
|
|
|
bool isRegIdx() const { return Kind == k_RegisterIndex; }
|
2014-04-29 07:58:02 +00:00
|
|
|
bool isImm() const override { 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isConstantImm() const {
|
|
|
|
return isImm() && dyn_cast<MCConstantExpr>(getImm());
|
|
|
|
}
|
2014-04-29 07:58:02 +00:00
|
|
|
bool isToken() const override {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
// Note: It's not possible to pretend that other operand kinds are tokens.
|
|
|
|
// The matcher emitter checks tokens first.
|
|
|
|
return Kind == k_Token;
|
|
|
|
}
|
2014-04-29 07:58:02 +00:00
|
|
|
bool isMem() const override { return Kind == k_Memory; }
|
2014-06-16 10:00:45 +00:00
|
|
|
bool isConstantMemOff() const {
|
|
|
|
return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
|
|
|
|
}
|
|
|
|
template <unsigned Bits> bool isMemWithSimmOffset() const {
|
|
|
|
return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
|
|
|
|
}
|
2014-11-24 14:39:13 +00:00
|
|
|
bool isMemWithGRPMM16Base() const {
|
|
|
|
return isMem() && getMemBase()->isMM16AsmReg();
|
|
|
|
}
|
2014-11-27 18:28:59 +00:00
|
|
|
template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
|
|
|
|
return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
|
|
|
|
&& getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
|
|
|
|
}
|
2014-12-23 16:16:33 +00:00
|
|
|
template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
|
|
|
|
return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
|
|
|
|
&& (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
|
|
|
|
&& (getMemBase()->getGPR32Reg() == Mips::SP);
|
|
|
|
}
|
2014-11-27 18:28:59 +00:00
|
|
|
bool isRegList16() const {
|
|
|
|
if (!isRegList())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int Size = RegList.List->size();
|
|
|
|
if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
|
|
|
|
RegList.List->back() != Mips::RA)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int PrevReg = *RegList.List->begin();
|
|
|
|
for (int i = 1; i < Size - 1; i++) {
|
|
|
|
int Reg = (*(RegList.List))[i];
|
|
|
|
if ( Reg != PrevReg + 1)
|
|
|
|
return false;
|
|
|
|
PrevReg = Reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-10-01 09:48:56 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isLSAImm() const {
|
|
|
|
if (!isConstantImm())
|
|
|
|
return false;
|
|
|
|
int64_t Val = getConstantImm();
|
|
|
|
return 1 <= Val && Val <= 4;
|
|
|
|
}
|
2014-11-19 16:44:02 +00:00
|
|
|
bool isRegList() const { return Kind == k_RegList; }
|
2012-08-17 20:16:42 +00:00
|
|
|
|
|
|
|
StringRef getToken() const {
|
|
|
|
assert(Kind == k_Token && "Invalid access!");
|
2012-09-05 23:34:03 +00:00
|
|
|
return StringRef(Tok.Data, Tok.Length);
|
2012-08-17 20:16:42 +00:00
|
|
|
}
|
2014-12-16 14:59:10 +00:00
|
|
|
bool isRegPair() const { return Kind == k_RegPair; }
|
2012-08-17 20:16:42 +00:00
|
|
|
|
2014-04-29 07:58:02 +00:00
|
|
|
unsigned getReg() const override {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
assert(Kind == k_PhysRegister && "Invalid access!");
|
|
|
|
return PhysReg.Num;
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
|
|
|
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
assert((Kind == k_Immediate) && "Invalid access!");
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
assert((Kind == k_Memory) && "Invalid access!");
|
|
|
|
return Mem.Base;
|
|
|
|
}
|
|
|
|
|
|
|
|
const MCExpr *getMemOff() const {
|
|
|
|
assert((Kind == k_Memory) && "Invalid access!");
|
|
|
|
return Mem.Off;
|
|
|
|
}
|
|
|
|
|
2014-06-16 10:00:45 +00:00
|
|
|
int64_t getConstantMemOff() const {
|
|
|
|
return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
|
|
|
|
}
|
|
|
|
|
2014-11-19 16:44:02 +00:00
|
|
|
const SmallVectorImpl<unsigned> &getRegList() const {
|
|
|
|
assert((Kind == k_RegList) && "Invalid access!");
|
|
|
|
return *(RegList.List);
|
|
|
|
}
|
|
|
|
|
2014-12-16 14:59:10 +00:00
|
|
|
unsigned getRegPair() const {
|
|
|
|
assert((Kind == k_RegPair) && "Invalid access!");
|
|
|
|
return RegIdx.Index;
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
|
|
|
|
MipsAsmParser &Parser) {
|
|
|
|
auto Op = make_unique<MipsOperand>(k_Token, Parser);
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Create a numeric register (e.g. $1). The exact register remains
|
|
|
|
/// unresolved until an instruction successfully matches
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
|
2014-06-08 16:18:35 +00:00
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
2014-09-04 13:23:44 +00:00
|
|
|
DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
|
2012-08-17 20:16:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Create a register that is definitely a GPR.
|
|
|
|
/// This is typically only used for named registers such as $gp.
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Create a register that is definitely a FGR.
|
|
|
|
/// This is typically only used for named registers such as $f0.
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
|
|
|
|
}
|
|
|
|
|
2014-11-11 10:31:31 +00:00
|
|
|
/// Create a register that is definitely a HWReg.
|
|
|
|
/// This is typically only used for named registers such as $hwr_cpunum.
|
|
|
|
static std::unique_ptr<MipsOperand>
|
|
|
|
createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
|
|
|
|
SMLoc S, SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
return CreateReg(Index, RegKind_HWRegs, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Create a register that is definitely an FCC.
|
|
|
|
/// This is typically only used for named registers such as $fcc0.
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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.
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
/// Create a register that is definitely an MSA128.
|
|
|
|
/// This is typically only used for named registers such as $w0.
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
|
2014-06-08 16:18:35 +00:00
|
|
|
SMLoc E, MipsAsmParser &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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.
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
2014-09-04 13:23:44 +00:00
|
|
|
createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
|
2014-06-08 16:18:35 +00:00
|
|
|
SMLoc E, MipsAsmParser &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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
|
|
|
CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
|
2013-11-18 12:32:49 +00:00
|
|
|
Op->Imm.Val = Val;
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = E;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
|
|
|
CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
|
|
|
|
SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
auto Op = make_unique<MipsOperand>(k_Memory, Parser);
|
|
|
|
Op->Mem.Base = Base.release();
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
Op->Mem.Off = Off;
|
|
|
|
Op->StartLoc = S;
|
|
|
|
Op->EndLoc = E;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
2014-11-19 16:44:02 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
|
|
|
CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
|
|
|
|
MipsAsmParser &Parser) {
|
|
|
|
assert (Regs.size() > 0 && "Empty list not allowed");
|
|
|
|
|
|
|
|
auto Op = make_unique<MipsOperand>(k_RegList, Parser);
|
|
|
|
Op->RegList.List = new SmallVector<unsigned, 10>();
|
|
|
|
for (auto Reg : Regs)
|
|
|
|
Op->RegList.List->push_back(Reg);
|
|
|
|
Op->StartLoc = StartLoc;
|
|
|
|
Op->EndLoc = EndLoc;
|
|
|
|
return Op;
|
|
|
|
}
|
|
|
|
|
2014-12-16 14:59:10 +00:00
|
|
|
static std::unique_ptr<MipsOperand>
|
|
|
|
CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
|
|
|
|
auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
|
|
|
|
Op->RegIdx.Index = RegNo;
|
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isGPRAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
|
2013-07-30 10:12:14 +00:00
|
|
|
}
|
2014-10-21 08:23:11 +00:00
|
|
|
bool isMM16AsmReg() const {
|
|
|
|
if (!(isRegIdx() && RegIdx.Kind))
|
|
|
|
return false;
|
|
|
|
return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
|
|
|
|
|| RegIdx.Index == 16 || RegIdx.Index == 17);
|
|
|
|
}
|
2014-11-24 14:25:53 +00:00
|
|
|
bool isMM16AsmRegZero() const {
|
|
|
|
if (!(isRegIdx() && RegIdx.Kind))
|
|
|
|
return false;
|
|
|
|
return (RegIdx.Index == 0 ||
|
|
|
|
(RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
|
|
|
|
RegIdx.Index == 17);
|
|
|
|
}
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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-06 22:20:40 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isHWRegsAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
|
2013-08-14 01:02:20 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isCCRAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
|
2013-08-14 01:02:20 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isFCCAsmReg() const {
|
2014-06-12 15:00:17 +00:00
|
|
|
if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
|
|
|
|
return false;
|
|
|
|
if (!AsmParser.hasEightFccRegisters())
|
|
|
|
return RegIdx.Index == 0;
|
|
|
|
return RegIdx.Index <= 7;
|
2013-09-25 23:50:44 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isACCAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
|
2013-09-25 23:50:44 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isCOP2AsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
|
2013-09-25 23:50:44 +00:00
|
|
|
}
|
2014-05-08 13:02:11 +00:00
|
|
|
bool isCOP3AsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
|
|
|
|
}
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isMSA128AsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
|
2013-09-25 23:50:44 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
bool isMSACtrlAsmReg() const {
|
|
|
|
return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
|
2013-10-21 12:26:50 +00:00
|
|
|
}
|
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
/// getStartLoc - Get the location of the first token of this operand.
|
2014-04-29 07:58:02 +00:00
|
|
|
SMLoc getStartLoc() const override { return StartLoc; }
|
2012-09-05 23:34:03 +00:00
|
|
|
/// getEndLoc - Get the location of the last token of this operand.
|
2014-04-29 07:58:02 +00:00
|
|
|
SMLoc getEndLoc() const override { return EndLoc; }
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2014-04-15 14:13:21 +00:00
|
|
|
virtual ~MipsOperand() {
|
|
|
|
switch (Kind) {
|
|
|
|
case k_Immediate:
|
|
|
|
break;
|
|
|
|
case k_Memory:
|
|
|
|
delete Mem.Base;
|
|
|
|
break;
|
2014-11-19 16:44:02 +00:00
|
|
|
case k_RegList:
|
|
|
|
delete RegList.List;
|
2014-04-15 14:13:21 +00:00
|
|
|
case k_PhysRegister:
|
|
|
|
case k_RegisterIndex:
|
|
|
|
case k_Token:
|
2014-12-16 14:59:10 +00:00
|
|
|
case k_RegPair:
|
2014-04-15 14:13:21 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-29 07:58:02 +00:00
|
|
|
void print(raw_ostream &OS) const override {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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;
|
2014-11-19 16:44:02 +00:00
|
|
|
case k_RegList:
|
|
|
|
OS << "RegList< ";
|
|
|
|
for (auto Reg : (*RegList.List))
|
|
|
|
OS << Reg << " ";
|
|
|
|
OS << ">";
|
|
|
|
break;
|
2014-12-16 14:59:10 +00:00
|
|
|
case k_RegPair:
|
|
|
|
OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
|
|
|
|
break;
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
}
|
2012-08-17 20:16:42 +00:00
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
}; // class MipsOperand
|
2013-11-06 11:27:05 +00:00
|
|
|
} // namespace
|
2012-08-17 20:16:42 +00:00
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
namespace llvm {
|
|
|
|
extern const MCInstrDesc MipsInsts[];
|
|
|
|
}
|
|
|
|
static const MCInstrDesc &getInstDesc(unsigned Opcode) {
|
|
|
|
return MipsInsts[Opcode];
|
|
|
|
}
|
|
|
|
|
2014-09-12 13:43:41 +00:00
|
|
|
static bool hasShortDelaySlot(unsigned Opcode) {
|
|
|
|
switch (Opcode) {
|
|
|
|
case Mips::JALS_MM:
|
|
|
|
case Mips::JALRS_MM:
|
2014-10-10 13:22:28 +00:00
|
|
|
case Mips::JALRS16_MM:
|
2014-09-12 13:51:58 +00:00
|
|
|
case Mips::BGEZALS_MM:
|
|
|
|
case Mips::BLTZALS_MM:
|
2014-09-12 13:43:41 +00:00
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
2013-04-17 00:18:04 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
2013-03-22 00:05:30 +00:00
|
|
|
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
|
2014-03-24 14:05:39 +00:00
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
Inst.setLoc(IDLoc);
|
2013-12-13 11:11:02 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
case Mips::BEQ_MM:
|
|
|
|
case Mips::BNE_MM:
|
2014-01-22 23:31:38 +00:00
|
|
|
assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
|
2013-12-13 11:11:02 +00:00
|
|
|
Offset = Inst.getOperand(2);
|
|
|
|
if (!Offset.isImm())
|
|
|
|
break; // We'll deal with this situation later on when applying fixups.
|
2014-07-08 08:59:22 +00:00
|
|
|
if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
|
2013-12-13 11:11:02 +00:00
|
|
|
return Error(IDLoc, "branch target out of range");
|
2014-07-08 08:59:22 +00:00
|
|
|
if (OffsetToAlignment(Offset.getImm(),
|
|
|
|
1LL << (inMicroMipsMode() ? 1 : 2)))
|
2013-12-13 11:11:02 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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-22 23:31:38 +00:00
|
|
|
assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
|
2013-12-13 11:11:02 +00:00
|
|
|
Offset = Inst.getOperand(1);
|
|
|
|
if (!Offset.isImm())
|
|
|
|
break; // We'll deal with this situation later on when applying fixups.
|
2014-07-08 08:59:22 +00:00
|
|
|
if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
|
2013-12-13 11:11:02 +00:00
|
|
|
return Error(IDLoc, "branch target out of range");
|
2014-07-08 08:59:22 +00:00
|
|
|
if (OffsetToAlignment(Offset.getImm(),
|
|
|
|
1LL << (inMicroMipsMode() ? 1 : 2)))
|
2013-12-13 11:11:02 +00:00
|
|
|
return Error(IDLoc, "branch to misaligned address");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-16 13:25:35 +00:00
|
|
|
// SSNOP is deprecated on MIPS32r6/MIPS64r6
|
|
|
|
// We still accept it but it is a normal nop.
|
|
|
|
if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
|
|
|
|
std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
|
|
|
|
Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
|
|
|
|
"nop instruction");
|
|
|
|
}
|
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
|
2013-04-25 23:31:35 +00:00
|
|
|
// If this instruction has a delay slot and .set reorder is active,
|
|
|
|
// emit a NOP after it.
|
|
|
|
Instructions.push_back(Inst);
|
|
|
|
MCInst NopInst;
|
2014-09-12 13:43:41 +00:00
|
|
|
if (hasShortDelaySlot(Inst.getOpcode())) {
|
|
|
|
NopInst.setOpcode(Mips::MOVE16_MM);
|
|
|
|
NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
|
|
|
NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
|
|
|
} else {
|
|
|
|
NopInst.setOpcode(Mips::SLL);
|
|
|
|
NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
|
|
|
NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
|
|
|
NopInst.addOperand(MCOperand::CreateImm(0));
|
|
|
|
}
|
2013-04-25 23:31:35 +00:00
|
|
|
Instructions.push_back(NopInst);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
if (MCID.mayLoad() || MCID.mayStore()) {
|
|
|
|
// Check the offset of memory operand, if it is a symbol
|
2013-04-18 00:41:53 +00:00
|
|
|
// reference or immediate we may have to expand instructions.
|
|
|
|
for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
|
2013-03-22 00:05:30 +00:00
|
|
|
const MCOperandInfo &OpInfo = MCID.OpInfo[i];
|
2013-11-06 11:27:05 +00:00
|
|
|
if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
|
|
|
|
(OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
|
2013-03-22 00:05:30 +00:00
|
|
|
MCOperand &Op = Inst.getOperand(i);
|
|
|
|
if (Op.isImm()) {
|
|
|
|
int MemOffset = Op.getImm();
|
|
|
|
if (MemOffset < -32768 || MemOffset > 32767) {
|
2013-04-18 00:41:53 +00:00
|
|
|
// Offset can't exceed 16bit value.
|
|
|
|
expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
|
2013-03-22 00:05:30 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (Op.isExpr()) {
|
|
|
|
const MCExpr *Expr = Op.getExpr();
|
2013-04-18 00:41:53 +00:00
|
|
|
if (Expr->getKind() == MCExpr::SymbolRef) {
|
2013-03-22 00:05:30 +00:00
|
|
|
const MCSymbolRefExpr *SR =
|
2013-11-06 11:27:05 +00:00
|
|
|
static_cast<const MCSymbolRefExpr *>(Expr);
|
2013-03-22 00:05:30 +00:00
|
|
|
if (SR->getKind() == MCSymbolRefExpr::VK_None) {
|
2013-04-18 00:41:53 +00:00
|
|
|
// Expand symbol.
|
|
|
|
expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
|
2013-03-22 00:05:30 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-17 00:18:04 +00:00
|
|
|
} else if (!isEvaluated(Expr)) {
|
2013-04-18 00:41:53 +00:00
|
|
|
expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
|
2013-04-17 00:18:04 +00:00
|
|
|
return false;
|
2013-03-22 00:05:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
} // for
|
2013-11-06 11:27:05 +00:00
|
|
|
} // if load/store
|
2013-03-22 00:05:30 +00:00
|
|
|
|
2014-10-10 13:45:34 +00:00
|
|
|
// TODO: Handle this with the AsmOperandClass.PredicateMethod.
|
|
|
|
if (inMicroMipsMode()) {
|
|
|
|
MCOperand Opnd;
|
|
|
|
int Imm;
|
|
|
|
|
|
|
|
switch (Inst.getOpcode()) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case Mips::ADDIUS5_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < -8 || Imm > 7)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-10-10 14:37:30 +00:00
|
|
|
case Mips::ADDIUSP_MM:
|
|
|
|
Opnd = Inst.getOperand(0);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
|
|
|
|
Imm % 4 != 0)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-10-23 10:42:01 +00:00
|
|
|
case Mips::SLL16_MM:
|
|
|
|
case Mips::SRL16_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < 1 || Imm > 8)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-10-23 10:59:24 +00:00
|
|
|
case Mips::LI16_MM:
|
|
|
|
Opnd = Inst.getOperand(1);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < -1 || Imm > 126)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-10-23 11:06:34 +00:00
|
|
|
case Mips::ADDIUR2_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (!(Imm == 1 || Imm == -1 ||
|
|
|
|
((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-10-23 11:13:59 +00:00
|
|
|
case Mips::ADDIUR1SP_MM:
|
|
|
|
Opnd = Inst.getOperand(1);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (OffsetToAlignment(Imm, 4LL))
|
|
|
|
return Error(IDLoc, "misaligned immediate operand value");
|
|
|
|
if (Imm < 0 || Imm > 255)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-11-05 17:31:00 +00:00
|
|
|
case Mips::ANDI16_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
|
|
|
|
Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
|
|
|
|
Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-11-24 14:39:13 +00:00
|
|
|
case Mips::LBU16_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < -1 || Imm > 14)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
|
|
|
case Mips::SB16_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < 0 || Imm > 15)
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
|
|
|
case Mips::LHU16_MM:
|
|
|
|
case Mips::SH16_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
|
|
|
case Mips::LW16_MM:
|
|
|
|
case Mips::SW16_MM:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-12-23 19:55:34 +00:00
|
|
|
case Mips::CACHE:
|
|
|
|
case Mips::PREF:
|
|
|
|
Opnd = Inst.getOperand(2);
|
|
|
|
if (!Opnd.isImm())
|
|
|
|
return Error(IDLoc, "expected immediate operand kind");
|
|
|
|
Imm = Opnd.getImm();
|
|
|
|
if (!isUInt<5>(Imm))
|
|
|
|
return Error(IDLoc, "immediate operand value out of range");
|
|
|
|
break;
|
2014-10-10 13:45:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
if (needsExpansion(Inst))
|
2014-06-19 14:39:14 +00:00
|
|
|
return expandInstruction(Inst, IDLoc, Instructions);
|
2013-03-22 00:05:30 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
bool MipsAsmParser::needsExpansion(MCInst &Inst) {
|
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
switch (Inst.getOpcode()) {
|
|
|
|
case Mips::LoadImm32Reg:
|
|
|
|
case Mips::LoadAddr32Imm:
|
|
|
|
case Mips::LoadAddr32Reg:
|
2014-06-19 15:08:04 +00:00
|
|
|
case Mips::LoadImm64Reg:
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
}
|
|
|
|
}
|
2012-10-06 00:53:28 +00:00
|
|
|
|
2014-06-19 14:39:14 +00:00
|
|
|
bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 11:27:05 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
2013-04-18 00:41:53 +00:00
|
|
|
switch (Inst.getOpcode()) {
|
2014-07-08 08:59:22 +00:00
|
|
|
default:
|
|
|
|
assert(0 && "unimplemented expansion");
|
2014-06-19 14:39:14 +00:00
|
|
|
return true;
|
2013-04-18 00:41:53 +00:00
|
|
|
case Mips::LoadImm32Reg:
|
|
|
|
return expandLoadImm(Inst, IDLoc, Instructions);
|
2014-06-19 15:08:04 +00:00
|
|
|
case Mips::LoadImm64Reg:
|
2014-07-08 08:59:22 +00:00
|
|
|
if (!isGP64bit()) {
|
2014-09-16 15:00:52 +00:00
|
|
|
Error(IDLoc, "instruction requires a 64-bit architecture");
|
2014-06-19 15:08:04 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return expandLoadImm(Inst, IDLoc, Instructions);
|
2013-04-18 00:41:53 +00:00
|
|
|
case Mips::LoadAddr32Imm:
|
|
|
|
return expandLoadAddressImm(Inst, IDLoc, Instructions);
|
|
|
|
case Mips::LoadAddr32Reg:
|
|
|
|
return expandLoadAddressReg(Inst, IDLoc, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
}
|
2012-10-06 00:53:28 +00:00
|
|
|
|
2014-06-19 15:08:04 +00:00
|
|
|
namespace {
|
2014-08-14 10:29:17 +00:00
|
|
|
template <bool PerformShift>
|
|
|
|
void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
|
2014-06-19 15:08:04 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
|
|
|
MCInst tmpInst;
|
|
|
|
if (PerformShift) {
|
|
|
|
tmpInst.setOpcode(Mips::DSLL);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(16));
|
|
|
|
tmpInst.setLoc(IDLoc);
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
tmpInst.clear();
|
|
|
|
}
|
|
|
|
tmpInst.setOpcode(Mips::ORi);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegNo));
|
2014-08-14 10:29:17 +00:00
|
|
|
tmpInst.addOperand(Operand);
|
2014-06-19 15:08:04 +00:00
|
|
|
tmpInst.setLoc(IDLoc);
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
}
|
2014-08-14 10:29:17 +00:00
|
|
|
|
|
|
|
template <int Shift, bool PerformShift>
|
|
|
|
void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
|
|
|
createShiftOr<PerformShift>(
|
|
|
|
MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
|
|
|
|
IDLoc, Instructions);
|
|
|
|
}
|
2014-06-19 15:08:04 +00:00
|
|
|
}
|
|
|
|
|
2014-06-19 14:39:14 +00:00
|
|
|
bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
|
2013-04-18 00:41:53 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
2012-10-06 00:53:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
const MCOperand &RegOp = Inst.getOperand(0);
|
|
|
|
assert(RegOp.isReg() && "expected register operand kind");
|
|
|
|
|
2014-06-19 15:08:04 +00:00
|
|
|
int64_t ImmValue = ImmOp.getImm();
|
2012-10-06 00:53:28 +00:00
|
|
|
tmpInst.setLoc(IDLoc);
|
2014-06-19 15:08:04 +00:00
|
|
|
// FIXME: gas has a special case for values that are 000...1111, which
|
|
|
|
// becomes a li -1 and then a dsrl
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
// li d,j => ori d,$zero,j
|
2013-01-12 01:03:14 +00:00
|
|
|
tmpInst.setOpcode(Mips::ORi);
|
2012-10-06 00:53:28 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2013-04-18 00:41:53 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
2012-10-06 00:53:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
Instructions.push_back(tmpInst);
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
// li d,j => addiu d,$zero,j
|
2013-01-12 01:03:14 +00:00
|
|
|
tmpInst.setOpcode(Mips::ADDiu);
|
2012-10-06 00:53:28 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2013-04-18 00:41:53 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
|
2012-10-06 00:53:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
Instructions.push_back(tmpInst);
|
2014-06-19 15:08:04 +00:00
|
|
|
} else if ((ImmValue & 0xffffffff) == ImmValue) {
|
|
|
|
// For any value of j that is representable as a 32-bit integer, create
|
|
|
|
// a sequence of:
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
// ori d,d,lo16(j)
|
2013-01-12 01:03:14 +00:00
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
2012-10-06 00:53:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
Instructions.push_back(tmpInst);
|
2014-06-19 15:08:04 +00:00
|
|
|
createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
|
|
|
|
} else if ((ImmValue & (0xffffLL << 48)) == 0) {
|
2014-07-08 08:59:22 +00:00
|
|
|
if (!isGP64bit()) {
|
2014-09-16 15:00:52 +00:00
|
|
|
Error(IDLoc, "instruction requires a 64-bit architecture");
|
2014-06-19 15:08:04 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// <------- lo32 ------>
|
|
|
|
// <------- hi32 ------>
|
|
|
|
// <- hi16 -> <- lo16 ->
|
|
|
|
// _________________________________
|
|
|
|
// | | | |
|
|
|
|
// | 16-bytes | 16-bytes | 16-bytes |
|
|
|
|
// |__________|__________|__________|
|
|
|
|
//
|
|
|
|
// For any value of j that is representable as a 48-bit integer, create
|
|
|
|
// a sequence of:
|
|
|
|
// li d,j => lui d,hi16(j)
|
|
|
|
// ori d,d,hi16(lo32(j))
|
|
|
|
// dsll d,d,16
|
|
|
|
// ori d,d,lo16(lo32(j))
|
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
2012-10-06 00:53:28 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2014-06-19 15:08:04 +00:00
|
|
|
tmpInst.addOperand(
|
|
|
|
MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
|
|
|
|
createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
|
|
|
|
} else {
|
2014-07-08 08:59:22 +00:00
|
|
|
if (!isGP64bit()) {
|
2014-09-16 15:00:52 +00:00
|
|
|
Error(IDLoc, "instruction requires a 64-bit architecture");
|
2014-06-19 15:08:04 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// <------- hi32 ------> <------- lo32 ------>
|
|
|
|
// <- hi16 -> <- lo16 ->
|
|
|
|
// ___________________________________________
|
|
|
|
// | | | | |
|
|
|
|
// | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
|
|
|
|
// |__________|__________|__________|__________|
|
|
|
|
//
|
|
|
|
// For any value of j that isn't representable as a 48-bit integer.
|
|
|
|
// li d,j => lui d,hi16(j)
|
|
|
|
// ori d,d,lo16(hi32(j))
|
|
|
|
// dsll d,d,16
|
|
|
|
// ori d,d,hi16(lo32(j))
|
|
|
|
// dsll d,d,16
|
|
|
|
// ori d,d,lo16(lo32(j))
|
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
2012-10-06 00:53:28 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2014-06-19 15:08:04 +00:00
|
|
|
tmpInst.addOperand(
|
|
|
|
MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
Instructions.push_back(tmpInst);
|
2014-06-19 15:08:04 +00:00
|
|
|
createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
|
|
|
|
createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
|
|
|
|
createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
}
|
2014-06-19 14:39:14 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00:00
|
|
|
}
|
2012-10-06 00:53:28 +00:00
|
|
|
|
2014-06-19 14:39:14 +00:00
|
|
|
bool
|
2013-11-06 11:27:05 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
MCInst tmpInst;
|
|
|
|
const MCOperand &ImmOp = Inst.getOperand(2);
|
2014-08-14 10:29:17 +00:00
|
|
|
assert((ImmOp.isImm() || ImmOp.isExpr()) &&
|
|
|
|
"expected immediate operand kind");
|
|
|
|
if (!ImmOp.isImm()) {
|
|
|
|
expandLoadAddressSym(Inst, IDLoc, Instructions);
|
|
|
|
return false;
|
|
|
|
}
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
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 00:41:53 +00:00
|
|
|
if (-32768 <= ImmValue && ImmValue <= 65535) {
|
|
|
|
// For -32768 <= j <= 65535.
|
|
|
|
// la d,j(s) => addiu d,s,j
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00: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 00:41:53 +00: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 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
tmpInst.clear();
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00: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);
|
|
|
|
}
|
2014-06-19 14:39:14 +00:00
|
|
|
return false;
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
}
|
|
|
|
|
2014-06-19 14:39:14 +00:00
|
|
|
bool
|
2013-11-06 11:27:05 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
MCInst tmpInst;
|
|
|
|
const MCOperand &ImmOp = Inst.getOperand(1);
|
2014-08-14 10:29:17 +00:00
|
|
|
assert((ImmOp.isImm() || ImmOp.isExpr()) &&
|
|
|
|
"expected immediate operand kind");
|
|
|
|
if (!ImmOp.isImm()) {
|
|
|
|
expandLoadAddressSym(Inst, IDLoc, Instructions);
|
|
|
|
return false;
|
|
|
|
}
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
const MCOperand &RegOp = Inst.getOperand(0);
|
|
|
|
assert(RegOp.isReg() && "expected register operand kind");
|
|
|
|
int ImmValue = ImmOp.getImm();
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
tmpInst.setOpcode(Mips::ADDiu);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
} else {
|
2013-04-18 00:41:53 +00: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 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
tmpInst.clear();
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
}
|
2014-06-19 14:39:14 +00:00
|
|
|
return false;
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00:00
|
|
|
}
|
|
|
|
|
2014-08-14 10:29:17 +00:00
|
|
|
void
|
|
|
|
MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
|
|
|
|
SmallVectorImpl<MCInst> &Instructions) {
|
|
|
|
// FIXME: If we do have a valid at register to use, we should generate a
|
|
|
|
// slightly shorter sequence here.
|
|
|
|
MCInst tmpInst;
|
|
|
|
int ExprOperandNo = 1;
|
|
|
|
// Sometimes the assembly parser will get the immediate expression as
|
|
|
|
// a $zero + an immediate.
|
|
|
|
if (Inst.getNumOperands() == 3) {
|
|
|
|
assert(Inst.getOperand(1).getReg() ==
|
|
|
|
(isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
|
|
|
|
ExprOperandNo = 2;
|
|
|
|
}
|
|
|
|
const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
|
|
|
|
assert(SymOp.isExpr() && "expected symbol operand kind");
|
|
|
|
const MCOperand &RegOp = Inst.getOperand(0);
|
|
|
|
unsigned RegNo = RegOp.getReg();
|
|
|
|
const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
|
|
|
|
const MCSymbolRefExpr *HiExpr =
|
|
|
|
MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
|
|
|
|
MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
|
|
|
|
const MCSymbolRefExpr *LoExpr =
|
|
|
|
MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
|
|
|
|
MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
|
|
|
|
if (isGP64bit()) {
|
|
|
|
// If it's a 64-bit architecture, expand to:
|
|
|
|
// la d,sym => lui d,highest(sym)
|
|
|
|
// ori d,d,higher(sym)
|
|
|
|
// dsll d,d,16
|
|
|
|
// ori d,d,hi16(sym)
|
|
|
|
// dsll d,d,16
|
|
|
|
// ori d,d,lo16(sym)
|
|
|
|
const MCSymbolRefExpr *HighestExpr =
|
|
|
|
MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
|
|
|
|
MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
|
|
|
|
const MCSymbolRefExpr *HigherExpr =
|
|
|
|
MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
|
|
|
|
MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
|
|
|
|
|
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
|
|
|
|
createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
|
|
|
|
Instructions);
|
|
|
|
createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
|
|
|
|
Instructions);
|
|
|
|
createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
|
|
|
|
Instructions);
|
|
|
|
} else {
|
|
|
|
// Otherwise, expand to:
|
|
|
|
// la d,sym => lui d,hi16(sym)
|
|
|
|
// ori d,d,lo16(sym)
|
|
|
|
tmpInst.setOpcode(Mips::LUi);
|
|
|
|
tmpInst.addOperand(MCOperand::CreateReg(RegNo));
|
|
|
|
tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
|
|
|
|
Instructions.push_back(tmpInst);
|
|
|
|
|
|
|
|
createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
|
|
|
|
Instructions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-22 00:05:30 +00:00
|
|
|
void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
|
2013-11-06 11:27:05 +00:00
|
|
|
SmallVectorImpl<MCInst> &Instructions,
|
|
|
|
bool isLoad, bool isImmOpnd) {
|
2013-03-22 00:05:30 +00:00
|
|
|
const MCSymbolRefExpr *SR;
|
|
|
|
MCInst TempInst;
|
2013-04-18 00:41:53 +00:00
|
|
|
unsigned ImmOffset, HiOffset, LoOffset;
|
2013-03-22 00:05:30 +00:00
|
|
|
const MCExpr *ExprOffset;
|
|
|
|
unsigned TmpRegNum;
|
2013-04-18 00:41:53 +00:00
|
|
|
// 1st operand is either the source or destination register.
|
2013-03-22 00:05:30 +00:00
|
|
|
assert(Inst.getOperand(0).isReg() && "expected register operand kind");
|
|
|
|
unsigned RegOpNum = Inst.getOperand(0).getReg();
|
2013-04-18 00:41:53 +00:00
|
|
|
// 2nd operand is the base register.
|
2013-03-22 00:05:30 +00:00
|
|
|
assert(Inst.getOperand(1).isReg() && "expected register operand kind");
|
|
|
|
unsigned BaseRegNum = Inst.getOperand(1).getReg();
|
2013-04-18 00:41:53 +00:00
|
|
|
// 3rd operand is either an immediate or expression.
|
2013-03-22 00:05:30 +00: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 00:41:53 +00:00
|
|
|
// If msb of LoOffset is 1(negative number) we must increment HiOffset.
|
2013-03-22 00:05:30 +00:00
|
|
|
if (LoOffset & 0x8000)
|
|
|
|
HiOffset++;
|
2013-04-18 00:41:53 +00:00
|
|
|
} else
|
2013-03-22 00:05:30 +00:00
|
|
|
ExprOffset = Inst.getOperand(2).getExpr();
|
2013-04-18 00:41:53 +00:00
|
|
|
// All instructions will have the same location.
|
2013-03-22 00:05:30 +00:00
|
|
|
TempInst.setLoc(IDLoc);
|
2014-06-18 14:49:56 +00:00
|
|
|
// These are some of the types of expansions we perform here:
|
|
|
|
// 1) lw $8, sym => lui $8, %hi(sym)
|
|
|
|
// lw $8, %lo(sym)($8)
|
|
|
|
// 2) lw $8, offset($9) => lui $8, %hi(offset)
|
|
|
|
// add $8, $8, $9
|
|
|
|
// lw $8, %lo(offset)($9)
|
|
|
|
// 3) lw $8, offset($8) => lui $at, %hi(offset)
|
|
|
|
// add $at, $at, $8
|
|
|
|
// lw $8, %lo(offset)($at)
|
|
|
|
// 4) sw $8, sym => lui $at, %hi(sym)
|
|
|
|
// sw $8, %lo(sym)($at)
|
|
|
|
// 5) sw $8, offset($8) => lui $at, %hi(offset)
|
|
|
|
// add $at, $at, $8
|
|
|
|
// sw $8, %lo(offset)($at)
|
|
|
|
// 6) ldc1 $f0, sym => lui $at, %hi(sym)
|
|
|
|
// ldc1 $f0, %lo(sym)($at)
|
|
|
|
//
|
|
|
|
// For load instructions we can use the destination register as a temporary
|
|
|
|
// if base and dst are different (examples 1 and 2) and if the base register
|
|
|
|
// is general purpose otherwise we must use $at (example 6) and error if it's
|
|
|
|
// not available. For stores we must use $at (examples 4 and 5) because we
|
|
|
|
// must not clobber the source register setting up the offset.
|
|
|
|
const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
|
|
|
|
int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
|
|
|
|
unsigned RegClassIDOp0 =
|
|
|
|
getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
|
|
|
|
bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
|
|
|
|
(RegClassIDOp0 == Mips::GPR64RegClassID);
|
|
|
|
if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
|
2014-06-18 14:15:42 +00:00
|
|
|
TmpRegNum = RegOpNum;
|
2014-06-18 14:46:05 +00:00
|
|
|
else {
|
|
|
|
int AT = getATReg(IDLoc);
|
|
|
|
// At this point we need AT to perform the expansions and we exit if it is
|
|
|
|
// not available.
|
|
|
|
if (!AT)
|
|
|
|
return;
|
2014-07-08 08:59:22 +00:00
|
|
|
TmpRegNum = getReg(
|
|
|
|
(isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
|
2014-06-18 14:46:05 +00:00
|
|
|
}
|
2014-06-18 14:15:42 +00:00
|
|
|
|
2013-03-22 00:05:30 +00: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 11:27:05 +00:00
|
|
|
SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
|
2013-04-18 00:41:53 +00:00
|
|
|
const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
|
|
|
|
SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
|
|
|
|
getContext());
|
2013-03-22 00:05:30 +00:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
|
2013-04-17 00:18:04 +00:00
|
|
|
} else {
|
2013-04-18 00:41:53 +00:00
|
|
|
const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
|
2013-04-17 00:18:04 +00:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
|
2013-03-22 00:05:30 +00:00
|
|
|
}
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
// Add the instruction to the list.
|
2013-03-22 00:05:30 +00:00
|
|
|
Instructions.push_back(TempInst);
|
2013-04-18 00:41:53 +00:00
|
|
|
// Prepare TempInst for next instruction.
|
2013-03-22 00:05:30 +00:00
|
|
|
TempInst.clear();
|
2013-04-18 00:41:53 +00:00
|
|
|
// Add temp register to base.
|
2013-03-22 00:05:30 +00: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-24 17:20:08 +00:00
|
|
|
// And finally, create original instruction with low part
|
2013-04-18 00:41:53 +00:00
|
|
|
// of offset and new base.
|
2013-03-22 00:05:30 +00: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 00:41:53 +00:00
|
|
|
const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
|
|
|
|
SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
|
|
|
|
getContext());
|
2013-03-22 00:05:30 +00:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
|
2013-04-17 00:18:04 +00:00
|
|
|
} else {
|
2013-04-18 00:41:53 +00:00
|
|
|
const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
|
2013-04-17 00:18:04 +00:00
|
|
|
TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
|
2013-03-22 00:05:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Instructions.push_back(TempInst);
|
|
|
|
TempInst.clear();
|
|
|
|
}
|
|
|
|
|
2014-06-11 15:05:56 +00:00
|
|
|
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
|
|
|
|
// As described by the Mips32r2 spec, the registers Rd and Rs for
|
|
|
|
// jalr.hb must be different.
|
|
|
|
unsigned Opcode = Inst.getOpcode();
|
|
|
|
|
|
|
|
if (Opcode == Mips::JALR_HB &&
|
|
|
|
(Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
|
|
|
|
return Match_RequiresDifferentSrcAndDst;
|
|
|
|
|
|
|
|
return Match_Success;
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|
|
|
OperandVector &Operands,
|
|
|
|
MCStreamer &Out,
|
2014-08-18 11:49:42 +00:00
|
|
|
uint64_t &ErrorInfo,
|
2014-06-08 16:18:35 +00:00
|
|
|
bool MatchingInlineAsm) {
|
2014-06-11 15:05:56 +00:00
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
MCInst Inst;
|
2013-03-22 00:05:30 +00:00
|
|
|
SmallVector<MCInst, 8> Instructions;
|
2013-11-06 11:27:05 +00:00
|
|
|
unsigned MatchResult =
|
|
|
|
MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
|
2012-09-05 23:34:03 +00:00
|
|
|
|
|
|
|
switch (MatchResult) {
|
2013-04-18 00:41:53 +00:00
|
|
|
default:
|
|
|
|
break;
|
2012-09-05 23:34:03 +00:00
|
|
|
case Match_Success: {
|
2013-04-18 00:41:53 +00:00
|
|
|
if (processInstruction(Inst, IDLoc, Instructions))
|
2013-03-22 00:05:30 +00:00
|
|
|
return true;
|
2013-04-18 00:41:53 +00:00
|
|
|
for (unsigned i = 0; i < Instructions.size(); i++)
|
2014-01-28 23:12:42 +00:00
|
|
|
Out.EmitInstruction(Instructions[i], STI);
|
2012-09-05 23:34:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case Match_MissingFeature:
|
|
|
|
Error(IDLoc, "instruction requires a CPU feature not currently enabled");
|
|
|
|
return true;
|
|
|
|
case Match_InvalidOperand: {
|
|
|
|
SMLoc ErrorLoc = IDLoc;
|
2014-08-18 11:49:42 +00:00
|
|
|
if (ErrorInfo != ~0ULL) {
|
2012-09-05 23:34:03 +00:00
|
|
|
if (ErrorInfo >= Operands.size())
|
|
|
|
return Error(IDLoc, "too few operands for instruction");
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
|
2013-04-18 00:41:53 +00:00
|
|
|
if (ErrorLoc == SMLoc())
|
|
|
|
ErrorLoc = IDLoc;
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Error(ErrorLoc, "invalid operand for instruction");
|
|
|
|
}
|
|
|
|
case Match_MnemonicFail:
|
|
|
|
return Error(IDLoc, "invalid instruction");
|
2014-06-11 15:05:56 +00:00
|
|
|
case Match_RequiresDifferentSrcAndDst:
|
|
|
|
return Error(IDLoc, "source and destination must be different");
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
2012-01-11 03:56:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
|
2014-09-09 10:15:38 +00:00
|
|
|
if ((RegIndex != 0) &&
|
|
|
|
((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (RegIndex == 1)
|
2014-09-16 15:00:52 +00:00
|
|
|
Warning(Loc, "used $at without \".set noat\"");
|
2014-03-25 11:16:03 +00:00
|
|
|
else
|
2014-09-16 15:00:52 +00:00
|
|
|
Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Twine(RegIndex) + "\"");
|
2014-03-25 10:57:07 +00:00
|
|
|
}
|
2014-03-25 11:16:03 +00:00
|
|
|
}
|
|
|
|
|
2014-10-03 15:37:37 +00:00
|
|
|
void
|
|
|
|
MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
|
|
|
|
SMRange Range, bool ShowColors) {
|
|
|
|
getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
|
2014-10-03 17:16:24 +00:00
|
|
|
Range, SMFixIt(Range, FixMsg),
|
2014-10-03 15:37:37 +00:00
|
|
|
ShowColors);
|
|
|
|
}
|
|
|
|
|
2014-03-25 11:16:03 +00:00
|
|
|
int MipsAsmParser::matchCPURegisterName(StringRef Name) {
|
|
|
|
int CC;
|
2013-02-20 23:11:17 +00:00
|
|
|
|
2013-11-06 11:27:05 +00:00
|
|
|
CC = StringSwitch<unsigned>(Name)
|
|
|
|
.Case("zero", 0)
|
2014-03-25 11:16:03 +00:00
|
|
|
.Case("at", 1)
|
2013-11-06 11:27:05 +00: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 11:05:24 +00:00
|
|
|
.Case("gp", 28)
|
2013-11-06 11:27:05 +00:00
|
|
|
.Case("sp", 29)
|
|
|
|
.Case("fp", 30)
|
2014-03-26 11:05:24 +00:00
|
|
|
.Case("s8", 30)
|
2013-11-06 11:27:05 +00: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-20 23:11:17 +00:00
|
|
|
|
2014-09-15 15:33:01 +00:00
|
|
|
if (!(isABI_N32() || isABI_N64()))
|
|
|
|
return CC;
|
|
|
|
|
2014-10-03 15:37:37 +00:00
|
|
|
if (12 <= CC && CC <= 15) {
|
|
|
|
// Name is one of t4-t7
|
|
|
|
AsmToken RegTok = getLexer().peekTok();
|
|
|
|
SMRange RegRange = RegTok.getLocRange();
|
|
|
|
|
|
|
|
StringRef FixedName = StringSwitch<StringRef>(Name)
|
|
|
|
.Case("t4", "t0")
|
|
|
|
.Case("t5", "t1")
|
|
|
|
.Case("t6", "t2")
|
|
|
|
.Case("t7", "t3")
|
|
|
|
.Default("");
|
|
|
|
assert(FixedName != "" && "Register name is not one of t4-t7.");
|
|
|
|
|
|
|
|
printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
|
|
|
|
"Did you mean $" + FixedName + "?", RegRange);
|
|
|
|
}
|
|
|
|
|
2014-09-15 15:33:01 +00:00
|
|
|
// 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-09 16:27:43 +00:00
|
|
|
|
2013-02-20 23:11:17 +00:00
|
|
|
return CC;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
|
2014-11-11 10:31:31 +00:00
|
|
|
int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
|
|
|
|
int CC;
|
|
|
|
|
|
|
|
CC = StringSwitch<unsigned>(Name)
|
|
|
|
.Case("hwr_cpunum", 0)
|
|
|
|
.Case("hwr_synci_step", 1)
|
|
|
|
.Case("hwr_cc", 2)
|
|
|
|
.Case("hwr_ccres", 3)
|
2014-11-11 11:22:39 +00:00
|
|
|
.Case("hwr_ulr", 29)
|
2014-11-11 10:31:31 +00:00
|
|
|
.Default(-1);
|
|
|
|
|
|
|
|
return CC;
|
|
|
|
}
|
|
|
|
|
2013-08-13 13:07:09 +00:00
|
|
|
int MipsAsmParser::matchFPURegisterName(StringRef Name) {
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2012-09-07 00:23:42 +00:00
|
|
|
if (Name[0] == 'f') {
|
|
|
|
StringRef NumString = Name.substr(1);
|
|
|
|
unsigned IntVal;
|
2013-04-18 00:41:53 +00:00
|
|
|
if (NumString.getAsInteger(10, IntVal))
|
2013-11-06 11:27:05 +00:00
|
|
|
return -1; // This is not an integer.
|
2013-08-13 13:07:09 +00:00
|
|
|
if (IntVal > 31) // Maximum index for fpu register.
|
2012-09-07 00:23:42 +00:00
|
|
|
return -1;
|
2013-08-13 13:07:09 +00:00
|
|
|
return IntVal;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2012-09-07 00:23:42 +00:00
|
|
|
|
2013-08-13 13:07:09 +00: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 11:27:05 +00:00
|
|
|
return -1; // This is not an integer.
|
2013-08-13 13:07:09 +00:00
|
|
|
if (IntVal > 7) // There are only 8 fcc registers.
|
|
|
|
return -1;
|
|
|
|
return IntVal;
|
2012-09-07 00:23:42 +00:00
|
|
|
}
|
2012-09-05 23:34:03 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
|
2013-08-13 13:07:09 +00:00
|
|
|
int MipsAsmParser::matchACRegisterName(StringRef Name) {
|
|
|
|
|
2013-08-14 01:15:52 +00:00
|
|
|
if (Name.startswith("ac")) {
|
|
|
|
StringRef NumString = Name.substr(2);
|
2013-08-13 13:07:09 +00:00
|
|
|
unsigned IntVal;
|
|
|
|
if (NumString.getAsInteger(10, IntVal))
|
2013-11-06 11:27:05 +00:00
|
|
|
return -1; // This is not an integer.
|
2013-08-13 13:07:09 +00:00
|
|
|
if (IntVal > 3) // There are only 3 acc registers.
|
|
|
|
return -1;
|
|
|
|
return IntVal;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2013-06-20 11:21:49 +00:00
|
|
|
|
2013-09-25 23:50:44 +00: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 12:26:50 +00:00
|
|
|
int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
|
|
|
|
int CC;
|
|
|
|
|
|
|
|
CC = StringSwitch<unsigned>(Name)
|
2013-11-06 11:27:05 +00: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 12:26:50 +00:00
|
|
|
|
|
|
|
return CC;
|
|
|
|
}
|
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
bool MipsAssemblerOptions::setATReg(unsigned Reg) {
|
|
|
|
if (Reg > 31)
|
|
|
|
return false;
|
|
|
|
|
2014-09-05 15:43:21 +00:00
|
|
|
ATReg = Reg;
|
2012-10-04 02:29:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-06-18 14:46:05 +00:00
|
|
|
int MipsAsmParser::getATReg(SMLoc Loc) {
|
2014-09-09 10:15:38 +00:00
|
|
|
int AT = AssemblerOptions.back()->getATRegNum();
|
2014-03-24 16:48:01 +00:00
|
|
|
if (AT == 0)
|
2014-06-18 14:46:05 +00:00
|
|
|
reportParseError(Loc,
|
2014-09-16 15:00:52 +00:00
|
|
|
"pseudo-instruction requires $at, which is not available");
|
2014-03-24 16:48:01 +00:00
|
|
|
return AT;
|
|
|
|
}
|
2012-10-04 02:29:46 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
unsigned MipsAsmParser::getReg(int RC, int RegNo) {
|
2013-06-18 07:20:20 +00:00
|
|
|
return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
|
|
|
|
2014-03-27 13:52:53 +00:00
|
|
|
unsigned MipsAsmParser::getGPR(int RegNo) {
|
2014-07-08 08:59:22 +00:00
|
|
|
return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
|
2014-03-27 16:42:17 +00:00
|
|
|
RegNo);
|
2014-03-27 13:52:53 +00:00
|
|
|
}
|
|
|
|
|
2013-01-12 01:03:14 +00:00
|
|
|
int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
|
2013-08-13 13:07:09 +00:00
|
|
|
if (RegNum >
|
2014-03-27 15:00:44 +00:00
|
|
|
getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
|
2012-09-05 23:34:03 +00:00
|
|
|
return -1;
|
|
|
|
|
2013-01-12 01:03:14 +00:00
|
|
|
return getReg(RegClass, RegNum);
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-04 13:23:44 +00:00
|
|
|
DEBUG(dbgs() << "parseOperand\n");
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165199 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-04 04:03:53 +00: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-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
DEBUG(dbgs() << ".. Generic Parser\n");
|
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
switch (getLexer().getKind()) {
|
|
|
|
default:
|
|
|
|
Error(Parser.getTok().getLoc(), "unexpected token in operand");
|
|
|
|
return true;
|
|
|
|
case AsmToken::Dollar: {
|
2013-04-18 00:41:53 +00:00
|
|
|
// Parse the register.
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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.
|
2014-09-04 13:23:44 +00:00
|
|
|
if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
// Maybe it is a symbol reference.
|
2012-09-05 23:34:03 +00:00
|
|
|
StringRef Identifier;
|
2013-02-20 22:21:35 +00:00
|
|
|
if (Parser.parseIdentifier(Identifier))
|
2012-09-05 23:34:03 +00:00
|
|
|
return true;
|
|
|
|
|
2013-01-12 01:03:14 +00:00
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
2012-09-07 09:47:42 +00:00
|
|
|
MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
|
2013-04-18 00:41:53 +00:00
|
|
|
// Otherwise create a symbol reference.
|
2013-11-06 11:27:05 +00:00
|
|
|
const MCExpr *Res =
|
|
|
|
MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
|
2012-09-05 23:34:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-11-06 11:27:05 +00:00
|
|
|
// Else drop to expression parsing.
|
2012-09-05 23:34:03 +00:00
|
|
|
case AsmToken::LParen:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Plus:
|
|
|
|
case AsmToken::Integer:
|
2014-06-18 13:55:18 +00:00
|
|
|
case AsmToken::Tilde:
|
2012-09-05 23:34:03 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
DEBUG(dbgs() << ".. generic integer\n");
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = parseImm(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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return ResTy != MatchOperand_Success;
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
case AsmToken::Percent: {
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
const MCExpr *IdVal;
|
2013-04-18 00:41:53 +00:00
|
|
|
SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
return true;
|
|
|
|
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
return false;
|
2012-10-04 02:29:46 +00:00
|
|
|
} // case AsmToken::Percent
|
|
|
|
} // switch(getLexer().getKind())
|
2012-01-11 03:56:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-06 11:27:05 +00:00
|
|
|
const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
|
2013-04-17 00:18:04 +00:00
|
|
|
StringRef RelocStr) {
|
|
|
|
const MCExpr *Res;
|
2013-04-18 00:41:53 +00:00
|
|
|
// Check the type of the expression.
|
2013-04-17 00:18:04 +00:00
|
|
|
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
|
2014-04-03 10:37:45 +00:00
|
|
|
// It's a constant, evaluate reloc value.
|
|
|
|
int16_t Val;
|
|
|
|
switch (getVariantKind(RelocStr)) {
|
|
|
|
case MCSymbolRefExpr::VK_Mips_ABS_LO:
|
|
|
|
// Get the 1st 16-bits.
|
|
|
|
Val = MCE->getValue() & 0xffff;
|
|
|
|
break;
|
|
|
|
case MCSymbolRefExpr::VK_Mips_ABS_HI:
|
|
|
|
// Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
|
|
|
|
// 16 bits being negative.
|
|
|
|
Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
|
|
|
|
break;
|
|
|
|
case MCSymbolRefExpr::VK_Mips_HIGHER:
|
|
|
|
// Get the 3rd 16-bits.
|
|
|
|
Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
|
|
|
|
break;
|
|
|
|
case MCSymbolRefExpr::VK_Mips_HIGHEST:
|
|
|
|
// Get the 4th 16-bits.
|
|
|
|
Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
|
|
|
|
break;
|
|
|
|
default:
|
2014-09-16 15:00:52 +00:00
|
|
|
report_fatal_error("unsupported reloc value");
|
2013-04-17 00:18:04 +00:00
|
|
|
}
|
2014-04-03 10:37:45 +00:00
|
|
|
return MCConstantExpr::Create(Val, getContext());
|
2013-04-17 00:18:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
|
2013-04-18 00:41:53 +00:00
|
|
|
// It's a symbol, create a symbolic expression from the symbol.
|
2013-04-17 00:18:04 +00:00
|
|
|
StringRef Symbol = MSRE->getSymbol().getName();
|
|
|
|
MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
|
2013-04-18 00:41:53 +00:00
|
|
|
Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
|
2013-04-17 00:18:04 +00:00
|
|
|
return Res;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
|
2014-02-04 18:41:57 +00:00
|
|
|
MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
|
|
|
|
|
2014-04-03 10:37:45 +00:00
|
|
|
// Try to create target expression.
|
|
|
|
if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
|
|
|
|
return MipsMCExpr::Create(VK, Expr, getContext());
|
2014-02-04 18:41:57 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
|
|
|
|
const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
|
2013-04-17 00:18:04 +00:00
|
|
|
Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
|
|
|
|
return Res;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
|
2013-04-18 00:41:53 +00:00
|
|
|
const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
|
|
|
|
Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
|
|
|
|
return Res;
|
2013-04-17 00:18:04 +00:00
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
// Just return the original expression.
|
2013-04-17 00:18:04 +00: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-04 18:41:57 +00:00
|
|
|
case MCExpr::Target:
|
|
|
|
return true;
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-11-06 11:27:05 +00:00
|
|
|
Parser.Lex(); // Eat the % token.
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
if (Tok.isNot(AsmToken::Identifier))
|
|
|
|
return true;
|
|
|
|
|
2012-09-07 09:47:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
const MCExpr *IdVal;
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
|
|
|
if (getLexer().getKind() == AsmToken::LParen) {
|
|
|
|
while (1) {
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
if (getLexer().getKind() == AsmToken::Percent) {
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
const AsmToken &nextTok = Parser.getTok();
|
|
|
|
if (nextTok.isNot(AsmToken::Identifier))
|
|
|
|
return true;
|
2012-09-07 09:47:42 +00:00
|
|
|
Str += "(%";
|
|
|
|
Str += nextTok.getIdentifier();
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
if (getLexer().getKind() != AsmToken::LParen)
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
return true;
|
|
|
|
|
2013-01-12 01:03:14 +00:00
|
|
|
while (getLexer().getKind() == AsmToken::RParen)
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
|
|
|
} else
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
Res = evaluateRelocExpr(IdVal, Str);
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
}
|
|
|
|
|
2012-09-05 23:34:03 +00:00
|
|
|
bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
|
|
|
|
SMLoc &EndLoc) {
|
2014-06-08 16:18:35 +00:00
|
|
|
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = parseAnyRegister(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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (ResTy == MatchOperand_Success) {
|
|
|
|
assert(Operands.size() == 1);
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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.
|
2014-07-08 08:59:22 +00:00
|
|
|
RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (RegNo == (unsigned)-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(Operands.size() == 0);
|
2013-11-06 11:27:05 +00:00
|
|
|
return (RegNo == (unsigned)-1);
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
|
|
|
|
2013-04-17 00:18:04 +00:00
|
|
|
bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-01-12 01:03:14 +00:00
|
|
|
SMLoc S;
|
2013-04-17 00:18:04 +00:00
|
|
|
bool Result = true;
|
|
|
|
|
|
|
|
while (getLexer().getKind() == AsmToken::LParen)
|
|
|
|
Parser.Lex();
|
2013-01-12 01:03:14 +00:00
|
|
|
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
default:
|
|
|
|
return true;
|
2013-03-22 00:05:30 +00:00
|
|
|
case AsmToken::Identifier:
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
case AsmToken::Integer:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Plus:
|
2013-04-17 00:18:04 +00:00
|
|
|
if (isParenExpr)
|
2013-04-18 00:41:53 +00:00
|
|
|
Result = getParser().parseParenExpression(Res, S);
|
2013-04-17 00:18:04 +00:00
|
|
|
else
|
|
|
|
Result = (getParser().parseExpression(Res));
|
2013-04-18 00:41:53 +00:00
|
|
|
while (getLexer().getKind() == AsmToken::RParen)
|
2013-04-17 00:18:04 +00:00
|
|
|
Parser.Lex();
|
2013-04-18 00:41:53 +00:00
|
|
|
break;
|
2013-01-12 01:03:14 +00:00
|
|
|
case AsmToken::Percent:
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
}
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
|
|
|
MipsAsmParser::parseMemOperand(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
DEBUG(dbgs() << "parseMemOperand\n");
|
2014-04-25 05:30:21 +00:00
|
|
|
const MCExpr *IdVal = nullptr;
|
2013-01-12 01:03:14 +00:00
|
|
|
SMLoc S;
|
2013-04-17 00:18:04 +00:00
|
|
|
bool isParenExpr = false;
|
2013-08-13 13:07:09 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
|
2013-04-18 00:41:53 +00:00
|
|
|
// First operand is the offset.
|
2013-01-12 01:03:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-04-17 00:18:04 +00:00
|
|
|
if (getLexer().getKind() != AsmToken::Dollar) {
|
2013-04-18 00:41:53 +00:00
|
|
|
if (parseMemOffset(IdVal, isParenExpr))
|
2013-04-17 00:18:04 +00:00
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
const AsmToken &Tok = Parser.getTok(); // Get the next token.
|
2013-04-17 00:18:04 +00:00
|
|
|
if (Tok.isNot(AsmToken::LParen)) {
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
|
|
|
|
if (Mnemonic.getToken() == "la") {
|
2013-11-06 11:27:05 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
|
2013-04-17 00:18:04 +00:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
if (Tok.is(AsmToken::EndOfStatement)) {
|
2013-11-06 11:27:05 +00:00
|
|
|
SMLoc E =
|
|
|
|
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
2013-04-17 00:18:04 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
// Zero register assumed, add a memory operand with ZERO as its base.
|
2014-04-15 14:13:21 +00:00
|
|
|
// "Base" will be managed by k_Memory.
|
2014-09-04 13:23:44 +00:00
|
|
|
auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
|
2014-06-08 16:18:35 +00:00
|
|
|
S, E, *this);
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165561 91177308-0d34-0410-b5e6-96231b3b80d8
2012-10-09 23:29:45 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Eat the '(' token.
|
2013-04-17 00:18:04 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
Res = parseAnyRegister(Operands);
|
2013-08-13 13:07:09 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2013-08-13 13:07:09 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
Error(Parser.getTok().getLoc(), "')' expected");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
2013-01-12 01:03:14 +00:00
|
|
|
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
|
|
|
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2014-04-25 05:30:21 +00:00
|
|
|
if (!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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
IdVal = MCConstantExpr::Create(0, getContext());
|
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
// Replace the register operand with the memory operand.
|
2014-06-08 16:18:35 +00:00
|
|
|
std::unique_ptr<MipsOperand> op(
|
|
|
|
static_cast<MipsOperand *>(Operands.back().release()));
|
2013-04-18 00:41:53 +00:00
|
|
|
// Remove the register from the operands.
|
2014-04-15 14:13:21 +00:00
|
|
|
// "op" will be managed by k_Memory.
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
Operands.pop_back();
|
2013-04-18 00:41:53 +00:00
|
|
|
// Add the memory operand.
|
2013-04-17 00:18:04 +00: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());
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
|
2012-09-05 23:34:03 +00:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (Expr->getKind() == MCExpr::SymbolRef) {
|
|
|
|
const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
|
2014-08-30 16:48:02 +00:00
|
|
|
StringRef DefSymbol = Ref->getSymbol().getName();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (DefSymbol.startswith("$")) {
|
|
|
|
OperandMatchResultTy ResTy =
|
2014-09-04 13:23:44 +00:00
|
|
|
matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
|
2014-04-01 10:37:46 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return true;
|
2014-04-01 10:37:46 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
llvm_unreachable("Should never ParseFail");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (Expr->getKind() == MCExpr::Constant) {
|
|
|
|
Parser.Lex();
|
|
|
|
const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
|
2014-06-08 16:18:35 +00:00
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateImm(Const, S, Parser.getTok().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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return true;
|
|
|
|
}
|
2013-08-28 00:55:15 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return false;
|
2013-08-28 00:55:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
|
2014-06-08 16:18:35 +00:00
|
|
|
StringRef Identifier,
|
|
|
|
SMLoc S) {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
int Index = matchCPURegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createGPRReg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
2013-08-28 00:55:15 +00:00
|
|
|
|
2014-11-11 10:31:31 +00:00
|
|
|
Index = matchHWRegsRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
|
|
|
Operands.push_back(MipsOperand::createHWRegsReg(
|
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index = matchFPURegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createFGRReg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
2013-01-12 01:03:14 +00:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
2013-07-16 10:07:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index = matchFCCRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createFCCReg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00:00
|
|
|
}
|
2013-10-14 11:49:30 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index = matchACRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createACCReg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
2013-10-14 11:49:30 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
}
|
2013-10-14 11:49:30 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index = matchMSA128RegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createMSA128Reg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00:00
|
|
|
return MatchOperand_Success;
|
2013-10-14 11:49:30 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index = matchMSA128CtrlRegisterName(Identifier);
|
|
|
|
if (Index != -1) {
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createMSACtrlReg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
|
|
|
|
return MatchOperand_Success;
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return MatchOperand_NoMatch;
|
2014-03-31 18:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-04-01 10:40:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
|
|
|
|
if (Token.is(AsmToken::Identifier)) {
|
|
|
|
DEBUG(dbgs() << ".. identifier\n");
|
|
|
|
StringRef Identifier = Token.getIdentifier();
|
2014-04-01 10:37:46 +00:00
|
|
|
OperandMatchResultTy ResTy =
|
2014-09-04 13:23:44 +00:00
|
|
|
matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
|
2014-04-01 10:37:46 +00:00
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
} else if (Token.is(AsmToken::Integer)) {
|
|
|
|
DEBUG(dbgs() << ".. integer\n");
|
2014-09-04 13:23:44 +00:00
|
|
|
Operands.push_back(MipsOperand::createNumericReg(
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
|
|
|
|
*this));
|
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
2013-08-14 01:02:20 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
|
2013-08-14 01:02:20 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return MatchOperand_NoMatch;
|
2014-03-31 18:51:43 +00:00
|
|
|
}
|
2013-08-14 01:02:20 +00:00
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-04 13:23:44 +00:00
|
|
|
DEBUG(dbgs() << "parseAnyRegister\n");
|
2013-08-14 01:02:20 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
auto Token = Parser.getTok();
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
SMLoc S = Token.getLoc();
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
}
|
|
|
|
DEBUG(dbgs() << ".. $\n");
|
2014-03-31 18:51:43 +00:00
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
|
2014-04-01 10:40:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return ResTy;
|
2013-08-14 01:02:20 +00:00
|
|
|
}
|
|
|
|
|
2014-03-31 18:51:43 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::parseImm(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
switch (getLexer().getKind()) {
|
|
|
|
default:
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
case AsmToken::LParen:
|
|
|
|
case AsmToken::Minus:
|
|
|
|
case AsmToken::Plus:
|
|
|
|
case AsmToken::Integer:
|
2014-06-18 13:55:18 +00:00
|
|
|
case AsmToken::Tilde:
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
case AsmToken::String:
|
|
|
|
break;
|
|
|
|
}
|
2013-09-16 10:29:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
const MCExpr *IdVal;
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (getParser().parseExpression(IdVal))
|
|
|
|
return MatchOperand_ParseFail;
|
2013-04-18 00:41:53 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205229 91177308-0d34-0410-b5e6-96231b3b80d8
2014-03-31 17:43:46 +00:00
|
|
|
return MatchOperand_Success;
|
2014-03-31 18:51:43 +00:00
|
|
|
}
|
2013-01-12 01:03:14 +00:00
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-04 13:23:44 +00:00
|
|
|
DEBUG(dbgs() << "parseJumpTarget\n");
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
SMLoc S = getLexer().getLoc();
|
2014-03-31 18:51:43 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
// Integers and expressions are acceptable
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = parseImm(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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (ResTy != MatchOperand_NoMatch)
|
|
|
|
return ResTy;
|
2014-03-31 18:51:43 +00:00
|
|
|
|
2014-04-01 10:40:14 +00:00
|
|
|
// Registers are a valid target and have priority over symbols.
|
2014-09-04 13:23:44 +00:00
|
|
|
ResTy = parseAnyRegister(Operands);
|
2014-04-01 10:40:14 +00:00
|
|
|
if (ResTy != MatchOperand_NoMatch)
|
|
|
|
return ResTy;
|
|
|
|
|
2014-04-01 10:41:48 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
}
|
2014-04-01 10:41:48 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return MatchOperand_Success;
|
2013-01-12 01:03:14 +00:00
|
|
|
}
|
|
|
|
|
2013-10-01 09:48:56 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsAsmParser::parseInvNum(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-10-01 09:48:56 +00: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 11:27:05 +00:00
|
|
|
assert(MCE && "Unexpected MCExpr type.");
|
2013-10-01 09:48:56 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
|
2013-10-01 09:48:56 +00:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
2013-11-18 12:32:49 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
2014-09-04 13:23:44 +00:00
|
|
|
MipsAsmParser::parseLSAImm(OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-11-18 12:32:49 +00: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-22 23:31:38 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
|
2013-11-18 12:32:49 +00:00
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
2014-11-19 16:44:02 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
|
|
|
MipsAsmParser::parseRegisterList(OperandVector &Operands) {
|
|
|
|
MCAsmParser &Parser = getParser();
|
|
|
|
SmallVector<unsigned, 10> Regs;
|
|
|
|
unsigned RegNo;
|
|
|
|
unsigned PrevReg = Mips::NoRegister;
|
|
|
|
bool RegRange = false;
|
|
|
|
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
|
|
|
|
|
|
|
|
if (Parser.getTok().isNot(AsmToken::Dollar))
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
|
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
|
|
|
while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
|
|
|
|
SMLoc E = getLexer().getLoc();
|
|
|
|
MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
|
|
|
|
RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
|
|
|
|
if (RegRange) {
|
|
|
|
// Remove last register operand because registers from register range
|
|
|
|
// should be inserted first.
|
|
|
|
if (RegNo == Mips::RA) {
|
|
|
|
Regs.push_back(RegNo);
|
|
|
|
} else {
|
|
|
|
unsigned TmpReg = PrevReg + 1;
|
|
|
|
while (TmpReg <= RegNo) {
|
|
|
|
if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
|
|
|
|
Error(E, "invalid register operand");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
|
|
|
PrevReg = TmpReg;
|
|
|
|
Regs.push_back(TmpReg++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RegRange = false;
|
|
|
|
} else {
|
|
|
|
if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
|
|
|
|
(RegNo != Mips::RA)) {
|
|
|
|
Error(E, "$16 or $31 expected");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
} else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
|
|
|
|
(RegNo != Mips::FP) && (RegNo != Mips::RA)) {
|
|
|
|
Error(E, "invalid register operand");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
} else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
|
|
|
|
(RegNo != Mips::FP) && (RegNo != Mips::RA)) {
|
|
|
|
Error(E, "consecutive register numbers expected");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
|
|
|
Regs.push_back(RegNo);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Parser.getTok().is(AsmToken::Minus))
|
|
|
|
RegRange = true;
|
|
|
|
|
|
|
|
if (!Parser.getTok().isNot(AsmToken::Minus) &&
|
|
|
|
!Parser.getTok().isNot(AsmToken::Comma)) {
|
|
|
|
Error(E, "',' or '-' expected");
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
}
|
|
|
|
|
|
|
|
Lex(); // Consume comma or minus
|
|
|
|
if (Parser.getTok().isNot(AsmToken::Dollar))
|
|
|
|
break;
|
|
|
|
|
|
|
|
PrevReg = RegNo;
|
|
|
|
}
|
|
|
|
|
|
|
|
SMLoc E = Parser.getTok().getLoc();
|
|
|
|
Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
|
|
|
|
parseMemOperand(Operands);
|
|
|
|
return MatchOperand_Success;
|
|
|
|
}
|
|
|
|
|
2014-12-16 14:59:10 +00:00
|
|
|
MipsAsmParser::OperandMatchResultTy
|
|
|
|
MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
|
|
|
|
MCAsmParser &Parser = getParser();
|
|
|
|
|
|
|
|
SMLoc S = Parser.getTok().getLoc();
|
|
|
|
if (parseAnyRegister(Operands) != MatchOperand_Success)
|
|
|
|
return MatchOperand_ParseFail;
|
|
|
|
|
|
|
|
SMLoc E = Parser.getTok().getLoc();
|
|
|
|
MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
|
|
|
|
unsigned Reg = Op.getGPR32Reg();
|
|
|
|
Operands.pop_back();
|
|
|
|
Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
|
|
|
|
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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
|
|
|
|
|
2013-11-06 11:27:05 +00: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 15:15:02 +00: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)
|
2014-05-27 14:58:51 +00:00
|
|
|
.Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
|
|
|
|
.Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
|
2013-11-06 11:27:05 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
|
2014-04-22 10:15:54 +00:00
|
|
|
assert(VK != MCSymbolRefExpr::VK_None);
|
2014-03-31 15:15:02 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163346 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 20:00:02 +00:00
|
|
|
return VK;
|
|
|
|
}
|
2012-09-07 00:23:42 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00: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.
|
2014-09-04 13:23:44 +00:00
|
|
|
bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (getLexer().is(AsmToken::LParen)) {
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
|
|
|
|
Parser.Lex();
|
2014-09-04 13:23:44 +00:00
|
|
|
if (parseOperand(Operands, Name)) {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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.
|
2014-09-04 13:23:44 +00:00
|
|
|
bool MipsAsmParser::parseBracketSuffix(StringRef Name,
|
2014-06-08 16:18:35 +00:00
|
|
|
OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
if (getLexer().is(AsmToken::LBrac)) {
|
|
|
|
Operands.push_back(
|
|
|
|
MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
|
|
|
|
Parser.Lex();
|
2014-09-04 13:23:44 +00:00
|
|
|
if (parseOperand(Operands, Name)) {
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
|
|
|
|
SMLoc NameLoc, OperandVector &Operands) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
DEBUG(dbgs() << "ParseInstruction\n");
|
2014-08-14 09:18:14 +00:00
|
|
|
|
|
|
|
// We have reached first instruction, module directive are now forbidden.
|
|
|
|
getTargetStreamer().forbidModuleDirective();
|
|
|
|
|
2013-07-17 15:00:42 +00:00
|
|
|
// Check if we have valid mnemonic
|
2013-07-24 07:33:14 +00:00
|
|
|
if (!mnemonicIsValid(Name, 0)) {
|
2013-07-17 15:00:42 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
2014-09-16 15:00:52 +00:00
|
|
|
return Error(NameLoc, "unknown instruction");
|
2013-07-17 15:00:42 +00:00
|
|
|
}
|
2013-07-16 10:07:14 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
|
2012-09-05 23:34:03 +00:00
|
|
|
|
|
|
|
// Read the remaining operands.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
// Read the first operand.
|
2014-09-04 13:23:44 +00:00
|
|
|
if (parseOperand(Operands, Name)) {
|
2012-09-05 23:34:03 +00:00
|
|
|
SMLoc Loc = getLexer().getLoc();
|
2013-02-20 22:21:35 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-05 23:34:03 +00:00
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
2014-09-04 13:23:44 +00:00
|
|
|
if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return true;
|
|
|
|
// AFAIK, parenthesis suffixes are never on the first operand
|
2012-09-05 23:34:03 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
while (getLexer().is(AsmToken::Comma)) {
|
|
|
|
Parser.Lex(); // Eat the comma.
|
2012-09-05 23:34:03 +00:00
|
|
|
// Parse and remember the operand.
|
2014-09-04 13:23:44 +00:00
|
|
|
if (parseOperand(Operands, Name)) {
|
2012-09-05 23:34:03 +00:00
|
|
|
SMLoc Loc = getLexer().getLoc();
|
2013-02-20 22:21:35 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-05 23:34:03 +00: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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
// Parse bracket and parenthesis suffixes before we iterate
|
|
|
|
if (getLexer().is(AsmToken::LBrac)) {
|
2014-09-04 13:23:44 +00:00
|
|
|
if (parseBracketSuffix(Name, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return true;
|
|
|
|
} else if (getLexer().is(AsmToken::LParen) &&
|
2014-09-04 13:23:44 +00:00
|
|
|
parseParenSuffix(Name, 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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205292 91177308-0d34-0410-b5e6-96231b3b80d8
2014-04-01 10:35:28 +00:00
|
|
|
return true;
|
2012-09-05 23:34:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
2013-02-20 22:21:35 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
2012-09-05 23:34:03 +00:00
|
|
|
return Error(Loc, "unexpected token in argument list");
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-09-05 23:34:03 +00:00
|
|
|
return false;
|
2012-01-11 03:56:41 +00:00
|
|
|
}
|
|
|
|
|
2014-07-08 10:11:38 +00:00
|
|
|
bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-04-18 00:41:53 +00:00
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, ErrorMsg);
|
2012-10-04 02:29:46 +00:00
|
|
|
}
|
|
|
|
|
2014-07-08 10:11:38 +00:00
|
|
|
bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
|
2014-04-30 11:28:42 +00:00
|
|
|
return Error(Loc, ErrorMsg);
|
|
|
|
}
|
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
bool MipsAsmParser::parseSetNoAtDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-04-18 00:41:53 +00:00
|
|
|
// Line should look like: ".set noat".
|
|
|
|
// set at reg to 0.
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setATReg(0);
|
2012-10-04 02:29:46 +00:00
|
|
|
// eat noat
|
|
|
|
Parser.Lex();
|
2013-04-18 00:41:53 +00:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 02:29:46 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
bool MipsAsmParser::parseSetAtDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-04-18 00:41:53 +00:00
|
|
|
// Line can be .set at - defaults to $1
|
2012-10-04 02:29:46 +00:00
|
|
|
// or .set at=$reg
|
2013-02-20 23:11:17 +00:00
|
|
|
int AtRegNo;
|
2012-10-04 02:29:46 +00:00
|
|
|
getParser().Lex();
|
|
|
|
if (getLexer().is(AsmToken::EndOfStatement)) {
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setATReg(1);
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
} else if (getLexer().is(AsmToken::Equal)) {
|
2013-04-18 00:41:53 +00:00
|
|
|
getParser().Lex(); // Eat the '='.
|
2012-10-04 02:29:46 +00:00
|
|
|
if (getLexer().isNot(AsmToken::Dollar)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected dollar sign '$'");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Eat the '$'.
|
2013-02-20 23:11:17 +00: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 {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected identifier or integer");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-02-20 23:11:17 +00:00
|
|
|
|
2014-03-25 13:01:06 +00:00
|
|
|
if (AtRegNo < 0 || AtRegNo > 31) {
|
2013-02-20 23:11:17 +00:00
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("invalid register");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
getParser().Lex(); // Eat the register.
|
2012-10-04 02:29:46 +00:00
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
2013-04-18 00:41:53 +00:00
|
|
|
}
|
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
reportParseError("unexpected token in statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetReorderDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2012-10-04 02:29:46 +00:00
|
|
|
Parser.Lex();
|
2013-04-18 00:41:53 +00:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 02:29:46 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setReorder();
|
2014-03-10 13:21:10 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetReorder();
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetNoReorderDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex();
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
2013-04-18 00:41:53 +00:00
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setNoReorder();
|
2014-01-26 06:57:13 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetNoReorder();
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
|
|
|
return false;
|
2012-10-04 02:29:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetMacroDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2012-10-04 02:29:46 +00:00
|
|
|
Parser.Lex();
|
2013-04-18 00:41:53 +00:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 02:29:46 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setMacro();
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetNoMacroDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2012-10-04 02:29:46 +00:00
|
|
|
Parser.Lex();
|
2013-04-18 00:41:53 +00:00
|
|
|
// If this is not the end of the statement, report an error.
|
2012-10-04 02:29:46 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
if (AssemblerOptions.back()->isReorder()) {
|
2012-10-04 02:29:46 +00:00
|
|
|
reportParseError("`noreorder' must be set before `nomacro'");
|
|
|
|
return false;
|
|
|
|
}
|
2014-09-09 10:15:38 +00:00
|
|
|
AssemblerOptions.back()->setNoMacro();
|
2013-04-18 00:41:53 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2012-10-04 02:29:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
2013-03-21 21:44:16 +00:00
|
|
|
|
2014-08-07 12:03:36 +00:00
|
|
|
bool MipsAsmParser::parseSetMsaDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-08-07 12:03:36 +00:00
|
|
|
Parser.Lex();
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
2014-09-16 15:00:52 +00:00
|
|
|
return reportParseError("unexpected token, expected end of statement");
|
2014-08-07 12:03:36 +00:00
|
|
|
|
|
|
|
setFeatureBits(Mips::FeatureMSA, "msa");
|
|
|
|
getTargetStreamer().emitDirectiveSetMsa();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetNoMsaDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-08-07 12:03:36 +00:00
|
|
|
Parser.Lex();
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
2014-09-16 15:00:52 +00:00
|
|
|
return reportParseError("unexpected token, expected end of statement");
|
2014-08-07 12:03:36 +00:00
|
|
|
|
|
|
|
clearFeatureBits(Mips::FeatureMSA, "msa");
|
|
|
|
getTargetStreamer().emitDirectiveSetNoMsa();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-17 09:01:54 +00:00
|
|
|
bool MipsAsmParser::parseSetNoDspDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-17 09:01:54 +00:00
|
|
|
Parser.Lex(); // Eat "nodsp".
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
clearFeatureBits(Mips::FeatureDSP, "dsp");
|
|
|
|
getTargetStreamer().emitDirectiveSetNoDsp();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-04 17:18:07 +00:00
|
|
|
bool MipsAsmParser::parseSetMips16Directive() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-11-04 17:18:07 +00:00
|
|
|
Parser.Lex(); // Eat "mips16".
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
setFeatureBits(Mips::FeatureMips16, "mips16");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips16();
|
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-22 23:08:42 +00:00
|
|
|
bool MipsAsmParser::parseSetNoMips16Directive() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-11-04 17:18:07 +00:00
|
|
|
Parser.Lex(); // Eat "nomips16".
|
|
|
|
|
2014-01-22 23:08:42 +00:00
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2014-01-22 23:08:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-11-04 17:18:07 +00:00
|
|
|
|
|
|
|
clearFeatureBits(Mips::FeatureMips16, "mips16");
|
|
|
|
getTargetStreamer().emitDirectiveSetNoMips16();
|
2014-01-22 23:08:42 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
bool MipsAsmParser::parseSetFpDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-07-10 13:38:23 +00:00
|
|
|
MipsABIFlagsSection::FpABIKind FpAbiVal;
|
2014-07-08 08:59:22 +00:00
|
|
|
// Line can be: .set fp=32
|
|
|
|
// .set fp=xx
|
|
|
|
// .set fp=64
|
|
|
|
Parser.Lex(); // Eat fp token
|
|
|
|
AsmToken Tok = Parser.getTok();
|
|
|
|
if (Tok.isNot(AsmToken::Equal)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected equals sign '='");
|
2014-07-08 08:59:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Parser.Lex(); // Eat '=' token.
|
|
|
|
Tok = Parser.getTok();
|
2014-07-08 10:11:38 +00:00
|
|
|
|
|
|
|
if (!parseFpABIValue(FpAbiVal, ".set"))
|
|
|
|
return false;
|
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2014-07-08 08:59:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-07-10 13:38:23 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
|
2014-07-08 08:59:22 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-09 10:15:38 +00:00
|
|
|
bool MipsAsmParser::parseSetPopDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-09 10:15:38 +00:00
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
|
|
|
|
Parser.Lex();
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
|
|
|
return reportParseError("unexpected token, expected end of statement");
|
|
|
|
|
|
|
|
// Always keep an element on the options "stack" to prevent the user
|
|
|
|
// from changing the initial options. This is how we remember them.
|
|
|
|
if (AssemblerOptions.size() == 2)
|
|
|
|
return reportParseError(Loc, ".set pop with no .set push");
|
|
|
|
|
|
|
|
AssemblerOptions.pop_back();
|
|
|
|
setAvailableFeatures(AssemblerOptions.back()->getFeatures());
|
|
|
|
|
|
|
|
getTargetStreamer().emitDirectiveSetPop();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MipsAsmParser::parseSetPushDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-09 10:15:38 +00:00
|
|
|
Parser.Lex();
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
|
|
|
return reportParseError("unexpected token, expected end of statement");
|
|
|
|
|
|
|
|
// Create a copy of the current assembler options environment and push it.
|
2014-09-12 05:17:20 +00:00
|
|
|
AssemblerOptions.push_back(
|
|
|
|
make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
|
2014-09-09 10:15:38 +00:00
|
|
|
|
|
|
|
getTargetStreamer().emitDirectiveSetPush();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-03-21 21:44:16 +00:00
|
|
|
bool MipsAsmParser::parseSetAssignment() {
|
|
|
|
StringRef Name;
|
|
|
|
const MCExpr *Value;
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-03-21 21:44:16 +00:00
|
|
|
|
|
|
|
if (Parser.parseIdentifier(Name))
|
|
|
|
reportParseError("expected identifier after .set");
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::Comma))
|
2014-09-16 15:00:52 +00:00
|
|
|
return reportParseError("unexpected token, expected comma");
|
2013-04-17 00:18:04 +00:00
|
|
|
Lex(); // Eat comma
|
2013-03-21 21:44:16 +00:00
|
|
|
|
2014-01-22 23:31:38 +00:00
|
|
|
if (Parser.parseExpression(Value))
|
2013-05-28 22:21:05 +00:00
|
|
|
return reportParseError("expected valid expression after comma");
|
2013-03-21 21:44:16 +00:00
|
|
|
|
2013-04-18 00:41:53 +00:00
|
|
|
// Check if the Name already exists as a symbol.
|
2013-03-21 21:44:16 +00:00
|
|
|
MCSymbol *Sym = getContext().LookupSymbol(Name);
|
2013-04-18 00:41:53 +00:00
|
|
|
if (Sym)
|
2013-03-21 21:44:16 +00:00
|
|
|
return reportParseError("symbol already defined");
|
|
|
|
Sym = getContext().GetOrCreateSymbol(Name);
|
|
|
|
Sym->setVariableValue(Value);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-18 00:41:53 +00:00
|
|
|
|
2014-09-09 12:52:14 +00:00
|
|
|
bool MipsAsmParser::parseSetMips0Directive() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-09-09 12:52:14 +00:00
|
|
|
Parser.Lex();
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
|
|
|
return reportParseError("unexpected token, expected end of statement");
|
|
|
|
|
|
|
|
// Reset assembler options to their initial values.
|
|
|
|
setAvailableFeatures(AssemblerOptions.front()->getFeatures());
|
|
|
|
AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
|
|
|
|
|
|
|
|
getTargetStreamer().emitDirectiveSetMips0();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-08-19 14:22:52 +00:00
|
|
|
bool MipsAsmParser::parseSetArchDirective() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-08-19 14:22:52 +00:00
|
|
|
Parser.Lex();
|
|
|
|
if (getLexer().isNot(AsmToken::Equal))
|
|
|
|
return reportParseError("unexpected token, expected equals sign");
|
|
|
|
|
|
|
|
Parser.Lex();
|
|
|
|
StringRef Arch;
|
|
|
|
if (Parser.parseIdentifier(Arch))
|
|
|
|
return reportParseError("expected arch identifier");
|
|
|
|
|
|
|
|
StringRef ArchFeatureName =
|
|
|
|
StringSwitch<StringRef>(Arch)
|
|
|
|
.Case("mips1", "mips1")
|
|
|
|
.Case("mips2", "mips2")
|
|
|
|
.Case("mips3", "mips3")
|
|
|
|
.Case("mips4", "mips4")
|
|
|
|
.Case("mips5", "mips5")
|
|
|
|
.Case("mips32", "mips32")
|
|
|
|
.Case("mips32r2", "mips32r2")
|
|
|
|
.Case("mips32r6", "mips32r6")
|
|
|
|
.Case("mips64", "mips64")
|
|
|
|
.Case("mips64r2", "mips64r2")
|
|
|
|
.Case("mips64r6", "mips64r6")
|
|
|
|
.Case("cnmips", "cnmips")
|
|
|
|
.Case("r4000", "mips3") // This is an implementation of Mips3.
|
|
|
|
.Default("");
|
|
|
|
|
|
|
|
if (ArchFeatureName.empty())
|
|
|
|
return reportParseError("unsupported architecture");
|
|
|
|
|
|
|
|
selectArch(ArchFeatureName);
|
|
|
|
getTargetStreamer().emitDirectiveSetArch(Arch);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-26 14:26:27 +00:00
|
|
|
bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-03-26 14:26:27 +00:00
|
|
|
Parser.Lex();
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
2014-09-16 15:00:52 +00:00
|
|
|
return reportParseError("unexpected token, expected end of statement");
|
2014-03-26 14:26:27 +00:00
|
|
|
|
2014-04-22 10:15:54 +00:00
|
|
|
switch (Feature) {
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unimplemented feature");
|
|
|
|
case Mips::FeatureDSP:
|
|
|
|
setFeatureBits(Mips::FeatureDSP, "dsp");
|
|
|
|
getTargetStreamer().emitDirectiveSetDsp();
|
2014-03-26 14:26:27 +00:00
|
|
|
break;
|
2014-04-22 10:15:54 +00:00
|
|
|
case Mips::FeatureMicroMips:
|
|
|
|
getTargetStreamer().emitDirectiveSetMicroMips();
|
2014-03-26 14:26:27 +00:00
|
|
|
break;
|
2014-08-04 12:20:00 +00:00
|
|
|
case Mips::FeatureMips1:
|
|
|
|
selectArch("mips1");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips1();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips2:
|
|
|
|
selectArch("mips2");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips2();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips3:
|
|
|
|
selectArch("mips3");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips3();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips4:
|
|
|
|
selectArch("mips4");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips4();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips5:
|
|
|
|
selectArch("mips5");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips5();
|
|
|
|
break;
|
|
|
|
case Mips::FeatureMips32:
|
|
|
|
selectArch("mips32");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips32();
|
|
|
|
break;
|
2014-04-22 10:15:54 +00:00
|
|
|
case Mips::FeatureMips32r2:
|
2014-08-04 12:20:00 +00:00
|
|
|
selectArch("mips32r2");
|
2014-04-22 10:15:54 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetMips32R2();
|
2014-03-26 14:26:27 +00:00
|
|
|
break;
|
2014-08-04 12:20:00 +00:00
|
|
|
case Mips::FeatureMips32r6:
|
|
|
|
selectArch("mips32r6");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips32R6();
|
|
|
|
break;
|
2014-04-22 10:15:54 +00:00
|
|
|
case Mips::FeatureMips64:
|
2014-08-04 12:20:00 +00:00
|
|
|
selectArch("mips64");
|
2014-04-22 10:15:54 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetMips64();
|
2014-03-26 15:14:32 +00:00
|
|
|
break;
|
2014-04-22 10:15:54 +00:00
|
|
|
case Mips::FeatureMips64r2:
|
2014-08-04 12:20:00 +00:00
|
|
|
selectArch("mips64r2");
|
2014-04-22 10:15:54 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetMips64R2();
|
2014-03-26 14:52:22 +00:00
|
|
|
break;
|
2014-08-04 12:20:00 +00:00
|
|
|
case Mips::FeatureMips64r6:
|
|
|
|
selectArch("mips64r6");
|
|
|
|
getTargetStreamer().emitDirectiveSetMips64R6();
|
|
|
|
break;
|
2014-03-26 14:26:27 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-27 13:52:53 +00:00
|
|
|
bool MipsAsmParser::eatComma(StringRef ErrorStr) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-03-27 13:52:53 +00:00
|
|
|
if (getLexer().isNot(AsmToken::Comma)) {
|
|
|
|
SMLoc Loc = getLexer().getLoc();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return Error(Loc, ErrorStr);
|
|
|
|
}
|
|
|
|
|
2014-04-22 10:15:54 +00:00
|
|
|
Parser.Lex(); // Eat the comma.
|
2014-03-27 13:52:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-01 14:53:19 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
|
2014-09-09 10:15:38 +00:00
|
|
|
if (AssemblerOptions.back()->isReorder())
|
2014-11-06 10:02:45 +00:00
|
|
|
Warning(Loc, ".cpload should be inside a noreorder section");
|
2014-04-30 11:28:42 +00:00
|
|
|
|
2014-11-06 10:02:45 +00:00
|
|
|
if (inMips16Mode()) {
|
|
|
|
reportParseError(".cpload is not supported in Mips16 mode");
|
|
|
|
return false;
|
|
|
|
}
|
2014-04-30 11:28:42 +00:00
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = parseAnyRegister(Reg);
|
2014-04-30 11:28:42 +00:00
|
|
|
if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
|
|
|
|
reportParseError("expected register containing function address");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-06-08 16:18:35 +00:00
|
|
|
MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
|
|
|
|
if (!RegOpnd.isGPRAsmReg()) {
|
|
|
|
reportParseError(RegOpnd.getStartLoc(), "invalid register");
|
2014-04-30 11:28:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-06 10:02:45 +00:00
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-01 14:53:19 +00:00
|
|
|
getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
|
2014-04-30 11:28:42 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-27 13:52:53 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveCPSetup() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-03-27 13:52:53 +00:00
|
|
|
unsigned FuncReg;
|
|
|
|
unsigned Save;
|
|
|
|
bool SaveIsReg = true;
|
|
|
|
|
2014-06-18 13:08:59 +00:00
|
|
|
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
|
2014-06-18 13:08:59 +00:00
|
|
|
if (ResTy == MatchOperand_NoMatch) {
|
|
|
|
reportParseError("expected register containing function address");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
|
|
|
|
if (!FuncRegOpnd.isGPRAsmReg()) {
|
|
|
|
reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
FuncReg = FuncRegOpnd.getGPR32Reg();
|
|
|
|
TmpReg.clear();
|
2014-03-27 13:52:53 +00:00
|
|
|
|
2014-09-16 15:00:52 +00:00
|
|
|
if (!eatComma("unexpected token, expected comma"))
|
2014-03-27 13:52:53 +00:00
|
|
|
return true;
|
|
|
|
|
2014-09-04 13:23:44 +00:00
|
|
|
ResTy = parseAnyRegister(TmpReg);
|
2014-06-18 13:08:59 +00:00
|
|
|
if (ResTy == MatchOperand_NoMatch) {
|
2014-03-27 13:52:53 +00:00
|
|
|
const AsmToken &Tok = Parser.getTok();
|
|
|
|
if (Tok.is(AsmToken::Integer)) {
|
|
|
|
Save = Tok.getIntVal();
|
|
|
|
SaveIsReg = false;
|
|
|
|
Parser.Lex();
|
2014-06-18 13:08:59 +00:00
|
|
|
} else {
|
|
|
|
reportParseError("expected save register or stack offset");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
|
|
|
|
if (!SaveOpnd.isGPRAsmReg()) {
|
|
|
|
reportParseError(SaveOpnd.getStartLoc(), "invalid register");
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Save = SaveOpnd.getGPR32Reg();
|
|
|
|
}
|
2014-03-27 13:52:53 +00:00
|
|
|
|
2014-09-16 15:00:52 +00:00
|
|
|
if (!eatComma("unexpected token, expected comma"))
|
2014-03-27 13:52:53 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
StringRef Name;
|
|
|
|
if (Parser.parseIdentifier(Name))
|
|
|
|
reportParseError("expected identifier");
|
|
|
|
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
|
|
|
|
|
2014-05-01 10:24:46 +00:00
|
|
|
getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
|
2014-03-27 13:52:53 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-04-16 15:48:55 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveNaN() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-04-16 15:48:55 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
const AsmToken &Tok = Parser.getTok();
|
|
|
|
|
|
|
|
if (Tok.getString() == "2008") {
|
|
|
|
Parser.Lex();
|
|
|
|
getTargetStreamer().emitDirectiveNaN2008();
|
|
|
|
return false;
|
|
|
|
} else if (Tok.getString() == "legacy") {
|
|
|
|
Parser.Lex();
|
|
|
|
getTargetStreamer().emitDirectiveNaNLegacy();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If we don't recognize the option passed to the .nan
|
|
|
|
// directive (e.g. no option or unknown option), emit an error.
|
|
|
|
reportParseError("invalid option in .nan directive");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveSet() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-04-18 00:41:53 +00:00
|
|
|
// Get the next token.
|
2012-10-04 02:29:46 +00:00
|
|
|
const AsmToken &Tok = Parser.getTok();
|
|
|
|
|
|
|
|
if (Tok.getString() == "noat") {
|
|
|
|
return parseSetNoAtDirective();
|
|
|
|
} else if (Tok.getString() == "at") {
|
|
|
|
return parseSetAtDirective();
|
2014-08-19 14:22:52 +00:00
|
|
|
} else if (Tok.getString() == "arch") {
|
|
|
|
return parseSetArchDirective();
|
2014-07-08 08:59:22 +00:00
|
|
|
} else if (Tok.getString() == "fp") {
|
|
|
|
return parseSetFpDirective();
|
2014-09-09 10:15:38 +00:00
|
|
|
} else if (Tok.getString() == "pop") {
|
|
|
|
return parseSetPopDirective();
|
|
|
|
} else if (Tok.getString() == "push") {
|
|
|
|
return parseSetPushDirective();
|
2012-10-04 02:29:46 +00:00
|
|
|
} 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-22 23:08:42 +00:00
|
|
|
} else if (Tok.getString() == "mips16") {
|
2014-11-04 17:18:07 +00:00
|
|
|
return parseSetMips16Directive();
|
2012-10-04 02:29:46 +00:00
|
|
|
} else if (Tok.getString() == "nomips16") {
|
2014-01-22 23:08:42 +00:00
|
|
|
return parseSetNoMips16Directive();
|
2012-10-04 02:29:46 +00:00
|
|
|
} else if (Tok.getString() == "nomicromips") {
|
2014-01-14 04:25:13 +00:00
|
|
|
getTargetStreamer().emitDirectiveSetNoMicroMips();
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
} else if (Tok.getString() == "micromips") {
|
2014-04-22 10:15:54 +00:00
|
|
|
return parseSetFeature(Mips::FeatureMicroMips);
|
2014-09-09 12:52:14 +00:00
|
|
|
} else if (Tok.getString() == "mips0") {
|
|
|
|
return parseSetMips0Directive();
|
2014-08-04 12:20:00 +00:00
|
|
|
} else if (Tok.getString() == "mips1") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips1);
|
|
|
|
} else if (Tok.getString() == "mips2") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips2);
|
|
|
|
} else if (Tok.getString() == "mips3") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips3);
|
|
|
|
} else if (Tok.getString() == "mips4") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips4);
|
|
|
|
} else if (Tok.getString() == "mips5") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips5);
|
|
|
|
} else if (Tok.getString() == "mips32") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips32);
|
2014-03-04 09:54:09 +00:00
|
|
|
} else if (Tok.getString() == "mips32r2") {
|
2014-04-22 10:15:54 +00:00
|
|
|
return parseSetFeature(Mips::FeatureMips32r2);
|
2014-08-04 12:20:00 +00:00
|
|
|
} else if (Tok.getString() == "mips32r6") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips32r6);
|
2014-03-26 15:14:32 +00:00
|
|
|
} else if (Tok.getString() == "mips64") {
|
2014-04-22 10:15:54 +00:00
|
|
|
return parseSetFeature(Mips::FeatureMips64);
|
2014-03-26 14:52:22 +00:00
|
|
|
} else if (Tok.getString() == "mips64r2") {
|
2014-04-22 10:15:54 +00:00
|
|
|
return parseSetFeature(Mips::FeatureMips64r2);
|
2014-08-04 12:20:00 +00:00
|
|
|
} else if (Tok.getString() == "mips64r6") {
|
|
|
|
return parseSetFeature(Mips::FeatureMips64r6);
|
2014-03-05 11:05:09 +00:00
|
|
|
} else if (Tok.getString() == "dsp") {
|
2014-04-22 10:15:54 +00:00
|
|
|
return parseSetFeature(Mips::FeatureDSP);
|
2014-09-17 09:01:54 +00:00
|
|
|
} else if (Tok.getString() == "nodsp") {
|
|
|
|
return parseSetNoDspDirective();
|
2014-08-07 12:03:36 +00:00
|
|
|
} else if (Tok.getString() == "msa") {
|
|
|
|
return parseSetMsaDirective();
|
|
|
|
} else if (Tok.getString() == "nomsa") {
|
|
|
|
return parseSetNoMsaDirective();
|
2013-03-21 21:44:16 +00:00
|
|
|
} else {
|
2013-04-18 00:41:53 +00:00
|
|
|
// It is just an identifier, look for an assignment.
|
2013-03-21 21:44:16 +00:00
|
|
|
parseSetAssignment();
|
|
|
|
return false;
|
2012-10-04 02:29:46 +00:00
|
|
|
}
|
2013-01-25 01:31:34 +00:00
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-26 15:24:36 +00:00
|
|
|
/// parseDataDirective
|
2013-01-25 01:31:34 +00:00
|
|
|
/// ::= .word [ expression (, expression)* ]
|
2014-03-26 15:24:36 +00:00
|
|
|
bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-01-25 01:31:34 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
for (;;) {
|
|
|
|
const MCExpr *Value;
|
2013-02-20 22:21:35 +00:00
|
|
|
if (getParser().parseExpression(Value))
|
2013-01-25 01:31:34 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
getParser().getStreamer().EmitValue(Value, Size);
|
|
|
|
|
|
|
|
if (getLexer().is(AsmToken::EndOfStatement))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::Comma))
|
2014-09-16 15:00:52 +00:00
|
|
|
return Error(L, "unexpected token, expected comma");
|
2013-01-25 01:31:34 +00:00
|
|
|
Parser.Lex();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Parser.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-11-06 11:27:05 +00:00
|
|
|
/// parseDirectiveGpWord
|
|
|
|
/// ::= .gpword local_sym
|
|
|
|
bool MipsAsmParser::parseDirectiveGpWord() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-11-06 11:27:05 +00:00
|
|
|
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 13:18:04 +00:00
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
2014-09-16 15:00:52 +00:00
|
|
|
return Error(getLexer().getLoc(),
|
|
|
|
"unexpected token, expected end of statement");
|
2013-11-13 13:18:04 +00:00
|
|
|
Parser.Lex(); // Eat EndOfStatement token.
|
2013-11-06 11:27:05 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-31 14:15:07 +00:00
|
|
|
/// parseDirectiveGpDWord
|
2014-03-28 18:50:26 +00:00
|
|
|
/// ::= .gpdword local_sym
|
2014-03-31 14:15:07 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveGpDWord() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-03-28 18:50:26 +00: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))
|
2014-09-16 15:00:52 +00:00
|
|
|
return Error(getLexer().getLoc(),
|
|
|
|
"unexpected token, expected end of statement");
|
2014-03-28 18:50:26 +00:00
|
|
|
Parser.Lex(); // Eat EndOfStatement token.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-06 23:27:31 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveOption() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-01-06 23:27:31 +00:00
|
|
|
// Get the option token.
|
|
|
|
AsmToken Tok = Parser.getTok();
|
|
|
|
// At the moment only identifiers are supported.
|
|
|
|
if (Tok.isNot(AsmToken::Identifier)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
|
2014-01-06 23:27:31 +00:00
|
|
|
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(),
|
2014-09-16 15:00:52 +00:00
|
|
|
"unexpected token, expected end of statement");
|
2014-01-06 23:27:31 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-26 13:40:29 +00:00
|
|
|
if (Option == "pic2") {
|
|
|
|
getTargetStreamer().emitDirectiveOptionPic2();
|
|
|
|
Parser.Lex();
|
|
|
|
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
Error(Parser.getTok().getLoc(),
|
2014-09-16 15:00:52 +00:00
|
|
|
"unexpected token, expected end of statement");
|
2014-03-26 13:40:29 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-06 23:27:31 +00:00
|
|
|
// Unknown option.
|
2014-09-16 15:00:52 +00:00
|
|
|
Warning(Parser.getTok().getLoc(),
|
|
|
|
"unknown option, expected 'pic0' or 'pic2'");
|
2014-01-06 23:27:31 +00:00
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-10 13:38:23 +00:00
|
|
|
/// parseDirectiveModule
|
|
|
|
/// ::= .module oddspreg
|
|
|
|
/// ::= .module nooddspreg
|
|
|
|
/// ::= .module fp=value
|
2014-07-08 08:59:22 +00:00
|
|
|
bool MipsAsmParser::parseDirectiveModule() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-07-10 13:38:23 +00:00
|
|
|
MCAsmLexer &Lexer = getLexer();
|
|
|
|
SMLoc L = Lexer.getLoc();
|
|
|
|
|
2014-08-14 09:18:14 +00:00
|
|
|
if (!getTargetStreamer().isModuleDirectiveAllowed()) {
|
2014-07-08 08:59:22 +00:00
|
|
|
// TODO : get a better message.
|
|
|
|
reportParseError(".module directive must appear before any code");
|
|
|
|
return false;
|
|
|
|
}
|
2014-07-10 13:38:23 +00:00
|
|
|
|
|
|
|
if (Lexer.is(AsmToken::Identifier)) {
|
|
|
|
StringRef Option = Parser.getTok().getString();
|
|
|
|
Parser.Lex();
|
|
|
|
|
|
|
|
if (Option == "oddspreg") {
|
|
|
|
getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
|
|
|
|
clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2014-07-10 13:38:23 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
} else if (Option == "nooddspreg") {
|
|
|
|
if (!isABI_O32()) {
|
|
|
|
Error(L, "'.module nooddspreg' requires the O32 ABI");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
|
|
|
|
setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2014-07-10 13:38:23 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
} else if (Option == "fp") {
|
|
|
|
return parseDirectiveModuleFP();
|
|
|
|
}
|
|
|
|
|
|
|
|
return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
|
2014-07-08 08:59:22 +00:00
|
|
|
}
|
2014-07-10 13:38:23 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// parseDirectiveModuleFP
|
|
|
|
/// ::= =32
|
|
|
|
/// ::= =xx
|
|
|
|
/// ::= =64
|
|
|
|
bool MipsAsmParser::parseDirectiveModuleFP() {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-07-10 13:38:23 +00:00
|
|
|
MCAsmLexer &Lexer = getLexer();
|
|
|
|
|
|
|
|
if (Lexer.isNot(AsmToken::Equal)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected equals sign '='");
|
2014-07-08 08:59:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Parser.Lex(); // Eat '=' token.
|
2014-07-08 10:11:38 +00:00
|
|
|
|
2014-07-10 13:38:23 +00:00
|
|
|
MipsABIFlagsSection::FpABIKind FpABI;
|
2014-07-08 10:11:38 +00:00
|
|
|
if (!parseFpABIValue(FpABI, ".module"))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
reportParseError("unexpected token, expected end of statement");
|
2014-07-08 10:11:38 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-08 10:35:52 +00:00
|
|
|
// Emit appropriate flags.
|
|
|
|
getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
|
2014-07-10 13:38:23 +00:00
|
|
|
Parser.Lex(); // Consume the EndOfStatement.
|
2014-07-08 10:11:38 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-10 13:38:23 +00:00
|
|
|
bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
|
2014-07-08 10:11:38 +00:00
|
|
|
StringRef Directive) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2014-07-08 10:11:38 +00:00
|
|
|
MCAsmLexer &Lexer = getLexer();
|
|
|
|
|
|
|
|
if (Lexer.is(AsmToken::Identifier)) {
|
|
|
|
StringRef Value = Parser.getTok().getString();
|
|
|
|
Parser.Lex();
|
|
|
|
|
|
|
|
if (Value != "xx") {
|
|
|
|
reportParseError("unsupported value, expected 'xx', '32' or '64'");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isABI_O32()) {
|
|
|
|
reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
|
2014-07-08 08:59:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-07-08 10:11:38 +00:00
|
|
|
|
2014-07-10 13:38:23 +00:00
|
|
|
FpABI = MipsABIFlagsSection::FpABIKind::XX;
|
2014-07-08 10:11:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Lexer.is(AsmToken::Integer)) {
|
|
|
|
unsigned Value = Parser.getTok().getIntVal();
|
|
|
|
Parser.Lex();
|
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
if (Value != 32 && Value != 64) {
|
2014-07-08 10:11:38 +00:00
|
|
|
reportParseError("unsupported value, expected 'xx', '32' or '64'");
|
2014-07-08 08:59:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-07-08 10:11:38 +00:00
|
|
|
|
|
|
|
if (Value == 32) {
|
|
|
|
if (!isABI_O32()) {
|
|
|
|
reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-07-10 13:38:23 +00:00
|
|
|
FpABI = MipsABIFlagsSection::FpABIKind::S32;
|
|
|
|
} else
|
|
|
|
FpABI = MipsABIFlagsSection::FpABIKind::S64;
|
2014-07-08 10:11:38 +00:00
|
|
|
|
2014-07-10 13:38:23 +00:00
|
|
|
return true;
|
2014-07-08 08:59:22 +00:00
|
|
|
}
|
2014-07-08 10:11:38 +00:00
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-07-08 10:11:38 +00:00
|
|
|
|
2012-10-04 02:29:46 +00:00
|
|
|
bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
|
2014-11-11 05:18:41 +00:00
|
|
|
MCAsmParser &Parser = getParser();
|
2013-01-25 01:31:34 +00:00
|
|
|
StringRef IDVal = DirectiveID.getString();
|
|
|
|
|
2014-04-30 11:28:42 +00:00
|
|
|
if (IDVal == ".cpload")
|
2014-10-01 14:53:19 +00:00
|
|
|
return parseDirectiveCpLoad(DirectiveID.getLoc());
|
2014-03-26 15:44:18 +00:00
|
|
|
if (IDVal == ".dword") {
|
|
|
|
parseDataDirective(8, DirectiveID.getLoc());
|
|
|
|
return false;
|
|
|
|
}
|
2014-08-11 16:10:19 +00:00
|
|
|
if (IDVal == ".ent") {
|
2014-08-13 10:07:34 +00:00
|
|
|
StringRef SymbolName;
|
|
|
|
|
|
|
|
if (Parser.parseIdentifier(SymbolName)) {
|
|
|
|
reportParseError("expected identifier after .ent");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// There's an undocumented extension that allows an integer to
|
|
|
|
// follow the name of the procedure which AFAICS is ignored by GAS.
|
|
|
|
// Example: .ent foo,2
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
if (getLexer().isNot(AsmToken::Comma)) {
|
|
|
|
// Even though we accept this undocumented extension for compatibility
|
|
|
|
// reasons, the additional integer argument does not actually change
|
|
|
|
// the behaviour of the '.ent' directive, so we would like to discourage
|
|
|
|
// its use. We do this by not referring to the extended version in
|
|
|
|
// error messages which are not directly related to its use.
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Parser.Lex(); // Eat the comma.
|
|
|
|
const MCExpr *DummyNumber;
|
|
|
|
int64_t DummyNumberVal;
|
|
|
|
// If the user was explicitly trying to use the extended version,
|
|
|
|
// we still give helpful extension-related error messages.
|
|
|
|
if (Parser.parseExpression(DummyNumber)) {
|
|
|
|
reportParseError("expected number after comma");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
|
|
|
|
reportParseError("expected an absolute expression after comma");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
|
|
|
|
|
|
|
|
getTargetStreamer().emitDirectiveEnt(*Sym);
|
|
|
|
CurrentFn = Sym;
|
2012-09-07 00:48:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 01:31:34 +00:00
|
|
|
if (IDVal == ".end") {
|
2014-08-13 10:07:34 +00:00
|
|
|
StringRef SymbolName;
|
|
|
|
|
|
|
|
if (Parser.parseIdentifier(SymbolName)) {
|
|
|
|
reportParseError("expected identifier after .end");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CurrentFn == nullptr) {
|
|
|
|
reportParseError(".end used without .ent");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((SymbolName != CurrentFn->getName())) {
|
|
|
|
reportParseError(".end symbol does not match .ent symbol");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
getTargetStreamer().emitDirectiveEnd(SymbolName);
|
|
|
|
CurrentFn = nullptr;
|
2012-09-07 00:48:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 01:31:34 +00:00
|
|
|
if (IDVal == ".frame") {
|
2014-08-13 10:07:34 +00:00
|
|
|
// .frame $stack_reg, frame_size_in_bytes, $return_reg
|
|
|
|
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
|
2014-09-04 13:23:44 +00:00
|
|
|
OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
|
2014-08-13 10:07:34 +00:00
|
|
|
if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
|
|
|
|
reportParseError("expected stack register");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
|
|
|
|
if (!StackRegOpnd.isGPRAsmReg()) {
|
|
|
|
reportParseError(StackRegOpnd.getStartLoc(),
|
|
|
|
"expected general purpose register");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
unsigned StackReg = StackRegOpnd.getGPR32Reg();
|
|
|
|
|
|
|
|
if (Parser.getTok().is(AsmToken::Comma))
|
|
|
|
Parser.Lex();
|
|
|
|
else {
|
|
|
|
reportParseError("unexpected token, expected comma");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the frame size.
|
|
|
|
const MCExpr *FrameSize;
|
|
|
|
int64_t FrameSizeVal;
|
|
|
|
|
|
|
|
if (Parser.parseExpression(FrameSize)) {
|
|
|
|
reportParseError("expected frame size value");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
|
|
|
|
reportParseError("frame size not an absolute expression");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Parser.getTok().is(AsmToken::Comma))
|
|
|
|
Parser.Lex();
|
|
|
|
else {
|
|
|
|
reportParseError("unexpected token, expected comma");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the return register.
|
|
|
|
TmpReg.clear();
|
2014-09-04 13:23:44 +00:00
|
|
|
ResTy = parseAnyRegister(TmpReg);
|
2014-08-13 10:07:34 +00:00
|
|
|
if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
|
|
|
|
reportParseError("expected return register");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
|
|
|
|
if (!ReturnRegOpnd.isGPRAsmReg()) {
|
|
|
|
reportParseError(ReturnRegOpnd.getStartLoc(),
|
|
|
|
"expected general purpose register");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
|
|
|
|
ReturnRegOpnd.getGPR32Reg());
|
2012-09-07 00:48:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 01:31:34 +00:00
|
|
|
if (IDVal == ".set") {
|
2012-10-04 02:29:46 +00:00
|
|
|
return parseDirectiveSet();
|
2012-09-07 00:48:02 +00:00
|
|
|
}
|
|
|
|
|
2014-08-13 10:07:34 +00:00
|
|
|
if (IDVal == ".mask" || IDVal == ".fmask") {
|
|
|
|
// .mask bitmask, frame_offset
|
|
|
|
// bitmask: One bit for each register used.
|
|
|
|
// frame_offset: Offset from Canonical Frame Address ($sp on entry) where
|
|
|
|
// first register is expected to be saved.
|
|
|
|
// Examples:
|
|
|
|
// .mask 0x80000000, -4
|
|
|
|
// .fmask 0x80000000, -4
|
|
|
|
//
|
2014-08-11 15:28:56 +00:00
|
|
|
|
2014-08-13 10:07:34 +00:00
|
|
|
// Parse the bitmask
|
|
|
|
const MCExpr *BitMask;
|
|
|
|
int64_t BitMaskVal;
|
|
|
|
|
|
|
|
if (Parser.parseExpression(BitMask)) {
|
|
|
|
reportParseError("expected bitmask value");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
|
|
|
|
reportParseError("bitmask not an absolute expression");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Parser.getTok().is(AsmToken::Comma))
|
|
|
|
Parser.Lex();
|
|
|
|
else {
|
|
|
|
reportParseError("unexpected token, expected comma");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the frame_offset
|
|
|
|
const MCExpr *FrameOffset;
|
|
|
|
int64_t FrameOffsetVal;
|
|
|
|
|
|
|
|
if (Parser.parseExpression(FrameOffset)) {
|
|
|
|
reportParseError("expected frame offset value");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
|
|
|
|
reportParseError("frame offset not an absolute expression");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is not the end of the statement, report an error.
|
|
|
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
|
|
|
reportParseError("unexpected token, expected end of statement");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IDVal == ".mask")
|
|
|
|
getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
|
|
|
|
else
|
|
|
|
getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
|
2012-09-07 00:48:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-04-16 15:48:55 +00:00
|
|
|
if (IDVal == ".nan")
|
|
|
|
return parseDirectiveNaN();
|
|
|
|
|
2013-01-25 01:31:34 +00:00
|
|
|
if (IDVal == ".gpword") {
|
2013-11-06 11:27:05 +00:00
|
|
|
parseDirectiveGpWord();
|
2012-09-07 00:48:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-28 18:50:26 +00:00
|
|
|
if (IDVal == ".gpdword") {
|
2014-03-31 14:15:07 +00:00
|
|
|
parseDirectiveGpDWord();
|
2014-03-28 18:50:26 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-25 01:31:34 +00:00
|
|
|
if (IDVal == ".word") {
|
2014-03-26 15:24:36 +00:00
|
|
|
parseDataDirective(4, DirectiveID.getLoc());
|
2013-01-25 01:31:34 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-06 23:27:31 +00:00
|
|
|
if (IDVal == ".option")
|
|
|
|
return parseDirectiveOption();
|
|
|
|
|
|
|
|
if (IDVal == ".abicalls") {
|
|
|
|
getTargetStreamer().emitDirectiveAbiCalls();
|
|
|
|
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
|
2014-09-16 15:00:52 +00:00
|
|
|
Error(Parser.getTok().getLoc(),
|
|
|
|
"unexpected token, expected end of statement");
|
2014-01-06 23:27:31 +00:00
|
|
|
// Clear line
|
|
|
|
Parser.eatToEndOfStatement();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-27 13:52:53 +00:00
|
|
|
if (IDVal == ".cpsetup")
|
|
|
|
return parseDirectiveCPSetup();
|
|
|
|
|
2014-07-08 08:59:22 +00:00
|
|
|
if (IDVal == ".module")
|
|
|
|
return parseDirectiveModule();
|
|
|
|
|
2012-01-11 03:56:41 +00: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-05 23:34:03 +00:00
|
|
|
|
|
|
|
#define GET_REGISTER_MATCHER
|
|
|
|
#define GET_MATCHER_IMPLEMENTATION
|
|
|
|
#include "MipsGenAsmMatcher.inc"
|