This isn't as hard as it might seem.
We can simplify two of your arguments to one:
float3 viewDirection = target - source;
Then our strategy will be to cross the vertical axis and view direction to get a vector perpendicular to both (the right/sideways direction).
Next, we cross this with our vertical axis to complete the basis.
A rotation matrix is just a unit vector in each basis direction, so we can assign our vectors directly to the rows/columns of our matrix.
float3x3 AxisBillboard(float3 upAxis, float3 viewDirection) {
float3 rightAxis = normalize(cross(upAxis, viewDirection));
float3 forwardAxis = cross(rightAxis, upAxis);
float3x3 result;
result[0].xyz = rightAxis;
result[1].xyz = upAxis;
result[2].xyz = forwardAxis;
return transpose(result);
}
Some details can differ depending on the handedness of your coordinate system, or the multiplication convention you use (Matrix * vector or vector * Matrix), but this will get you within a sign flip or a transpose of the desired result.