So the core problem was my "restore multiple" insn contained a CALL insn
and was a call_insn. The symbol it called is in the static section of
libgcc. However, during peephole2 pass, get_call_reg_set_usage in
final.c didn't find a function declaration attached to the symbol and so
defaulted to say that it depends upon and clobbers most registers. (the
target's default set)
My solution was to change the pattern so that I do not generate a CALL
and emit the parallel using emit_insn instead of emit_call_insn. In this
way, I still declare everything that calling stub ("__msabi_restore_15"
in the below case) does and it doesn't presume that I depend upon or
clobber any other regs, so that the sibling call emitted after this
still works. Since I'm using RSI for the base address, I'm only changing
registers that have to be saved anyway, so the sibcall should never need
to use one of these registers anyway (I hope :)
(insn/f 148 147 149 11 (parallel [
(use (symbol_ref:DI ("__msabi_restore_15")))
(clobber (reg:CC 17 flags))
(set (reg:V4SF 52 xmm15)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -88 [0xffffffffffffffa8])) [0 S16 A8]))
(set (reg:V4SF 51 xmm14)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -72 [0xffffffffffffffb8])) [0 S16 A8]))
(set (reg:V4SF 50 xmm13)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -56 [0xffffffffffffffc8])) [0 S16 A8]))
(set (reg:V4SF 49 xmm12)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -40 [0xffffffffffffffd8])) [0 S16 A8]))
(set (reg:V4SF 48 xmm11)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -24 [0xffffffffffffffe8])) [0 S16 A8]))
(set (reg:V4SF 47 xmm10)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -8 [0xfffffffffffffff8])) [0 S16 A8]))
(set (reg:V4SF 46 xmm9)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 8 [0x8])) [0 S16 A8]))
(set (reg:V4SF 45 xmm8)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 24 [0x18])) [0 S16 A8]))
(set (reg:V4SF 28 xmm7)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 40 [0x28])) [0 S16 A8]))
(set (reg:V4SF 27 xmm6)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 56 [0x38])) [0 S16 A8]))
(set (reg:DI 5 di)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 72 [0x48])) [0 S8 A8]))
(set (reg:DI 3 bx)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 80 [0x50])) [0 S8 A8]))
(set (reg:DI 6 bp)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 88 [0x58])) [0 S8 A8]))
(set (reg:DI 41 r12)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 96 [0x60])) [0 S8 A8]))
(set (reg:DI 4 si)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 64 [0x40])) [0 S8 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_UNUSED (reg:CC 17 flags)
(expr_list:REG_CFA_RESTORE (reg:DI 4 si)
(expr_list:REG_CFA_RESTORE (reg:DI 41 r12)
(expr_list:REG_CFA_RESTORE (reg:DI 6 bp)
(expr_list:REG_CFA_RESTORE (reg:DI 3 bx)
(expr_list:REG_CFA_RESTORE (reg:DI 5 di)
(expr_list:REG_CFA_RESTORE (reg:V4SF 27 xmm6)
(expr_list:REG_CFA_RESTORE (reg:V4SF 28
xmm7)
(expr_list:REG_CFA_RESTORE
(reg:V4SF 45 xmm8)
(expr_list:REG_CFA_RESTORE
(reg:V4SF 46 xmm9)
(nil))))))))))))