Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 09e9256

Browse files
Hrvoje VargaHrvoje Varga
authored andcommitted
[mips][microMIPS] Implement DBITSWAP, DLSA and LWUPC and add tests for AUI instructions
Differential Revision: https://reviews.llvm.org/D16452 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280909 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 52bc7ab commit 09e9256

File tree

11 files changed

+146
-12
lines changed

11 files changed

+146
-12
lines changed

lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "MipsRegisterInfo.h"
1414
#include "MipsTargetObjectFile.h"
1515
#include "MipsTargetStreamer.h"
16+
#include "MCTargetDesc/MipsBaseInfo.h"
1617
#include "llvm/ADT/SmallVector.h"
1718
#include "llvm/ADT/StringSwitch.h"
1819
#include "llvm/MC/MCContext.h"
@@ -1166,8 +1167,14 @@ class MipsOperand : public MCParsedAsmOperand {
11661167
}
11671168
template <unsigned Bits, unsigned ShiftLeftAmount>
11681169
bool isScaledSImm() const {
1169-
return isConstantImm() &&
1170-
isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm());
1170+
if (isConstantImm() && isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm()))
1171+
return true;
1172+
// Operand can also be a symbol or symbol plus offset in case of relocations.
1173+
if (Kind != k_Immediate)
1174+
return false;
1175+
MCValue Res;
1176+
bool Success = getImm()->evaluateAsRelocatable(Res, nullptr, nullptr);
1177+
return Success && isShiftedInt<Bits, ShiftLeftAmount>(Res.getConstant());
11711178
}
11721179
bool isRegList16() const {
11731180
if (!isRegList())
@@ -1839,7 +1846,8 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
18391846
ExpandedJalSym = true;
18401847
}
18411848

1842-
if (MCID.mayLoad() || MCID.mayStore()) {
1849+
bool IsPCRelativeLoad = (MCID.TSFlags & MipsII::IsPCRelativeLoad) != 0;
1850+
if ((MCID.mayLoad() || MCID.mayStore()) && !IsPCRelativeLoad) {
18431851
// Check the offset of memory operand, if it is a symbol
18441852
// reference or immediate we may have to expand instructions.
18451853
for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
@@ -4030,6 +4038,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
40304038
case Match_SImm16_Relaxed:
40314039
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
40324040
"expected 16-bit signed immediate");
4041+
case Match_SImm19_Lsl2:
4042+
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
4043+
"expected both 19-bit signed immediate and multiple of 4");
40334044
case Match_UImm20_0:
40344045
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
40354046
"expected 20-bit unsigned immediate");

lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ namespace MipsII {
120120
/// IsCTI - Instruction is a Control Transfer Instruction.
121121
IsCTI = 1 << 4,
122122
/// HasForbiddenSlot - Instruction has a forbidden slot.
123-
HasForbiddenSlot = 1 << 5
123+
HasForbiddenSlot = 1 << 5,
124+
/// IsPCRelativeLoad - A Load instruction with implicit source register
125+
/// ($pc) with explicit offset and destination register
126+
IsPCRelativeLoad = 1 << 6
124127

125128
};
126129
}

lib/Target/Mips/MicroMips64r6InstrFormats.td

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,49 @@ class POOL32S_3R_FM_MMR6<string instr_asm, bits<9> funct>
219219
let Inst{10-9} = 0b00;
220220
let Inst{8-0} = funct;
221221
}
222+
223+
class POOL32S_DBITSWAP_FM_MMR6<string instr_asm> : MMR6Arch<instr_asm>,
224+
MipsR6Inst {
225+
bits<5> rt;
226+
bits<5> rd;
227+
228+
bits<32> Inst;
229+
230+
let Inst{31-26} = 0b010110;
231+
let Inst{25-21} = rt;
232+
let Inst{20-16} = rd;
233+
let Inst{15-12} = 0b0000;
234+
let Inst{11-6} = 0b101100;
235+
let Inst{5-0} = 0b111100;
236+
}
237+
238+
class POOL32S_3RSA_FM_MMR6<string instr_asm> : MMR6Arch<instr_asm>,
239+
MipsR6Inst {
240+
bits<5> rt;
241+
bits<5> rs;
242+
bits<5> rd;
243+
bits<2> sa;
244+
245+
bits<32> Inst;
246+
247+
let Inst{31-26} = 0b010110;
248+
let Inst{25-21} = rt;
249+
let Inst{20-16} = rs;
250+
let Inst{15-11} = rd;
251+
let Inst{10-9} = sa;
252+
let Inst{8-6} = 0b100;
253+
let Inst{5-0} = 0b000100;
254+
}
255+
256+
class PCREL_1ROFFSET19_FM_MMR6<string instr_asm> : MMR6Arch<instr_asm>,
257+
MipsR6Inst {
258+
bits<5> rt;
259+
bits<19> offset;
260+
261+
bits<32> Inst;
262+
263+
let Inst{31-26} = 0b011110;
264+
let Inst{25-21} = rt;
265+
let Inst{20-19} = 0b10;
266+
let Inst{18-0} = offset;
267+
}

lib/Target/Mips/MicroMips64r6InstrInfo.td

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class SD_MM64R6_ENC : LD_SD_32_2R_OFFSET16_FM_MMR6<"sd", 0b110110>;
6767
class DSRL_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsrl", 0b001000000>;
6868
class DSRL32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<"dsrl32", 0b001001000>;
6969
class DSRLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<"dsrlv", 0b001010000>;
70+
class DBITSWAP_MM64R6_ENC : POOL32S_DBITSWAP_FM_MMR6<"dbitswap">;
71+
class DLSA_MM64R6_ENC : POOL32S_3RSA_FM_MMR6<"dlsa">;
72+
class LWUPC_MM64R6_ENC : PCREL_1ROFFSET19_FM_MMR6<"lwupc">;
7073

7174
//===----------------------------------------------------------------------===//
7275
//
@@ -323,6 +326,32 @@ class SD_MM64R6_DESC {
323326
string DecoderMethod = "DecodeMemMMImm16";
324327
}
325328

329+
class DBITSWAP_MM64R6_DESC {
330+
dag OutOperandList = (outs GPR64Opnd:$rd);
331+
dag InOperandList = (ins GPR64Opnd:$rt);
332+
string AsmString = !strconcat("dbitswap", "\t$rd, $rt");
333+
list<dag> Pattern = [];
334+
InstrItinClass Itinerary = II_DBITSWAP;
335+
}
336+
337+
class DLSA_MM64R6_DESC {
338+
dag OutOperandList = (outs GPR64Opnd:$rd);
339+
dag InOperandList = (ins GPR64Opnd:$rt, GPR64Opnd:$rs, uimm2_plus1:$sa);
340+
string AsmString = "dlsa\t$rt, $rs, $rd, $sa";
341+
list<dag> Pattern = [];
342+
InstrItinClass Itinerary = II_DLSA;
343+
}
344+
345+
class LWUPC_MM64R6_DESC {
346+
dag OutOperandList = (outs GPR64Opnd:$rt);
347+
dag InOperandList = (ins simm19_lsl2:$offset);
348+
string AsmString = "lwupc\t$rt, $offset";
349+
list<dag> Pattern = [];
350+
InstrItinClass Itinerary = II_LWUPC;
351+
bit mayLoad = 1;
352+
bit IsPCRelativeLoad = 1;
353+
}
354+
326355
//===----------------------------------------------------------------------===//
327356
//
328357
// Instruction Definitions
@@ -427,6 +456,12 @@ let DecoderNamespace = "MicroMipsR6" in {
427456
ISA_MICROMIPS64R6;
428457
def DSRLV_MM64R6 : StdMMR6Rel, DSRLV_MM64R6_ENC, DSRLV_MM64R6_DESC,
429458
ISA_MICROMIPS64R6;
459+
def DBITSWAP_MM64R6 : R6MMR6Rel, DBITSWAP_MM64R6_ENC, DBITSWAP_MM64R6_DESC,
460+
ISA_MICROMIPS64R6;
461+
def DLSA_MM64R6 : R6MMR6Rel, DLSA_MM64R6_ENC, DLSA_MM64R6_DESC,
462+
ISA_MICROMIPS64R6;
463+
def LWUPC_MM64R6 : R6MMR6Rel, LWUPC_MM64R6_ENC, LWUPC_MM64R6_DESC,
464+
ISA_MICROMIPS64R6;
430465
}
431466

432467
let AdditionalPredicates = [InMicroMips] in

lib/Target/Mips/Mips32r6InstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,8 +831,8 @@ let AdditionalPredicates = [NotInMicroMips] in {
831831
def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6;
832832
}
833833
def LWPC : R6MMR6Rel, LWPC_ENC, LWPC_DESC, ISA_MIPS32R6;
834-
def LWUPC : LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6;
835834
let AdditionalPredicates = [NotInMicroMips] in {
835+
def LWUPC : R6MMR6Rel, LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6;
836836
def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
837837
def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
838838
def MAXA_D : MAXA_D_ENC, MAXA_D_DESC, ISA_MIPS32R6, HARDFLOAT;

lib/Target/Mips/Mips64r6InstrInfo.td

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,14 @@ let AdditionalPredicates = [NotInMicroMips] in {
115115
def DAHI : DAHI_ENC, DAHI_DESC, ISA_MIPS64R6;
116116
def DAUI : DAUI_ENC, DAUI_DESC, ISA_MIPS64R6;
117117
def DALIGN : DALIGN_ENC, DALIGN_DESC, ISA_MIPS64R6;
118-
}
119-
def DBITSWAP : DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6;
120-
let AdditionalPredicates = [NotInMicroMips] in {
118+
def DBITSWAP : R6MMR6Rel, DBITSWAP_ENC, DBITSWAP_DESC, ISA_MIPS64R6;
121119
def DCLO_R6 : R6MMR6Rel, DCLO_R6_ENC, DCLO_R6_DESC, ISA_MIPS64R6;
122120
def DCLZ_R6 : R6MMR6Rel, DCLZ_R6_ENC, DCLZ_R6_DESC, ISA_MIPS64R6;
123121
def DDIV : DDIV_ENC, DDIV_DESC, ISA_MIPS64R6;
124122
def DDIVU : DDIVU_ENC, DDIVU_DESC, ISA_MIPS64R6;
125123
def DMOD : DMOD_ENC, DMOD_DESC, ISA_MIPS64R6;
126124
def DMODU : DMODU_ENC, DMODU_DESC, ISA_MIPS64R6;
127-
}
128-
def DLSA_R6 : DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6;
129-
let AdditionalPredicates = [NotInMicroMips] in {
125+
def DLSA_R6 : R6MMR6Rel, DLSA_R6_ENC, DLSA_R6_DESC, ISA_MIPS64R6;
130126
def DMUH: DMUH_ENC, DMUH_DESC, ISA_MIPS64R6;
131127
def DMUHU: DMUHU_ENC, DMUHU_DESC, ISA_MIPS64R6;
132128
def DMUL_R6: DMUL_R6_ENC, DMUL_R6_DESC, ISA_MIPS64R6;

lib/Target/Mips/MipsInstrFormats.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,15 @@ class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
9898
bit isCTI = 0; // Any form of Control Transfer Instruction.
9999
// Required for MIPSR6
100100
bit hasForbiddenSlot = 0; // Instruction has a forbidden slot.
101+
bit IsPCRelativeLoad = 0; // Load instruction with implicit source register
102+
// ($pc) and with explicit offset and destination
103+
// register
101104

102105
// TSFlags layout should be kept in sync with MipsInstrInfo.h.
103106
let TSFlags{3-0} = FormBits;
104107
let TSFlags{4} = isCTI;
105108
let TSFlags{5} = hasForbiddenSlot;
109+
let TSFlags{6} = IsPCRelativeLoad;
106110

107111
let DecoderNamespace = "Mips";
108112

lib/Target/Mips/MipsInstrInfo.td

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,15 @@ class ConstantSImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
413413
let DiagnosticType = "SImm" # Bits # "_" # Offset;
414414
}
415415

416+
class SimmLslAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
417+
int Shift = 0> : AsmOperandClass {
418+
let Name = "Simm" # Bits # "_Lsl" # Shift;
419+
let RenderMethod = "addImmOperands";
420+
let PredicateMethod = "isScaledSImm<" # Bits # ", " # Shift # ">";
421+
let SuperClasses = Supers;
422+
let DiagnosticType = "SImm" # Bits # "_Lsl" # Shift;
423+
}
424+
416425
class ConstantUImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = [],
417426
int Offset = 0> : AsmOperandClass {
418427
let Name = "ConstantUImm" # Bits # "_" # Offset;
@@ -485,6 +494,13 @@ def ConstantUImm26AsmOperandClass
485494
: ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
486495
def ConstantUImm20AsmOperandClass
487496
: ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
497+
def ConstantSImm19Lsl2AsmOperandClass : AsmOperandClass {
498+
let Name = "SImm19Lsl2";
499+
let RenderMethod = "addImmOperands";
500+
let PredicateMethod = "isScaledSImm<19, 2>";
501+
let SuperClasses = [ConstantUImm20AsmOperandClass];
502+
let DiagnosticType = "SImm19_Lsl2";
503+
}
488504
def UImm16RelaxedAsmOperandClass
489505
: UImmAsmOperandClass<16, [ConstantUImm20AsmOperandClass]> {
490506
let Name = "UImm16_Relaxed";
@@ -611,6 +627,9 @@ def ConstantImmzAsmOperandClass : AsmOperandClass {
611627
let DiagnosticType = "Immz";
612628
}
613629

630+
def Simm19Lsl2AsmOperand
631+
: SimmLslAsmOperandClass<19, [], 2>;
632+
614633
def MipsJumpTargetAsmOperand : AsmOperandClass {
615634
let Name = "JumpTarget";
616635
let ParserMethod = "parseJumpTarget";
@@ -645,7 +664,7 @@ def imm64: Operand<i64>;
645664
def simm19_lsl2 : Operand<i32> {
646665
let EncoderMethod = "getSimm19Lsl2Encoding";
647666
let DecoderMethod = "DecodeSimm19Lsl2";
648-
let ParserMatchClass = MipsJumpTargetAsmOperand;
667+
let ParserMatchClass = Simm19Lsl2AsmOperand;
649668
}
650669

651670
def simm18_lsl3 : Operand<i32> {

test/MC/Disassembler/Mips/micromips64r6/valid.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,7 @@
314314
0xf4 0x40 0x00 0x40 # CHECK: blezc $2, 260
315315
0xf6 0x10 0x00 0x80 # CHECK: bgezc $16, 516
316316
0xd5 0x80 0x01 0x00 # CHECK: bgtzc $12, 1028
317+
0x10 0x64 0x01 0x00 # CHECK: aui $3, $4, 256
318+
0x58 0x83 0x0b 0x3c # CHECK: dbitswap $3, $4
319+
0x58 0x64 0x2d 0x04 # CHECK: dlsa $3, $4, $5, 3
320+
0x78 0x50 0x00 0x43 # CHECK: lwupc $2, 268

test/MC/Mips/micromips64r6/invalid.s

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,13 @@
391391
bnezc $2, -4194303 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address
392392
bnezc $2, 4194304 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch target out of range
393393
bnezc $2, 4194303 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: branch to misaligned address
394+
dlsa $3, $4, $5, 5 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected immediate in range 1 .. 4
395+
dlsa $3, $4, $5, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected immediate in range 1 .. 4
396+
dlsa $3, $4, $5, 0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected immediate in range 1 .. 4
397+
lwupc $2, 262145 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4
398+
lwupc $2, 5 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4
399+
lwupc $2, -262145 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4
400+
lwupc $2, $2 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4
401+
lwupc $2, bar+267 # CHECK: :[[@LINE]]:13: error: expected both 19-bit signed immediate and multiple of 4
402+
aui $3, $4, 32768 # CHECK: :[[@LINE]]:15: error: expected 16-bit signed immediate
403+
aui $3, $4, -32769 # CHECK: :[[@LINE]]:15: error: expected 16-bit signed immediate

test/MC/Mips/micromips64r6/valid.s

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,5 +330,11 @@ a:
330330
blezc $2, 256 # CHECK: blezc $2, 256 # encoding: [0xf4,0x40,0x00,0x40]
331331
bgezc $16, 512 # CHECK: bgezc $16, 512 # encoding: [0xf6,0x10,0x00,0x80]
332332
bgtzc $12, 1024 # CHECK: bgtzc $12, 1024 # encoding: [0xd5,0x80,0x01,0x00]
333+
aui $3, $4, 256 # CHECK: aui $3, $4, 256 # encoding: [0x10,0x64,0x01,0x00]
334+
dbitswap $3, $4 # CHECK: dbitswap $3, $4 # encoding: [0x58,0x83,0x0b,0x3c]
335+
dlsa $3, $4, $5, 3 # CHECK: dlsa $3, $4, $5, 3 # encoding: [0x58,0x64,0x2d,0x04]
336+
lwupc $2, 268 # CHECK: lwupc $2, 268 # encoding: [0x78,0x50,0x00,0x43]
337+
lwupc $2, bar # CHECK: lwupc $2, bar # encoding: [0x78,0b01010AAA,A,A]
338+
lwupc $2, bar+268 # CHECK: lwupc $2, bar+268 # encoding: [0x78,0b01010AAA,A,A]
333339

334340
1:

0 commit comments

Comments
 (0)