| 3131 | } |
| 3132 | |
| 3133 | void OpDispatchBuilder::PMULHRWOp(OpcodeArgs) { |
| 3134 | const auto Size = OpSizeFromSrc(Op); |
| 3135 | |
| 3136 | Ref Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags); |
| 3137 | Ref Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags); |
| 3138 | |
| 3139 | Ref Res {}; |
| 3140 | |
| 3141 | // Implementation is more efficient for 8byte registers |
| 3142 | // Multiplies 4 16bit values in to 4 32bit values |
| 3143 | Res = _VSMull(Size << 1, OpSize::i16Bit, Dest, Src); |
| 3144 | |
| 3145 | // Load 0x0000_8000 in to each 32-bit element. |
| 3146 | Ref VConstant = _VectorImm(OpSize::i128Bit, OpSize::i32Bit, 0x80, 8); |
| 3147 | |
| 3148 | Res = _VAdd(Size << 1, OpSize::i32Bit, Res, VConstant); |
| 3149 | |
| 3150 | // Now shift and narrow to convert 32-bit values to 16bit, storing the top 16bits |
| 3151 | Res = _VUShrNI(Size << 1, OpSize::i32Bit, Res, 16); |
| 3152 | |
| 3153 | StoreResult(FPRClass, Op, Res, OpSize::iInvalid); |
| 3154 | } |
| 3155 | |
| 3156 | template<uint8_t CompType> |
| 3157 | void OpDispatchBuilder::VPFCMPOp(OpcodeArgs) { |
nothing calls this directly
no outgoing calls
no test coverage detected