| //====--- SPU64InstrInfo.td - Cell SPU 64-bit operations -*- tablegen -*--====// | |
| // | |
| // Cell SPU 64-bit operations | |
| // | |
| //===----------------------------------------------------------------------===// | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // 64-bit comparisons: | |
| // | |
| // 1. The instruction sequences for vector vice scalar differ by a | |
| // constant. In the scalar case, we're only interested in the | |
| // top two 32-bit slots, whereas we're interested in an exact | |
| // all-four-slot match in the vector case. | |
| // | |
| // 2. There are no "immediate" forms, since loading 64-bit constants | |
| // could be a constant pool load. | |
| // | |
| // 3. i64 setcc results are i32, which are subsequently converted to a FSM | |
| // mask when used in a select pattern. | |
| // | |
| // 4. v2i64 setcc results are v4i32, which can be converted to a FSM mask (TODO) | |
| // [Note: this may be moot, since gb produces v4i32 or r32.] | |
| // | |
| // 5. The code sequences for r64 and v2i64 are probably overly conservative, | |
| // compared to the code that gcc produces. | |
| // | |
| // M00$E B!tes Kan be Pretty N@sTi!!!!! (apologies to Monty!) | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // selb instruction definition for i64. Note that the selection mask is | |
| // a vector, produced by various forms of FSM: | |
| def SELBr64_cond: | |
| SELBInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB, VECREG:$rC), | |
| [/* no pattern */]>; | |
| // The generic i64 select pattern, which assumes that the comparison result | |
| // is in a 32-bit register that contains a select mask pattern (i.e., gather | |
| // bits result): | |
| def : Pat<(select R32C:$rCond, R64C:$rFalse, R64C:$rTrue), | |
| (SELBr64_cond R64C:$rTrue, R64C:$rFalse, (FSMr32 R32C:$rCond))>; | |
| // select the negative condition: | |
| class I64SELECTNegCond<PatFrag cond, CodeFrag compare>: | |
| Pat<(select (i32 (cond R64C:$rA, R64C:$rB)), R64C:$rTrue, R64C:$rFalse), | |
| (SELBr64_cond R64C:$rTrue, R64C:$rFalse, (FSMr32 compare.Fragment))>; | |
| // setcc the negative condition: | |
| class I64SETCCNegCond<PatFrag cond, CodeFrag compare>: | |
| Pat<(cond R64C:$rA, R64C:$rB), | |
| (XORIr32 compare.Fragment, -1)>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // The i64 seteq fragment that does the scalar->vector conversion and | |
| // comparison: | |
| def CEQr64compare: | |
| CodeFrag<(CGTIv4i32 (GBv4i32 (CEQv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG))), 0xb)>; | |
| // The i64 seteq fragment that does the vector comparison | |
| def CEQv2i64compare: | |
| CodeFrag<(CEQIv4i32 (GBv4i32 (CEQv4i32 VECREG:$rA, VECREG:$rB)), 0xf)>; | |
| // i64 seteq (equality): the setcc result is i32, which is converted to a | |
| // vector FSM mask when used in a select pattern. | |
| // | |
| // v2i64 seteq (equality): the setcc result is v4i32 | |
| multiclass CompareEqual64 { | |
| // Plain old comparison, converts back to i32 scalar | |
| def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CEQr64compare.Fragment, R32C))>; | |
| def v2i64: CodeFrag<(i32 (COPY_TO_REGCLASS CEQv2i64compare.Fragment, R32C))>; | |
| // SELB mask from FSM: | |
| def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CEQr64compare.Fragment), R32C))>; | |
| def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CEQv2i64compare.Fragment), R32C))>; | |
| } | |
| defm I64EQ: CompareEqual64; | |
| def : Pat<(seteq R64C:$rA, R64C:$rB), I64EQr64.Fragment>; | |
| def : Pat<(seteq (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)), I64EQv2i64.Fragment>; | |
| // i64 setne: | |
| def : I64SETCCNegCond<setne, I64EQr64>; | |
| def : I64SELECTNegCond<setne, I64EQr64>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // i64 setugt/setule: | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| def CLGTr64ugt: | |
| CodeFrag<(CLGTv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG))>; | |
| def CLGTr64eq: | |
| CodeFrag<(CEQv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG))>; | |
| def CLGTr64compare: | |
| CodeFrag<(SELBv2i64 CLGTr64ugt.Fragment, | |
| (XSWDv2i64 CLGTr64ugt.Fragment), | |
| CLGTr64eq.Fragment)>; | |
| def CLGTv2i64ugt: | |
| CodeFrag<(CLGTv4i32 VECREG:$rA, VECREG:$rB)>; | |
| def CLGTv2i64eq: | |
| CodeFrag<(CEQv4i32 VECREG:$rA, VECREG:$rB)>; | |
| def CLGTv2i64compare: | |
| CodeFrag<(SELBv2i64 CLGTv2i64ugt.Fragment, | |
| (XSWDv2i64 CLGTr64ugt.Fragment), | |
| CLGTv2i64eq.Fragment)>; | |
| multiclass CompareLogicalGreaterThan64 { | |
| // Plain old comparison, converts back to i32 scalar | |
| def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CLGTr64compare.Fragment, R32C))>; | |
| def v2i64: CodeFrag<CLGTv2i64compare.Fragment>; | |
| // SELB mask from FSM: | |
| def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CLGTr64compare.Fragment), R32C))>; | |
| def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CLGTv2i64compare.Fragment), R32C))>; | |
| } | |
| defm I64LGT: CompareLogicalGreaterThan64; | |
| def : Pat<(setugt R64C:$rA, R64C:$rB), I64LGTr64.Fragment>; | |
| //def : Pat<(setugt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)), | |
| // I64LGTv2i64.Fragment>; | |
| // i64 setult: | |
| def : I64SETCCNegCond<setule, I64LGTr64>; | |
| def : I64SELECTNegCond<setule, I64LGTr64>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // i64 setuge/setult: | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| def CLGEr64compare: | |
| CodeFrag<(CGTIv4i32 (GBv4i32 (ORv4i32 CLGTr64ugt.Fragment, | |
| CLGTr64eq.Fragment)), 0xb)>; | |
| def CLGEv2i64compare: | |
| CodeFrag<(CEQIv4i32 (GBv4i32 (ORv4i32 CLGTv2i64ugt.Fragment, | |
| CLGTv2i64eq.Fragment)), 0xf)>; | |
| multiclass CompareLogicalGreaterEqual64 { | |
| // Plain old comparison, converts back to i32 scalar | |
| def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CLGEr64compare.Fragment, R32C))>; | |
| def v2i64: CodeFrag<CLGEv2i64compare.Fragment>; | |
| // SELB mask from FSM: | |
| def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CLGEr64compare.Fragment), R32C))>; | |
| def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CLGEv2i64compare.Fragment),R32C))>; | |
| } | |
| defm I64LGE: CompareLogicalGreaterEqual64; | |
| def : Pat<(setuge R64C:$rA, R64C:$rB), I64LGEr64.Fragment>; | |
| def : Pat<(v2i64 (setuge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB))), | |
| I64LGEv2i64.Fragment>; | |
| // i64 setult: | |
| def : I64SETCCNegCond<setult, I64LGEr64>; | |
| def : I64SELECTNegCond<setult, I64LGEr64>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // i64 setgt/setle: | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| def CGTr64sgt: | |
| CodeFrag<(CGTv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG))>; | |
| def CGTr64eq: | |
| CodeFrag<(CEQv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG))>; | |
| def CGTr64compare: | |
| CodeFrag<(SELBv2i64 CGTr64sgt.Fragment, | |
| (XSWDv2i64 CGTr64sgt.Fragment), | |
| CGTr64eq.Fragment)>; | |
| def CGTv2i64sgt: | |
| CodeFrag<(CGTv4i32 VECREG:$rA, VECREG:$rB)>; | |
| def CGTv2i64eq: | |
| CodeFrag<(CEQv4i32 VECREG:$rA, VECREG:$rB)>; | |
| def CGTv2i64compare: | |
| CodeFrag<(SELBv2i64 CGTv2i64sgt.Fragment, | |
| (XSWDv2i64 CGTr64sgt.Fragment), | |
| CGTv2i64eq.Fragment)>; | |
| multiclass CompareGreaterThan64 { | |
| // Plain old comparison, converts back to i32 scalar | |
| def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CGTr64compare.Fragment, R32C))>; | |
| def v2i64: CodeFrag<CGTv2i64compare.Fragment>; | |
| // SELB mask from FSM: | |
| def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CGTr64compare.Fragment), R32C))>; | |
| def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS | |
| (FSMv4i32 CGTv2i64compare.Fragment), R32C))>; | |
| } | |
| defm I64GT: CompareLogicalGreaterThan64; | |
| def : Pat<(setgt R64C:$rA, R64C:$rB), I64GTr64.Fragment>; | |
| //def : Pat<(setgt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)), | |
| // I64GTv2i64.Fragment>; | |
| // i64 setult: | |
| def : I64SETCCNegCond<setle, I64GTr64>; | |
| def : I64SELECTNegCond<setle, I64GTr64>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // i64 setge/setlt: | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| def CGEr64compare: | |
| CodeFrag<(CGTIv4i32 (GBv4i32 (ORv4i32 CGTr64sgt.Fragment, | |
| CGTr64eq.Fragment)), 0xb)>; | |
| def CGEv2i64compare: | |
| CodeFrag<(CEQIv4i32 (GBv4i32 (ORv4i32 CGTv2i64sgt.Fragment, | |
| CGTv2i64eq.Fragment)), 0xf)>; | |
| multiclass CompareGreaterEqual64 { | |
| // Plain old comparison, converts back to i32 scalar | |
| def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CGEr64compare.Fragment, R32C))>; | |
| def v2i64: CodeFrag<CGEv2i64compare.Fragment>; | |
| // SELB mask from FSM: | |
| def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS (FSMv4i32 CGEr64compare.Fragment),R32C))>; | |
| def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS (FSMv4i32 CGEv2i64compare.Fragment),R32C))>; | |
| } | |
| defm I64GE: CompareGreaterEqual64; | |
| def : Pat<(setge R64C:$rA, R64C:$rB), I64GEr64.Fragment>; | |
| def : Pat<(v2i64 (setge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB))), | |
| I64GEv2i64.Fragment>; | |
| // i64 setult: | |
| def : I64SETCCNegCond<setlt, I64GEr64>; | |
| def : I64SELECTNegCond<setlt, I64GEr64>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // v2i64, i64 add | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| class v2i64_add_cg<dag lhs, dag rhs>: | |
| CodeFrag<(CGv4i32 lhs, rhs)>; | |
| class v2i64_add_1<dag lhs, dag rhs, dag cg, dag cg_mask>: | |
| CodeFrag<(ADDXv4i32 lhs, rhs, (SHUFBv4i32 cg, cg, cg_mask))>; | |
| class v2i64_add<dag lhs, dag rhs, dag cg_mask>: | |
| v2i64_add_1<lhs, rhs, v2i64_add_cg<lhs, rhs>.Fragment, cg_mask>; | |
| def : Pat<(SPUadd64 R64C:$rA, R64C:$rB, (v4i32 VECREG:$rCGmask)), | |
| (COPY_TO_REGCLASS v2i64_add<(COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG), | |
| (v4i32 VECREG:$rCGmask)>.Fragment, R64C)>; | |
| def : Pat<(SPUadd64 (v2i64 VECREG:$rA), (v2i64 VECREG:$rB), | |
| (v4i32 VECREG:$rCGmask)), | |
| v2i64_add<(v2i64 VECREG:$rA), | |
| (v2i64 VECREG:$rB), | |
| (v4i32 VECREG:$rCGmask)>.Fragment>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // v2i64, i64 subtraction | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| class v2i64_sub_bg<dag lhs, dag rhs>: CodeFrag<(BGv4i32 lhs, rhs)>; | |
| class v2i64_sub<dag lhs, dag rhs, dag bg, dag bg_mask>: | |
| CodeFrag<(SFXv4i32 lhs, rhs, (SHUFBv4i32 bg, bg, bg_mask))>; | |
| def : Pat<(SPUsub64 R64C:$rA, R64C:$rB, (v4i32 VECREG:$rCGmask)), | |
| (COPY_TO_REGCLASS | |
| v2i64_sub<(COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG), | |
| v2i64_sub_bg<(COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG)>.Fragment, | |
| (v4i32 VECREG:$rCGmask)>.Fragment, R64C)>; | |
| def : Pat<(SPUsub64 (v2i64 VECREG:$rA), (v2i64 VECREG:$rB), | |
| (v4i32 VECREG:$rCGmask)), | |
| v2i64_sub<(v2i64 VECREG:$rA), | |
| (v2i64 VECREG:$rB), | |
| v2i64_sub_bg<(v2i64 VECREG:$rA), | |
| (v2i64 VECREG:$rB)>.Fragment, | |
| (v4i32 VECREG:$rCGmask)>.Fragment>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // v2i64, i64 multiply | |
| // | |
| // Note: i64 multiply is simply the vector->scalar conversion of the | |
| // full-on v2i64 multiply, since the entire vector has to be manipulated | |
| // anyway. | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| class v2i64_mul_ahi64<dag rA> : | |
| CodeFrag<(SELBv4i32 rA, (ILv4i32 0), (FSMBIv4i32 0x0f0f))>; | |
| class v2i64_mul_bhi64<dag rB> : | |
| CodeFrag<(SELBv4i32 rB, (ILv4i32 0), (FSMBIv4i32 0x0f0f))>; | |
| class v2i64_mul_alo64<dag rB> : | |
| CodeFrag<(SELBv4i32 rB, (ILv4i32 0), (FSMBIv4i32 0xf0f0))>; | |
| class v2i64_mul_blo64<dag rB> : | |
| CodeFrag<(SELBv4i32 rB, (ILv4i32 0), (FSMBIv4i32 0xf0f0))>; | |
| class v2i64_mul_ashlq2<dag rA>: | |
| CodeFrag<(SHLQBYIv4i32 rA, 0x2)>; | |
| class v2i64_mul_ashlq4<dag rA>: | |
| CodeFrag<(SHLQBYIv4i32 rA, 0x4)>; | |
| class v2i64_mul_bshlq2<dag rB> : | |
| CodeFrag<(SHLQBYIv4i32 rB, 0x2)>; | |
| class v2i64_mul_bshlq4<dag rB> : | |
| CodeFrag<(SHLQBYIv4i32 rB, 0x4)>; | |
| class v2i64_highprod<dag rA, dag rB>: | |
| CodeFrag<(Av4i32 | |
| (Av4i32 | |
| (MPYUv4i32 v2i64_mul_bshlq4<rB>.Fragment, // a1 x b3 | |
| v2i64_mul_ahi64<rA>.Fragment), | |
| (MPYHv4i32 v2i64_mul_ahi64<rA>.Fragment, // a0 x b3 | |
| v2i64_mul_bshlq4<rB>.Fragment)), | |
| (Av4i32 | |
| (MPYHv4i32 v2i64_mul_bhi64<rB>.Fragment, | |
| v2i64_mul_ashlq4<rA>.Fragment), | |
| (Av4i32 | |
| (MPYHv4i32 v2i64_mul_ashlq4<rA>.Fragment, | |
| v2i64_mul_bhi64<rB>.Fragment), | |
| (Av4i32 | |
| (MPYUv4i32 v2i64_mul_ashlq4<rA>.Fragment, | |
| v2i64_mul_bhi64<rB>.Fragment), | |
| (Av4i32 | |
| (MPYHv4i32 v2i64_mul_ashlq2<rA>.Fragment, | |
| v2i64_mul_bshlq2<rB>.Fragment), | |
| (MPYUv4i32 v2i64_mul_ashlq2<rA>.Fragment, | |
| v2i64_mul_bshlq2<rB>.Fragment))))))>; | |
| class v2i64_mul_a3_b3<dag rA, dag rB>: | |
| CodeFrag<(MPYUv4i32 v2i64_mul_alo64<rA>.Fragment, | |
| v2i64_mul_blo64<rB>.Fragment)>; | |
| class v2i64_mul_a2_b3<dag rA, dag rB>: | |
| CodeFrag<(SELBv4i32 (SHLQBYIv4i32 | |
| (MPYHHUv4i32 v2i64_mul_alo64<rA>.Fragment, | |
| v2i64_mul_bshlq2<rB>.Fragment), 0x2), | |
| (ILv4i32 0), | |
| (FSMBIv4i32 0xc3c3))>; | |
| class v2i64_mul_a3_b2<dag rA, dag rB>: | |
| CodeFrag<(SELBv4i32 (SHLQBYIv4i32 | |
| (MPYHHUv4i32 v2i64_mul_blo64<rB>.Fragment, | |
| v2i64_mul_ashlq2<rA>.Fragment), 0x2), | |
| (ILv4i32 0), | |
| (FSMBIv4i32 0xc3c3))>; | |
| class v2i64_lowsum<dag rA, dag rB, dag rCGmask>: | |
| v2i64_add<v2i64_add<v2i64_mul_a3_b3<rA, rB>.Fragment, | |
| v2i64_mul_a2_b3<rA, rB>.Fragment, rCGmask>.Fragment, | |
| v2i64_mul_a3_b2<rA, rB>.Fragment, rCGmask>; | |
| class v2i64_mul<dag rA, dag rB, dag rCGmask>: | |
| v2i64_add<v2i64_lowsum<rA, rB, rCGmask>.Fragment, | |
| (SELBv4i32 v2i64_highprod<rA, rB>.Fragment, | |
| (ILv4i32 0), | |
| (FSMBIv4i32 0x0f0f)), | |
| rCGmask>; | |
| def : Pat<(SPUmul64 R64C:$rA, R64C:$rB, (v4i32 VECREG:$rCGmask)), | |
| (COPY_TO_REGCLASS v2i64_mul<(COPY_TO_REGCLASS R64C:$rA, VECREG), | |
| (COPY_TO_REGCLASS R64C:$rB, VECREG), | |
| (v4i32 VECREG:$rCGmask)>.Fragment, R64C)>; | |
| def : Pat<(SPUmul64 (v2i64 VECREG:$rA), (v2i64 VECREG:$rB), | |
| (v4i32 VECREG:$rCGmask)), | |
| v2i64_mul<(v2i64 VECREG:$rA), (v2i64 VECREG:$rB), | |
| (v4i32 VECREG:$rCGmask)>.Fragment>; | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // f64 comparisons | |
| //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ | |
| // selb instruction definition for i64. Note that the selection mask is | |
| // a vector, produced by various forms of FSM: | |
| def SELBf64_cond: | |
| SELBInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB, R32C:$rC), | |
| [(set R64FP:$rT, | |
| (select R32C:$rC, R64FP:$rB, R64FP:$rA))]>; |