From: Rhys Weatherley Date: Sun, 30 May 2004 05:37:05 +0000 (+0000) Subject: Improve instruction selection for floating-point "push" operations. X-Git-Tag: r.0.0.4~68 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=67f91eeaa4588f65d00467c7305d234571dbc171;p=francis%2Flibjit.git Improve instruction selection for floating-point "push" operations. --- diff --git a/ChangeLog b/ChangeLog index ba53d45..f0a53b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ * jit/jit-insn.c (jit_insn_convert): use intrinsic functions for conversions when the back end doesn't support the opcode. + * jit/jit-rules-x86.sel, tools/gen-sel-parser.y, + tools/gen-sel-scanner.l: improve instruction selection for + floating-point "push" operations. + 2004-05-29 Rhys Weatherley * jit/jit-insn.c, jit/jit-reg-alloc.c, jit/jit-reg-alloc.h, diff --git a/jit/jit-rules-x86.sel b/jit/jit-rules-x86.sel index c01a69c..609dc31 100644 --- a/jit/jit-rules-x86.sel +++ b/jit/jit-rules-x86.sel @@ -721,13 +721,13 @@ JIT_OP_COPY_LONG: spill_before 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 @@ -847,6 +847,7 @@ JIT_OP_PUSH_INT: unary_note 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]); @@ -862,9 +863,10 @@ JIT_OP_PUSH_LONG: spill_before } } -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); @@ -872,12 +874,14 @@ JIT_OP_PUSH_FLOAT32: unary_note [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); @@ -886,16 +890,18 @@ JIT_OP_PUSH_FLOAT64: unary_note [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)) @@ -905,7 +911,7 @@ JIT_OP_PUSH_NFLOAT: unary_note 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)); @@ -916,6 +922,7 @@ JIT_OP_PUSH_NFLOAT: unary_note 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 diff --git a/tools/gen-sel-parser.y b/tools/gen-sel-parser.y index b6ac6fe..5b44506 100644 --- a/tools/gen-sel-parser.y +++ b/tools/gen-sel-parser.y @@ -77,6 +77,8 @@ static int gensel_first_stack_reg = 8; /* st0 under x86 */ #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. @@ -334,7 +336,9 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options) 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; } @@ -350,7 +354,8 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options) 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; @@ -405,7 +410,7 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options) case GENSEL_PATT_IMM: { - printf("%s->is_nint_constant", arg); + printf("%s->is_constant", arg); } break; @@ -469,7 +474,7 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options) { 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) { @@ -565,7 +570,8 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options) 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"); @@ -670,6 +676,8 @@ static void gensel_output_supported(void) %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'" @@ -751,6 +759,8 @@ Option | 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; } diff --git a/tools/gen-sel-scanner.l b/tools/gen-sel-scanner.l index 51a7934..5a9320f 100644 --- a/tools/gen-sel-scanner.l +++ b/tools/gen-sel-scanner.l @@ -98,8 +98,8 @@ WHITE [ \t\v\r\f] "ternary" { RETURNTOK(K_TERNARY); } "unary_branch" { RETURNTOK(K_UNARY_BRANCH); } "binary_branch" { RETURNTOK(K_BINARY_BRANCH); } -"unary_note" { RETURNTOK(K_UNARY_BRANCH); } -"binary_note" { RETURNTOK(K_BINARY_BRANCH); } +"unary_note" { RETURNTOK(K_UNARY_NOTE); } +"binary_note" { RETURNTOK(K_BINARY_NOTE); } "manual" { RETURNTOK(K_MANUAL); } "stack" { RETURNTOK(K_STACK); } "only" { RETURNTOK(K_ONLY); }