This fixes both IR generation and code generation for
DeferredVariableBinding stores. In order to optimize the code, it is necessary to add an argument to BEFORE_PUSH (which stores the stack top on the stack). For symmetry, I did the same for EXPORT_SP (which stores the stack top and additionally updates the "sp" global). Now, only the -static issue is to be fixed before releasing rc2. Paolo 2007-12-09 Paolo Bonzini <[hidden email]> * libgst/xlat.c: Fix DeferredVariableBinding stores. --- orig/libgst/xlat.c +++ mod/libgst/xlat.c @@ -249,7 +249,8 @@ typedef mst_Boolean (*decode_func) (gst_ #define TREE_BINARY_BOOL 00003 /* 2 skipped - reserved to LIT_CONST */ #define TREE_UNARY_SPECIAL 00004 #define TREE_UNARY_BOOL 00005 -#define TREE_DIRTY_BLOCK 00006 /* doesn't use tree->data! */ +#define TREE_STORE_LIT_VAR 00006 /* receiver in V1 */ +#define TREE_DIRTY_BLOCK 00007 /* doesn't use tree->data! */ /* stack suboperations value of tree->data */ #define TREE_REC_VAR 00000 /* variable number */ @@ -341,6 +342,7 @@ static void gen_send (code_tree *tree); static void gen_binary_int (code_tree *tree); static void gen_pop_into_array (code_tree *tree); static void gen_binary_bool (code_tree *tree); +static void gen_send_store_lit_var (code_tree *tree); static void gen_dirty_block (code_tree *tree); static void gen_unary_special (code_tree *tree); static void gen_unary_bool (code_tree *tree); @@ -375,7 +377,7 @@ static void gen_invalid (code_tree *tree /* Function table for the code generator */ static const emit_func emit_operation_funcs[96] = { gen_send, gen_binary_int, gen_invalid, gen_binary_bool, - gen_unary_special, gen_unary_bool, gen_dirty_block, gen_invalid, + gen_unary_special, gen_unary_bool, gen_send_store_lit_var, gen_dirty_block, gen_store_rec_var, gen_store_temp, gen_invalid, gen_store_lit_var, gen_invalid, gen_invalid, gen_store_outer, gen_pop_into_array, @@ -1052,10 +1054,10 @@ defer_send (code_tree *tree, mst_Boolean /* Common pieces of code for generating stack operations */ /* Save the old stack top if it was cached in V0 */ -#define BEFORE_PUSH do { \ +#define BEFORE_PUSH(reg) do { \ sp_delta += sizeof (PTR); \ if (sp_delta > 0) { \ - jit_stxi_p(sp_delta, JIT_V2, JIT_V0); \ + jit_stxi_p(sp_delta, JIT_V2, (reg)); \ } \ } while(0) @@ -1181,10 +1183,10 @@ defer_send (code_tree *tree, mst_Boolean /* Export V2 (the stack pointer) into the sp variable; the top of the * stack is assured to be in *sp, not in V0. */ -#define EXPORT_SP do { \ +#define EXPORT_SP(reg) do { \ if (sp_delta >= 0) { \ sp_delta += sizeof (PTR); \ - jit_stxi_p(sp_delta, JIT_V2, JIT_V0); \ + jit_stxi_p(sp_delta, JIT_V2, (reg)); \ jit_addi_p(JIT_V2, JIT_V2, sp_delta); \ jit_sti_p(&sp, JIT_V2); \ sp_delta = -sizeof (PTR); \ @@ -1197,7 +1199,7 @@ defer_send (code_tree *tree, mst_Boolean if (sp_delta < 0) { \ jit_ldr_p(JIT_V0, JIT_V2); \ } else { \ - EXPORT_SP; \ + EXPORT_SP (JIT_V0); \ } \ } while(0) @@ -1413,7 +1415,7 @@ gen_send (code_tree *tree) if (ic->is_super) KEEP_V0_EXPORT_SP; else - EXPORT_SP; + EXPORT_SP (JIT_V0); jit_movi_ul (JIT_R0, tree->bp - bc + BYTECODE_SIZE); jit_ldxi_p (JIT_R1, JIT_V1, jit_field (inline_cache, cachedIP)); @@ -1807,7 +1809,7 @@ gen_binary_int (code_tree *tree) break; } - EXPORT_SP; + EXPORT_SP (JIT_V0); if (overflow) finish_deferred_send (); } @@ -1869,12 +1871,31 @@ gen_binary_bool (code_tree *tree) #undef FALSE_BRANCH #undef FALSE_SET - EXPORT_SP; + EXPORT_SP (JIT_V0); if (deferredSend) finish_deferred_send (); } void +gen_send_store_lit_var (code_tree *tree) +{ + inline_cache *ic = (inline_cache *) tree->data; + label *overflow; + int reg0, reg1; + OOP oop; + intptr_t imm; + jit_insn *addr; + + /* tree->child = value + tree->child->next = var. */ + BEFORE_STORE; + emit_code_tree(tree->child->next); + BEFORE_PUSH (JIT_V1); + EXPORT_SP (JIT_V0); + gen_send (tree); +} + +void gen_dirty_block (code_tree *tree) { GET_UNARY_ARG; @@ -2117,7 +2138,7 @@ gen_store_outer (code_tree *tree) void gen_push_rec_var (code_tree *tree) { - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); CACHE_REC_VAR; jit_ldxi_p (JIT_V0, JIT_R1, REC_VAR_OFS (tree)); @@ -2127,7 +2148,7 @@ gen_push_rec_var (code_tree *tree) void gen_push_temp (code_tree *tree) { - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); CACHE_TEMP; jit_ldxi_p (JIT_V0, JIT_V1, TEMP_OFS (tree)); @@ -2137,7 +2158,7 @@ gen_push_temp (code_tree *tree) void gen_push_lit_const (code_tree *tree) { - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); jit_movi_p (JIT_V0, tree->data); self_cached = false; @@ -2147,7 +2168,7 @@ void gen_push_lit_var (code_tree *tree) { char *assocOOP = ((char *) tree->data) + jit_ptr_field (OOP, object); - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); jit_ldi_p (JIT_V0, assocOOP); jit_ldxi_p (JIT_V0, JIT_V0, jit_ptr_field (gst_association, value)); @@ -2160,13 +2181,13 @@ gen_dup_top (code_tree *tree) if (sp_delta < 0) jit_ldr_p (JIT_V0, JIT_V2); - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); } void gen_push_self (code_tree *tree) { - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); if (!self_cached) jit_ldi_p (JIT_V0, &_gst_self); @@ -2177,7 +2198,7 @@ gen_push_self (code_tree *tree) void gen_push_outer (code_tree *tree) { - BEFORE_PUSH; + BEFORE_PUSH (JIT_V0); CACHE_OUTER_CONTEXT; jit_ldxi_p (JIT_V0, JIT_V1, STACK_OFS (tree)); @@ -3388,16 +3409,16 @@ decode_bytecode (gst_uchar *bp) TREE_STORE | TREE_LIT_VAR, literals[n]); else { - code_tree *value = pop_tree_node (NULL); - code_tree *var = push_tree_node_oop (IP0, NULL, - TREE_PUSH | TREE_LIT_CONST, - literals[n]); + code_tree *value, *var; + push_tree_node_oop (IP0, NULL, + TREE_ALT_PUSH | TREE_LIT_CONST, literals[n]); inline_cache *ic = set_inline_cache (_gst_builtin_selectors[VALUE_COLON_SPECIAL].symbol, 1, false, TREE_SEND, 0); - var->next = value; - push_tree_node (IP0, var, TREE_SEND, (PTR) ic); + var = pop_tree_node (NULL); + value = pop_tree_node (var); + push_tree_node (IP0, value, TREE_SEND | TREE_STORE_LIT_VAR, (PTR) ic); } } _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |