The following covers most of the issues with adapting the SPIR-V backend for SM 6.
**Types:**
SM 6 adds half, int16 and int64 support. The DXIL code uses the required width, and emits any necessary casts, so a dedicated backend compiles these correctly without any special handling except feature requirements. The existing backend must handle them explicitly. This will occur in more places than the current support for double because it includes integer types.
Support for integer width casts SEXT, ZEXT and TRUNC is required, plus DXIL sometimes uses BITCAST too.
DXIL types have no signedness, which causes problems when a sampled type is signed int. Bitcasts need to be added to convert signed SPIR-V types to unsigned after sampling/reading and back to signed for image writes.
**SSA:**
An SSA register type will remove the need to emit large numbers of unnecessary Load/Store instructions.
**Instructions:**
ALLOCA:
I think this must be done using DCL_TEMPS.
ATOMICRMW:
Addressing seems to be wrong in the backend; raw/structured addressing won't work for DXIL because it uses an array index not a byte offset. I can't test TPF because fxc crashes on arrayed groupshared variables. If it proves impossible to check addressing for SM <= 5.x then just fix it for DXIL.
BINOP:
Bool is a 1-bit integer in DXIL which means binops are valid for them, as are some casts such as SEXT, ZEXT, SITOFP and UITOFP. Special handling is required - synthesise ops on registers of COMPONENT_BOOL?
BR:
Create new instruction.
ATOMIC_BINOP:
In DXIL it can support 64-bit on capable hardware.
BUFFER LOAD/STORE:
Must be able to support 16-bit ops when native 16-bit types are enabled.
CBUFFER LOAD:
Must be able to support loading a float scalar for when CBufferLoad is used instead of CBufferLoadLegacy.
CREATE HANDLE:
Translates to one of the DCL_RESOURCE/UAV/CONSTANT_BUFFER instructions.
LOAD/STORE_INPUT:
It's probably not worth trying to sort through the tangle of private variables and other complications in the existing backend. Private variables are not needed, nor are variables for I/O between phases. Create a new instruction, or have the existing handler detect SM 6 and pass control to a separate handler function.
SAMPLE/TEXTURE_LOAD (and any other instruction which uses coords/offsets):
Coordinates are specified as individual scalars of any origin, so they need to be assembled into a vector. A new instruction or register type may be a good idea, instead of e.g.: mov r0.x, coord1.x mov r0.y, coord2.x mov r0.z, coord3.x
EXTRACTVAL:
Probably just a mov instruction.
GEP:
In TPF this is the address part of an instruction which accesses an array. We may need new instructions, one to express the GEP and another the LOAD.
PHI:
Create an instruction for it.
SWITCH:
There are no separate CASE and ENDSWITCH instructions; instead the switch instruction contains all cases and the default. Merge info needs to be supplied by the structuriser. A new instruction is probably best.
Unary, binary, and trinary arithmetic ops like BFREV, SIN, EXP, FMAD, FRC, UMAX etc probably require no special handling.