Skip to content

Commit

Permalink
[mips][msa] Added cfcmsa, and ctcmsa
Browse files Browse the repository at this point in the history
The MSA control registers have been added as reserved registers,
and are only used via ISD::Copy(To|From)Reg. The intrinsics are lowered
into these nodes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189468 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dsandersllvm committed Aug 28, 2013
1 parent f00539c commit a6c3a4e
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/llvm/IR/IntrinsicsMips.td
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,9 @@ def int_mips_ceqi_w : GCCBuiltin<"__builtin_msa_ceqi_w">,
def int_mips_ceqi_d : GCCBuiltin<"__builtin_msa_ceqi_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;

def int_mips_cfcmsa : GCCBuiltin<"__builtin_msa_cfcmsa">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;

def int_mips_cle_s_b : GCCBuiltin<"__builtin_msa_cle_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_cle_s_h : GCCBuiltin<"__builtin_msa_cle_s_h">,
Expand Down Expand Up @@ -765,6 +768,9 @@ def int_mips_copy_u_h : GCCBuiltin<"__builtin_msa_copy_u_h">,
def int_mips_copy_u_w : GCCBuiltin<"__builtin_msa_copy_u_w">,
Intrinsic<[llvm_i32_ty], [llvm_v4i32_ty, llvm_i32_ty], []>;

def int_mips_ctcmsa : GCCBuiltin<"__builtin_msa_ctcmsa">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>;

def int_mips_div_s_b : GCCBuiltin<"__builtin_msa_div_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_div_s_h : GCCBuiltin<"__builtin_msa_div_s_h">,
Expand Down
5 changes: 5 additions & 0 deletions lib/Target/Mips/MipsMSAInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ class MSA_3RF_FMT<bits<4> major, bits<1> df, bits<6> minor>: MSAInst {
let Inst{5-0} = minor;
}

class MSA_ELM_FMT<bits<10> major, bits<6> minor>: MSAInst {
let Inst{25-16} = major;
let Inst{5-0} = minor;
}

class MSA_ELM_B_FMT<bits<4> major, bits<6> minor>: MSAInst {
let Inst{25-22} = major;
let Inst{21-20} = 0b00;
Expand Down
24 changes: 24 additions & 0 deletions lib/Target/Mips/MipsMSAInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ class CEQI_H_ENC : MSA_I5_FMT<0b000, 0b01, 0b000111>;
class CEQI_W_ENC : MSA_I5_FMT<0b000, 0b10, 0b000111>;
class CEQI_D_ENC : MSA_I5_FMT<0b000, 0b11, 0b000111>;

class CFCMSA_ENC : MSA_ELM_FMT<0b0001111110, 0b011001>;

class CLE_S_B_ENC : MSA_3R_FMT<0b100, 0b00, 0b001111>;
class CLE_S_H_ENC : MSA_3R_FMT<0b100, 0b01, 0b001111>;
class CLE_S_W_ENC : MSA_3R_FMT<0b100, 0b10, 0b001111>;
Expand Down Expand Up @@ -219,6 +221,8 @@ class COPY_U_B_ENC : MSA_ELM_B_FMT<0b0011, 0b011001>;
class COPY_U_H_ENC : MSA_ELM_H_FMT<0b0011, 0b011001>;
class COPY_U_W_ENC : MSA_ELM_W_FMT<0b0011, 0b011001>;

class CTCMSA_ENC : MSA_ELM_FMT<0b0000111110, 0b011001>;

class DIV_S_B_ENC : MSA_3R_FMT<0b100, 0b00, 0b010010>;
class DIV_S_H_ENC : MSA_3R_FMT<0b100, 0b01, 0b010010>;
class DIV_S_W_ENC : MSA_3R_FMT<0b100, 0b10, 0b010010>;
Expand Down Expand Up @@ -1155,6 +1159,14 @@ class CEQI_W_DESC : MSA_SI5_DESC_BASE<"ceqi.w", int_mips_ceqi_w, NoItinerary,
class CEQI_D_DESC : MSA_SI5_DESC_BASE<"ceqi.d", int_mips_ceqi_d, NoItinerary,
MSA128D, MSA128D>;

class CFCMSA_DESC {
dag OutOperandList = (outs GPR32:$rd);
dag InOperandList = (ins MSACtrl:$cs);
string AsmString = "cfcmsa\t$rd, $cs";
InstrItinClass Itinerary = NoItinerary;
bit hasSideEffects = 1;
}

class CLE_S_B_DESC : MSA_3R_DESC_BASE<"cle_s.b", int_mips_cle_s_b, NoItinerary,
MSA128B, MSA128B>;
class CLE_S_H_DESC : MSA_3R_DESC_BASE<"cle_s.h", int_mips_cle_s_h, NoItinerary,
Expand Down Expand Up @@ -1241,6 +1253,14 @@ class COPY_U_H_DESC : MSA_COPY_DESC_BASE<"copy_u.h", int_mips_copy_u_h,
class COPY_U_W_DESC : MSA_COPY_DESC_BASE<"copy_u.w", int_mips_copy_u_w,
NoItinerary, GPR32, MSA128W>;

class CTCMSA_DESC {
dag OutOperandList = (outs);
dag InOperandList = (ins MSACtrl:$cd, GPR32:$rs);
string AsmString = "ctcmsa\t$cd, $rs";
InstrItinClass Itinerary = NoItinerary;
bit hasSideEffects = 1;
}

class DIV_S_B_DESC : MSA_3R_DESC_BASE<"div_s.b", int_mips_div_s_b, NoItinerary,
MSA128B, MSA128B>;
class DIV_S_H_DESC : MSA_3R_DESC_BASE<"div_s.h", int_mips_div_s_h, NoItinerary,
Expand Down Expand Up @@ -2299,6 +2319,8 @@ def CEQI_H : CEQI_H_ENC, CEQI_H_DESC, Requires<[HasMSA]>;
def CEQI_W : CEQI_W_ENC, CEQI_W_DESC, Requires<[HasMSA]>;
def CEQI_D : CEQI_D_ENC, CEQI_D_DESC, Requires<[HasMSA]>;

def CFCMSA : CFCMSA_ENC, CFCMSA_DESC, Requires<[HasMSA]>;

def CLE_S_B : CLE_S_B_ENC, CLE_S_B_DESC, Requires<[HasMSA]>;
def CLE_S_H : CLE_S_H_ENC, CLE_S_H_DESC, Requires<[HasMSA]>;
def CLE_S_W : CLE_S_W_ENC, CLE_S_W_DESC, Requires<[HasMSA]>;
Expand Down Expand Up @@ -2347,6 +2369,8 @@ def COPY_U_B : COPY_U_B_ENC, COPY_U_B_DESC, Requires<[HasMSA]>;
def COPY_U_H : COPY_U_H_ENC, COPY_U_H_DESC, Requires<[HasMSA]>;
def COPY_U_W : COPY_U_W_ENC, COPY_U_W_DESC, Requires<[HasMSA]>;

def CTCMSA : CTCMSA_ENC, CTCMSA_DESC, Requires<[HasMSA]>;

def DIV_S_B : DIV_S_B_ENC, DIV_S_B_DESC, Requires<[HasMSA]>;
def DIV_S_H : DIV_S_H_ENC, DIV_S_H_DESC, Requires<[HasMSA]>;
def DIV_S_W : DIV_S_W_ENC, DIV_S_W_DESC, Requires<[HasMSA]>;
Expand Down
10 changes: 10 additions & 0 deletions lib/Target/Mips/MipsRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ getReservedRegs(const MachineFunction &MF) const {
Reserved.set(Mips::DSPEFI);
Reserved.set(Mips::DSPOutFlag);

// Reserve MSA control registers.
Reserved.set(Mips::MSAIR);
Reserved.set(Mips::MSACSR);
Reserved.set(Mips::MSAAccess);
Reserved.set(Mips::MSASave);
Reserved.set(Mips::MSAModify);
Reserved.set(Mips::MSARequest);
Reserved.set(Mips::MSAMap);
Reserved.set(Mips::MSAUnmap);

// Reserve RA if in mips16 mode.
if (Subtarget.inMips16Mode()) {
Reserved.set(Mips::RA);
Expand Down
13 changes: 13 additions & 0 deletions lib/Target/Mips/MipsRegisterInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,16 @@ let Namespace = "Mips" in {
def DSPOutFlag : RegisterWithSubRegs<"", [DSPOutFlag16_19, DSPOutFlag20,
DSPOutFlag21, DSPOutFlag22,
DSPOutFlag23]>;

// MSA-ASE control registers.
def MSAIR : Register<"0">;
def MSACSR : Register<"1">;
def MSAAccess : Register<"2">;
def MSASave : Register<"3">;
def MSAModify : Register<"4">;
def MSARequest : Register<"5">;
def MSAMap : Register<"6">;
def MSAUnmap : Register<"7">;
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -329,6 +339,9 @@ def MSA128W: RegisterClass<"Mips", [v4i32, v4f32], 128,
def MSA128D: RegisterClass<"Mips", [v2i64, v2f64], 128,
(sequence "W%u", 0, 31)>;

def MSACtrl: RegisterClass<"Mips", [i32], 32, (add
MSAIR, MSACSR, MSAAccess, MSASave, MSAModify, MSARequest, MSAMap, MSAUnmap)>;

// Hi/Lo Registers
def LO32 : RegisterClass<"Mips", [i32], 32, (add LO0)>;
def HI32 : RegisterClass<"Mips", [i32], 32, (add HI0)>;
Expand Down
48 changes: 48 additions & 0 deletions lib/Target/Mips/MipsSEISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI,
MIB.addReg(Mips::DSPEFI, Flag);
}

unsigned MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const {
switch (cast<ConstantSDNode>(RegIdx)->getZExtValue()) {
default:
llvm_unreachable("Could not map int to register");
case 0: return Mips::MSAIR;
case 1: return Mips::MSACSR;
case 2: return Mips::MSAAccess;
case 3: return Mips::MSASave;
case 4: return Mips::MSAModify;
case 5: return Mips::MSARequest;
case 6: return Mips::MSAMap;
case 7: return Mips::MSAUnmap;
}
}

bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI,
const MachineInstr& MI) {
unsigned DstReg = 0, ZeroReg = 0;
Expand Down Expand Up @@ -432,6 +447,39 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) {
return std::make_pair(true, RegOpnd);
}

case ISD::INTRINSIC_W_CHAIN: {
switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
default:
break;

case Intrinsic::mips_cfcmsa: {
SDValue ChainIn = Node->getOperand(0);
SDValue RegIdx = Node->getOperand(2);
SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL,
getMSACtrlReg(RegIdx), MVT::i32);
return std::make_pair(true, Reg.getNode());
}
}
break;
}

case ISD::INTRINSIC_VOID: {
switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
default:
break;

case Intrinsic::mips_ctcmsa: {
SDValue ChainIn = Node->getOperand(0);
SDValue RegIdx = Node->getOperand(2);
SDValue Value = Node->getOperand(3);
SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL,
getMSACtrlReg(RegIdx), Value);
return std::make_pair(true, ChainOut.getNode());
}
}
break;
}

case MipsISD::ThreadPointer: {
EVT PtrVT = getTargetLowering()->getPointerTy();
unsigned RdhwrOpc, DestReg;
Expand Down
2 changes: 2 additions & 0 deletions lib/Target/Mips/MipsSEISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel {
void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI,
MachineFunction &MF);

unsigned getMSACtrlReg(const SDValue RegIdx) const;

bool replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&);

std::pair<SDNode*, SDNode*> selectMULT(SDNode *N, unsigned Opc, SDLoc dl,
Expand Down
4 changes: 4 additions & 0 deletions lib/Target/Mips/MipsSEInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
.addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
return;
}
else if (Mips::MSACtrlRegClass.contains(SrcReg))
Opc = Mips::CFCMSA;
}
else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg.
if (Mips::CCRRegClass.contains(DestReg))
Expand All @@ -130,6 +132,8 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
.addReg(DestReg, RegState::ImplicitDefine);
return;
}
else if (Mips::MSACtrlRegClass.contains(DestReg))
Opc = Mips::CTCMSA;
}
else if (Mips::FGR32RegClass.contains(DestReg, SrcReg))
Opc = Mips::FMOV_S;
Expand Down
167 changes: 167 additions & 0 deletions test/CodeGen/Mips/msa/elm_cxcmsa.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
; Test the MSA ctcmsa and cfcmsa intrinsics (which are encoded with the ELM
; instruction format).

; RUN: llc -march=mips -mattr=+msa < %s | FileCheck %s

define i32 @msa_ir_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 0)
ret i32 %0
}

; CHECK: msa_ir_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $0
; CHECK: .size msa_ir_cfcmsa_test
;
define i32 @msa_csr_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 1)
ret i32 %0
}

; CHECK: msa_csr_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $1
; CHECK: .size msa_csr_cfcmsa_test
;
define i32 @msa_access_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 2)
ret i32 %0
}

; CHECK: msa_access_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $2
; CHECK: .size msa_access_cfcmsa_test
;
define i32 @msa_save_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 3)
ret i32 %0
}

; CHECK: msa_save_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $3
; CHECK: .size msa_save_cfcmsa_test
;
define i32 @msa_modify_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 4)
ret i32 %0
}

; CHECK: msa_modify_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $4
; CHECK: .size msa_modify_cfcmsa_test
;
define i32 @msa_request_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 5)
ret i32 %0
}

; CHECK: msa_request_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $5
; CHECK: .size msa_request_cfcmsa_test
;
define i32 @msa_map_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 6)
ret i32 %0
}

; CHECK: msa_map_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $6
; CHECK: .size msa_map_cfcmsa_test
;
define i32 @msa_unmap_cfcmsa_test() nounwind {
entry:
%0 = tail call i32 @llvm.mips.cfcmsa(i32 7)
ret i32 %0
}

; CHECK: msa_unmap_cfcmsa_test:
; CHECK: cfcmsa $[[R1:[0-9]+]], $7
; CHECK: .size msa_unmap_cfcmsa_test
;
define void @msa_ir_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 0, i32 1)
ret void
}

; CHECK: msa_ir_ctcmsa_test:
; CHECK: ctcmsa $0
; CHECK: .size msa_ir_ctcmsa_test
;
define void @msa_csr_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 1, i32 1)
ret void
}

; CHECK: msa_csr_ctcmsa_test:
; CHECK: ctcmsa $1
; CHECK: .size msa_csr_ctcmsa_test
;
define void @msa_access_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 2, i32 1)
ret void
}

; CHECK: msa_access_ctcmsa_test:
; CHECK: ctcmsa $2
; CHECK: .size msa_access_ctcmsa_test
;
define void @msa_save_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 3, i32 1)
ret void
}

; CHECK: msa_save_ctcmsa_test:
; CHECK: ctcmsa $3
; CHECK: .size msa_save_ctcmsa_test
;
define void @msa_modify_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 4, i32 1)
ret void
}

; CHECK: msa_modify_ctcmsa_test:
; CHECK: ctcmsa $4
; CHECK: .size msa_modify_ctcmsa_test
;
define void @msa_request_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 5, i32 1)
ret void
}

; CHECK: msa_request_ctcmsa_test:
; CHECK: ctcmsa $5
; CHECK: .size msa_request_ctcmsa_test
;
define void @msa_map_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 6, i32 1)
ret void
}

; CHECK: msa_map_ctcmsa_test:
; CHECK: ctcmsa $6
; CHECK: .size msa_map_ctcmsa_test
;
define void @msa_unmap_ctcmsa_test() nounwind {
entry:
tail call void @llvm.mips.ctcmsa(i32 7, i32 1)
ret void
}

; CHECK: msa_unmap_ctcmsa_test:
; CHECK: ctcmsa $7
; CHECK: .size msa_unmap_ctcmsa_test
;
declare i32 @llvm.mips.cfcmsa(i32) nounwind
declare void @llvm.mips.ctcmsa(i32, i32) nounwind

0 comments on commit a6c3a4e

Please sign in to comment.