TODO();
}
-JIT_OP_COPY_FLOAT32: unary
+JIT_OP_COPY_FLOAT32: unary, stack
[freg] -> {}
-JIT_OP_COPY_FLOAT64: unary
+JIT_OP_COPY_FLOAT64: unary, stack
[freg] -> {}
-JIT_OP_COPY_NFLOAT: unary
+JIT_OP_COPY_NFLOAT: unary, stack
[freg] -> {}
JIT_OP_COPY_STRUCT: manual
JIT_OP_PUSH_LONG: spill_before
[] -> {
+ /* TODO: use 'manual' to avoid register spills */
if(jit_value_is_constant(insn->value1))
{
x86_push_imm(inst, ((jit_int *)(insn->value1->address))[1]);
}
}
-JIT_OP_PUSH_FLOAT32: unary_note
+JIT_OP_PUSH_FLOAT32: unary_note, stack
[imm] -> {
- x86_push_imm(inst, *((jit_int *)(insn->value1->address)));
+ jit_int *ptr = (jit_int *)($1);
+ x86_push_imm(inst, ptr[0]);
}
[local] -> {
x86_push_membase(inst, X86_EBP, $1);
[reg] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float32));
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
+ _jit_regs_free_reg(gen, $1, 1);
}
-JIT_OP_PUSH_FLOAT64: unary_note
+JIT_OP_PUSH_FLOAT64: unary_note, stack
[imm] -> {
- x86_push_imm(inst, ((jit_int *)(insn->value1->address))[1]);
- x86_push_imm(inst, ((jit_int *)(insn->value1->address))[0]);
+ jit_int *ptr = (jit_int *)($1);
+ x86_push_imm(inst, ptr[1]);
+ x86_push_imm(inst, ptr[0]);
}
[local] -> {
x86_push_membase(inst, X86_EBP, $1 + 4);
[reg] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64));
x86_fst_membase(inst, X86_ESP, 0, 1, 1);
+ _jit_regs_free_reg(gen, $1, 1);
}
-JIT_OP_PUSH_NFLOAT: unary_note
+JIT_OP_PUSH_NFLOAT: unary_note, stack
[imm] -> {
+ jit_int *ptr = (jit_int *)($1);
if(sizeof(jit_nfloat) != sizeof(jit_float64))
{
- x86_push_imm(inst, ((jit_int *)(insn->value1->address))[2]);
+ x86_push_imm(inst, ptr[2]);
}
- x86_push_imm(inst, ((jit_int *)(insn->value1->address))[1]);
- x86_push_imm(inst, ((jit_int *)(insn->value1->address))[0]);
+ x86_push_imm(inst, ptr[1]);
+ x86_push_imm(inst, ptr[0]);
}
[local] -> {
if(sizeof(jit_nfloat) != sizeof(jit_float64))
x86_push_membase(inst, X86_EBP, $1 + 4);
x86_push_membase(inst, X86_EBP, $1);
}
- [reg] -> {
+ [freg] -> {
if(sizeof(jit_nfloat) != sizeof(jit_float64))
{
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_nfloat));
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64));
x86_fst_membase(inst, X86_ESP, 0, 1, 1);
}
+ _jit_regs_free_reg(gen, $1, 1);
}
JIT_OP_PUSH_STRUCT: unary_note
#define GENSEL_OPT_BINARY_BRANCH 0x0040
#define GENSEL_OPT_ONLY 0x0080
#define GENSEL_OPT_MANUAL 0x0100
+#define GENSEL_OPT_UNARY_NOTE 0x0200
+#define GENSEL_OPT_BINARY_NOTE 0x0400
/*
* Pattern values.
flag2 = "VALUE2";
flag3 = "??";
if((options & (GENSEL_OPT_BINARY_BRANCH |
- GENSEL_OPT_UNARY_BRANCH)) != 0)
+ GENSEL_OPT_UNARY_BRANCH |
+ GENSEL_OPT_BINARY_NOTE |
+ GENSEL_OPT_UNARY_NOTE)) != 0)
{
destroy1 = 0;
}
value into a register before we start checking cases */
check_index = 0;
if((options & (GENSEL_OPT_BINARY | GENSEL_OPT_UNARY |
- GENSEL_OPT_BINARY_BRANCH | GENSEL_OPT_UNARY_BRANCH)) != 0 &&
+ GENSEL_OPT_BINARY_BRANCH | GENSEL_OPT_UNARY_BRANCH |
+ GENSEL_OPT_BINARY_NOTE | GENSEL_OPT_UNARY_NOTE)) != 0 &&
(options & GENSEL_OPT_STACK) == 0)
{
clause = clauses;
case GENSEL_PATT_IMM:
{
- printf("%s->is_nint_constant", arg);
+ printf("%s->is_constant", arg);
}
break;
{
printf("\telse\n\t{\n");
}
- if((options & GENSEL_OPT_STACK) == 0)
+ if((options & GENSEL_OPT_STACK) == 0 || clause->next)
{
for(index = check_index; clause->pattern[index]; ++index)
{
gensel_first_stack_reg);
}
else if((options & (GENSEL_OPT_UNARY |
- GENSEL_OPT_UNARY_BRANCH)) != 0)
+ GENSEL_OPT_UNARY_BRANCH |
+ GENSEL_OPT_UNARY_NOTE)) != 0)
{
printf("\t\treg = _jit_regs_load_to_top\n");
printf("\t\t\t(gen, insn->value1,\n");
%token K_UNARY "`unary'"
%token K_UNARY_BRANCH "`unary_branch'"
%token K_BINARY_BRANCH "`binary_branch'"
+%token K_UNARY_NOTE "`unary_note'"
+%token K_BINARY_NOTE "`binary_note'"
%token K_TERNARY "`ternary'"
%token K_STACK "`stack'"
%token K_ONLY "`only'"
| K_UNARY { $$ = GENSEL_OPT_UNARY; }
| K_UNARY_BRANCH { $$ = GENSEL_OPT_UNARY_BRANCH; }
| K_BINARY_BRANCH { $$ = GENSEL_OPT_BINARY_BRANCH; }
+ | K_UNARY_NOTE { $$ = GENSEL_OPT_UNARY_NOTE; }
+ | K_BINARY_NOTE { $$ = GENSEL_OPT_BINARY_NOTE; }
| K_TERNARY { $$ = GENSEL_OPT_TERNARY; }
| K_STACK { $$ = GENSEL_OPT_STACK; }
| K_ONLY { $$ = GENSEL_OPT_ONLY; }