From 0eba5c97448ed4c54645a1f08e732eda125b2666 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Mon, 21 Jun 2004 02:09:44 +0000 Subject: [PATCH] Move the code for loading/storing small structures into a central location. --- ChangeLog | 5 + jit/jit-rules-x86.c | 303 ++++++++++++++++++++++++++++++++++++++---- jit/jit-rules-x86.sel | 164 +---------------------- 3 files changed, 285 insertions(+), 187 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9fb4eca..9b9cc5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ +2004-06-21 Rhys Weatherley + + * jit/jit-rules-x86.c, jit/jit-rules-x86.sel: move the code + for loading/storing small structures into a central location. + 2004-06-18 Rhys Weatherley * jit/jit-dump.c, jit/jit-reg-alloc.c, jit/jit-rules-arm.c, diff --git a/jit/jit-rules-x86.c b/jit/jit-rules-x86.c index 76c60e8..a814c66 100644 --- a/jit/jit-rules-x86.c +++ b/jit/jit-rules-x86.c @@ -400,6 +400,281 @@ void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func) #define jit_cache_end_output() \ gen->posn.ptr = inst +/* + * Get a temporary register that isn't one of the specified registers. + */ +static int get_temp_reg(int reg1, int reg2, int reg3) +{ + if(reg1 != X86_EAX && reg2 != X86_EAX && reg3 != X86_EAX) + { + return X86_EAX; + } + if(reg1 != X86_EDX && reg2 != X86_EDX && reg3 != X86_EDX) + { + return X86_EDX; + } + if(reg1 != X86_ECX && reg2 != X86_ECX && reg3 != X86_ECX) + { + return X86_ECX; + } + if(reg1 != X86_EBX && reg2 != X86_EBX && reg3 != X86_EBX) + { + return X86_EBX; + } + if(reg1 != X86_ESI && reg2 != X86_ESI && reg3 != X86_ESI) + { + return X86_ESI; + } + return X86_EDI; +} + +/* + * Load a small structure from a pointer into registers. + */ +static unsigned char *load_small_struct + (unsigned char *inst, int reg, int other_reg, + int base_reg, jit_nint offset, jit_nint size, int save_temp) +{ + int temp_reg; + switch(size) + { + case 1: + { + x86_widen_membase(inst, reg, base_reg, offset, 0, 0); + } + break; + + case 2: + { + x86_widen_membase(inst, reg, base_reg, offset, 0, 1); + } + break; + + case 3: + { + temp_reg = get_temp_reg(reg, -1, base_reg); + if(save_temp || temp_reg >= X86_EBX) + { + x86_push_reg(inst, temp_reg); + } + x86_widen_membase(inst, temp_reg, base_reg, offset, 0, 1); + x86_widen_membase(inst, reg, base_reg, offset + 2, 0, 0); + x86_shift_reg_imm(inst, X86_SHL, reg, 16); + x86_alu_reg_reg(inst, X86_OR, reg, temp_reg); + if(save_temp || temp_reg >= X86_EBX) + { + x86_pop_reg(inst, temp_reg); + } + } + break; + + case 4: + { + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + } + break; + + case 5: + { + if(reg != base_reg) + { + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 0); + } + else + { + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 0); + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + } + } + break; + + case 6: + { + if(reg != base_reg) + { + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1); + } + else + { + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1); + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + } + } + break; + + case 7: + { + temp_reg = get_temp_reg(reg, other_reg, base_reg); + if(save_temp || temp_reg >= X86_EBX) + { + x86_push_reg(inst, temp_reg); + } + if(reg != base_reg && other_reg != base_reg) + { + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1); + x86_widen_membase(inst, temp_reg, base_reg, offset + 6, 0, 0); + x86_shift_reg_imm(inst, X86_SHL, temp_reg, 16); + x86_alu_reg_reg(inst, X86_OR, other_reg, temp_reg); + } + else if(reg != base_reg) + { + /* other_reg == base_reg */ + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + x86_widen_membase(inst, temp_reg, base_reg, offset + 6, 0, 0); + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1); + x86_shift_reg_imm(inst, X86_SHL, temp_reg, 16); + x86_alu_reg_reg(inst, X86_OR, other_reg, temp_reg); + } + else + { + /* reg == base_reg */ + x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1); + x86_widen_membase(inst, temp_reg, base_reg, offset + 6, 0, 0); + x86_shift_reg_imm(inst, X86_SHL, temp_reg, 16); + x86_alu_reg_reg(inst, X86_OR, other_reg, temp_reg); + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + } + if(save_temp || temp_reg >= X86_EBX) + { + x86_pop_reg(inst, temp_reg); + } + } + break; + + case 8: + { + if(reg != base_reg) + { + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + x86_mov_reg_membase(inst, other_reg, base_reg, offset + 4, 4); + } + else + { + x86_mov_reg_membase(inst, other_reg, base_reg, offset + 4, 4); + x86_mov_reg_membase(inst, reg, base_reg, offset, 4); + } + } + break; + } + return inst; +} + +/* + * Store a byte value to a membase address. + */ +static unsigned char *mov_membase_reg_byte + (unsigned char *inst, int basereg, int offset, int srcreg) +{ + if(srcreg == X86_EAX || srcreg == X86_EBX || + srcreg == X86_ECX || srcreg == X86_EDX) + { + x86_mov_membase_reg(inst, basereg, offset, srcreg, 1); + } + else if(basereg != X86_EAX) + { + x86_push_reg(inst, X86_EAX); + x86_mov_reg_reg(inst, X86_EAX, srcreg, 4); + x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1); + x86_pop_reg(inst, X86_EAX); + } + else + { + x86_push_reg(inst, X86_EDX); + x86_mov_reg_reg(inst, X86_EDX, srcreg, 4); + x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1); + x86_pop_reg(inst, X86_EDX); + } + return inst; +} + +/* + * Store a small structure from registers to a pointer. The base + * register must not be either "reg" or "other_reg". + */ +static unsigned char *store_small_struct + (unsigned char *inst, int reg, int other_reg, + int base_reg, jit_nint offset, jit_nint size, int preserve) +{ + switch(size) + { + case 1: + { + inst = mov_membase_reg_byte(inst, base_reg, offset, reg); + } + break; + + case 2: + { + x86_mov_membase_reg(inst, base_reg, offset, reg, 2); + } + break; + + case 3: + { + if(preserve) + { + x86_push_reg(inst, reg); + } + x86_mov_membase_reg(inst, base_reg, offset, reg, 2); + x86_shift_reg_imm(inst, reg, X86_SHR, 16); + inst = mov_membase_reg_byte(inst, base_reg, offset + 2, reg); + if(preserve) + { + x86_pop_reg(inst, reg); + } + } + break; + + case 4: + { + x86_mov_membase_reg(inst, base_reg, offset, reg, 4); + } + break; + + case 5: + { + x86_mov_membase_reg(inst, base_reg, offset, reg, 4); + inst = mov_membase_reg_byte(inst, base_reg, offset + 4, other_reg); + } + break; + + case 6: + { + x86_mov_membase_reg(inst, base_reg, offset, reg, 4); + x86_mov_membase_reg(inst, base_reg, offset + 4, other_reg, 2); + } + break; + + case 7: + { + if(preserve) + { + x86_push_reg(inst, other_reg); + } + x86_mov_membase_reg(inst, base_reg, offset, reg, 4); + x86_mov_membase_reg(inst, base_reg, offset + 4, other_reg, 2); + x86_shift_reg_imm(inst, other_reg, X86_SHR, 16); + inst = mov_membase_reg_byte(inst, base_reg, offset + 6, other_reg); + if(preserve) + { + x86_pop_reg(inst, other_reg); + } + } + break; + + case 8: + { + x86_mov_membase_reg(inst, base_reg, offset, reg, 4); + x86_mov_membase_reg(inst, base_reg, offset + 4, other_reg, 4); + } + break; + } + return inst; +} + void _jit_gen_spill_reg(jit_gencode_t gen, int reg, int other_reg, jit_value_t value) { @@ -935,34 +1210,6 @@ static unsigned char *jump_to_epilog return inst; } -/* - * Store a byte value to a membase address. - */ -static unsigned char *mov_membase_reg_byte - (unsigned char *inst, int basereg, int offset, int srcreg) -{ - if(srcreg == X86_EAX || srcreg == X86_EBX || - srcreg == X86_ECX || srcreg == X86_EDX) - { - x86_mov_membase_reg(inst, basereg, offset, srcreg, 1); - } - else if(basereg != X86_EAX) - { - x86_push_reg(inst, X86_EAX); - x86_mov_reg_reg(inst, X86_EAX, srcreg, 4); - x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1); - x86_pop_reg(inst, X86_EAX); - } - else - { - x86_push_reg(inst, X86_EDX); - x86_mov_reg_reg(inst, X86_EDX, srcreg, 4); - x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1); - x86_pop_reg(inst, X86_EDX); - } - return inst; -} - /* * Store a byte value to a memindex address. */ diff --git a/jit/jit-rules-x86.sel b/jit/jit-rules-x86.sel index 225d0d6..734cf21 100644 --- a/jit/jit-rules-x86.sel +++ b/jit/jit-rules-x86.sel @@ -1706,107 +1706,9 @@ JIT_OP_RETURN_NFLOAT: unary_branch, stack, only JIT_OP_RETURN_SMALL_STRUCT: unary_branch [reg] -> { - int reg = $1; - switch(jit_value_get_nint_constant(insn->value2)) - { - case 1: - { - x86_widen_membase(inst, X86_EAX, reg, 0, 0, 0); - } - break; - - case 2: - { - x86_widen_membase(inst, X86_EAX, reg, 0, 0, 1); - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 2); - } - break; - - case 3: - { - if(reg != X86_EAX) - { - x86_widen_membase(inst, X86_EAX, reg, 0, 0, 1); - x86_widen_membase(inst, reg, reg, 2, 0, 0); - x86_shift_reg_imm(inst, X86_SHL, reg, 16); - x86_alu_reg_reg(inst, X86_OR, X86_EAX, reg); - } - else - { - x86_widen_membase(inst, X86_ECX, reg, 0, 0, 1); - x86_widen_membase(inst, X86_EAX, reg, 2, 0, 0); - x86_shift_reg_imm(inst, X86_SHL, X86_EAX, 16); - x86_alu_reg_reg(inst, X86_OR, X86_EAX, X86_ECX); - } - } - break; - - case 4: - { - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - } - break; - - case 5: - { - if(reg != X86_EAX) - { - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - x86_widen_membase(inst, X86_EDX, reg, 4, 0, 0); - } - else - { - x86_widen_membase(inst, X86_EDX, reg, 4, 0, 0); - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - } - } - break; - - case 6: - { - if(reg != X86_EAX) - { - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - x86_widen_membase(inst, X86_EDX, reg, 4, 0, 1); - } - else - { - x86_widen_membase(inst, X86_EDX, reg, 4, 0, 1); - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - } - } - break; - - case 7: - { - if(reg == X86_EAX || reg == X86_EDX) - { - x86_mov_reg_reg(inst, X86_ECX, reg, 4); - reg = X86_ECX; - } - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - x86_widen_membase(inst, X86_EDX, reg, 4, 0, 1); - x86_widen_membase(inst, X86_ECX, reg, 6, 0, 0); - x86_shift_reg_imm(inst, X86_SHL, X86_ECX, 16); - x86_alu_reg_reg(inst, X86_OR, X86_EAX, X86_ECX); - } - break; - - case 8: - { - if(reg != X86_EAX) - { - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - x86_mov_reg_membase(inst, X86_EDX, reg, 4, 4); - } - else - { - x86_mov_reg_membase(inst, X86_EDX, reg, 4, 4); - x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4); - } - } - break; - } + inst = load_small_struct + (inst, X86_EAX, X86_EDX, $1, 0, + jit_value_get_nint_constant(insn->value2), 0); inst = jump_to_epilog(gen, inst, block); } @@ -2256,64 +2158,8 @@ JIT_OP_FLUSH_SMALL_STRUCT: _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; - } + inst = store_small_struct + (inst, X86_EAX, X86_EDX, X86_EBP, offset, (jit_nint)size, 0); } /* -- 2.47.3