From d187959ecd4ceeebb187446a9d79accd4d3354e2 Mon Sep 17 00:00:00 2001 From: Hrvoje Varga Date: Wed, 11 May 2016 11:17:04 +0000 Subject: [PATCH] [mips][micromips] Implement DSBH, DSHD, DSLL, DSLL32, DSLLV, DSRA, DSRA32 and DSRAV instructions Differential Revision: http://reviews.llvm.org/D16800 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269169 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MicroMips64r6InstrFormats.td | 43 +++++++++++ lib/Target/Mips/MicroMips64r6InstrInfo.td | 91 +++++++++++++++++++++++ lib/Target/Mips/Mips64InstrInfo.td | 38 +++++++--- test/MC/Disassembler/Mips/micromips64r6/valid.txt | 7 ++ test/MC/Mips/micromips64r6/invalid.s | 8 ++ test/MC/Mips/micromips64r6/valid.s | 8 ++ 6 files changed, 183 insertions(+), 12 deletions(-) diff --git a/lib/Target/Mips/MicroMips64r6InstrFormats.td b/lib/Target/Mips/MicroMips64r6InstrFormats.td index 59467a1e61d..1f294423d3f 100644 --- a/lib/Target/Mips/MicroMips64r6InstrFormats.td +++ b/lib/Target/Mips/MicroMips64r6InstrFormats.td @@ -142,3 +142,46 @@ class PCREL18_FM_MMR6 funct> : MipsR6Inst { let Inst{20-18} = funct; let Inst{17-0} = imm; } + +class POOL32S_2R_FM_MMR6 funct> { + bits<5> rt; + bits<5> rs; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-6} = funct; + let Inst{5-0} = 0b111100; +} + +class POOL32S_2RSA5B0_FM_MMR6 funct> { + bits<5> rt; + bits<5> rs; + bits<5> sa; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = sa; + let Inst{10-9} = 0b00; + let Inst{8-0} = funct; +} + +class POOL32S_3R_FM_MMR6 funct> { + bits<5> rt; + bits<5> rs; + bits<5> rd; + + bits<32> Inst; + + let Inst{31-26} = 0b010110; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-11} = rd; + let Inst{10-9} = 0b00; + let Inst{8-0} = funct; +} diff --git a/lib/Target/Mips/MicroMips64r6InstrInfo.td b/lib/Target/Mips/MicroMips64r6InstrInfo.td index 29de4ceefd0..f69bf347224 100644 --- a/lib/Target/Mips/MicroMips64r6InstrInfo.td +++ b/lib/Target/Mips/MicroMips64r6InstrInfo.td @@ -47,6 +47,14 @@ class DMUL_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmul", 0b000011000>; class DMUH_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuh", 0b001011000>; class DMULU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmulu", 0b010011000>; class DMUHU_MM64R6_ENC : POOL32S_ARITH_FM_MMR6<"dmuhu", 0b011011000>; +class DSBH_MM64R6_ENC : POOL32S_2R_FM_MMR6<0b0111101100>; +class DSHD_MM64R6_ENC : POOL32S_2R_FM_MMR6<0b1111101100>; +class DSLL_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b000000000>; +class DSLL32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b000001000>; +class DSLLV_MM64R6_ENC : POOL32S_3R_FM_MMR6<0b000010000>; +class DSRAV_MM64R6_ENC : POOL32S_3R_FM_MMR6<0b010010000>; +class DSRA_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b010000000>; +class DSRA32_MM64R6_ENC : POOL32S_2RSA5B0_FM_MMR6<0b010000100>; //===----------------------------------------------------------------------===// // @@ -167,6 +175,73 @@ class DMULU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmulu", GPR64Opnd, II_DMULU>; class DMUHU_MM64R6_DESC : MUL_MM64R6_DESC_BASE<"dmuhu", GPR64Opnd, II_DMUHU, mulhu>; +class DSBH_DSHD_DESC_BASE + : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs GPROpnd:$rt); + dag InOperandList = (ins GPROpnd:$rs); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs"); + bit hasSideEffects = 0; + list Pattern = []; + InstrItinClass Itinerary = NoItinerary; + Format Form = FrmR; +} + +class DSBH_MM64R6_DESC : DSBH_DSHD_DESC_BASE<"dsbh", GPR64Opnd>; +class DSHD_MM64R6_DESC : DSBH_DSHD_DESC_BASE<"dshd", GPR64Opnd>; + +class DSLL_DSLL32_DESC_BASE + : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs GPR64Opnd:$rt); + dag InOperandList = (ins GPR64Opnd:$rs, ImmOpnd:$sa); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); + InstrItinClass Itinerary = itin; + list Pattern = [(set GPR64Opnd:$rt, (OpNode GPR64Opnd:$rs, PO:$sa))]; + string TwoOperandAliasConstraint = "$rs = $rt"; +} + +class DSLL_MM64R6_DESC : DSLL_DSLL32_DESC_BASE<"dsll", uimm6, II_DSLL, shl, + immZExt6>; +class DSLL32_MM64R6_DESC : DSLL_DSLL32_DESC_BASE<"dsll32", uimm5, II_DSLL32>; + +class DSLLV_DSRAV_MM64R6_DESC_BASE + : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs RO:$rd); + dag InOperandList = (ins RO:$rt, GPR32Opnd:$rs); + string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs"); + list Pattern = [(set RO:$rd, (OpNode RO:$rt, GPR32Opnd:$rs))]; + InstrItinClass Itinerary = itin; + Format Form = FrmR; +} + +class DSLLV_MM64R6_DESC : DSLLV_DSRAV_MM64R6_DESC_BASE<"dsllv", GPR64Opnd, + II_DSLLV, shl>; +class DSRAV_MM64R6_DESC : DSLLV_DSRAV_MM64R6_DESC_BASE<"dsrav", GPR64Opnd, + II_DSRAV, sra>; + +class DSRA_DSRA32_MM64R6_DESC_BASE + : MMR6Arch, MipsR6Inst { + dag OutOperandList = (outs RO:$rt); + dag InOperandList = (ins RO:$rs, ImmOpnd:$sa); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); + list Pattern = [(set RO:$rt, (OpNode RO:$rs, PF:$sa))]; + InstrItinClass Itinerary = itin; + Format Form = FrmR; + string BaseOpcode = instr_asm; +} + +class DSRA_MM64R6_DESC : DSRA_DSRA32_MM64R6_DESC_BASE<"dsra", uimm6, GPR64Opnd, + II_DSRA, sra, immZExt6>; +class DSRA32_MM64R6_DESC : DSRA_DSRA32_MM64R6_DESC_BASE<"dsra32", uimm5, + GPR64Opnd, II_DSRA32>; + //===----------------------------------------------------------------------===// // // Instruction Definitions @@ -231,6 +306,22 @@ let DecoderNamespace = "MicroMipsR6" in { ISA_MICROMIPS64R6; def DMUHU_MM64R6 : R6MMR6Rel, DMUHU_MM64R6_DESC, DMUHU_MM64R6_ENC, ISA_MICROMIPS64R6; + def DSBH_MM64R6 : R6MMR6Rel, DSBH_MM64R6_DESC, DSBH_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSHD_MM64R6 : R6MMR6Rel, DSHD_MM64R6_DESC, DSHD_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSLL_MM64R6 : R6MMR6Rel, DSLL_MM64R6_DESC, DSLL_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSLL32_MM64R6 : R6MMR6Rel, DSLL32_MM64R6_DESC, DSLL32_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSLLV_MM64R6 : R6MMR6Rel, DSLLV_MM64R6_DESC, DSLLV_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSRAV_MM64R6 : R6MMR6Rel, DSRAV_MM64R6_DESC, DSRAV_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSRA_MM64R6 : R6MMR6Rel, DSRA_MM64R6_DESC, DSRA_MM64R6_ENC, + ISA_MICROMIPS64R6; + def DSRA32_MM64R6 : R6MMR6Rel, DSRA32_MM64R6_DESC, DSRA32_MM64R6_ENC, + ISA_MICROMIPS64R6; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 8cb0589dc68..8723d5ce0be 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -136,24 +136,36 @@ def NOR64 : LogicNOR<"nor", GPR64Opnd>, ADD_FM<0, 0x27>; } /// Shift Instructions -def DSLL : shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL, shl, immZExt6>, - SRA_FM<0x38, 0>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def DSLL : shift_rotate_imm<"dsll", uimm6, GPR64Opnd, II_DSLL, shl, immZExt6>, + SRA_FM<0x38, 0>, ISA_MIPS3; +} def DSRL : shift_rotate_imm<"dsrl", uimm6, GPR64Opnd, II_DSRL, srl, immZExt6>, SRA_FM<0x3a, 0>, ISA_MIPS3; -def DSRA : shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA, sra, immZExt6>, +let AdditionalPredicates = [NotInMicroMips] in { + def DSRA : shift_rotate_imm<"dsra", uimm6, GPR64Opnd, II_DSRA, sra, immZExt6>, SRA_FM<0x3b, 0>, ISA_MIPS3; -def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>, +} +let AdditionalPredicates = [NotInMicroMips] in { + def DSLLV : shift_rotate_reg<"dsllv", GPR64Opnd, II_DSLLV, shl>, SRLV_FM<0x14, 0>, ISA_MIPS3; +} def DSRLV : shift_rotate_reg<"dsrlv", GPR64Opnd, II_DSRLV, srl>, SRLV_FM<0x16, 0>, ISA_MIPS3; -def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>, - SRLV_FM<0x17, 0>, ISA_MIPS3; -def DSLL32 : shift_rotate_imm<"dsll32", uimm5, GPR64Opnd, II_DSLL32>, - SRA_FM<0x3c, 0>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def DSRAV : shift_rotate_reg<"dsrav", GPR64Opnd, II_DSRAV, sra>, + SRLV_FM<0x17, 0>, ISA_MIPS3; +} +let AdditionalPredicates = [NotInMicroMips] in { + def DSLL32 : shift_rotate_imm<"dsll32", uimm5, GPR64Opnd, II_DSLL32>, + SRA_FM<0x3c, 0>, ISA_MIPS3; +} def DSRL32 : shift_rotate_imm<"dsrl32", uimm5, GPR64Opnd, II_DSRL32>, SRA_FM<0x3e, 0>, ISA_MIPS3; -def DSRA32 : shift_rotate_imm<"dsra32", uimm5, GPR64Opnd, II_DSRA32>, - SRA_FM<0x3f, 0>, ISA_MIPS3; +let AdditionalPredicates = [NotInMicroMips] in { + def DSRA32 : shift_rotate_imm<"dsra32", uimm5, GPR64Opnd, II_DSRA32>, + SRA_FM<0x3f, 0>, ISA_MIPS3; +} // Rotate Instructions def DROTR : shift_rotate_imm<"drotr", uimm6, GPR64Opnd, II_DROTR, rotr, @@ -268,8 +280,10 @@ def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>, ISA_MIPS64_NOT_64R6; def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>, ISA_MIPS64_NOT_64R6; /// Double Word Swap Bytes/HalfWords -def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>, ISA_MIPS64R2; -def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>, ISA_MIPS64R2; +let AdditionalPredicates = [NotInMicroMips] in { + def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>, ISA_MIPS64R2; + def DSHD : SubwordSwap<"dshd", GPR64Opnd>, SEB_FM<5, 0x24>, ISA_MIPS64R2; +} def LEA_ADDiu64 : EffectiveAddress<"daddiu", GPR64Opnd>, LW_FM<0x19>; diff --git a/test/MC/Disassembler/Mips/micromips64r6/valid.txt b/test/MC/Disassembler/Mips/micromips64r6/valid.txt index 58e27a490e1..66db06a5c79 100644 --- a/test/MC/Disassembler/Mips/micromips64r6/valid.txt +++ b/test/MC/Disassembler/Mips/micromips64r6/valid.txt @@ -258,3 +258,10 @@ 0x58 0xa4 0x18 0xd8 # CHECK: dmuhu $3, $4, $5 0x22 0x04 0x10 0x08 # CHECK: lwp $16, 8($4) 0x22 0x04 0x90 0x08 # CHECK: swp $16, 8($4) +0x58 0x64 0x7b 0x3c # CHECK: dsbh $3, $4 +0x58 0x64 0xfb 0x3c # CHECK: dshd $3, $4 +0x58 0x64 0x28 0x00 # CHECK: dsll $3, $4, 5 +0x58 0x64 0x28 0x08 # CHECK: dsll32 $3, $4, 5 +0x58 0xa6 0x20 0x10 # CHECK: dsllv $4, $5, $6 +0x58 0x85 0x28 0x80 # CHECK: dsra $4, $5, 5 +0x58 0xa6 0x20 0x90 # CHECK: dsrav $4, $5, $6 diff --git a/test/MC/Mips/micromips64r6/invalid.s b/test/MC/Mips/micromips64r6/invalid.s index c1c00dc5edf..2ddb9a31867 100644 --- a/test/MC/Mips/micromips64r6/invalid.s +++ b/test/MC/Mips/micromips64r6/invalid.s @@ -228,3 +228,11 @@ swp $31, 8($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: invalid operand for instruction swp $16, 8($34) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset swp $16, 4096($4) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected memory with 12-bit signed offset + dsll $3, $4, 64 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate + dsll $3, $4, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate + dsll32 $3, $4, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 5-bit unsigned immediate + dsll32 $3, $4, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 5-bit unsigned immediate + dsra $4, $5, 64 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate + dsra $4, $5, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 6-bit unsigned immediate + dsra32 $4, $5, 32 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 5-bit unsigned immediate + dsra32 $4, $5, -1 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: expected 5-bit unsigned immediate diff --git a/test/MC/Mips/micromips64r6/valid.s b/test/MC/Mips/micromips64r6/valid.s index b08bb7b5f62..cad295b1cb3 100644 --- a/test/MC/Mips/micromips64r6/valid.s +++ b/test/MC/Mips/micromips64r6/valid.s @@ -261,5 +261,13 @@ a: dmuhu $3, $4, $5 # CHECK dmuhu $3, $4, $5 # encoding: [0x58,0xa4,0x18,0xd8] lwp $16, 8($4) # CHECK: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08] swp $16, 8($4) # CHECK: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08] + dsbh $3, $4 # CHECK: dsbh $3, $4 # encoding: [0x58,0x64,0x7b,0x3c] + dshd $3, $4 # CHECK: dshd $3, $4 # encoding: [0x58,0x64,0xfb,0x3c] + dsll $3, $4, 5 # CHECK: dsll $3, $4, 5 # encoding: [0x58,0x64,0x28,0x00] + dsll32 $3, $4, 5 # CHECK: dsll32 $3, $4, 5 # encoding: [0x58,0x64,0x28,0x08] + dsllv $4, $5, $6 # CHECK: dsllv $4, $5, $6 # encoding: [0x58,0xa6,0x20,0x10] + dsra $4, $5, 5 # CHECK: dsra $4, $5, 5 # encoding: [0x58,0x85,0x28,0x80] + dsra32 $4, $5, 5 # CHECK: dsra32 $4, $5, 5 # encoding: [0x58,0x85,0x28,0x84] + dsrav $4, $5, $6 # CHECK: dsrav $4, $5, $6 # encoding: [0x58,0xa6,0x20,0x90] 1: -- 2.11.0