I'm not sure what you mean by "use VFP code". Do you mean floating-point code, which may get compiled to run on VFP, or do you mean actual VFP assembly instructions?
If you compile in thumb mode and use floating point, a function call will be made for each floating point operation in your code. These function calls (they'll have names like __muldf3vfp
) switch the mode to ARM, move the data into the floating point registers, perform the operation, move the data back to integer registers, and return. That's a lot of work for something that's only one instruction if you compile in ARM mode, so don't use thumb in float-intensive code.
If you try to use VFP assembly instructions in thumb mode, you'll just get an assembler error.
As you noted, the 3GS supports thumb2, which does have access to the VFP and NEON registers, so this situation doesn't apply.
Also note that the switch between thumb and ARM compilation can be done per source file, so you can compile most of your project in thumb and use ARM for a few routines that do a lot of floating-point, for example. If you want to write assembly code, you can switch between ARM and thumb per function.