]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
More selection cases for the x86 back end.
authorRhys Weatherley <rweather@southern-storm.com.au>
Wed, 26 May 2004 03:47:38 +0000 (03:47 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Wed, 26 May 2004 03:47:38 +0000 (03:47 +0000)
ChangeLog
jit/jit-rules-x86.c
jit/jit-rules-x86.sel
tools/gen-sel-parser.y
tools/gen-sel-scanner.l

index f3b4dc50726524e4ab85d63b2e514fc1bb93d312..d808343183d47800514bd20b027399026dbf576c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,9 @@
        testing if the last block is reachable or not, taking empty
        trailing blocks into account.
 
+       * jit/jit-rules-x86.c, jit/jit-rules-x86.sel, tools/gen-sel-parser.y,
+       tools/gen-sel-scanner.l: more selection cases for the x86 back end.
+
 2004-05-25  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * tools/.cvsignore, tools/Makefile.am, tools/gen-sel-parser.y,
index 8a337906ae5a98c4b56c69e016e2bcf3fcab495f..81d549c35518b64671dd10f811d660f05f67f8ec 100644 (file)
@@ -1045,7 +1045,14 @@ void _jit_gen_load_value
                                }
                                ptr = _jit_cache_alloc(&(gen->posn), sizeof(jit_nfloat));
                                jit_memcpy(ptr, &nfloat_value, sizeof(nfloat_value));
-                               x86_fld80_mem(inst, ptr);
+                               if(sizeof(jit_nfloat) != sizeof(jit_float64))
+                               {
+                                       x86_fld80_mem(inst, ptr);
+                               }
+                               else
+                               {
+                                       x86_fld(inst, ptr, 1);
+                               }
                        }
                        break;
                }
index bf62140e029bcde61acdf2828f056a58c864069a..ddd8eab8fec76e6f2fbeb5dc2f3de1d24acd87f6 100644 (file)
@@ -78,6 +78,81 @@ JIT_OP_INEG: unary
                x86_neg_reg(inst, $1);
        }
 
+JIT_OP_FADD: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FADD, 1, 1);
+       }
+
+JIT_OP_FSUB: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FSUB, 1, 1);
+       }
+
+JIT_OP_FMUL: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FMUL, 1, 1);
+       }
+
+JIT_OP_FDIV: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FDIV, 1, 1);
+       }
+
+JIT_OP_FNEG: unary, stack
+       [freg] -> {
+               x86_fchs(inst);
+       }
+
+JIT_OP_DADD: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FADD, 1, 1);
+       }
+
+JIT_OP_DSUB: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FSUB, 1, 1);
+       }
+
+JIT_OP_DMUL: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FMUL, 1, 1);
+       }
+
+JIT_OP_DDIV: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FDIV, 1, 1);
+       }
+
+JIT_OP_DNEG: unary, stack
+       [freg] -> {
+               x86_fchs(inst);
+       }
+
+JIT_OP_NFADD: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FADD, 1, 1);
+       }
+
+JIT_OP_NFSUB: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FSUB, 1, 1);
+       }
+
+JIT_OP_NFMUL: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FMUL, 1, 1);
+       }
+
+JIT_OP_NFDIV: binary, stack
+       [freg, freg] -> {
+               x86_fp_op_reg(inst, X86_FDIV, 1, 1);
+       }
+
+JIT_OP_NFNEG: unary, stack
+       [freg] -> {
+               x86_fchs(inst);
+       }
+
 /*
  * Bitwise opcodes.
  */
@@ -469,7 +544,7 @@ JIT_OP_IGE_UN: binary
  * Pointer check opcodes.
  */
 
-JIT_OP_CHECK_NULL: unary_branch
+JIT_OP_CHECK_NULL: unary_note
        [reg] -> {
                /* TODO: won't work in a function with a "try" block */
                unsigned char *patch;
@@ -517,7 +592,7 @@ JIT_OP_RETURN:
                inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_INT: unary_branch
+JIT_OP_RETURN_INT: unary_note
        [reg] -> {
                int cpu_reg = $1;
                if(cpu_reg != X86_EAX)
@@ -529,21 +604,35 @@ JIT_OP_RETURN_INT: unary_branch
 
 JIT_OP_RETURN_LONG: spill_before
        [] -> {
-               /* TODO: load the return value into EAX:EDX */
+               if(jit_value_is_constant(insn->value1))
+               {
+                       x86_mov_reg_imm(inst, X86_EAX,
+                                                       ((jit_int *)(insn->value1->address))[0]);
+                       x86_mov_reg_imm(inst, X86_EDX,
+                                                       ((jit_int *)(insn->value1->address))[1]);
+               }
+               else
+               {
+                       jit_nint offset;
+                       _jit_gen_fix_value(insn->value1);
+                       offset = insn->value1->frame_offset;
+                       x86_mov_reg_membase(inst, X86_EAX, X86_EBP, offset, 4);
+                       x86_mov_reg_membase(inst, X86_EDX, X86_EBP, offset + 4, 4);
+               }
                inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_FLOAT32: unary_branch, stack /*, only*/
+JIT_OP_RETURN_FLOAT32: unary_note, stack, only
        [freg] -> {
                inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_FLOAT64: unary_branch, stack /*, only*/
+JIT_OP_RETURN_FLOAT64: unary_note, stack, only
        [freg] -> {
                inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_NFLOAT: unary_branch, stack /*, only*/
+JIT_OP_RETURN_NFLOAT: unary_note, stack, only
        [freg] -> {
                inst = jump_to_epilog(gen, inst, block);
        }
@@ -604,11 +693,65 @@ JIT_OP_IMPORT:
                /* TODO */
        }
 
+/*
+ * Data manipulation.
+ */
+
+JIT_OP_COPY_LOAD_SBYTE: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LOAD_UBYTE: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LOAD_SHORT: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LOAD_USHORT: unary
+       [reg] -> {}
+
+JIT_OP_COPY_INT: unary
+       [reg] -> {}
+
+JIT_OP_COPY_LONG: spill_before
+       [] -> {
+               /* TODO */
+       }
+
+JIT_OP_COPY_FLOAT32: unary
+       [freg] -> {}
+
+JIT_OP_COPY_FLOAT64: unary
+       [freg] -> {}
+
+JIT_OP_COPY_NFLOAT: unary
+       [freg] -> {}
+
+JIT_OP_COPY_STRUCT:
+       [] -> {
+               /* TODO */
+       }
+
+JIT_OP_COPY_STORE_BYTE:
+       [] -> {
+               /* TODO */
+       }
+
+JIT_OP_COPY_STORE_SHORT:
+       [] -> {
+               /* TODO */
+       }
+
+JIT_OP_ADDRESS_OF:
+       [] -> {
+               _jit_gen_fix_value(insn->value1);
+               /* TODO: get a register to hold the result */
+       }
+
 /*
  * Stack pushes and pops.
  */
 
-JIT_OP_PUSH_INT: unary_branch
+JIT_OP_PUSH_INT: unary_note
        [imm] -> {
                x86_push_imm(inst, $1);
        }
@@ -619,28 +762,81 @@ JIT_OP_PUSH_INT: unary_branch
                x86_push_reg(inst, $1);
        }
 
-JIT_OP_PUSH_LONG:
+JIT_OP_PUSH_LONG: spill_before
        [] -> {
-               /* TODO */
+               if(jit_value_is_constant(insn->value1))
+               {
+                       x86_push_imm(inst, ((jit_int *)(insn->value1->address))[1]);
+                       x86_push_imm(inst, ((jit_int *)(insn->value1->address))[0]);
+               }
+               else
+               {
+                       jit_nint offset;
+                       _jit_gen_fix_value(insn->value1);
+                       offset = insn->value1->frame_offset;
+                       x86_push_membase(inst, X86_EBP, offset + 4);
+                       x86_push_membase(inst, X86_EBP, offset);
+               }
        }
 
-JIT_OP_PUSH_FLOAT32:
-       [] -> {
-               /* TODO */
+JIT_OP_PUSH_FLOAT32: unary_note
+       [imm] -> {
+               x86_push_imm(inst, *((jit_int *)(insn->value1->address)));
+       }
+       [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_OP_PUSH_FLOAT64:
-       [] -> {
-               /* TODO */
+JIT_OP_PUSH_FLOAT64: unary_note
+       [imm] -> {
+               x86_push_imm(inst, ((jit_int *)(insn->value1->address))[1]);
+               x86_push_imm(inst, ((jit_int *)(insn->value1->address))[0]);
+       }
+       [local] -> {
+               x86_push_membase(inst, X86_EBP, $1 + 4);
+               x86_push_membase(inst, X86_EBP, $1);
+       }
+       [reg] -> {
+               x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64));
+               x86_fst_membase(inst, X86_ESP, 0, 1, 1);
        }
 
-JIT_OP_PUSH_NFLOAT:
-       [] -> {
-               /* TODO */
+JIT_OP_PUSH_NFLOAT: unary_note
+       [imm] -> {
+               if(sizeof(jit_nfloat) != sizeof(jit_float64))
+               {
+                       x86_push_imm(inst, ((jit_int *)(insn->value1->address))[2]);
+               }
+               x86_push_imm(inst, ((jit_int *)(insn->value1->address))[1]);
+               x86_push_imm(inst, ((jit_int *)(insn->value1->address))[0]);
+       }
+       [local] -> {
+               if(sizeof(jit_nfloat) != sizeof(jit_float64))
+               {
+                       x86_push_membase(inst, X86_EBP, $1 + 8);
+               }
+               x86_push_membase(inst, X86_EBP, $1 + 4);
+               x86_push_membase(inst, X86_EBP, $1);
+       }
+       [reg] -> {
+               if(sizeof(jit_nfloat) != sizeof(jit_float64))
+               {
+                       x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_nfloat));
+                       x86_fst80_membase(inst, X86_ESP, 0);
+               }
+               else
+               {
+                       x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64));
+                       x86_fst_membase(inst, X86_ESP, 0, 1, 1);
+               }
        }
 
-JIT_OP_PUSH_STRUCT:
-       [] -> {
+JIT_OP_PUSH_STRUCT: unary_note
+       [reg] -> {
                /* TODO */
        }
 
@@ -651,5 +847,67 @@ JIT_OP_POP_STACK:
 
 JIT_OP_FLUSH_SMALL_STRUCT:
        [] -> {
-               /* TODO */
+               jit_nuint size;
+               jit_nint offset;
+               _jit_gen_fix_value(insn->value1);
+               size = jit_type_get_size(jit_value_get_type(insn->value1));
+               offset = insn->value1->frame_offset;
+               switch(size)
+               {
+                       case 1:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 1);
+                       }
+                       break;
+
+                       case 2:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 2);
+                       }
+                       break;
+
+                       case 3:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 2);
+                               x86_shift_reg_imm(inst, X86_EAX, X86_SHR, 16);
+                               x86_mov_membase_reg(inst, X86_EBP, offset + 2, X86_EAX, 1);
+                       }
+                       break;
+
+                       case 4:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
+                       }
+                       break;
+
+                       case 5:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
+                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 1);
+                       }
+                       break;
+
+                       case 6:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
+                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 2);
+                       }
+                       break;
+
+                       case 7:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
+                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 2);
+                               x86_shift_reg_imm(inst, X86_EDX, X86_SHR, 16);
+                               x86_mov_membase_reg(inst, X86_EBP, offset + 6, X86_EDX, 1);
+                       }
+                       break;
+
+                       case 8:
+                       {
+                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
+                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 4);
+                       }
+                       break;
+               }
        }
index a8e30d461df2aff205007b4a9ac48fadf94dcb4c..368e102434e95dc1ebce9d7db278cf13526a7abc 100644 (file)
@@ -75,6 +75,7 @@ static int gensel_first_stack_reg = 8;        /* st0 under x86 */
 #define        GENSEL_OPT_STACK                                0x0010
 #define        GENSEL_OPT_UNARY_BRANCH                 0x0020
 #define        GENSEL_OPT_BINARY_BRANCH                0x0040
+#define        GENSEL_OPT_ONLY                                 0x0080
 
 /*
  * Pattern values.
@@ -512,6 +513,15 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options)
                }
                else
                {
+                       if((options & GENSEL_OPT_ONLY) != 0)
+                       {
+                               printf("\t\tif(!_jit_regs_is_top(gen, insn->value1) ||\n");
+                               printf("\t\t   _jit_regs_num_used(gen, %d) != 1)\n",
+                                          gensel_first_stack_reg);
+                               printf("\t\t{\n");
+                               printf("\t\t\t_jit_regs_spill_all(gen);\n");
+                               printf("\t\t}\n");
+                       }
                        if((options & GENSEL_OPT_TERNARY) != 0)
                        {
                                printf("\t\treg = _jit_regs_load_to_top_three\n");
@@ -525,7 +535,8 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options)
                                                                                           "%d);\n",
                                           gensel_first_stack_reg);
                        }
-                       else if((options & GENSEL_OPT_BINARY) != 0)
+                       else if((options & (GENSEL_OPT_BINARY |
+                                                               GENSEL_OPT_BINARY_BRANCH)) != 0)
                        {
                                printf("\t\treg = _jit_regs_load_to_top_two\n");
                                printf("\t\t\t(gen, insn->value1, insn->value2,\n");
@@ -536,7 +547,8 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options)
                                                                                           "%d);\n",
                                           gensel_first_stack_reg);
                        }
-                       else if((options & GENSEL_OPT_UNARY) != 0)
+                       else if((options & (GENSEL_OPT_UNARY |
+                                                               GENSEL_OPT_UNARY_BRANCH)) != 0)
                        {
                                printf("\t\treg = _jit_regs_load_to_top\n");
                                printf("\t\t\t(gen, insn->value1,\n");
@@ -643,6 +655,7 @@ static void gensel_output_supported(void)
 %token K_BINARY_BRANCH         "`binary_branch'"
 %token K_TERNARY                       "`ternary'"
 %token K_STACK                         "`stack'"
+%token K_ONLY                          "`only'"
 %token K_INST_TYPE                     "`%inst_type'"
 
 /*
@@ -719,6 +732,7 @@ Option
        | K_BINARY_BRANCH                       { $$ = GENSEL_OPT_BINARY_BRANCH; }
        | K_TERNARY                                     { $$ = GENSEL_OPT_TERNARY; }
        | K_STACK                                       { $$ = GENSEL_OPT_STACK; }
+       | K_ONLY                                        { $$ = GENSEL_OPT_ONLY; }
        ;
 
 Clauses
index 9cfa20fcab0226f4709aa7f24325fe154f6098a9..69a7df5003de4682a4b6a1a9fbcd78cdbd5f5797 100644 (file)
@@ -98,7 +98,10 @@ 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); }
 "stack"                                        { RETURNTOK(K_STACK); }
+"only"                                 { RETURNTOK(K_ONLY); }
 "%inst_type"                   { RETURNTOK(K_INST_TYPE); }
 
 {IDALPHA}({DIGIT}|{IDALPHA})*  {