Skip to content

Commit

Permalink
Use PUSH/POP to save/restore persistent registers in prologue/epilogie
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Mar 14, 2024
1 parent b447d62 commit 9176609
Show file tree
Hide file tree
Showing 36 changed files with 310 additions and 92 deletions.
2 changes: 1 addition & 1 deletion ir_aarch64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
|.globals ir_lb
|.section code, cold_code, rodata, jmp_table

|.define IR_LOOP_ALIGNMENT, 16
|.define IR_LOOP_ALIGNMENT, 8

#ifdef IR_DEBUG
typedef struct _ir_mem {uint64_t v;} ir_mem;
Expand Down
88 changes: 62 additions & 26 deletions ir_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -3229,43 +3229,48 @@ static void ir_emit_prologue(ir_ctx *ctx)
{
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;
int offset = ctx->stack_frame_size + ctx->call_stack_size;

if (ctx->flags & IR_USE_FRAME_POINTER) {
| push Ra(IR_REG_RBP)
| mov Ra(IR_REG_RBP), Ra(IR_REG_RSP)
}
if (IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_GP)) {
int i;
ir_regset used_preserved_regs = IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_GP);

for (i = IR_REG_GP_FIRST; i <= IR_REG_GP_LAST; i++) {
if (IR_REGSET_IN(used_preserved_regs, i)) {
offset -= sizeof(void*);
| push Ra(i)
}
}
}
if (ctx->stack_frame_size + ctx->call_stack_size) {
if (ctx->fixed_stack_red_zone) {
IR_ASSERT(ctx->stack_frame_size + ctx->call_stack_size <= ctx->fixed_stack_red_zone);
} else {
| sub Ra(IR_REG_RSP), (ctx->stack_frame_size + ctx->call_stack_size)
} else if (offset) {
| sub Ra(IR_REG_RSP), offset
}
}
if (ctx->used_preserved_regs) {
if (IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_FP)) {
ir_reg fp;
int offset;
uint32_t i;
ir_regset used_preserved_regs = (ir_regset)ctx->used_preserved_regs;
int i;
ir_regset used_preserved_regs = IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_FP);

if (ctx->flags & IR_USE_FRAME_POINTER) {
fp = IR_REG_FRAME_POINTER;
offset = 0;
offset -= ctx->stack_frame_size + ctx->call_stack_size;
} else {
fp = IR_REG_STACK_POINTER;
offset = ctx->stack_frame_size + ctx->call_stack_size;
}
for (i = 0; i < IR_REG_NUM; i++) {
for (i = IR_REG_FP_FIRST; i <= IR_REG_FP_LAST; i++) {
if (IR_REGSET_IN(used_preserved_regs, i)) {
if (i < IR_REG_FP_FIRST) {
offset -= sizeof(void*);
| mov aword [Ra(fp)+offset], Ra(i)
offset -= sizeof(void*);
if (ctx->mflags & IR_X86_AVX) {
| vmovsd qword [Ra(fp)+offset], xmm(i-IR_REG_FP_FIRST)
} else {
offset -= sizeof(void*);
if (ctx->mflags & IR_X86_AVX) {
| vmovsd qword [Ra(fp)+offset], xmm(i-IR_REG_FP_FIRST)
} else {
| movsd qword [Ra(fp)+offset], xmm(i-IR_REG_FP_FIRST)
}
| movsd qword [Ra(fp)+offset], xmm(i-IR_REG_FP_FIRST)
}
}
}
Expand Down Expand Up @@ -3332,26 +3337,24 @@ static void ir_emit_epilogue(ir_ctx *ctx)
ir_backend_data *data = ctx->data;
dasm_State **Dst = &data->dasm_state;

if (ctx->used_preserved_regs) {
if (IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_FP)) {
int i;
int offset;
uint32_t i;
ir_reg fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
ir_regset used_preserved_regs = (ir_regset)ctx->used_preserved_regs;

if (ctx->flags & IR_USE_FRAME_POINTER) {
fp = IR_REG_FRAME_POINTER;
offset = 0;
} else {
fp = IR_REG_STACK_POINTER;
offset = ctx->stack_frame_size + ctx->call_stack_size;
}
for (i = 0; i < IR_REG_NUM; i++) {
if (IR_REGSET_IN(used_preserved_regs, i)) {
if (i < IR_REG_FP_FIRST) {
ir_reg fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;

offset -= sizeof(void*);
| mov Ra(i), aword [Ra(fp)+offset]
} else {
ir_reg fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;

offset -= sizeof(void*);
if (ctx->mflags & IR_X86_AVX) {
| vmovsd xmm(i-IR_REG_FP_FIRST), qword [Ra(fp)+offset]
Expand All @@ -3363,7 +3366,40 @@ static void ir_emit_epilogue(ir_ctx *ctx)
}
}

if (ctx->flags & IR_USE_FRAME_POINTER) {
if (IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_GP)) {
int i;
ir_regset used_preserved_regs = IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_GP);
int offset;

if (ctx->flags & IR_USE_FRAME_POINTER) {
offset = 0;
} else {
offset = ctx->stack_frame_size + ctx->call_stack_size;
}
if (IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_GP)) {
int i;
ir_regset used_preserved_regs = IR_REGSET_INTERSECTION((ir_regset)ctx->used_preserved_regs, IR_REGSET_GP);

for (i = IR_REG_GP_LAST; i >= IR_REG_GP_FIRST; i--) {
if (IR_REGSET_IN(used_preserved_regs, i)) {
offset -= sizeof(void*);
}
}
}
if (ctx->flags & IR_USE_FRAME_POINTER) {
| lea Ra(IR_REG_RSP), [Ra(IR_REG_RBP)+offset]
} else if (offset) {
| add Ra(IR_REG_RSP), offset
}
for (i = IR_REG_GP_LAST; i >= IR_REG_GP_FIRST; i--) {
if (IR_REGSET_IN(used_preserved_regs, i)) {
| pop Ra(i)
}
}
if (ctx->flags & IR_USE_FRAME_POINTER) {
| pop Ra(IR_REG_RBP)
}
} else if (ctx->flags & IR_USE_FRAME_POINTER) {
| mov Ra(IR_REG_RSP), Ra(IR_REG_RBP)
| pop Ra(IR_REG_RBP)
} else if (ctx->stack_frame_size + ctx->call_stack_size) {
Expand Down
1 change: 1 addition & 0 deletions tests/debug.aarch64/dessa_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ aarch64
--EXPECT--
test:
b .L2
nop
.L1:
mov w0, w1
.L2:
Expand Down
1 change: 1 addition & 0 deletions tests/debug.aarch64/dessa_003.irt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ test:
movz w3, #0xc
sdiv w0, w0, w3
b .L2
nop
.L1:
mov w3, w0
mov w0, w1
Expand Down
1 change: 1 addition & 0 deletions tests/debug.aarch64/fig.irt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ test:
mul w9, w2, w1
add w10, w9, #4
b .L3
nop
.L1:
mul w6, w0, w1
add w7, w6, #1
Expand Down
1 change: 1 addition & 0 deletions tests/debug.aarch64/loop_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ test:
mov w1, wzr
mov w0, wzr
b .L4
nop
.L1:
cmp w2, w1
b.eq .L2
Expand Down
2 changes: 1 addition & 1 deletion tests/debug.aarch64/regset-fib.irt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ main:
ldr d0, .L3
str d0, [x29, #0x18]
b .L2
nop
.L1:
ldr d0, [x29, #0x10]
fadd d1, d1, d0
Expand All @@ -98,7 +99,6 @@ main:
ldp x29, x30, [sp], #0x20
ret
.rodata
.db 0x1f, 0x20, 0x03, 0xd5
.L3:
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f
.L4:
Expand Down
2 changes: 2 additions & 0 deletions tests/debug.aarch64/regset-fib2.irt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ main:
ldr d0, .L3
str d0, [x29, #0x18]
b .L2
nop
.L1:
ldr d0, [x29, #0x10]
fadd d1, d1, d0
Expand All @@ -101,6 +102,7 @@ main:
ldp x29, x30, [sp], #0x20
ret
.rodata
.db 0x1f, 0x20, 0x03, 0xd5
.L3:
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f
.L4:
Expand Down
2 changes: 2 additions & 0 deletions tests/debug.aarch64/regset-test.irt
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ test:
str d1, [sp, #0x18]
mov w0, wzr
b .L2
nop
.L1:
ldr d1, [sp, #0x18]
ldr d0, [sp, #0x10]
Expand Down Expand Up @@ -197,6 +198,7 @@ test:
add sp, sp, #0x38
ret
.rodata
.db 0x1f, 0x20, 0x03, 0xd5
.L4:
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f
.L5:
Expand Down
1 change: 1 addition & 0 deletions tests/debug.aarch64/sccp_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ test:
movz w0, #0x3
.L4:
ret
nop
.L5:
cmp w1, #0
b.ne .L5
Expand Down
10 changes: 10 additions & 0 deletions tests/debug.x86/dessa_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ x86
test:
movl 4(%esp), %eax
jmp .L2
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
.L1:
movl %ecx, %eax
.L2:
Expand Down
18 changes: 12 additions & 6 deletions tests/debug.x86/dessa_003.irt
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,28 @@ x86
}
--EXPECT--
test:
subl $8, %esp
movl %ebx, 4(%esp)
movl %ebp, (%esp)
pushl %ebx
pushl %ebp
movl 0x10(%esp), %ecx
movl 0x14(%esp), %ebx
movl 0xc(%esp), %eax
movl $0xc, %ebp
cltd
idivl %ebp
jmp .L2
nop
nop
nop
nop
nop
nop
nop
nop
.L1:
xchgl %eax, %ecx
.L2:
testl %ebx, %ebx
jne .L1
movl 4(%esp), %ebx
movl (%esp), %ebp
addl $8, %esp
popl %ebp
popl %ebx
retl
30 changes: 20 additions & 10 deletions tests/debug.x86/fig.irt
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ x86
}
--EXPECT--
test:
subl $0x14, %esp
movl %ebx, 0x10(%esp)
movl %ebp, 0xc(%esp)
movl %esi, 8(%esp)
movl %edi, 4(%esp)
pushl %ebx
pushl %ebp
pushl %esi
pushl %edi
subl $4, %esp
movl 0x18(%esp), %eax
movl 0x1c(%esp), %ecx
movl 0x24(%esp), %ebx
Expand All @@ -80,6 +80,16 @@ test:
movl %edx, (%esp)
leal 4(%edx), %edx
jmp .L3
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
.L1:
movl %eax, %esi
imull %ecx, %esi
Expand Down Expand Up @@ -111,9 +121,9 @@ test:
movl 0x34(%esp), %edi
addl %edi, %eax
leal 1(%eax, %esi), %eax
movl 0x10(%esp), %ebx
movl 0xc(%esp), %ebp
movl 8(%esp), %esi
movl 4(%esp), %edi
addl $0x14, %esp
addl $4, %esp
popl %edi
popl %esi
popl %ebp
popl %ebx
retl
10 changes: 10 additions & 0 deletions tests/debug.x86/loop_002.irt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ test:
xorl %ecx, %ecx
xorl %eax, %eax
jmp .L4
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
.L1:
cmpl %ecx, %edx
je .L2
Expand Down
11 changes: 10 additions & 1 deletion tests/debug.x86/regset-fib.irt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ main:
movsd .L4, %xmm0
movsd %xmm0, 0xc(%esp)
jmp .L2
nop
nop
nop
nop
nop
nop
nop
nop
nop
.L1:
addsd %xmm1, %xmm0
movsd %xmm0, 0xc(%esp)
Expand All @@ -96,7 +105,7 @@ main:
addl $0x1c, %esp
retl
.rodata
.db 0x90, 0x90, 0x90, 0x90, 0x90
.db 0x90, 0x90, 0x90, 0x90
.L4:
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f
.L5:
Expand Down
Loading

0 comments on commit 9176609

Please sign in to comment.