Add rounding/saturation conversions for OpenCL
OpenCL requires us to implement a lot of rounding/saturation modes when converting between types or bit widths. Every from-float conversion mode must take a rounding modifier, with one of four possible rounding modes; every conversion where not every source value can be represented in the destination type must take a saturation modifier, clamping to the nearest representable value.
NIR already has support for rtne/rtz when storing to f16 destinations, to support graphics SPIR-V's demand that this happens. However, adding an opcode for every conversion type with every rounding mode with and without saturation would be far too much, and we'd need to write out a C-runtime equivalent for every opcode to handle constant values.
I'm marking this as WIP because the history is rough, and it's occurred to me that I'm not correctly handling vector conversions either. I'm not sure I completely love the details of how it's implemented it now, but I've rewritten it about four times and none of them have really made me truly happy.
(It's worth noting that we can't use libclc to do this; libclc's built-in convert implementations are buggy as they use uninitialised data, we never see calls to those functions as LLVM-SPIRV-Translator specifically emits them as opcodes and so have to rewrite from decorated opcode -> CLC function call, and CLC's own function-call implementations get rewritten to use the decorated ops anyway ...)