mirror of
https://github.com/danog/ir.git
synced 2024-11-30 04:39:43 +01:00
Add support for Windows-64 ABI ("home space")
Fix parameter passing code to perform sign or zero extension when pass a regiser or a constant TODO: ARM code maight need similar changes
This commit is contained in:
parent
ebdeba9fff
commit
5a48805c81
@ -139,6 +139,7 @@ enum _ir_reg {
|
||||
#define IR_REG_FP_ARG7 IR_REG_V6
|
||||
#define IR_REG_FP_ARG8 IR_REG_V7
|
||||
#define IR_MAX_REG_ARGS 16
|
||||
#define IR_SHADOW_ARGS 0
|
||||
|
||||
# define IR_REGSET_SCRATCH \
|
||||
(IR_REGSET_INTERVAL(IR_REG_X0, IR_REG_X18) \
|
||||
|
40
ir_x86.dasc
40
ir_x86.dasc
@ -5737,6 +5737,8 @@ static void ir_emit_switch(ir_ctx *ctx, uint32_t b, ir_ref def, ir_insn *insn)
|
||||
|
||||
static int ir_parallel_copy(ir_ctx *ctx, ir_copy *copies, int count, ir_reg tmp_reg, ir_reg tmp_fp_reg)
|
||||
{
|
||||
ir_backend_data *data = ctx->data;
|
||||
dasm_State **Dst = &data->dasm_state;
|
||||
int i;
|
||||
int8_t *pred, *loc, *types;
|
||||
ir_reg to, from_reg;
|
||||
@ -5756,7 +5758,7 @@ static int ir_parallel_copy(ir_ctx *ctx, ir_copy *copies, int count, ir_reg tmp_
|
||||
if (from_reg != to) {
|
||||
loc[from_reg] = from_reg;
|
||||
pred[to] = from_reg;
|
||||
types[to] = copies[i].type;
|
||||
types[from_reg] = copies[i].type;
|
||||
IR_REGSET_INCL(todo, to);
|
||||
}
|
||||
}
|
||||
@ -5774,13 +5776,32 @@ static int ir_parallel_copy(ir_ctx *ctx, ir_copy *copies, int count, ir_reg tmp_
|
||||
to = IR_REGSET_FIRST(ready);
|
||||
IR_REGSET_EXCL(ready, to);
|
||||
from_reg = pred[to];
|
||||
type = types[to];
|
||||
c = loc[from_reg];
|
||||
type = types[c];
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
if (ir_type_size[type] > 2) {
|
||||
ir_emit_mov(ctx, type, to, c);
|
||||
} else if (ir_type_size[type] == 2) {
|
||||
if (IR_IS_TYPE_SIGNED(type)) {
|
||||
| movsx Rd(to), Rw(c)
|
||||
type = IR_I32;
|
||||
} else {
|
||||
| movzx Rd(to), Rw(c)
|
||||
type = IR_U32;
|
||||
}
|
||||
} else /* if (ir_type_size[type] == 1) */ {
|
||||
if (IR_IS_TYPE_SIGNED(type)) {
|
||||
| movsx Rd(to), Rb(c)
|
||||
type = IR_I32;
|
||||
} else {
|
||||
| movzx Rd(to), Rb(c)
|
||||
type = IR_U32;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ir_emit_fp_mov(ctx, type, to, c);
|
||||
}
|
||||
types[to] = type;
|
||||
loc[from_reg] = to;
|
||||
if (from_reg == c && pred[from_reg] != IR_REG_NONE) {
|
||||
IR_REGSET_INCL(ready, from_reg);
|
||||
@ -5790,11 +5811,12 @@ static int ir_parallel_copy(ir_ctx *ctx, ir_copy *copies, int count, ir_reg tmp_
|
||||
IR_REGSET_EXCL(todo, to);
|
||||
from_reg = pred[to];
|
||||
if (to != loc[from_reg]) {
|
||||
type = types[to];
|
||||
type = types[from_reg];
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
IR_ASSERT(tmp_reg != IR_REG_NONE);
|
||||
IR_ASSERT(tmp_reg >= IR_REG_GP_FIRST && tmp_reg <= IR_REG_GP_LAST);
|
||||
ir_emit_mov(ctx, type, tmp_reg, to);
|
||||
types[tmp_reg] = type;
|
||||
loc[to] = tmp_reg;
|
||||
} else {
|
||||
IR_ASSERT(tmp_fp_reg != IR_REG_NONE);
|
||||
@ -5846,6 +5868,9 @@ static int32_t ir_call_used_stack(ir_ctx *ctx, ir_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Reserved "home space" or "shadow store" for register arguments (used in Windows64 ABI) */
|
||||
used_stack += IR_SHADOW_ARGS;
|
||||
|
||||
return used_stack;
|
||||
}
|
||||
|
||||
@ -5865,7 +5890,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
int fp_reg_params_count = IR_REG_FP_ARGS;
|
||||
const int8_t *int_reg_params = _ir_int_reg_params;
|
||||
const int8_t *fp_reg_params = _ir_fp_reg_params;
|
||||
int32_t used_stack, stack_offset = 0;
|
||||
int32_t used_stack, stack_offset = IR_SHADOW_ARGS;
|
||||
ir_copy *copies;
|
||||
bool do_pass3 = 0;
|
||||
ir_reg tmp_fp_reg = IR_REG_FP_LAST; /* Temporary register for FP loads and swap */
|
||||
@ -5976,7 +6001,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
|
||||
/* 3. move the remaining memory and immediate values */
|
||||
if (do_pass3) {
|
||||
stack_offset = 0;
|
||||
stack_offset = IR_SHADOW_ARGS;
|
||||
int_param = 0;
|
||||
fp_param = 0;
|
||||
for (j = 3; j <= n; j++) {
|
||||
@ -6019,6 +6044,11 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
type = IR_ADDR;
|
||||
}
|
||||
}
|
||||
if (type == IR_I8 || type == IR_I16) {
|
||||
type = IR_I32;
|
||||
} else if (type == IR_U8 || type == IR_U16) {
|
||||
type = IR_U32;
|
||||
}
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
} else {
|
||||
ir_emit_load(ctx, type, dst_reg, arg);
|
||||
|
5
ir_x86.h
5
ir_x86.h
@ -124,7 +124,8 @@ enum _ir_reg {
|
||||
# define IR_REG_FP_ARG2 IR_REG_XMM1
|
||||
# define IR_REG_FP_ARG3 IR_REG_XMM2
|
||||
# define IR_REG_FP_ARG4 IR_REG_XMM3
|
||||
# define IR_MAX_REG_ARGS 8
|
||||
# define IR_MAX_REG_ARGS 4
|
||||
# define IR_SHADOW_ARGS 32 /* Reserved space in bytes - "home space" or "shadow store" for register arguments */
|
||||
|
||||
# define IR_REGSET_SCRATCH \
|
||||
(IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \
|
||||
@ -158,6 +159,7 @@ enum _ir_reg {
|
||||
# define IR_REG_FP_ARG7 IR_REG_XMM6
|
||||
# define IR_REG_FP_ARG8 IR_REG_XMM7
|
||||
# define IR_MAX_REG_ARGS 14
|
||||
# define IR_SHADOW_ARGS 0
|
||||
|
||||
# define IR_REGSET_SCRATCH \
|
||||
(IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) \
|
||||
@ -183,6 +185,7 @@ enum _ir_reg {
|
||||
# define IR_REG_INT_FCARG1 IR_REG_RCX
|
||||
# define IR_REG_INT_FCARG2 IR_REG_RDX
|
||||
# define IR_MAX_REG_ARGS 2
|
||||
# define IR_SHADOW_ARGS 0
|
||||
|
||||
# define IR_REGSET_SCRATCH \
|
||||
(IR_REGSET_INTERVAL(IR_REG_RAX, IR_REG_RDX) | IR_REGSET_FP)
|
||||
|
@ -27,7 +27,7 @@ test:
|
||||
subq $0x28, %rsp
|
||||
leaq .L1(%rip), %rdi
|
||||
movl $1, %esi
|
||||
movw $2, %dx
|
||||
movl $2, %edx
|
||||
movl $3, %ecx
|
||||
movl $4, %r8d
|
||||
movabsq $0x100000000, %r9
|
||||
@ -42,7 +42,7 @@ test:
|
||||
addq $0x28, %rsp
|
||||
retq
|
||||
.rodata
|
||||
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||
.db 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
||||
.L1:
|
||||
.db 0x25, 0x64, 0x20, 0x25, 0x64, 0x20, 0x25, 0x64, 0x20, 0x25, 0x6c, 0x6c, 0x64, 0x20, 0x30, 0x78
|
||||
.db 0x25, 0x6c, 0x6c, 0x78, 0x20, 0x25, 0x64, 0x20, 0x25, 0x64, 0x20, 0x25, 0x64, 0x20, 0x25, 0x6c
|
||||
|
Loading…
Reference in New Issue
Block a user