forked from Mirrors/tinycc
i386-gen: use EBX as 4th register
May be enabled/disabled by changing this line: #define USE_EBX 1master
parent
02642bc94c
commit
3054a76249
17
i386-gen.c
17
i386-gen.c
|
@ -21,7 +21,7 @@
|
||||||
#ifdef TARGET_DEFS_ONLY
|
#ifdef TARGET_DEFS_ONLY
|
||||||
|
|
||||||
/* number of available registers */
|
/* number of available registers */
|
||||||
#define NB_REGS 4
|
#define NB_REGS 5
|
||||||
#define NB_ASM_REGS 8
|
#define NB_ASM_REGS 8
|
||||||
|
|
||||||
/* a register can belong to several classes. The classes must be
|
/* a register can belong to several classes. The classes must be
|
||||||
|
@ -33,6 +33,8 @@
|
||||||
#define RC_ST0 0x0008
|
#define RC_ST0 0x0008
|
||||||
#define RC_ECX 0x0010
|
#define RC_ECX 0x0010
|
||||||
#define RC_EDX 0x0020
|
#define RC_EDX 0x0020
|
||||||
|
#define RC_EBX 0x0040
|
||||||
|
|
||||||
#define RC_IRET RC_EAX /* function return: integer register */
|
#define RC_IRET RC_EAX /* function return: integer register */
|
||||||
#define RC_LRET RC_EDX /* function return: second integer register */
|
#define RC_LRET RC_EDX /* function return: second integer register */
|
||||||
#define RC_FRET RC_ST0 /* function return: float register */
|
#define RC_FRET RC_ST0 /* function return: float register */
|
||||||
|
@ -42,6 +44,7 @@ enum {
|
||||||
TREG_EAX = 0,
|
TREG_EAX = 0,
|
||||||
TREG_ECX,
|
TREG_ECX,
|
||||||
TREG_EDX,
|
TREG_EDX,
|
||||||
|
TREG_EBX,
|
||||||
TREG_ST0,
|
TREG_ST0,
|
||||||
TREG_ESP = 4
|
TREG_ESP = 4
|
||||||
};
|
};
|
||||||
|
@ -89,10 +92,14 @@ enum {
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
|
|
||||||
|
/* define to 1/0 to [not] have EBX as 4th register */
|
||||||
|
#define USE_EBX 1
|
||||||
|
|
||||||
ST_DATA const int reg_classes[NB_REGS] = {
|
ST_DATA const int reg_classes[NB_REGS] = {
|
||||||
/* eax */ RC_INT | RC_EAX,
|
/* eax */ RC_INT | RC_EAX,
|
||||||
/* ecx */ RC_INT | RC_ECX,
|
/* ecx */ RC_INT | RC_ECX,
|
||||||
/* edx */ RC_INT | RC_EDX,
|
/* edx */ RC_INT | RC_EDX,
|
||||||
|
/* ebx */ (RC_INT | RC_EBX) * USE_EBX,
|
||||||
/* st0 */ RC_FLOAT | RC_ST0,
|
/* st0 */ RC_FLOAT | RC_ST0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -518,9 +525,9 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
#define FUNC_PROLOG_SIZE 10
|
#define FUNC_PROLOG_SIZE (10 + USE_EBX)
|
||||||
#else
|
#else
|
||||||
#define FUNC_PROLOG_SIZE 9
|
#define FUNC_PROLOG_SIZE (9 + USE_EBX)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* generate function prolog of type 't' */
|
/* generate function prolog of type 't' */
|
||||||
|
@ -646,6 +653,7 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
o(0x585a); /* restore returned value, if any */
|
o(0x585a); /* restore returned value, if any */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
o(0x5b * USE_EBX); /* pop ebx */
|
||||||
o(0xc9); /* leave */
|
o(0xc9); /* leave */
|
||||||
if (func_ret_sub == 0) {
|
if (func_ret_sub == 0) {
|
||||||
o(0xc3); /* ret */
|
o(0xc3); /* ret */
|
||||||
|
@ -669,10 +677,11 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
||||||
o(0xec81); /* sub esp, stacksize */
|
o(0xec81); /* sub esp, stacksize */
|
||||||
gen_le32(v);
|
gen_le32(v);
|
||||||
#if FUNC_PROLOG_SIZE == 10
|
#ifdef TCC_TARGET_PE
|
||||||
o(0x90); /* adjust to FUNC_PROLOG_SIZE */
|
o(0x90); /* adjust to FUNC_PROLOG_SIZE */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
o(0x53 * USE_EBX); /* push ebx */
|
||||||
ind = saved_ind;
|
ind = saved_ind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue