// V66 HVX Instructions.
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo, "V16iV16iV16iv*", "", HVXV66)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo_128B, "V32iV32iV32iv*", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat, "V16iV16iV16iV64b", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B, "V32iV32iV32iV128b", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into, "V32iV32iV16iV16i", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr_128B, "V32iV32iV32i", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw, "V16iV16iV16i", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B, "V32iV32iV32i", "", HVXV66)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo, "V16iV16iV16iv*", "", HVXV66)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo_128B, "V32iV32iV32iv*", "", HVXV66)
// V68 HVX Instructions.
CUSTOM_BUILTIN_MAPPING(V6_vaddcarry_128B, 128)
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry, 64)
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry_128B, 128)
+CUSTOM_BUILTIN_MAPPING(V6_vaddcarryo, 64)
+CUSTOM_BUILTIN_MAPPING(V6_vaddcarryo_128B, 128)
+CUSTOM_BUILTIN_MAPPING(V6_vsubcarryo, 64)
+CUSTOM_BUILTIN_MAPPING(V6_vsubcarryo_128B, 128)
PredAddr.getAlignment());
return Builder.CreateExtractValue(Result, 0);
}
+ // These are identical to the builtins above, except they don't consume
+ // input carry, only generate carry-out. Since they still produce two
+ // outputs, generate the store of the predicate, but no load.
+ case Hexagon::BI__builtin_HEXAGON_V6_vaddcarryo:
+ case Hexagon::BI__builtin_HEXAGON_V6_vaddcarryo_128B:
+ case Hexagon::BI__builtin_HEXAGON_V6_vsubcarryo:
+ case Hexagon::BI__builtin_HEXAGON_V6_vsubcarryo_128B: {
+ // Get the type from the 0-th argument.
+ llvm::Type *VecType = ConvertType(E->getArg(0)->getType());
+ Address PredAddr = Builder.CreateElementBitCast(
+ EmitPointerWithAlignment(E->getArg(2)), VecType);
+ llvm::Value *Result = Builder.CreateCall(CGM.getIntrinsic(ID),
+ {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))});
+
+ llvm::Value *PredOut = Builder.CreateExtractValue(Result, 1);
+ Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.getPointer(),
+ PredAddr.getAlignment());
+ return Builder.CreateExtractValue(Result, 0);
+ }
case Hexagon::BI__builtin_HEXAGON_V6_vmaskedstoreq:
case Hexagon::BI__builtin_HEXAGON_V6_vmaskedstorenq:
return __builtin_HEXAGON_V6_vasr_into_128B(vr, v1, v2);
}
+
+// CHECK-LABEL: @test29
+// CHECK: call { <32 x i32>, <128 x i1> } @llvm.hexagon.V6.vaddcarryo.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}})
+HEXAGON_Vect1024 test29(void *in, void *out) {
+ HEXAGON_Vect1024 v1, v2;
+ HEXAGON_Vect1024 *p;
+ HEXAGON_VecPred128 q1;
+
+ p = (HEXAGON_Vect1024 *)in;
+ v1 = *p++;
+ v2 = *p++;
+ q1 = *p++;
+
+ return __builtin_HEXAGON_V6_vaddcarryo_128B(v1, v2, &q1);
+}
+
+// CHECK-LABEL: @test30
+// CHECK: call { <32 x i32>, <128 x i1> } @llvm.hexagon.V6.vsubcarryo.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}})
+HEXAGON_Vect1024 test30(void *in, void *out) {
+ HEXAGON_Vect1024 v1, v2;
+ HEXAGON_Vect1024 *p;
+ HEXAGON_VecPred128 q1;
+
+ p = (HEXAGON_Vect1024 *)in;
+ v1 = *p++;
+ v2 = *p++;
+ q1 = *p++;
+
+ return __builtin_HEXAGON_V6_vsubcarryo_128B(v1, v2, &q1);
+}
+
+
return __builtin_HEXAGON_V6_vasr_into(vr, v1, v2);
}
+
+// CHECK-LABEL: @test9
+// CHECK: call { <16 x i32>, <64 x i1> } @llvm.hexagon.V6.vaddcarryo(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
+HEXAGON_Vect512 test9(void *in, void *out) {
+ HEXAGON_Vect512 v1, v2;
+ HEXAGON_Vect512 *p;
+ HEXAGON_VecPred64 q1;
+
+ p = (HEXAGON_Vect512 *)in;
+ v1 = *p++;
+ v2 = *p++;
+ q1 = *p++;
+
+ return __builtin_HEXAGON_V6_vaddcarryo(v1, v2, &q1);
+}
+
+// CHECK-LABEL: @test10
+// CHECK: call { <16 x i32>, <64 x i1> } @llvm.hexagon.V6.vsubcarryo(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
+HEXAGON_Vect512 test10(void *in, void *out) {
+ HEXAGON_Vect512 v1, v2;
+ HEXAGON_Vect512 *p;
+ HEXAGON_VecPred64 q1;
+
+ p = (HEXAGON_Vect512 *)in;
+ v1 = *p++;
+ v2 = *p++;
+ q1 = *p++;
+
+ return __builtin_HEXAGON_V6_vsubcarryo(v1, v2, &q1);
+}
+
+
[llvm_v32i32_ty,llvm_v128i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v128i1_ty],
intr_properties>;
+// tag : V6_vaddcarryo
+class Hexagon_custom_v16i32v64i1_v16i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty,llvm_v64i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vaddcarryo
+class Hexagon_custom_v32i32v128i1_v32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty,llvm_v128i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
// tag : V6_vaddcarrysat
class Hexagon_v16i32_v16i32v16i32v64i1_Intrinsic<string GCCIntSuffix,
list<IntrinsicProperty> intr_properties = [IntrNoMem]>
// V66 HVX Instructions.
+def int_hexagon_V6_vaddcarryo :
+Hexagon_custom_v16i32v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddcarryo_128B :
+Hexagon_custom_v32i32v128i1_v32i32v32i32_Intrinsic_128B;
+
def int_hexagon_V6_vaddcarrysat :
Hexagon_v16i32_v16i32v16i32v64i1_Intrinsic<"HEXAGON_V6_vaddcarrysat">;
def int_hexagon_V6_vsatdw_128B :
Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatdw_128B">;
+def int_hexagon_V6_vsubcarryo :
+Hexagon_custom_v16i32v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubcarryo_128B :
+Hexagon_custom_v32i32v128i1_v32i32v32i32_Intrinsic_128B;
+
// V68 HVX Instructions.
def int_hexagon_V6_v6mpyhubs10 :
{Hexagon::V6_vaddbsat, Intrinsic::hexagon_V6_vaddbsat, Intrinsic::hexagon_V6_vaddbsat_128B},
{Hexagon::V6_vaddbsat_dv, Intrinsic::hexagon_V6_vaddbsat_dv, Intrinsic::hexagon_V6_vaddbsat_dv_128B},
{Hexagon::V6_vaddcarry, Intrinsic::hexagon_V6_vaddcarry, Intrinsic::hexagon_V6_vaddcarry_128B},
+{Hexagon::V6_vaddcarryo, Intrinsic::hexagon_V6_vaddcarryo, Intrinsic::hexagon_V6_vaddcarryo_128B},
{Hexagon::V6_vaddcarrysat, Intrinsic::hexagon_V6_vaddcarrysat, Intrinsic::hexagon_V6_vaddcarrysat_128B},
{Hexagon::V6_vaddclbh, Intrinsic::hexagon_V6_vaddclbh, Intrinsic::hexagon_V6_vaddclbh_128B},
{Hexagon::V6_vaddclbw, Intrinsic::hexagon_V6_vaddclbw, Intrinsic::hexagon_V6_vaddclbw_128B},
{Hexagon::V6_vsubbsat, Intrinsic::hexagon_V6_vsubbsat, Intrinsic::hexagon_V6_vsubbsat_128B},
{Hexagon::V6_vsubbsat_dv, Intrinsic::hexagon_V6_vsubbsat_dv, Intrinsic::hexagon_V6_vsubbsat_dv_128B},
{Hexagon::V6_vsubcarry, Intrinsic::hexagon_V6_vsubcarry, Intrinsic::hexagon_V6_vsubcarry_128B},
+{Hexagon::V6_vsubcarryo, Intrinsic::hexagon_V6_vsubcarryo, Intrinsic::hexagon_V6_vsubcarryo_128B},
{Hexagon::V6_vsubh, Intrinsic::hexagon_V6_vsubh, Intrinsic::hexagon_V6_vsubh_128B},
{Hexagon::V6_vsubh_dv, Intrinsic::hexagon_V6_vsubh_dv, Intrinsic::hexagon_V6_vsubh_dv_128B},
{Hexagon::V6_vsubhnq, Intrinsic::hexagon_V6_vsubhnq, Intrinsic::hexagon_V6_vsubhnq_128B},
// V66 HVX Instructions.
+def: Pat<(int_hexagon_V6_vaddcarryo HvxVR:$src1, HvxVR:$src2),
+ (V6_vaddcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX64B]>;
+def: Pat<(int_hexagon_V6_vaddcarryo_128B HvxVR:$src1, HvxVR:$src2),
+ (V6_vaddcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX128B]>;
def: Pat<(int_hexagon_V6_vaddcarrysat HvxVR:$src1, HvxVR:$src2, HvxQR:$src3),
(V6_vaddcarrysat HvxVR:$src1, HvxVR:$src2, HvxQR:$src3)>, Requires<[HasV66, UseHVX64B]>;
def: Pat<(int_hexagon_V6_vaddcarrysat_128B HvxVR:$src1, HvxVR:$src2, HvxQR:$src3),
(V6_vsatdw HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX64B]>;
def: Pat<(int_hexagon_V6_vsatdw_128B HvxVR:$src1, HvxVR:$src2),
(V6_vsatdw HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX128B]>;
+def: Pat<(int_hexagon_V6_vsubcarryo HvxVR:$src1, HvxVR:$src2),
+ (V6_vsubcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX64B]>;
+def: Pat<(int_hexagon_V6_vsubcarryo_128B HvxVR:$src1, HvxVR:$src2),
+ (V6_vsubcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX128B]>;
// V68 HVX Instructions.