unsigned int size;
unsigned int num_stack_words;
- /* Reset the frame size for this function. We start by assuming
- that ESI, EDI, and EBX need to be saved in the local frame */
- func->builder->frame_size = 3 * sizeof(void *);
+ /* Reset the local variable frame size for this function */
+ func->builder->frame_size = 0;
/* Determine the number of registers to allocate to parameters */
#if JIT_APPLY_X86_FASTCALL == 1
unsigned char prolog[JIT_PROLOG_SIZE];
unsigned char *inst = prolog;
int reg;
- unsigned int saved;
/* Push ebp onto the stack */
x86_push_reg(inst, X86_EBP);
/* Initialize EBP for the current frame */
x86_mov_reg_reg(inst, X86_EBP, X86_ESP, sizeof(void *));
+ /* Allocate space for the local variable frame */
+ if(func->builder->frame_size > 0)
+ {
+ x86_alu_reg_imm(inst, X86_SUB, X86_ESP,
+ (int)(func->builder->frame_size));
+ }
+
/* Save registers that we need to preserve */
- saved = 0;
for(reg = 0; reg <= 7; ++reg)
{
if(jit_reg_is_used(gen->touched, reg) &&
(_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0)
{
x86_push_reg(inst, _jit_reg_info[reg].cpu_reg);
- saved += sizeof(void *);
}
}
- /* Allocate space for the local variable frame. Subtract off
- the space for the registers that we just saved */
- if((func->builder->frame_size - saved) > 0)
- {
- x86_alu_reg_imm(inst, X86_SUB, X86_ESP,
- (int)(func->builder->frame_size - saved));
- }
-
/* Copy the prolog into place and return the adjusted entry position */
reg = (int)(inst - prolog);
jit_memcpy(((unsigned char *)buf) + JIT_PROLOG_SIZE - reg, prolog, reg);
void _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
{
jit_nint pop_bytes = 0;
- int num_regs, reg;
+ int reg, offset;
unsigned char *inst;
int struct_return_offset = 0;
void **fixup;
void **next;
/* Bail out if there is insufficient space for the epilog */
- if(!jit_cache_check_for_n(&(gen->posn), 32))
+ if(!jit_cache_check_for_n(&(gen->posn), 48))
{
jit_cache_mark_full(&(gen->posn));
return;
x86_mov_reg_membase(inst, X86_EAX, X86_EBP, struct_return_offset, 4);
}
- /* Determine the number of callee save registers on the stack */
- num_regs = 0;
- for(reg = 7; reg >= 0; --reg)
- {
- if(jit_reg_is_used(gen->touched, reg) &&
- (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0)
- {
- ++num_regs;
- }
- }
-
- /* Pop the local stack frame, and get back to the callee save regs */
- if(num_regs == 0)
- {
- x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *));
- }
- else
- {
- x86_lea_membase(inst, X86_ESP, X86_EBP, -(sizeof(void *) * num_regs));
- }
-
- /* Pop the callee save registers that we used */
- for(reg = 7; reg >= 0; --reg)
+ /* Restore the callee save registers that we used */
+ offset = -(func->builder->frame_size);
+ for(reg = 0; reg <= 7; ++reg)
{
if(jit_reg_is_used(gen->touched, reg) &&
(_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0)
{
- x86_pop_reg(inst, _jit_reg_info[reg].cpu_reg);
+ offset -= sizeof(void *);
+ x86_mov_reg_membase(inst, _jit_reg_info[reg].cpu_reg,
+ X86_EBP, offset, sizeof(void *));
}
}
- /* Pop the saved copy of ebp */
+ /* Pop the stack frame and restore the saved copy of ebp */
+ x86_mov_reg_reg(inst, X86_ESP, X86_EBP, sizeof(void *));
x86_pop_reg(inst, X86_EBP);
/* Return from the current function */
/* The value belongs to the entry block, no matter
where it happens to be created */
values[current]->block = func->builder->entry;
+ values[current]->is_parameter = 1;
}
}
/* The value belongs to the entry block, no matter
where it happens to be created */
value->block = func->builder->entry;
+ value->is_parameter = 1;
}
jit_type_free(type);
}
return value->is_constant;
}
+/*@
+ * @deftypefun int jit_value_is_parameter (jit_value_t value)
+ * Determine if a value is a function parameter.
+ * @end deftypefun
+@*/
+int jit_value_is_parameter(jit_value_t value)
+{
+ return value->is_parameter;
+}
+
/*@
* @deftypefun void jit_value_ref (jit_function_t func, jit_value_t value)
* Create a reference to the specified @code{value} from the current