The old syntax for target_feature allowed enabling or disabling arbitrary features, which was convenient on ARM platforms where deciding per-function whether to use the ARM or Thumb ISA by enabling or disabling the thumb-mode feature was possible and even desirable. (For example: I’m writing Rust code which ends up running on a Game Boy Advance. Most code is compiled as Thumb for speed since the Game Pak only has a sixteen-bit bus, but if I provide an interrupt dispatcher it has to be compiled as ARM code because of how Nintendo wrote the firmware.)
The new stable target_feature adds a whitelist requirement, and doesn’t define syntax for disabling features; this makes it better-suited for the things it was being used for. I don’t think this is a problem; while avx is a binary feature (either a target has it or doesn’t have it), thumb-mode is a toggle switch where both settings are meaningful.
As such, rather than extending target_feature in ways which risk trying to make it into both a floor wax and a dessert topping, it seems more appropriate to suggest another way to configure ARM/Thumb status: two new function attributes, #[arm] and #[thumb]. These would disable and enable thumb-mode for the annotated function in the same way #[target_feature = "±thumb-mode"] used to; annotating the same function with both results in a compile-time error. (I can’t imagine anyone doing this deliberately, and it’s good for the compiler to catch typos.) As far as I know LLVM already knows how to provide the necessary interworking shims, so everything should just work.
An obvious extension of this (which was supported under the old syntax for target_feature) is to use cfg!(arm) and cfg!(thumb) to generate different code in ARM and Thumb mode, but this is a problem for inline assembly—while the ARM and Thumb ISAs share many mnemonics, there’s often significant differences in encoding. An example: the Game Boy Advance provides several library functions using the swi instruction, but in ARM mode the argument needs to be left-shifted sixteen bits, which is an invalid instruction if the file is processed in Thumb mode. Currently it’s not really a problem, but if we allow cfg!(arm)/cfg!(thumb) it’s something that needs to be sorted out.
That’s about where my knowledge runs out; I’d appreciate some input on things I may have missed.