mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
[mips][msa] Fix immediate value of LSA instruction as it was being wrongly encoded.
The immediate field should be encoded as "imm - 1" as the CPU always adds one to that field. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195004 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f56f1dfecc
commit
95adf91f29
@ -157,7 +157,10 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
|
||||
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
|
||||
|
||||
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||
unsigned RegKind);
|
||||
|
||||
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
|
||||
@ -299,7 +302,8 @@ private:
|
||||
k_PostIndexRegister,
|
||||
k_Register,
|
||||
k_PtrReg,
|
||||
k_Token
|
||||
k_Token,
|
||||
k_LSAImm
|
||||
} Kind;
|
||||
|
||||
MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
|
||||
@ -374,6 +378,7 @@ public:
|
||||
bool isMem() const { return Kind == k_Memory; }
|
||||
bool isPtrReg() const { return Kind == k_PtrReg; }
|
||||
bool isInvNum() const { return Kind == k_Immediate; }
|
||||
bool isLSAImm() const { return Kind == k_LSAImm; }
|
||||
|
||||
StringRef getToken() const {
|
||||
assert(Kind == k_Token && "Invalid access!");
|
||||
@ -396,7 +401,7 @@ public:
|
||||
}
|
||||
|
||||
const MCExpr *getImm() const {
|
||||
assert((Kind == k_Immediate) && "Invalid access!");
|
||||
assert((Kind == k_Immediate || Kind == k_LSAImm) && "Invalid access!");
|
||||
return Imm.Val;
|
||||
}
|
||||
|
||||
@ -443,8 +448,16 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
|
||||
SMLoc E) {
|
||||
static MipsOperand *CreateLSAImm(const MCExpr *Val, SMLoc S, SMLoc E) {
|
||||
MipsOperand *Op = new MipsOperand(k_LSAImm);
|
||||
Op->Imm.Val = Val;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
|
||||
SMLoc S, SMLoc E) {
|
||||
MipsOperand *Op = new MipsOperand(k_Memory);
|
||||
Op->Mem.Base = Base;
|
||||
Op->Mem.Off = Off;
|
||||
@ -2058,6 +2071,45 @@ MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
MipsAsmParser::OperandMatchResultTy
|
||||
MipsAsmParser::parseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
|
||||
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;
|
||||
}
|
||||
|
||||
Operands.push_back(MipsOperand::CreateLSAImm(Expr, S,
|
||||
Parser.getTok().getLoc()));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
|
||||
|
||||
MCSymbolRefExpr::VariantKind VK =
|
||||
|
@ -246,6 +246,13 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
// Decode the immediate field of an LSA instruction which
|
||||
// is off by one.
|
||||
static DecodeStatus DecodeLSAImm(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeInsSize(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
@ -785,6 +792,15 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLSAImm(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
// We add one to the immediate field as it was encoded as 'imm - 1'.
|
||||
Inst.addOperand(MCOperand::CreateImm(Insn + 1));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeInsSize(MCInst &Inst,
|
||||
unsigned Insn,
|
||||
uint64_t Address,
|
||||
|
@ -116,6 +116,10 @@ public:
|
||||
unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
// getLSAImmEncoding - Return binary encoding of LSA immediate.
|
||||
unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
unsigned
|
||||
getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
@ -521,5 +525,13 @@ MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
|
||||
return Position + Size - 1;
|
||||
}
|
||||
|
||||
unsigned
|
||||
MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
assert(MI.getOperand(OpNo).isImm());
|
||||
// The immediate is encoded as 'immediate - 1'.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) - 1;
|
||||
}
|
||||
|
||||
#include "MipsGenMCCodeEmitter.inc"
|
||||
|
||||
|
@ -114,6 +114,7 @@ private:
|
||||
unsigned getMemEncodingMMImm12(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getLSAImmEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
|
||||
void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
|
||||
int Offset) const;
|
||||
@ -236,6 +237,12 @@ unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
|
||||
getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getLSAImmEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
llvm_unreachable("Unimplemented function.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||
/// operand requires relocation, record the relocation and return zero.
|
||||
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||
|
@ -65,6 +65,21 @@ def uimm2 : Operand<i32> {
|
||||
let PrintMethod = "printUnsignedImm";
|
||||
}
|
||||
|
||||
// The immediate of an LSA instruction needs special handling
|
||||
// as the encoded value should be subtracted by one.
|
||||
def uimm2LSAAsmOperand : AsmOperandClass {
|
||||
let Name = "LSAImm";
|
||||
let ParserMethod = "parseLSAImm";
|
||||
let RenderMethod = "addImmOperands";
|
||||
}
|
||||
|
||||
def LSAImm : Operand<i32> {
|
||||
let PrintMethod = "printUnsignedImm";
|
||||
let EncoderMethod = "getLSAImmEncoding";
|
||||
let DecoderMethod = "DecodeLSAImm";
|
||||
let ParserMatchClass = uimm2LSAAsmOperand;
|
||||
}
|
||||
|
||||
def uimm3 : Operand<i32> {
|
||||
let PrintMethod = "printUnsignedImm8";
|
||||
}
|
||||
@ -2283,7 +2298,7 @@ class LDI_D_DESC : MSA_I10_LDI_DESC_BASE<"ldi.d", MSA128DOpnd>;
|
||||
|
||||
class LSA_DESC {
|
||||
dag OutOperandList = (outs GPR32Opnd:$rd);
|
||||
dag InOperandList = (ins GPR32Opnd:$rs, GPR32Opnd:$rt, uimm2:$sa);
|
||||
dag InOperandList = (ins GPR32Opnd:$rs, GPR32Opnd:$rt, LSAImm:$sa);
|
||||
string AsmString = "lsa\t$rd, $rs, $rt, $sa";
|
||||
list<dag> Pattern = [(set GPR32Opnd:$rd, (add GPR32Opnd:$rs,
|
||||
(shl GPR32Opnd:$rt,
|
||||
|
@ -2,8 +2,17 @@
|
||||
#
|
||||
# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=+msa -arch=mips -filetype=obj -o - | llvm-objdump -d -triple=mipsel-unknown-linux -mattr=+msa -arch=mips - | FileCheck %s -check-prefix=CHECKOBJDUMP
|
||||
#
|
||||
# CHECK: lsa $8, $9, $10, 2 # encoding: [0x01,0x2a,0x40,0x85]
|
||||
# CHECK: lsa $8, $9, $10, 1 # encoding: [0x01,0x2a,0x40,0x05]
|
||||
# CHECK: lsa $8, $9, $10, 2 # encoding: [0x01,0x2a,0x40,0x45]
|
||||
# CHECK: lsa $8, $9, $10, 3 # encoding: [0x01,0x2a,0x40,0x85]
|
||||
# CHECK: lsa $8, $9, $10, 4 # encoding: [0x01,0x2a,0x40,0xc5]
|
||||
|
||||
# CHECKOBJDUMP: lsa $8, $9, $10, 1
|
||||
# CHECKOBJDUMP: lsa $8, $9, $10, 2
|
||||
# CHECKOBJDUMP: lsa $8, $9, $10, 3
|
||||
# CHECKOBJDUMP: lsa $8, $9, $10, 4
|
||||
|
||||
lsa $8, $9, $10, 1
|
||||
lsa $8, $9, $10, 2
|
||||
lsa $8, $9, $10, 3
|
||||
lsa $8, $9, $10, 4
|
||||
|
Loading…
Reference in New Issue
Block a user