]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Introduce conditional rules into "gen-sel" so that we can disable
authorRhys Weatherley <rweather@southern-storm.com.au>
Tue, 8 Jun 2004 05:33:37 +0000 (05:33 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Tue, 8 Jun 2004 05:33:37 +0000 (05:33 +0000)
certain rules on ARM platforms that lack floating-point support.

ChangeLog
jit/jit-rules-arm.sel
tools/gen-sel-parser.y
tools/gen-sel-scanner.l

index 87b755a582e126b439a13aa02149223a9fc827a1..b1221705a0de886bb9d675116cfb7ede0dae37d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * jit/jit-gen-arm.h (arm_call): use a more efficient form of
        call for offsets beyond the simple target range.
 
+       * jit/jit-rules-arm.sel, tools/gen-sel-parser.y,
+       tools/gen-sel-scanner.l: introduce conditional rules into "gen-sel"
+       so that we can disable certain rules on ARM platforms that lack
+       floating-point support.
+
 2004-06-08  Miroslaw Dobrzanski-Neumann  <mne@mosaic-ag.com>
 
        * jit/jit-alloc.c: fix ROUND_END_PTR so that it adds the size
index 046359d980a2b9e312b75509bd68a5b2bfcf772f..810cf08dcb2b7ad2a54bb5661927bf42586b787b 100644 (file)
@@ -149,77 +149,52 @@ JIT_OP_INEG: unary
                arm_alu_reg_imm8(inst, ARM_RSB, $1, $1, 0);
        }
 
-JIT_OP_FADD: binary
+JIT_OP_FADD (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg_32(inst, ARM_ADF, $1, $1, $2);
        }
 
-JIT_OP_FSUB: binary
+JIT_OP_FSUB (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg_32(inst, ARM_SUF, $1, $1, $2);
        }
 
-JIT_OP_FMUL: binary
+JIT_OP_FMUL (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg_32(inst, ARM_MUF, $1, $1, $2);
        }
 
-JIT_OP_FDIV: binary
+JIT_OP_FDIV (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg_32(inst, ARM_DVF, $1, $1, $2);
        }
 
-JIT_OP_FNEG: unary
+JIT_OP_FNEG (JIT_ARM_HAS_FLOAT_REGS): unary
        [freg] -> {
                arm_alu_freg_32(inst, ARM_MNF, $1, $1);
        }
 
-JIT_OP_DADD: binary
+JIT_OP_DADD, JIT_OP_NFADD (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg(inst, ARM_ADF, $1, $1, $2);
        }
 
-JIT_OP_DSUB: binary
+JIT_OP_DSUB, JIT_OP_NFSUB (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg(inst, ARM_SUF, $1, $1, $2);
        }
 
-JIT_OP_DMUL: binary
+JIT_OP_DMUL, JIT_OP_NFMUL (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg(inst, ARM_MUF, $1, $1, $2);
        }
 
-JIT_OP_DDIV: binary
+JIT_OP_DDIV, JIT_OP_NFDIV (JIT_ARM_HAS_FLOAT_REGS): binary
        [freg, freg] -> {
                arm_alu_freg_freg(inst, ARM_DVF, $1, $1, $2);
        }
 
-JIT_OP_DNEG: unary
-       [freg] -> {
-               arm_alu_freg(inst, ARM_MNF, $1, $1);
-       }
-
-JIT_OP_NFADD: binary
-       [freg, freg] -> {
-               arm_alu_freg_freg(inst, ARM_ADF, $1, $1, $2);
-       }
-
-JIT_OP_NFSUB: binary
-       [freg, freg] -> {
-               arm_alu_freg_freg(inst, ARM_SUF, $1, $1, $2);
-       }
-
-JIT_OP_NFMUL: binary
-       [freg, freg] -> {
-               arm_alu_freg_freg(inst, ARM_MUF, $1, $1, $2);
-       }
-
-JIT_OP_NFDIV: binary
-       [freg, freg] -> {
-               arm_alu_freg_freg(inst, ARM_DVF, $1, $1, $2);
-       }
-
-JIT_OP_NFNEG: unary
+JIT_OP_DNEG, JIT_OP_NFNEG (JIT_ARM_HAS_FLOAT_REGS): unary
        [freg] -> {
                arm_alu_freg(inst, ARM_MNF, $1, $1);
        }
@@ -637,34 +612,142 @@ JIT_OP_RETURN_LONG: spill_before
                inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_FLOAT32: unary_note
+JIT_OP_RETURN_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_branch
        [freg] -> {
                if($1 != 0)
                {
                        arm_alu_freg_32(inst, ARM_MVF, ARM_F0, $1);
                }
+               inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_FLOAT64: unary_note
-       [freg] -> {
-               if($1 != 0)
+JIT_OP_RETURN_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
+       [] -> {
+               arm_inst_ptr inst;
+               _jit_regs_spill_all(gen);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
                {
-                       arm_alu_freg(inst, ARM_MVF, ARM_F0, $1);
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_R0, ((int *)(insn->value1->address))[0]);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_R0, ARM_FP, insn->value1->frame_offset);
                }
+               inst = jump_to_epilog(gen, inst, block);
+               gen->posn.ptr = (unsigned char *)inst;
        }
 
-JIT_OP_RETURN_NFLOAT: unary_note
+JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT
+               (JIT_ARM_HAS_FLOAT_REGS): unary_branch
        [freg] -> {
                if($1 != 0)
                {
                        arm_alu_freg(inst, ARM_MVF, ARM_F0, $1);
                }
+               inst = jump_to_epilog(gen, inst, block);
        }
 
-JIT_OP_RETURN_SMALL_STRUCT: spill_before
+JIT_OP_RETURN_FLOAT64, JIT_OP_RETURN_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
        [] -> {
-               /* TODO: load the structure value into r0:r1 */
-               TODO();
+               arm_inst_ptr inst;
+               _jit_regs_spill_all(gen);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_R0, ((int *)(insn->value1->address))[0]);
+                       arm_mov_reg_imm(inst, ARM_R1, ((int *)(insn->value1->address))[1]);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_R0, ARM_FP, insn->value1->frame_offset);
+                       arm_load_membase(inst, ARM_R1, ARM_FP,
+                                                        insn->value1->frame_offset + 4);
+               }
+               inst = jump_to_epilog(gen, inst, block);
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
+JIT_OP_RETURN_SMALL_STRUCT: unary_branch
+       [reg] -> {
+               int temp_reg = $1;
+               if(temp_reg < 3)
+               {
+                       arm_mov_reg_reg(inst, ARM_WORK, temp_reg);
+                       temp_reg = ARM_WORK;
+               }
+               switch(insn->value2->address)
+               {
+                       case 1:
+                       {
+                               arm_load_membase_byte(inst, ARM_R0, temp_reg, 0);
+                       }
+                       break;
+
+                       case 2:
+                       {
+                               arm_load_membase_ushort(inst, ARM_R0, temp_reg, 0);
+                       }
+                       break;
+
+                       case 3:
+                       {
+                               arm_load_membase_ushort(inst, ARM_R0, temp_reg, 0);
+                               arm_load_membase_byte(inst, ARM_R1, temp_reg, 2);
+                               arm_shift_reg_imm8(inst, ARM_SHL, ARM_R1, ARM_R1, 16);
+                               arm_alu_reg_reg(inst, ARM_ORR, ARM_R0, ARM_R0, ARM_R1);
+                       }
+                       break;
+
+                       case 4:
+                       {
+                               arm_load_membase(inst, ARM_R0, temp_reg, 0);
+                       }
+                       break;
+
+                       case 5:
+                       {
+                               arm_load_membase(inst, ARM_R0, temp_reg, 0);
+                               arm_load_membase_byte(inst, ARM_R1, temp_reg, 4);
+                       }
+                       break;
+
+                       case 6:
+                       {
+                               arm_load_membase(inst, ARM_R0, temp_reg, 0);
+                               arm_load_membase_ushort(inst, ARM_R1, temp_reg, 4);
+                       }
+                       break;
+
+                       case 7:
+                       {
+                               arm_load_membase(inst, ARM_R0, temp_reg, 0);
+                               arm_load_membase_ushort(inst, ARM_R1, temp_reg, 4);
+                               arm_load_membase_byte(inst, ARM_R2, temp_reg, 6);
+                               arm_shift_reg_imm8(inst, ARM_SHL, ARM_R2, ARM_R2, 16);
+                               arm_alu_reg_reg(inst, ARM_ORR, ARM_R1, ARM_R1, ARM_R2);
+                       }
+                       break;
+
+                       case 8:
+                       {
+                               arm_load_membase(inst, ARM_R0, temp_reg, 0);
+                               arm_load_membase(inst, ARM_R1, temp_reg, 4);
+                       }
+                       break;
+               }
                inst = jump_to_epilog(gen, inst, block);
        }
 
@@ -738,21 +821,115 @@ JIT_OP_COPY_LOAD_USHORT: unary
 JIT_OP_COPY_INT: unary
        [reg] -> {}
 
-JIT_OP_COPY_LONG: spill_before
+JIT_OP_COPY_LONG: manual
        [] -> {
-               /* TODO */
-               TODO();
+               arm_inst_ptr inst;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_regs_force_out(gen, insn->dest, 1);
+               _jit_gen_fix_value(insn->value1);
+               _jit_gen_fix_value(insn->dest);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[0]);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset);
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[1]);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset + 4);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset);
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset + 4);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset + 4);
+               }
+               gen->posn.ptr = (unsigned char *)inst;
        }
 
-JIT_OP_COPY_FLOAT32: unary
+JIT_OP_COPY_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary
        [freg] -> {}
 
-JIT_OP_COPY_FLOAT64: unary
-       [freg] -> {}
+JIT_OP_COPY_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
+       [] -> {
+               arm_inst_ptr inst;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_regs_force_out(gen, insn->dest, 1);
+               _jit_gen_fix_value(insn->value1);
+               _jit_gen_fix_value(insn->dest);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[0]);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset);
+               }
+               arm_store_membase(inst, ARM_WORK, ARM_FP, insn->dest->frame_offset);
+               gen->posn.ptr = (unsigned char *)inst;
+       }
 
-JIT_OP_COPY_NFLOAT: unary
+JIT_OP_COPY_FLOAT64, JIT_OP_COPY_NFLOAT (JIT_ARM_HAS_FLOAT_REGS): unary
        [freg] -> {}
 
+JIT_OP_COPY_FLOAT64, JIT_OP_COPY_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
+       [] -> {
+               arm_inst_ptr inst;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_regs_force_out(gen, insn->dest, 1);
+               _jit_gen_fix_value(insn->value1);
+               _jit_gen_fix_value(insn->dest);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[0]);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset);
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[1]);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset + 4);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset);
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset + 4);
+                       arm_store_membase(inst, ARM_WORK, ARM_FP,
+                                                         insn->dest->frame_offset + 4);
+               }
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
 JIT_OP_COPY_STRUCT: manual
        [] -> {
                /* TODO */
@@ -846,25 +1023,103 @@ JIT_OP_PUSH_INT: unary_note
 
 JIT_OP_PUSH_LONG: manual
        [] -> {
-               /* TODO */
-               TODO();
+               arm_inst_ptr inst;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[1]);
+                       arm_push_reg(inst, ARM_WORK);
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[0]);
+                       arm_push_reg(inst, ARM_WORK);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset + 4);
+                       arm_push_reg(inst, ARM_WORK);
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset);
+                       arm_push_reg(inst, ARM_WORK);
+               }
+               gen->posn.ptr = (unsigned char *)inst;
        }
 
-JIT_OP_PUSH_FLOAT32: unary_note
+JIT_OP_PUSH_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_note
        [freg] -> {
                arm_push_reg_float32(inst, $1);
        }
 
-JIT_OP_PUSH_FLOAT64: unary_note
-       [freg] -> {
-               arm_push_reg_float64(inst, $1);
+JIT_OP_PUSH_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual
+       [] -> {
+               arm_inst_ptr inst;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[0]);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset);
+               }
+               arm_push_reg(inst, ARM_WORK);
+               gen->posn.ptr = (unsigned char *)inst;
        }
 
-JIT_OP_PUSH_NFLOAT: unary_note
+JIT_OP_PUSH_FLOAT64, JIT_OP_PUSH_NFLOAT (JIT_ARM_HAS_FLOAT_REGS): unary_note
        [freg] -> {
                arm_push_reg_float64(inst, $1);
        }
 
+JIT_OP_PUSH_FLOAT64, JIT_OP_PUSH_NFLOAT (!JIT_ARM_HAS_FLOAT_REGS): manual
+       [] -> {
+               arm_inst_ptr inst;
+               _jit_regs_force_out(gen, insn->value1, 0);
+               _jit_gen_fix_value(insn->value1);
+               inst = (arm_inst_ptr)(gen->posn.ptr);
+               if(!jit_cache_check_for_n(&(gen->posn), 32))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+               if(insn->value1->is_constant)
+               {
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[1]);
+                       arm_push_reg(inst, ARM_WORK);
+                       arm_mov_reg_imm(inst, ARM_WORK,
+                                                       ((int *)(insn->value1->address))[0]);
+                       arm_push_reg(inst, ARM_WORK);
+               }
+               else
+               {
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset + 4);
+                       arm_push_reg(inst, ARM_WORK);
+                       arm_load_membase(inst, ARM_WORK, ARM_FP,
+                                                        insn->value1->frame_offset);
+                       arm_push_reg(inst, ARM_WORK);
+               }
+               gen->posn.ptr = (unsigned char *)inst;
+       }
+
 JIT_OP_PUSH_STRUCT: unary_note
        [reg] -> {
                /* TODO */
@@ -1009,13 +1264,7 @@ JIT_OP_LOAD_RELATIVE_FLOAT32: manual
                TODO();
        }
 
-JIT_OP_LOAD_RELATIVE_FLOAT64: manual
-       [] -> {
-               /* TODO */
-               TODO();
-       }
-
-JIT_OP_LOAD_RELATIVE_NFLOAT: manual
+JIT_OP_LOAD_RELATIVE_FLOAT64, JIT_OP_LOAD_RELATIVE_NFLOAT: manual
        [] -> {
                /* TODO */
                TODO();
@@ -1131,13 +1380,7 @@ JIT_OP_STORE_RELATIVE_FLOAT32: manual
                TODO();
        }
 
-JIT_OP_STORE_RELATIVE_FLOAT64: manual
-       [] -> {
-               /* TODO */
-               TODO();
-       }
-
-JIT_OP_STORE_RELATIVE_NFLOAT: manual
+JIT_OP_STORE_RELATIVE_FLOAT64, JIT_OP_STORE_RELATIVE_NFLOAT: manual
        [] -> {
                /* TODO */
                TODO();
index dd6e2c1954067e4dc6a162d4fd96d1075b19720b..dfc2e999088c7bd5e1870e3981adb6ed6343063a 100644 (file)
 
 #include <config.h>
 #include <stdio.h>
+#ifdef HAVE_STRING_H
+       #include <string.h>
+#elif defined(HAVE_STRINGS_H)
+       #include <strings.h>
+#endif
 #ifdef HAVE_STDLIB_H
        #include <stdlib.h>
 #endif
@@ -601,12 +606,13 @@ static void gensel_output_clauses(gensel_clause_t clauses, int options)
  * List of opcodes that are supported by the input rules.
  */
 static char **supported = 0;
+static char **supported_options = 0;
 static int num_supported = 0;
 
 /*
  * Add an opcode to the supported list.
  */
-static void gensel_add_supported(char *name)
+static void gensel_add_supported(char *name, char *option)
 {
        supported = (char **)realloc
                (supported, (num_supported + 1) * sizeof(char *));
@@ -614,7 +620,14 @@ static void gensel_add_supported(char *name)
        {
                exit(1);
        }
-       supported[num_supported++] = name;
+       supported[num_supported] = name;
+       supported_options = (char **)realloc
+               (supported_options, (num_supported + 1) * sizeof(char *));
+       if(!supported_options)
+       {
+               exit(1);
+       }
+       supported_options[num_supported++] = option;
 }
 
 /*
@@ -625,7 +638,23 @@ static void gensel_output_supported(void)
        int index;
        for(index = 0; index < num_supported; ++index)
        {
-               printf("case %s:\n", supported[index]);
+               if(supported_options[index])
+               {
+                       if(supported_options[index][0] == '!')
+                       {
+                               printf("#ifndef %s\n", supported_options[index] + 1);
+                       }
+                       else
+                       {
+                               printf("#ifdef %s\n", supported_options[index]);
+                       }
+                       printf("case %s:\n", supported[index]);
+                       printf("#endif\n");
+               }
+               else
+               {
+                       printf("case %s:\n", supported[index]);
+               }
        }
        printf("\treturn 1;\n\n");
 }
@@ -691,7 +720,7 @@ static void gensel_output_supported(void)
 /*
  * Define the yylval types of the various non-terminals.
  */
-%type <name>                           IDENTIFIER
+%type <name>                           IDENTIFIER IfClause IdentifierList
 %type <code>                           CODE_BLOCK
 %type <options>                                Options OptionList Option PatternElement
 %type <clauses>                                Clauses Clause
@@ -713,19 +742,30 @@ Rules
        ;
 
 Rule
-       : IDENTIFIER ':' Options Clauses {
+       : IdentifierList IfClause ':' Options Clauses {
+                               if($2)
+                               {
+                                       if(($2)[0] == '!')
+                                       {
+                                               printf("#ifndef %s\n\n", $2 + 1);
+                                       }
+                                       else
+                                       {
+                                               printf("#ifdef %s\n\n", $2);
+                                       }
+                               }
                                printf("case %s:\n{\n", $1);
-                               if(($3 & GENSEL_OPT_MANUAL) == 0)
+                               if(($4 & GENSEL_OPT_MANUAL) == 0)
                                {
                                        printf("\t%s inst;\n", gensel_inst_type);
                                }
-                               gensel_declare_regs($4.head, $3);
-                               if(($3 & GENSEL_OPT_SPILL_BEFORE) != 0)
+                               gensel_declare_regs($5.head, $4);
+                               if(($4 & GENSEL_OPT_SPILL_BEFORE) != 0)
                                {
                                        printf("\t_jit_regs_spill_all(gen);\n");
                                }
-                               gensel_output_clauses($4.head, $3);
-                               if(($3 & (GENSEL_OPT_BINARY | GENSEL_OPT_UNARY)) != 0)
+                               gensel_output_clauses($5.head, $4);
+                               if(($4 & (GENSEL_OPT_BINARY | GENSEL_OPT_UNARY)) != 0)
                                {
                                        printf("\tif((insn->flags & JIT_INSN_DEST_NEXT_USE) != 0)\n");
                                        printf("\t{\n");
@@ -742,14 +782,39 @@ Rule
                                        printf("\t}\n");
                                }
                                printf("}\nbreak;\n\n");
-                               gensel_free_clauses($4.head);
-                               gensel_add_supported($1);
+                               if($2)
+                               {
+                                       printf("#endif /* %s */\n\n", $2);
+                               }
+                               gensel_free_clauses($5.head);
+                               gensel_add_supported($1, $2);
                        }
        | K_INST_TYPE IDENTIFIER        {
                                gensel_inst_type = $2;
                        }
        ;
 
+IdentifierList
+       : IDENTIFIER                            { $$ = $1; }
+       | IdentifierList ',' IDENTIFIER {
+                               char *result = (char *)malloc(strlen($1) + strlen($3) + 16);
+                               if(!result)
+                               {
+                                       exit(1);
+                               }
+                               strcpy(result, $1);
+                               strcat(result, ":\ncase ");
+                               strcat(result, $3);
+                               free($1);
+                               free($3);
+                               $$ = result;
+                       }
+
+IfClause
+       : /* empty */                           { $$ = 0; }
+       | '(' IDENTIFIER ')'            { $$ = $2; }
+       ;
+
 Options
        : /* empty */                           { $$ = 0; }
        | OptionList                            { $$ = $1; }
index 374a533f4282fe491964e8271fcfdc000410709f..2aa44ee45b04886bfb03edd06323ad5541871237 100644 (file)
@@ -106,7 +106,7 @@ WHITE                                       [ \t\v\r\f]
 "more_space"                   { RETURNTOK(K_MORE_SPACE); }
 "%inst_type"                   { RETURNTOK(K_INST_TYPE); }
 
-{IDALPHA}({DIGIT}|{IDALPHA})*  {
+"!"?{IDALPHA}({DIGIT}|{IDALPHA})*      {
                        yylval.name = gensel_strdup(yytext);
                        if(!(yylval.name))
                        {