There's no byte-element shift (psrlb or whatever), so you can't just knock off the bits you don't want with right and then left shift. Even if you only have to do this once, it might still be best to use a mask.
You can generate the mask on the fly in fewer instruction bytes than it takes to store the mask, with no possibility of a cache-miss.
pcmpeqw xmm1,xmm1 ; -1
pabsb xmm1,xmm1 ; 1
psllw xmm1, 7 ; set1_epi8(0x80)
pand xmm1, xmm0
If you want the sign bits packed together in an integer reg
PMOVMSKB reg, xmm0
But unpacking that back to a vector is slower than generating the signbit-mask (until AVX512).
If you're only doing this once, you might be able to come up with something shorter than 4 insns, esp. if you can use AVX non-destructive operations. Here's an idea that didn't end up any shorter:
vpcmpeqw xmm1, xmm1,xmm1
vpsignb xmm2, xmm1, xmm0 ; xmm2 = -1 or +1 (or 0) depending on xmm0
vpsubb xmm3, xmm2, xmm1 ; xmm3 = 0 or +2 (or +1) depending on xmm0. (subtract -1 => add 1)
vpsllw xmm4, xmm3, 6 ; xmm4 = 0 or 0x80 (or 0x40) depending on xmm0
Nope, wasn't any shorter. Depending on what you need, part of this idea might help.