From 93ba059e489fd8fdf3a87db638a7283e66942a31 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 28 Sep 2012 20:50:31 +0000 Subject: [PATCH] MIPS DSP: other miscellaneous instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsDSPInstrFormats.td | 55 +++++++++++++++++ lib/Target/Mips/MipsDSPInstrInfo.td | 81 ++++++++++++++++++++++++++ test/CodeGen/Mips/dsp-r1.ll | 41 +++++++++++++ test/CodeGen/Mips/dsp-r2.ll | 30 ++++++++++ 4 files changed, 207 insertions(+) diff --git a/lib/Target/Mips/MipsDSPInstrFormats.td b/lib/Target/Mips/MipsDSPInstrFormats.td index c5939c7adea..8e01d06596a 100644 --- a/lib/Target/Mips/MipsDSPInstrFormats.td +++ b/lib/Target/Mips/MipsDSPInstrFormats.td @@ -141,6 +141,21 @@ class SHLL_QB_FMT op> : DSPInst { let Inst{5-0} = 0b010011; } +// LX sub-class format. +class LX_FMT op> : DSPInst { + bits<5> rd; + bits<5> base; + bits<5> index; + + let Opcode = SPECIAL3_OPCODE.V; + + let Inst{25-21} = base; + let Inst{20-16} = index; + let Inst{15-11} = rd; + let Inst{10-6} = op; + let Inst{5-0} = 0b001010; +} + // ADDUH.QB sub-class format. class ADDUH_QB_FMT op> : DSPInst { bits<5> rd; @@ -156,6 +171,21 @@ class ADDUH_QB_FMT op> : DSPInst { let Inst{5-0} = 0b011000; } +// APPEND sub-class format. +class APPEND_FMT op> : DSPInst { + bits<5> rt; + bits<5> rs; + bits<5> sa; + + let Opcode = SPECIAL3_OPCODE.V; + + let Inst{25-21} = rs; + let Inst{20-16} = rt; + let Inst{15-11} = sa; + let Inst{10-6} = op; + let Inst{5-0} = 0b110001; +} + // DPA.W.PH sub-class format. class DPA_W_PH_FMT op> : DSPInst { bits<2> ac; @@ -243,6 +273,18 @@ class RDDSP_FMT op> : DSPInst { let Inst{5-0} = 0b111000; } +class WRDSP_FMT op> : DSPInst { + bits<5> rs; + bits<10> mask; + + let Opcode = SPECIAL3_OPCODE.V; + + let Inst{25-21} = rs; + let Inst{20-11} = mask; + let Inst{10-6} = op; + let Inst{5-0} = 0b111000; +} + class BPOSGE32_FMT op> : DSPInst { bits<16> offset; @@ -252,3 +294,16 @@ class BPOSGE32_FMT op> : DSPInst { let Inst{20-16} = op; let Inst{15-0} = offset; } + +// INSV sub-class format. +class INSV_FMT op> : DSPInst { + bits<5> rt; + bits<5> rs; + + let Opcode = SPECIAL3_OPCODE.V; + + let Inst{25-21} = rs; + let Inst{20-16} = rt; + let Inst{15-6} = 0; + let Inst{5-0} = op; +} diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index acb78bbce78..ef9402865b0 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -179,7 +179,11 @@ class REPLV_QB_ENC : ABSQ_S_PH_R2_FMT<0b00011>; class REPLV_PH_ENC : ABSQ_S_PH_R2_FMT<0b01011>; class PICK_QB_ENC : CMP_EQ_QB_R3_FMT<0b00011>; class PICK_PH_ENC : CMP_EQ_QB_R3_FMT<0b01011>; +class LWX_ENC : LX_FMT<0b00000>; +class LHX_ENC : LX_FMT<0b00100>; +class LBUX_ENC : LX_FMT<0b00110>; class BPOSGE32_ENC : BPOSGE32_FMT<0b11100>; +class INSV_ENC : INSV_FMT<0b001100>; class EXTP_ENC : EXTR_W_TY1_FMT<0b00010>; class EXTPV_ENC : EXTR_W_TY1_FMT<0b00011>; @@ -198,6 +202,7 @@ class SHILOV_ENC : SHILO_R2_FMT<0b11011>; class MTHLIP_ENC : SHILO_R2_FMT<0b11111>; class RDDSP_ENC : RDDSP_FMT<0b10010>; +class WRDSP_ENC : WRDSP_FMT<0b10011>; class ADDU_PH_ENC : ADDU_QB_FMT<0b01000>; class ADDU_S_PH_ENC : ADDU_QB_FMT<0b01100>; class SUBU_PH_ENC : ADDU_QB_FMT<0b01001>; @@ -241,6 +246,9 @@ class SHRA_R_QB_ENC : SHLL_QB_FMT<0b00101>; class SHRAV_R_QB_ENC : SHLL_QB_FMT<0b00111>; class SHRL_PH_ENC : SHLL_QB_FMT<0b11001>; class SHRLV_PH_ENC : SHLL_QB_FMT<0b11011>; +class APPEND_ENC : APPEND_FMT<0b00000>; +class BALIGN_ENC : APPEND_FMT<0b10000>; +class PREPEND_ENC : APPEND_FMT<0b00001>; // Instruction desc. class ADDU_QB_DESC_BASE Defs = [DSPCtrl]; } +class LX_DESC_BASE { + dag OutOperandList = (outs CPURegs:$rd); + dag InOperandList = (ins CPURegs:$base, CPURegs:$index); + string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})"); + list Pattern = [(set CPURegs:$rd, + (OpNode CPURegs:$base, CPURegs:$index))]; + InstrItinClass Itinerary = itin; + list Defs = [DSPCtrl]; + bit mayLoad = 1; +} + class ADDUH_QB_DESC_BASE { @@ -352,6 +372,18 @@ class ADDUH_QB_DESC_BASE Defs = [DSPCtrl]; } +class APPEND_DESC_BASE { + dag OutOperandList = (outs CPURegs:$rt); + dag InOperandList = (ins CPURegs:$rs, shamt:$sa, CPURegs:$src); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); + list Pattern = [(set CPURegs:$rt, + (OpNode CPURegs:$src, CPURegs:$rs, ImmOp:$sa))]; + InstrItinClass Itinerary = itin; + list Defs = [DSPCtrl]; + string Constraints = "$src = $rt"; +} + class EXTR_W_TY1_R2_DESC_BASE { dag OutOperandList = (outs CPURegs:$rt); @@ -416,6 +448,16 @@ class RDDSP_DESC_BASE Uses = [DSPCtrl]; } +class WRDSP_DESC_BASE { + dag OutOperandList = (outs); + dag InOperandList = (ins CPURegs:$rs, uimm16:$mask); + string AsmString = !strconcat(instr_asm, "\t$rs, $mask"); + list Pattern = [(OpNode CPURegs:$rs, immZExt10:$mask)]; + InstrItinClass Itinerary = itin; + list Defs = [DSPCtrl]; +} + class DPA_W_PH_PSEUDO_BASE : PseudoDSP<(outs), (ins CPURegs:$rs, CPURegs:$rt), @@ -464,6 +506,17 @@ class BPOSGE32_DESC_BASE { bit hasDelaySlot = 1; } +class INSV_DESC_BASE { + dag OutOperandList = (outs CPURegs:$rt); + dag InOperandList = (ins CPURegs:$src, CPURegs:$rs); + string AsmString = !strconcat(instr_asm, "\t$rt, $rs"); + list Pattern = [(set CPURegs:$rt, (OpNode CPURegs:$src, CPURegs:$rs))]; + InstrItinClass Itinerary = itin; + list Uses = [DSPCtrl]; + string Constraints = "$src = $rt"; +} + //===----------------------------------------------------------------------===// // MIPS DSP Rev 1 //===----------------------------------------------------------------------===// @@ -777,6 +830,12 @@ class PICK_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.ph", int_mips_pick_ph, NoItinerary, DSPRegs, DSPRegs>, ClearDefs, UseDSPCtrl; +class LWX_DESC : LX_DESC_BASE<"lwx", int_mips_lwx, NoItinerary>, ClearDefs; + +class LHX_DESC : LX_DESC_BASE<"lhx", int_mips_lhx, NoItinerary>, ClearDefs; + +class LBUX_DESC : LX_DESC_BASE<"lbux", int_mips_lbux, NoItinerary>, ClearDefs; + class BPOSGE32_DESC : BPOSGE32_DESC_BASE<"bposge32", NoItinerary>; // Extr @@ -820,6 +879,10 @@ class MTHLIP_DESC : MTHLIP_DESC_BASE<"mthlip">; class RDDSP_DESC : RDDSP_DESC_BASE<"rddsp", int_mips_rddsp, NoItinerary>; +class WRDSP_DESC : WRDSP_DESC_BASE<"wrdsp", int_mips_wrdsp, NoItinerary>; + +class INSV_DESC : INSV_DESC_BASE<"insv", int_mips_insv, NoItinerary>; + //===----------------------------------------------------------------------===// // MIPS DSP Rev 2 // Addition/subtraction @@ -969,6 +1032,16 @@ class SHRL_PH_DESC : SHLL_QB_R2_DESC_BASE<"shrl.ph", int_mips_shrl_ph, immZExt4, class SHRLV_PH_DESC : SHLL_QB_R3_DESC_BASE<"shrlv.ph", int_mips_shrl_ph, NoItinerary, DSPRegs>, ClearDefs; +// Misc +class APPEND_DESC : APPEND_DESC_BASE<"append", int_mips_append, immZExt5, + NoItinerary>, ClearDefs; + +class BALIGN_DESC : APPEND_DESC_BASE<"balign", int_mips_balign, immZExt2, + NoItinerary>, ClearDefs; + +class PREPEND_DESC : APPEND_DESC_BASE<"prepend", int_mips_prepend, immZExt5, + NoItinerary>, ClearDefs; + // Pseudos. def BPOSGE32_PSEUDO : BPOSGE32_PSEUDO_DESC_BASE; @@ -1061,7 +1134,11 @@ def REPLV_QB : REPLV_QB_ENC, REPLV_QB_DESC; def REPLV_PH : REPLV_PH_ENC, REPLV_PH_DESC; def PICK_QB : PICK_QB_ENC, PICK_QB_DESC; def PICK_PH : PICK_PH_ENC, PICK_PH_DESC; +def LWX : LWX_ENC, LWX_DESC; +def LHX : LHX_ENC, LHX_DESC; +def LBUX : LBUX_ENC, LBUX_DESC; def BPOSGE32 : BPOSGE32_ENC, BPOSGE32_DESC; +def INSV : INSV_ENC, INSV_DESC; def EXTP : EXTP_ENC, EXTP_DESC; def EXTPV : EXTPV_ENC, EXTPV_DESC; def EXTPDP : EXTPDP_ENC, EXTPDP_DESC; @@ -1078,6 +1155,7 @@ def SHILO : SHILO_ENC, SHILO_DESC; def SHILOV : SHILOV_ENC, SHILOV_DESC; def MTHLIP : MTHLIP_ENC, MTHLIP_DESC; def RDDSP : RDDSP_ENC, RDDSP_DESC; +def WRDSP : WRDSP_ENC, WRDSP_DESC; // MIPS DSP Rev 2 let Predicates = [HasDSPR2] in { @@ -1125,6 +1203,9 @@ def SHRA_R_QB : SHRA_R_QB_ENC, SHRA_R_QB_DESC; def SHRAV_R_QB : SHRAV_R_QB_ENC, SHRAV_R_QB_DESC; def SHRL_PH : SHRL_PH_ENC, SHRL_PH_DESC; def SHRLV_PH : SHRLV_PH_ENC, SHRLV_PH_DESC; +def APPEND : APPEND_ENC, APPEND_DESC; +def BALIGN : BALIGN_ENC, BALIGN_DESC; +def PREPEND : PREPEND_ENC, PREPEND_DESC; } diff --git a/test/CodeGen/Mips/dsp-r1.ll b/test/CodeGen/Mips/dsp-r1.ll index c49e4fc00c1..f6b62c476ae 100644 --- a/test/CodeGen/Mips/dsp-r1.ll +++ b/test/CodeGen/Mips/dsp-r1.ll @@ -1198,3 +1198,44 @@ entry: } declare i32 @llvm.mips.bitrev(i32) nounwind readnone + +define i32 @test__builtin_mips_lbux1(i32 %i0, i8* %a0, i32 %a1) nounwind readonly { +entry: +; CHECK: lbux + + %0 = tail call i32 @llvm.mips.lbux(i8* %a0, i32 %a1) + ret i32 %0 +} + +declare i32 @llvm.mips.lbux(i8*, i32) nounwind readonly + +define i32 @test__builtin_mips_lhx1(i32 %i0, i8* %a0, i32 %a1) nounwind readonly { +entry: +; CHECK: lhx + + %0 = tail call i32 @llvm.mips.lhx(i8* %a0, i32 %a1) + ret i32 %0 +} + +declare i32 @llvm.mips.lhx(i8*, i32) nounwind readonly + +define i32 @test__builtin_mips_lwx1(i32 %i0, i8* %a0, i32 %a1) nounwind readonly { +entry: +; CHECK: lwx + + %0 = tail call i32 @llvm.mips.lwx(i8* %a0, i32 %a1) + ret i32 %0 +} + +declare i32 @llvm.mips.lwx(i8*, i32) nounwind readonly + +define i32 @test__builtin_mips_wrdsp1(i32 %i0, i32 %a0) nounwind { +entry: +; CHECK: wrdsp + + tail call void @llvm.mips.wrdsp(i32 %a0, i32 31) + %0 = tail call i32 @llvm.mips.rddsp(i32 31) + ret i32 %0 +} + +declare void @llvm.mips.wrdsp(i32, i32) nounwind diff --git a/test/CodeGen/Mips/dsp-r2.ll b/test/CodeGen/Mips/dsp-r2.ll index 4bd650c56dd..4656f70636e 100644 --- a/test/CodeGen/Mips/dsp-r2.ll +++ b/test/CodeGen/Mips/dsp-r2.ll @@ -536,3 +536,33 @@ entry: } declare i32 @llvm.mips.subqh.r.w(i32, i32) nounwind readnone + +define i32 @test__builtin_mips_append1(i32 %i0, i32 %a0, i32 %a1) nounwind readnone { +entry: +; CHECK: append + + %0 = tail call i32 @llvm.mips.append(i32 %a0, i32 %a1, i32 15) + ret i32 %0 +} + +declare i32 @llvm.mips.append(i32, i32, i32) nounwind readnone + +define i32 @test__builtin_mips_balign1(i32 %i0, i32 %a0, i32 %a1) nounwind readnone { +entry: +; CHECK: balign + + %0 = tail call i32 @llvm.mips.balign(i32 %a0, i32 %a1, i32 1) + ret i32 %0 +} + +declare i32 @llvm.mips.balign(i32, i32, i32) nounwind readnone + +define i32 @test__builtin_mips_prepend1(i32 %i0, i32 %a0, i32 %a1) nounwind readnone { +entry: +; CHECK: prepend + + %0 = tail call i32 @llvm.mips.prepend(i32 %a0, i32 %a1, i32 15) + ret i32 %0 +} + +declare i32 @llvm.mips.prepend(i32, i32, i32) nounwind readnone