MIPS DSP: other miscellaneous instructions.
authorAkira Hatanaka <ahatanaka@mips.com>
Fri, 28 Sep 2012 20:50:31 +0000 (20:50 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Fri, 28 Sep 2012 20:50:31 +0000 (20:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164845 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsDSPInstrFormats.td
lib/Target/Mips/MipsDSPInstrInfo.td
test/CodeGen/Mips/dsp-r1.ll
test/CodeGen/Mips/dsp-r2.ll

index c5939c7adea10d1926b00d6edc42f1586caebdb6..8e01d06596a1b0424b13754d45649051dd6e9461 100644 (file)
@@ -141,6 +141,21 @@ class SHLL_QB_FMT<bits<5> op> : DSPInst {
   let Inst{5-0}   = 0b010011;
 }
 
+// LX sub-class format.
+class LX_FMT<bits<5> 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<bits<5> op> : DSPInst {
   bits<5> rd;
@@ -156,6 +171,21 @@ class ADDUH_QB_FMT<bits<5> op> : DSPInst {
   let Inst{5-0} = 0b011000;
 }
 
+// APPEND sub-class format.
+class APPEND_FMT<bits<5> 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<bits<5> op> : DSPInst {
   bits<2> ac;
@@ -243,6 +273,18 @@ class RDDSP_FMT<bits<5> op> : DSPInst {
   let Inst{5-0} = 0b111000;
 }
 
+class WRDSP_FMT<bits<5> 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<bits<5> op> : DSPInst {
   bits<16> offset;
 
@@ -252,3 +294,16 @@ class BPOSGE32_FMT<bits<5> op> : DSPInst {
   let Inst{20-16} = op;
   let Inst{15-0} = offset;
 }
+
+// INSV sub-class format.
+class INSV_FMT<bits<6> 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;
+}
index acb78bbce78c86d6d5ad3ec2a11377b5eff3eef3..ef9402865b0d65dffbf94090b541318329bf3732 100644 (file)
@@ -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<string instr_asm, SDPatternOperator OpNode,
@@ -341,6 +349,18 @@ class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
   list<Register> Defs = [DSPCtrl];
 }
 
+class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
+                   InstrItinClass itin> {
+  dag OutOperandList = (outs CPURegs:$rd);
+  dag InOperandList = (ins CPURegs:$base, CPURegs:$index);
+  string AsmString = !strconcat(instr_asm, "\t$rd, ${index}(${base})");
+  list<dag> Pattern = [(set CPURegs:$rd,
+                       (OpNode CPURegs:$base, CPURegs:$index))];
+  InstrItinClass Itinerary = itin;
+  list<Register> Defs = [DSPCtrl];
+  bit mayLoad = 1;
+}
+
 class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
                          InstrItinClass itin, RegisterClass RCD,
                          RegisterClass RCS = RCD,  RegisterClass RCT = RCD> {
@@ -352,6 +372,18 @@ class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
   list<Register> Defs = [DSPCtrl];
 }
 
+class APPEND_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
+                       SDPatternOperator ImmOp, InstrItinClass itin> {
+  dag OutOperandList = (outs CPURegs:$rt);
+  dag InOperandList = (ins CPURegs:$rs, shamt:$sa, CPURegs:$src);
+  string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa");
+  list<dag> Pattern =  [(set CPURegs:$rt,
+                        (OpNode CPURegs:$src, CPURegs:$rs, ImmOp:$sa))];
+  InstrItinClass Itinerary = itin;
+  list<Register> Defs = [DSPCtrl];
+  string Constraints = "$src = $rt";
+}
+
 class EXTR_W_TY1_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
                               InstrItinClass itin> {
   dag OutOperandList = (outs CPURegs:$rt);
@@ -416,6 +448,16 @@ class RDDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
   list<Register> Uses = [DSPCtrl];
 }
 
+class WRDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
+                      InstrItinClass itin> {
+  dag OutOperandList = (outs);
+  dag InOperandList = (ins CPURegs:$rs, uimm16:$mask);
+  string AsmString = !strconcat(instr_asm, "\t$rs, $mask");
+  list<dag> Pattern = [(OpNode CPURegs:$rs, immZExt10:$mask)];
+  InstrItinClass Itinerary = itin;
+  list<Register> Defs = [DSPCtrl];
+}
+
 class DPA_W_PH_PSEUDO_BASE<SDPatternOperator OpNode, InstrItinClass itin,
                            Instruction realinst> :
   PseudoDSP<(outs), (ins CPURegs:$rs, CPURegs:$rt),
@@ -464,6 +506,17 @@ class BPOSGE32_DESC_BASE<string instr_asm, InstrItinClass itin> {
   bit hasDelaySlot = 1;
 }
 
+class INSV_DESC_BASE<string instr_asm, SDPatternOperator OpNode,
+                     InstrItinClass itin> {
+  dag OutOperandList = (outs CPURegs:$rt);
+  dag InOperandList = (ins CPURegs:$src, CPURegs:$rs);
+  string AsmString = !strconcat(instr_asm, "\t$rt, $rs");
+  list<dag> Pattern = [(set CPURegs:$rt, (OpNode CPURegs:$src, CPURegs:$rs))];
+  InstrItinClass Itinerary = itin;
+  list<Register> 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<int_mips_bposge32, NoItinerary>;
 
@@ -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;
 
 }
 
index c49e4fc00c15c0c99eda627fa8f5d8d419b2eae4..f6b62c476aefd045ac1b579874f657861ab9e778 100644 (file)
@@ -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
index 4bd650c56dd2f5a4bc7bade666f690daacc7c1f5..4656f70636e7c446b3b876cab3840627d8d822c1 100644 (file)
@@ -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