Skip to content

Commit 4168867

Browse files
author
Zoran Jovanovic
committedFeb 10, 2015
[mips][microMIPS] Implement movep instruction
Differential Revision: http://reviews.llvm.org/D7465 llvm-svn: 228703
1 parent 8ce4a06 commit 4168867

11 files changed

+250
-0
lines changed
 

‎llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

+78
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ class MipsAsmParser : public MCTargetAsmParser {
151151
MipsAsmParser::OperandMatchResultTy
152152
parseRegisterPair (OperandVector &Operands);
153153

154+
MipsAsmParser::OperandMatchResultTy
155+
parseMovePRegPair(OperandVector &Operands);
156+
154157
MipsAsmParser::OperandMatchResultTy
155158
parseRegisterList (OperandVector &Operands);
156159

@@ -683,6 +686,11 @@ class MipsOperand : public MCParsedAsmOperand {
683686
Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
684687
}
685688

689+
void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
690+
assert(N == 1 && "Invalid number of operands!");
691+
Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
692+
}
693+
686694
/// Render the operand to an MCInst as a GPR64
687695
/// Asserts if the wrong number of operands are requested, or the operand
688696
/// is not a k_RegisterIndex compatible with RegKind_GPR
@@ -803,6 +811,12 @@ class MipsOperand : public MCParsedAsmOperand {
803811
Inst.addOperand(MCOperand::CreateReg(RegNo));
804812
}
805813

814+
void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
815+
assert(N == 2 && "Invalid number of operands!");
816+
for (auto RegNo : getRegList())
817+
Inst.addOperand(MCOperand::CreateReg(RegNo));
818+
}
819+
806820
bool isReg() const override {
807821
// As a special case until we sort out the definition of div/divu, pretend
808822
// that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
@@ -867,6 +881,25 @@ class MipsOperand : public MCParsedAsmOperand {
867881
return 1 <= Val && Val <= 4;
868882
}
869883
bool isRegList() const { return Kind == k_RegList; }
884+
bool isMovePRegPair() const {
885+
if (Kind != k_RegList || RegList.List->size() != 2)
886+
return false;
887+
888+
unsigned R0 = RegList.List->front();
889+
unsigned R1 = RegList.List->back();
890+
891+
if ((R0 == Mips::A1 && R1 == Mips::A2) ||
892+
(R0 == Mips::A1 && R1 == Mips::A3) ||
893+
(R0 == Mips::A2 && R1 == Mips::A3) ||
894+
(R0 == Mips::A0 && R1 == Mips::S5) ||
895+
(R0 == Mips::A0 && R1 == Mips::S6) ||
896+
(R0 == Mips::A0 && R1 == Mips::A1) ||
897+
(R0 == Mips::A0 && R1 == Mips::A2) ||
898+
(R0 == Mips::A0 && R1 == Mips::A3))
899+
return true;
900+
901+
return false;
902+
}
870903

871904
StringRef getToken() const {
872905
assert(Kind == k_Token && "Invalid access!");
@@ -1053,6 +1086,12 @@ class MipsOperand : public MCParsedAsmOperand {
10531086
(RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
10541087
RegIdx.Index == 17);
10551088
}
1089+
bool isMM16AsmRegMoveP() const {
1090+
if (!(isRegIdx() && RegIdx.Kind))
1091+
return false;
1092+
return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1093+
(RegIdx.Index >= 16 && RegIdx.Index <= 20));
1094+
}
10561095
bool isFGRAsmReg() const {
10571096
// AFGR64 is $0-$15 but we handle this in getAFGR64()
10581097
return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
@@ -3036,6 +3075,45 @@ MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
30363075
return MatchOperand_Success;
30373076
}
30383077

3078+
MipsAsmParser::OperandMatchResultTy
3079+
MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3080+
MCAsmParser &Parser = getParser();
3081+
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3082+
SmallVector<unsigned, 10> Regs;
3083+
3084+
if (Parser.getTok().isNot(AsmToken::Dollar))
3085+
return MatchOperand_ParseFail;
3086+
3087+
SMLoc S = Parser.getTok().getLoc();
3088+
3089+
if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3090+
return MatchOperand_ParseFail;
3091+
3092+
MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3093+
unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3094+
Regs.push_back(RegNo);
3095+
3096+
SMLoc E = Parser.getTok().getLoc();
3097+
if (Parser.getTok().isNot(AsmToken::Comma)) {
3098+
Error(E, "',' expected");
3099+
return MatchOperand_ParseFail;
3100+
}
3101+
3102+
// Remove comma.
3103+
Parser.Lex();
3104+
3105+
if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3106+
return MatchOperand_ParseFail;
3107+
3108+
Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3109+
RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3110+
Regs.push_back(RegNo);
3111+
3112+
Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3113+
3114+
return MatchOperand_Success;
3115+
}
3116+
30393117
MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
30403118

30413119
MCSymbolRefExpr::VariantKind VK =

‎llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp

+65
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
114114
uint64_t Address,
115115
const void *Decoder);
116116

117+
static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
118+
unsigned RegNo,
119+
uint64_t Address,
120+
const void *Decoder);
121+
117122
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
118123
unsigned RegNo,
119124
uint64_t Address,
@@ -439,6 +444,10 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
439444
uint64_t Address,
440445
const void *Decoder);
441446

447+
static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
448+
uint64_t Address,
449+
const void *Decoder);
450+
442451
namespace llvm {
443452
extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
444453
TheMips64elTarget;
@@ -1005,6 +1014,17 @@ static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst,
10051014
return MCDisassembler::Success;
10061015
}
10071016

1017+
static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst,
1018+
unsigned RegNo,
1019+
uint64_t Address,
1020+
const void *Decoder) {
1021+
if (RegNo > 7)
1022+
return MCDisassembler::Fail;
1023+
unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo);
1024+
Inst.addOperand(MCOperand::CreateReg(Reg));
1025+
return MCDisassembler::Success;
1026+
}
1027+
10081028
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
10091029
unsigned RegNo,
10101030
uint64_t Address,
@@ -1835,6 +1855,51 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,
18351855
return MCDisassembler::Success;
18361856
}
18371857

1858+
static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn,
1859+
uint64_t Address, const void *Decoder) {
1860+
1861+
unsigned RegPair = fieldFromInstruction(Insn, 7, 3);
1862+
1863+
switch (RegPair) {
1864+
default:
1865+
return MCDisassembler::Fail;
1866+
case 0:
1867+
Inst.addOperand(MCOperand::CreateReg(Mips::A1));
1868+
Inst.addOperand(MCOperand::CreateReg(Mips::A2));
1869+
break;
1870+
case 1:
1871+
Inst.addOperand(MCOperand::CreateReg(Mips::A1));
1872+
Inst.addOperand(MCOperand::CreateReg(Mips::A3));
1873+
break;
1874+
case 2:
1875+
Inst.addOperand(MCOperand::CreateReg(Mips::A2));
1876+
Inst.addOperand(MCOperand::CreateReg(Mips::A3));
1877+
break;
1878+
case 3:
1879+
Inst.addOperand(MCOperand::CreateReg(Mips::A0));
1880+
Inst.addOperand(MCOperand::CreateReg(Mips::S5));
1881+
break;
1882+
case 4:
1883+
Inst.addOperand(MCOperand::CreateReg(Mips::A0));
1884+
Inst.addOperand(MCOperand::CreateReg(Mips::S6));
1885+
break;
1886+
case 5:
1887+
Inst.addOperand(MCOperand::CreateReg(Mips::A0));
1888+
Inst.addOperand(MCOperand::CreateReg(Mips::A1));
1889+
break;
1890+
case 6:
1891+
Inst.addOperand(MCOperand::CreateReg(Mips::A0));
1892+
Inst.addOperand(MCOperand::CreateReg(Mips::A2));
1893+
break;
1894+
case 7:
1895+
Inst.addOperand(MCOperand::CreateReg(Mips::A0));
1896+
Inst.addOperand(MCOperand::CreateReg(Mips::A3));
1897+
break;
1898+
}
1899+
1900+
return MCDisassembler::Success;
1901+
}
1902+
18381903
static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn,
18391904
uint64_t Address, const void *Decoder) {
18401905
Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2));

‎llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,40 @@ MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
942942
return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
943943
}
944944

945+
unsigned
946+
MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
947+
SmallVectorImpl<MCFixup> &Fixups,
948+
const MCSubtargetInfo &STI) const {
949+
unsigned res = 0;
950+
951+
if (MI.getOperand(0).getReg() == Mips::A1 &&
952+
MI.getOperand(1).getReg() == Mips::A2)
953+
res = 0;
954+
else if (MI.getOperand(0).getReg() == Mips::A1 &&
955+
MI.getOperand(1).getReg() == Mips::A3)
956+
res = 1;
957+
else if (MI.getOperand(0).getReg() == Mips::A2 &&
958+
MI.getOperand(1).getReg() == Mips::A3)
959+
res = 2;
960+
else if (MI.getOperand(0).getReg() == Mips::A0 &&
961+
MI.getOperand(1).getReg() == Mips::S5)
962+
res = 3;
963+
else if (MI.getOperand(0).getReg() == Mips::A0 &&
964+
MI.getOperand(1).getReg() == Mips::S6)
965+
res = 4;
966+
else if (MI.getOperand(0).getReg() == Mips::A0 &&
967+
MI.getOperand(1).getReg() == Mips::A1)
968+
res = 5;
969+
else if (MI.getOperand(0).getReg() == Mips::A0 &&
970+
MI.getOperand(1).getReg() == Mips::A2)
971+
res = 6;
972+
else if (MI.getOperand(0).getReg() == Mips::A0 &&
973+
MI.getOperand(1).getReg() == Mips::A3)
974+
res = 7;
975+
976+
return res;
977+
}
978+
945979
unsigned
946980
MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
947981
SmallVectorImpl<MCFixup> &Fixups,

‎llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h

+4
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
208208
SmallVectorImpl<MCFixup> &Fixups,
209209
const MCSubtargetInfo &STI) const;
210210

211+
unsigned getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
212+
SmallVectorImpl<MCFixup> &Fixups,
213+
const MCSubtargetInfo &STI) const;
214+
211215
unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
212216
SmallVectorImpl<MCFixup> &Fixups,
213217
const MCSubtargetInfo &STI) const;

‎llvm/lib/Target/Mips/MicroMipsInstrFormats.td

+14
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,20 @@ class B16_FM {
258258
let Inst{9-0} = offset;
259259
}
260260

261+
class MOVEP_FM_MM16 {
262+
bits<3> dst_regs;
263+
bits<3> rt;
264+
bits<3> rs;
265+
266+
bits<16> Inst;
267+
268+
let Inst{15-10} = 0x21;
269+
let Inst{9-7} = dst_regs;
270+
let Inst{6-4} = rt;
271+
let Inst{3-1} = rs;
272+
let Inst{0} = 0;
273+
}
274+
261275
//===----------------------------------------------------------------------===//
262276
// MicroMIPS 32-bit Instruction Formats
263277
//===----------------------------------------------------------------------===//

‎llvm/lib/Target/Mips/MicroMipsInstrInfo.td

+23
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,28 @@ class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
192192
let DecoderMethod = "DecodeMemMMImm12";
193193
}
194194

195+
/// A register pair used by movep instruction.
196+
def MovePRegPairAsmOperand : AsmOperandClass {
197+
let Name = "MovePRegPair";
198+
let ParserMethod = "parseMovePRegPair";
199+
let PredicateMethod = "isMovePRegPair";
200+
}
201+
202+
def movep_regpair : Operand<i32> {
203+
let EncoderMethod = "getMovePRegPairOpValue";
204+
let ParserMatchClass = MovePRegPairAsmOperand;
205+
let PrintMethod = "printRegisterList";
206+
let DecoderMethod = "DecodeMovePRegPair";
207+
let MIOperandInfo = (ops GPR32Opnd, GPR32Opnd);
208+
}
209+
210+
class MovePMM16<string opstr, RegisterOperand RO> :
211+
MicroMipsInst16<(outs movep_regpair:$dst_regs), (ins RO:$rs, RO:$rt),
212+
!strconcat(opstr, "\t$dst_regs, $rs, $rt"), [],
213+
NoItinerary, FrmR> {
214+
let isReMaterializable = 1;
215+
}
216+
195217
/// A register pair used by load/store pair instructions.
196218
def RegPairAsmOperand : AsmOperandClass {
197219
let Name = "RegPair";
@@ -572,6 +594,7 @@ def ADDIUSP_MM : AddImmUSP<"addiusp">, ADDIUSP_FM_MM16;
572594
def MFHI16_MM : MoveFromHILOMM<"mfhi", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x10>;
573595
def MFLO16_MM : MoveFromHILOMM<"mflo", GPR32Opnd, AC0>, MFHILO_FM_MM16<0x12>;
574596
def MOVE16_MM : MoveMM16<"move", GPR32Opnd>, MOVE_FM_MM16<0x03>;
597+
def MOVEP_MM : MovePMM16<"movep", GPRMM16OpndMoveP>, MOVEP_FM_MM16;
575598
def LI16_MM : LoadImmMM16<"li16", li_simm7, GPRMM16Opnd>, LI_FM_MM16,
576599
IsAsCheapAsAMove;
577600
def JALR16_MM : JumpLinkRegMM16<"jalr", GPR32Opnd>, JALR_FM_MM16<0x0e>;

‎llvm/lib/Target/Mips/MipsRegisterInfo.td

+19
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,16 @@ def GPRMM16Zero : RegisterClass<"Mips", [i32], 32, (add
302302
// Return Values and Arguments
303303
V0, V1, A0, A1, A2, A3)>;
304304

305+
def GPRMM16MoveP : RegisterClass<"Mips", [i32], 32, (add
306+
// Reserved
307+
ZERO,
308+
// Callee save
309+
S1,
310+
// Return Values and Arguments
311+
V0, V1,
312+
// Callee save
313+
S0, S2, S3, S4)>;
314+
305315
def GPR64 : RegisterClass<"Mips", [i64], 64, (add
306316
// Reserved
307317
ZERO_64, AT_64,
@@ -459,6 +469,11 @@ def GPRMM16AsmOperandZero : MipsAsmRegOperand {
459469
let PredicateMethod = "isMM16AsmRegZero";
460470
}
461471

472+
def GPRMM16AsmOperandMoveP : MipsAsmRegOperand {
473+
let Name = "GPRMM16AsmRegMoveP";
474+
let PredicateMethod = "isMM16AsmRegMoveP";
475+
}
476+
462477
def ACC64DSPAsmOperand : MipsAsmRegOperand {
463478
let Name = "ACC64DSPAsmReg";
464479
let PredicateMethod = "isACCAsmReg";
@@ -522,6 +537,10 @@ def GPRMM16OpndZero : RegisterOperand<GPRMM16Zero> {
522537
let ParserMatchClass = GPRMM16AsmOperandZero;
523538
}
524539

540+
def GPRMM16OpndMoveP : RegisterOperand<GPRMM16MoveP> {
541+
let ParserMatchClass = GPRMM16AsmOperandMoveP;
542+
}
543+
525544
def GPR64Opnd : RegisterOperand<GPR64> {
526545
let ParserMatchClass = GPR64AsmOperand;
527546
}

‎llvm/test/MC/Disassembler/Mips/micromips.txt

+3
Original file line numberDiff line numberDiff line change
@@ -501,3 +501,6 @@
501501

502502
# CHECK: sdbbp16 14
503503
0x46 0xce
504+
505+
# CHECK: movep $5, $6, $2, $3
506+
0x84 0x34

‎llvm/test/MC/Disassembler/Mips/micromips_le.txt

+3
Original file line numberDiff line numberDiff line change
@@ -501,3 +501,6 @@
501501

502502
# CHECK: sdbbp16 14
503503
0xce 0x46
504+
505+
# CHECK: movep $5, $6, $2, $3
506+
0x34 0x84

‎llvm/test/MC/Mips/micromips-16-bit-instructions.s

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
# CHECK-EL: mfhi $9 # encoding: [0x09,0x46]
4444
# CHECK-EL: mflo $9 # encoding: [0x49,0x46]
4545
# CHECK-EL: move $25, $1 # encoding: [0x21,0x0f]
46+
# CHECK-EL: movep $5, $6, $2, $3 # encoding: [0x34,0x84]
4647
# CHECK-EL: jrc $9 # encoding: [0xa9,0x45]
4748
# CHECK-NEXT: jalr $9 # encoding: [0xc9,0x45]
4849
# CHECK-EL: jraddiusp 20 # encoding: [0x05,0x47]
@@ -97,6 +98,7 @@
9798
# CHECK-EB: mfhi $9 # encoding: [0x46,0x09]
9899
# CHECK-EB: mflo $9 # encoding: [0x46,0x49]
99100
# CHECK-EB: move $25, $1 # encoding: [0x0f,0x21]
101+
# CHECK-EB: movep $5, $6, $2, $3 # encoding: [0x84,0x34]
100102
# CHECK-EB: jrc $9 # encoding: [0x45,0xa9]
101103
# CHECK-NEXT: jalr $9 # encoding: [0x45,0xc9]
102104
# CHECK-EB: jraddiusp 20 # encoding: [0x47,0x05]
@@ -149,6 +151,7 @@
149151
mfhi $9
150152
mflo $9
151153
move $25, $1
154+
movep $5, $6, $2, $3
152155
jrc $9
153156
jalr $9
154157
jraddiusp 20

‎llvm/test/MC/Mips/micromips-invalid.s

+4
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@
6969
pref 256, 8($5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: immediate operand value out of range
7070
beqz16 $9, 20 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
7171
bnez16 $9, 20 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
72+
movep $5, $21, $2, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
73+
movep $8, $6, $2, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
74+
movep $5, $6, $5, $3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction
75+
movep $5, $6, $2, $9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction

0 commit comments

Comments
 (0)
Please sign in to comment.