This code looks strange, however it is “simple”
#pragma push saves the current state of all the settings imposed via pragmas. Restore these settings by a subsequent #pragma pop. Any changes to the states that occur between a #pragma push and a #pragma pop will be discarded after the #pragma pop.
So, it is nothing special. In this case we can use #pragma DATA_SEG DEFAULT at end of this code. It will do the same (just restore variable placement back to default RAM).
XGATE in version 3 has two hardware sets of basic registers and this way naturally support interrupt nesting. Interrupts with priority 4..7 could interrupts routines with priority 1..3. XGATE simply switch register sets.
For these two sets we should define also two stacks and this is done by this code.
This code just creates two variables at specific location (in default project at 0xF8107E and 0xF810FE addresses, see prm file), nothing else.
More important is this code:
XGISPSEL= 1;
XGISP31= (unsigned int)(void*__far)(XGATE_STACK_L + 1);
XGISPSEL= 2;
XGISP74= (unsigned int)(void*__far)(XGATE_STACK_H + 1);
XGISPSEL= 0;
This way we define initial address of stacks for routines with priority 1..3 and for routines with priority 4..7. Every time a thread of such priority is started, RISC core register R7 will be initialized with the content of XGISP74 or XGISP31.
So, I suppose that both codes in your post do the same work however second code uses non-default linker definition in prm file. That is all.