"setjmp/longjmp" must save/restore only those registers that are defined by the C ABI as being preserved across function calls.
The program point to where "longjmp" jumps is viewed by the compiler as a function return point, so the compiler assumes that all the other registers hold undefined values.
For most CPUs, the C ABI defines the SIMD registers as being not preserved across function calls, so "setjmp" does not need to save them. Had some of them been defined as preserved registers, "setjmp" would have also saved those.
"setjmp/longjmp" cannot be used in any C++ program, unless all the nested functions that occur between a "setjmp" and a "longjmp" are C functions. This may happen in C libraries which are linked into C++ programs and which may use "setjmp/longjmp" internally, without interfering with C++ objects.
As you say, "attribute(cleanup)" is not something specified in the C language standard, so you cannot expect that "longjmp" will invoke the cleanup function, unless you use a specific libc implementation, whose documentation explicitly says that its "longjmp" will invoke the cleanup functions, when the program is compiled with a certain C compiler. I am not aware of any such "longjmp" implementation.
If you want to use exceptions in a C program, you must use "setjmp/longjmp". If you do not want to use exceptions in a C program, you have no need for them.
The same happens in any other programming language. If you do not want to use exceptions in a C++ program, you have no need to use keywords like "try" and "throw".