Skip to content

Commit

Permalink
[mips][mips64r6] [ls][wd]c2 were re-encoded with 11-bit signed immedi…
Browse files Browse the repository at this point in the history
…ates rather than 16-bit in MIPS32r6/MIPS64r6

Summary:
The error message for the invalid.s cases isn't very helpful. It happens because
there is an instruction with a wider immediate that would have matched if the
NotMips32r6 predicate were true. I have some WIP to improve the message but it
affects most error messages for removed/re-encoded instructions on
MIPS32r6/MIPS64r6 and should therefore be a separate commit.

Depens on D4115

Reviewers: zoran.jovanovic, jkolek, vmedic

Reviewed By: vmedic

Differential Revision: http://reviews.llvm.org/D4117

llvm-svn: 211012
  • Loading branch information
dsandersllvm committed Jun 16, 2014
1 parent aee59ae commit 5e6f54e
Show file tree
Hide file tree
Showing 18 changed files with 140 additions and 47 deletions.
10 changes: 10 additions & 0 deletions llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Expand Up @@ -620,6 +620,12 @@ class MipsOperand : public MCParsedAsmOperand {
return Kind == k_Token;
}
bool isMem() const override { return Kind == k_Memory; }
bool isConstantMemOff() const {
return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
}
template <unsigned Bits> bool isMemWithSimmOffset() const {
return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
}
bool isInvNum() const { return Kind == k_Immediate; }
bool isLSAImm() const {
if (!isConstantImm())
Expand Down Expand Up @@ -664,6 +670,10 @@ class MipsOperand : public MCParsedAsmOperand {
return Mem.Off;
}

int64_t getConstantMemOff() const {
return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
}

static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
MipsAsmParser &Parser) {
auto Op = make_unique<MipsOperand>(k_Token, Parser);
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/Target/Mips/Mips32r6InstrFormats.td
Expand Up @@ -40,6 +40,8 @@ def OPGROUP_PCREL : OPGROUP<0b111011>;
def OPGROUP_REGIMM : OPGROUP<0b000001>;
def OPGROUP_SPECIAL : OPGROUP<0b000000>;
def OPGROUP_SPECIAL3 : OPGROUP<0b011111>;
// The spec names this constant LWC2, LDC2, SWC2, and SDC2 in different places.
def OPGROUP_COP2LDST : OPGROUP<0b010010>;

class OPCODE2<bits<2> Val> {
bits<2> Value = Val;
Expand All @@ -65,6 +67,12 @@ def OPCODE5_BC1NEZ : OPCODE5<0b01101>;
def OPCODE5_BC2EQZ : OPCODE5<0b01001>;
def OPCODE5_BC2NEZ : OPCODE5<0b01101>;
def OPCODE5_BGEZAL : OPCODE5<0b10001>;
// The next four constants are unnamed in the spec. These names are taken from
// the OPGROUP names they are used with.
def OPCODE5_LDC2 : OPCODE5<0b01110>;
def OPCODE5_LWC2 : OPCODE5<0b01010>;
def OPCODE5_SDC2 : OPCODE5<0b01111>;
def OPCODE5_SWC2 : OPCODE5<0b01011>;

class OPCODE6<bits<6> Val> {
bits<6> Value = Val;
Expand Down Expand Up @@ -445,3 +453,18 @@ class JR_HB_R6_FM<OPCODE6 Operation> : MipsR6Inst {
let Inst{9-6} = 0;
let Inst{5-0} = Operation.Value;
}

class COP2LDST_FM<OPCODE5 Operation> : MipsR6Inst {
bits<5> rt;
bits<21> addr;
bits<5> base = addr{20-16};
bits<11> offset = addr{10-0};

bits<32> Inst;

let Inst{31-26} = OPGROUP_COP2LDST.Value;
let Inst{25-21} = Operation.Value;
let Inst{20-16} = rt;
let Inst{15-11} = base;
let Inst{10-0} = offset;
}
36 changes: 31 additions & 5 deletions llvm/lib/Target/Mips/Mips32r6InstrInfo.td
Expand Up @@ -18,13 +18,8 @@ include "Mips32r6InstrFormats.td"
// Reencoded: clo, clz
// Reencoded: jr -> jalr
// Reencoded: jr.hb -> jalr.hb
// Reencoded: ldc2
// Reencoded: ll, sc
// Reencoded: lwc2
// Reencoded: sdbbp
// Reencoded: sdc2
// Reencoded: swc2
// Rencoded: [ls][wd]c2

def brtarget21 : Operand<OtherVT> {
let EncoderMethod = "getBranchTarget21OpValue";
Expand Down Expand Up @@ -158,6 +153,11 @@ class CLASS_D_ENC : COP1_2R_FM<0b011011, FIELD_FMT_D>;
class CACHE_ENC : SPECIAL3_MEM_FM<OPCODE6_CACHE>;
class PREF_ENC : SPECIAL3_MEM_FM<OPCODE6_PREF>;

class LDC2_R6_ENC : COP2LDST_FM<OPCODE5_LDC2>;
class LWC2_R6_ENC : COP2LDST_FM<OPCODE5_LWC2>;
class SDC2_R6_ENC : COP2LDST_FM<OPCODE5_SDC2>;
class SWC2_R6_ENC : COP2LDST_FM<OPCODE5_SWC2>;

class CMP_CONDN_DESC_BASE<string CondStr, string Typestr,
RegisterOperand FGROpnd,
SDPatternOperator Op = null_frag> {
Expand Down Expand Up @@ -541,6 +541,28 @@ class CACHE_HINT_DESC<string instr_asm, Operand MemOpnd,
class CACHE_DESC : CACHE_HINT_DESC<"cache", mem_simm9, GPR32Opnd>;
class PREF_DESC : CACHE_HINT_DESC<"pref", mem_simm9, GPR32Opnd>;

class COP2LD_DESC_BASE<string instr_asm, RegisterOperand COPOpnd> {
dag OutOperandList = (outs COPOpnd:$rt);
dag InOperandList = (ins mem_simm11:$addr);
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
list<dag> Pattern = [];
bit mayLoad = 1;
}

class LDC2_R6_DESC : COP2LD_DESC_BASE<"ldc2", COP2Opnd>;
class LWC2_R6_DESC : COP2LD_DESC_BASE<"lwc2", COP2Opnd>;

class COP2ST_DESC_BASE<string instr_asm, RegisterOperand COPOpnd> {
dag OutOperandList = (outs);
dag InOperandList = (ins COPOpnd:$rt, mem_simm11:$addr);
string AsmString = !strconcat(instr_asm, "\t$rt, $addr");
list<dag> Pattern = [];
bit mayStore = 1;
}

class SDC2_R6_DESC : COP2ST_DESC_BASE<"sdc2", COP2Opnd>;
class SWC2_R6_DESC : COP2ST_DESC_BASE<"swc2", COP2Opnd>;

//===----------------------------------------------------------------------===//
//
// Instruction Definitions
Expand Down Expand Up @@ -590,7 +612,9 @@ def DIVU : DIVU_ENC, DIVU_DESC, ISA_MIPS32R6;
def JIALC : JIALC_ENC, JIALC_DESC, ISA_MIPS32R6;
def JIC : JIC_ENC, JIC_DESC, ISA_MIPS32R6;
def JR_HB_R6 : JR_HB_R6_ENC, JR_HB_R6_DESC, ISA_MIPS32R6;
def LDC2_R6 : LDC2_R6_ENC, LDC2_R6_DESC, ISA_MIPS32R6;
// def LSA; // See MSA
def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6;
def LWPC : LWPC_ENC, LWPC_DESC, ISA_MIPS32R6;
def LWUPC : LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6;
def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6;
Expand All @@ -615,6 +639,7 @@ def NAL; // BAL with rd=0
def PREF_R6 : PREF_ENC, PREF_DESC, ISA_MIPS32R6;
def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6;
def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6;
def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6;
def SELEQZ : SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6, GPR_32;
def SELEQZ_D : SELEQZ_D_ENC, SELEQZ_D_DESC, ISA_MIPS32R6;
def SELEQZ_S : SELEQZ_S_ENC, SELEQZ_S_DESC, ISA_MIPS32R6;
Expand All @@ -623,6 +648,7 @@ def SELNEZ_D : SELNEZ_D_ENC, SELNEZ_D_DESC, ISA_MIPS32R6;
def SELNEZ_S : SELNEZ_S_ENC, SELNEZ_S_DESC, ISA_MIPS32R6;
def SEL_D : SEL_D_ENC, SEL_D_DESC, ISA_MIPS32R6;
def SEL_S : SEL_S_ENC, SEL_S_DESC, ISA_MIPS32R6;
def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6;

//===----------------------------------------------------------------------===//
//
Expand Down
12 changes: 8 additions & 4 deletions llvm/lib/Target/Mips/MipsInstrFPU.td
Expand Up @@ -403,10 +403,14 @@ def SDC1 : MMRel, SW_FT<"sdc1", AFGR64Opnd, II_SDC1, store>, LW_FM<0x3d>,
// Cop2 Memory Instructions
// FIXME: These aren't really FPU instructions and as such don't belong in this
// file
def LWC2 : LW_FT<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>;
def SWC2 : SW_FT<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>;
def LDC2 : LW_FT<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>, ISA_MIPS2;
def SDC2 : SW_FT<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>, ISA_MIPS2;
def LWC2 : LW_FT<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
ISA_MIPS1_NOT_32R6_64R6;
def SWC2 : SW_FT<"swc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3a>,
ISA_MIPS1_NOT_32R6_64R6;
def LDC2 : LW_FT<"ldc2", COP2Opnd, NoItinerary, load>, LW_FM<0x36>,
ISA_MIPS2_NOT_32R6_64R6;
def SDC2 : SW_FT<"sdc2", COP2Opnd, NoItinerary, store>, LW_FM<0x3e>,
ISA_MIPS2_NOT_32R6_64R6;

// Cop3 Memory Instructions
// FIXME: These aren't really FPU instructions and as such don't belong in this
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/Target/Mips/MipsInstrInfo.td
Expand Up @@ -351,6 +351,7 @@ def calltarget : Operand<iPTR> {

def simm9 : Operand<i32>;
def simm10 : Operand<i32>;
def simm11 : Operand<i32>;

def simm16 : Operand<i32> {
let DecoderMethod= "DecodeSimm16";
Expand Down Expand Up @@ -415,6 +416,15 @@ def MipsMemAsmOperand : AsmOperandClass {
let ParserMethod = "parseMemOperand";
}

def MipsMemSimm11AsmOperand : AsmOperandClass {
let Name = "MemOffsetSimm11";
let SuperClasses = [MipsMemAsmOperand];
let RenderMethod = "addMemOperands";
let ParserMethod = "parseMemOperand";
let PredicateMethod = "isMemWithSimmOffset<11>";
//let DiagnosticType = "Simm11";
}

def MipsInvertedImmoperand : AsmOperandClass {
let Name = "InvNum";
let RenderMethod = "addImmOperands";
Expand Down Expand Up @@ -451,6 +461,12 @@ def mem_simm9 : mem_generic {
let EncoderMethod = "getMemEncoding";
}

def mem_simm11 : mem_generic {
let MIOperandInfo = (ops ptr_rc, simm11);
let EncoderMethod = "getMemEncoding";
let ParserMatchClass = MipsMemSimm11AsmOperand;
}

def mem_ea : Operand<iPTR> {
let PrintMethod = "printMemOperandEA";
let MIOperandInfo = (ops ptr_rc, simm16);
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/MC/Mips/mips1/valid.s
Expand Up @@ -44,7 +44,7 @@
li $zero,-29889
lw $8,5674($a1)
lwc1 $f16,10225($k0)
lwc2 $18,-841($a2)
lwc2 $18,-841($a2) # CHECK: lwc2 $18, -841($6) # encoding: [0xc8,0xd2,0xfc,0xb7]
lwc3 $10,-32265($k0)
lwl $s4,-4231($15)
lwr $zero,-19147($gp)
Expand Down Expand Up @@ -99,7 +99,7 @@
subu $sp,$s6,$s6
sw $ra,-10160($sp)
swc1 $f6,-8465($24)
swc2 $25,24880($s0)
swc2 $25,24880($s0) # CHECK: swc2 $25, 24880($16) # encoding: [0xea,0x19,0x61,0x30]
swc3 $10,-32265($k0)
swl $15,13694($s3)
swr $s1,-26590($14)
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/MC/Mips/mips2/valid.s
Expand Up @@ -43,7 +43,7 @@
lb $24,-14515($10)
lbu $8,30195($v1)
ldc1 $f11,16391($s0)
ldc2 $8,-21181($at)
ldc2 $8,-21181($at) # CHECK: ldc2 $8, -21181($1) # encoding: [0xd8,0x28,0xad,0x43]
ldc3 $29,-28645($s1)
lh $11,-8556($s5)
lhu $s3,-22851($v0)
Expand All @@ -52,7 +52,7 @@
ll $v0,-7321($s2)
lw $8,5674($a1)
lwc1 $f16,10225($k0)
lwc2 $18,-841($a2)
lwc2 $18,-841($a2) # CHECK: lwc2 $18, -841($6) # encoding: [0xc8,0xd2,0xfc,0xb7]
lwc3 $10,-32265($k0)
lwl $s4,-4231($15)
lwr $zero,-19147($gp)
Expand Down Expand Up @@ -86,7 +86,7 @@
sb $s6,-19857($14)
sc $15,18904($s3)
sdc1 $f31,30574($13)
sdc2 $20,23157($s2)
sdc2 $20,23157($s2) # CHECK: sdc2 $20, 23157($18) # encoding: [0xfa,0x54,0x5a,0x75]
sdc3 $12,5835($10)
sh $14,-6704($15)
sll $a3,18 # CHECK: sll $7, $7, 18 # encoding: [0x00,0x07,0x3c,0x80]
Expand Down Expand Up @@ -115,7 +115,7 @@
subu $sp,$s6,$s6
sw $ra,-10160($sp)
swc1 $f6,-8465($24)
swc2 $25,24880($s0)
swc2 $25,24880($s0) # CHECK: swc2 $25, 24880($16) # encoding: [0xea,0x19,0x61,0x30]
swc3 $10,-32265($k0)
swl $15,13694($s3)
swr $s1,-26590($14)
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/MC/Mips/mips3/valid.s
Expand Up @@ -92,7 +92,7 @@
lbu $8,30195($v1)
ld $sp,-28645($s1)
ldc1 $f11,16391($s0)
ldc2 $8,-21181($at)
ldc2 $8,-21181($at) # CHECK: ldc2 $8, -21181($1) # encoding: [0xd8,0x28,0xad,0x43]
ldl $24,-4167($24)
ldr $14,-30358($s4)
lh $11,-8556($s5)
Expand All @@ -103,7 +103,7 @@
lld $zero,-14736($ra)
lw $8,5674($a1)
lwc1 $f16,10225($k0)
lwc2 $18,-841($a2)
lwc2 $18,-841($a2) # CHECK: lwc2 $18, -841($6) # encoding: [0xc8,0xd2,0xfc,0xb7]
lwl $s4,-4231($15)
lwr $zero,-19147($gp)
lwu $s3,-24086($v1)
Expand Down Expand Up @@ -143,7 +143,7 @@
scd $15,-8243($sp)
sd $12,5835($10)
sdc1 $f31,30574($13)
sdc2 $20,23157($s2)
sdc2 $20,23157($s2) # CHECK: sdc2 $20, 23157($18) # encoding: [0xfa,0x54,0x5a,0x75]
sdl $a3,-20961($s8)
sdr $11,-20423($12)
sh $14,-6704($15)
Expand Down Expand Up @@ -173,7 +173,7 @@
subu $sp,$s6,$s6
sw $ra,-10160($sp)
swc1 $f6,-8465($24)
swc2 $25,24880($s0)
swc2 $25,24880($s0) # CHECK: swc2 $25, 24880($16) # encoding: [0xea,0x19,0x61,0x30]
swl $15,13694($s3)
swr $s1,-26590($14)
teqi $s5,-17504
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/MC/Mips/mips32/valid.s
Expand Up @@ -50,15 +50,15 @@
lb $24,-14515($10)
lbu $8,30195($v1)
ldc1 $f11,16391($s0)
ldc2 $8,-21181($at)
ldc2 $8,-21181($at) # CHECK: ldc2 $8, -21181($1) # encoding: [0xd8,0x28,0xad,0x43]
lh $11,-8556($s5)
lhu $s3,-22851($v0)
li $at,-29773
li $zero,-29889
ll $v0,-7321($s2)
lw $8,5674($a1)
lwc1 $f16,10225($k0)
lwc2 $18,-841($a2)
lwc2 $18,-841($a2) # CHECK: lwc2 $18, -841($6) # encoding: [0xc8,0xd2,0xfc,0xb7]
lwl $s4,-4231($15)
lwr $zero,-19147($gp)
madd $s6,$13
Expand Down Expand Up @@ -113,7 +113,7 @@
sb $s6,-19857($14)
sc $15,18904($s3)
sdc1 $f31,30574($13)
sdc2 $20,23157($s2)
sdc2 $20,23157($s2) # CHECK: sdc2 $20, 23157($18) # encoding: [0xfa,0x54,0x5a,0x75]
sh $14,-6704($15)
sll $a3,18 # CHECK: sll $7, $7, 18 # encoding: [0x00,0x07,0x3c,0x80]
sll $a3,$zero,18 # CHECK: sll $7, $zero, 18 # encoding: [0x00,0x00,0x3c,0x80]
Expand Down Expand Up @@ -141,7 +141,7 @@
subu $sp,$s6,$s6
sw $ra,-10160($sp)
swc1 $f6,-8465($24)
swc2 $25,24880($s0)
swc2 $25,24880($s0) # CHECK: swc2 $25, 24880($16) # encoding: [0xea,0x19,0x61,0x30]
swl $15,13694($s3)
swr $s1,-26590($14)
teqi $s5,-17504
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/MC/Mips/mips32r2/valid.s
Expand Up @@ -57,7 +57,7 @@
lb $24,-14515($10)
lbu $8,30195($v1)
ldc1 $f11,16391($s0)
ldc2 $8,-21181($at)
ldc2 $8,-21181($at) # CHECK: ldc2 $8, -21181($1) # encoding: [0xd8,0x28,0xad,0x43]
ldxc1 $f8,$s7($15)
lh $11,-8556($s5)
lhu $s3,-22851($v0)
Expand All @@ -67,7 +67,7 @@
luxc1 $f19,$s6($s5)
lw $8,5674($a1)
lwc1 $f16,10225($k0)
lwc2 $18,-841($a2)
lwc2 $18,-841($a2) # CHECK: lwc2 $18, -841($6) # encoding: [0xc8,0xd2,0xfc,0xb7]
lwl $s4,-4231($15)
lwr $zero,-19147($gp)
lwxc1 $f12,$s1($s8)
Expand Down Expand Up @@ -138,7 +138,7 @@
sb $s6,-19857($14)
sc $15,18904($s3)
sdc1 $f31,30574($13)
sdc2 $20,23157($s2)
sdc2 $20,23157($s2) # CHECK: sdc2 $20, 23157($18) # encoding: [0xfa,0x54,0x5a,0x75]
sdxc1 $f11,$10($14)
seb $25,$15
seh $v1,$12
Expand Down Expand Up @@ -170,7 +170,7 @@
suxc1 $f12,$k1($13)
sw $ra,-10160($sp)
swc1 $f6,-8465($24)
swc2 $25,24880($s0)
swc2 $25,24880($s0) # CHECK: swc2 $25, 24880($16) # encoding: [0xea,0x19,0x61,0x30]
swl $15,13694($s3)
swr $s1,-26590($14)
swxc1 $f19,$12($k0)
Expand Down
8 changes: 6 additions & 2 deletions llvm/test/MC/Mips/mips32r6/invalid.s
@@ -1,10 +1,14 @@
# Instructions that are valid for the current ISA but should be rejected by the assembler (e.g.
# invalid set of operands or operand's restrictions not met).
# Instructions that are available for the current ISA but should be rejected by
# the assembler (e.g. invalid set of operands or operand's restrictions not met).

# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r6 2>%t1
# RUN: FileCheck %s < %t1 -check-prefix=ASM

.text
.set noreorder
.set noat
jalr.hb $31 # ASM: :[[@LINE]]:9: error: source and destination must be different
jalr.hb $31, $31 # ASM: :[[@LINE]]:9: error: source and destination must be different
ldc2 $8,-21181($at) # ASM: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
sdc2 $20,23157($s2) # ASM: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
swc2 $25,24880($s0) # ASM: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled
4 changes: 4 additions & 0 deletions llvm/test/MC/Mips/mips32r6/valid.s
Expand Up @@ -132,3 +132,7 @@
jr.hb $4 # CHECK: jr.hb $4 # encoding: [0x00,0x80,0x04,0x09]
jalr.hb $4 # CHECK: jalr.hb $4 # encoding: [0x00,0x80,0xfc,0x09]
jalr.hb $4, $5 # CHECK: jalr.hb $4, $5 # encoding: [0x00,0xa0,0x24,0x09]
ldc2 $8, -701($at) # CHECK: ldc2 $8, -701($1) # encoding: [0x49,0xc8,0x0d,0x43]
lwc2 $18,-841($a2) # CHECK: lwc2 $18, -841($6) # encoding: [0x49,0x52,0x34,0xb7]
sdc2 $20,629($s2) # CHECK: sdc2 $20, 629($18) # encoding: [0x49,0xf4,0x92,0x75]
swc2 $25,304($s0) # CHECK: swc2 $25, 304($16) # encoding: [0x49,0x79,0x81,0x30]

0 comments on commit 5e6f54e

Please sign in to comment.