@@ -2925,54 +2925,41 @@ static bool interp__builtin_ia32_pternlog(InterpState &S, CodePtr OpPC,
29252925 const CallExpr *Call, bool MaskZ) {
29262926 assert (Call->getNumArgs () == 5 );
29272927
2928- const VectorType *VecT = Call->getArg (0 )->getType ()->castAs <VectorType>();
2929- const PrimType &DstElemT = *S.getContext ().classify (VecT->getElementType ());
2930- unsigned DstLen = VecT->getNumElements ();
2931- bool DstUnsigned =
2932- VecT->getElementType ()->isUnsignedIntegerOrEnumerationType ();
2933-
2934- APInt U = popToAPSInt (S, Call->getArg (4 ));
2935- APInt Imm = popToAPSInt (S, Call->getArg (3 ));
2928+ APInt U = popToAPSInt (S, Call->getArg (4 )); // Lane mask
2929+ APInt Imm = popToAPSInt (S, Call->getArg (3 )); // Ternary truth table
29362930 const Pointer &C = S.Stk .pop <Pointer>();
29372931 const Pointer &B = S.Stk .pop <Pointer>();
29382932 const Pointer &A = S.Stk .pop <Pointer>();
2939-
29402933 const Pointer &Dst = S.Stk .peek <Pointer>();
29412934
2942- for (unsigned I = 0 ; I < DstLen; ++I) {
2943- APInt ALane;
2944- APInt BLane;
2945- APInt CLane;
2946- INT_TYPE_SWITCH_NO_BOOL (DstElemT, {
2947- ALane = A.elem <T>(I).toAPSInt ();
2948- BLane = B.elem <T>(I).toAPSInt ();
2949- CLane = C.elem <T>(I).toAPSInt ();
2950- });
2951- const unsigned BitWidth = ALane.getBitWidth ();
2952- APInt RLane (BitWidth, 0 );
2953-
2954- if (U[I]) { // If lane not masked, compute ternary logic
2955- for (unsigned Bit = 0 ; Bit < BitWidth; ++Bit) {
2956- unsigned ABit = ALane[Bit];
2957- unsigned BBit = BLane[Bit];
2958- unsigned CBit = CLane[Bit];
2959-
2960- unsigned Idx = (ABit << 2 ) | (BBit << 1 ) | (CBit);
2961- RLane.setBitVal (Bit, Imm[Idx]);
2962- }
2963- INT_TYPE_SWITCH_NO_BOOL (DstElemT, {
2935+ unsigned DstLen = A.getNumElems ();
2936+ const QualType ElemQT = getElemType (A);
2937+ const OptPrimType ElemPT = S.getContext ().classify (ElemQT);
2938+ unsigned LaneWidth = S.getASTContext ().getTypeSize (ElemQT);
2939+ bool DstUnsigned = ElemQT->isUnsignedIntegerOrEnumerationType ();
2940+
2941+ INT_TYPE_SWITCH_NO_BOOL (*ElemPT, {
2942+ for (unsigned I = 0 ; I != DstLen; ++I) {
2943+ APInt ALane = A.elem <T>(I).toAPSInt ();
2944+ APInt BLane = B.elem <T>(I).toAPSInt ();
2945+ APInt CLane = C.elem <T>(I).toAPSInt ();
2946+ APInt RLane (LaneWidth, 0 );
2947+ if (U[I]) { // If lane not masked, compute ternary logic.
2948+ for (unsigned Bit = 0 ; Bit != LaneWidth; ++Bit) {
2949+ unsigned ABit = ALane[Bit];
2950+ unsigned BBit = BLane[Bit];
2951+ unsigned CBit = CLane[Bit];
2952+ unsigned Idx = (ABit << 2 ) | (BBit << 1 ) | (CBit);
2953+ RLane.setBitVal (Bit, Imm[Idx]);
2954+ }
29642955 Dst.elem <T>(I) = static_cast <T>(APSInt (RLane, DstUnsigned));
2965- });
2966- } else if (MaskZ) { // If zero masked, zero the lane
2967- INT_TYPE_SWITCH_NO_BOOL (DstElemT, {
2956+ } else if (MaskZ) { // If zero masked, zero the lane.
29682957 Dst.elem <T>(I) = static_cast <T>(APSInt (RLane, DstUnsigned));
2969- });
2970- } else { // Just masked, put in A lane
2971- INT_TYPE_SWITCH_NO_BOOL (DstElemT, {
2958+ } else { // Just masked, put in A lane.
29722959 Dst.elem <T>(I) = static_cast <T>(APSInt (ALane, DstUnsigned));
2973- });
2960+ }
29742961 }
2975- }
2962+ });
29762963 Dst.initializeAllElements ();
29772964 return true ;
29782965}
0 commit comments