Commit 6bb28287 authored by Matthias Braun's avatar Matthias Braun
Browse files

make opcode list global

The opcode list was a member of irprog before which wasn't really
handled consistently. Also make sure opcodes are properly freed at
ir_finish().
parent dc0ab1c4
...@@ -283,6 +283,20 @@ FIRM_API ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p, ...@@ -283,6 +283,20 @@ FIRM_API ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p,
unsigned flags, op_arity opar, int op_index, unsigned flags, op_arity opar, int op_index,
size_t attr_size, const ir_op_ops *ops); size_t attr_size, const ir_op_ops *ops);
/** Returns one more than the highest opcode code in use. */
FIRM_API unsigned ir_get_n_opcodes(void);
/**
* Returns the opcode with code @p code.
*
* @p code has to be smaller than get_irp_n_opcode(), returns NULL if
* no opcode with the code exists.
*/
FIRM_API ir_op *ir_get_opcode(unsigned code);
/** Sets the generic function pointer of all opcodes to NULL */
FIRM_API void ir_clear_opcodes_generic_func(void);
/** /**
* Sets memory input of operation using memory * Sets memory input of operation using memory
*/ */
......
...@@ -236,22 +236,6 @@ FIRM_API size_t get_irp_n_modes(void); ...@@ -236,22 +236,6 @@ FIRM_API size_t get_irp_n_modes(void);
/** Returns the mode at position pos in the irp. */ /** Returns the mode at position pos in the irp. */
FIRM_API ir_mode *get_irp_mode(size_t pos); FIRM_API ir_mode *get_irp_mode(size_t pos);
/** Adds opcode to the list of opcodes in irp. */
FIRM_API void add_irp_opcode(ir_op *opcode);
/** Removes opcode from the list of opcodes, deallocates it and
shrinks the list by one. */
FIRM_API void remove_irp_opcode(ir_op *opcode);
/** Returns the number of all opcodes in the irp. */
FIRM_API size_t get_irp_n_opcodes(void);
/** Returns the opcode at position pos in the irp. */
FIRM_API ir_op *get_irp_opcode(size_t pos);
/** Sets the generic function pointer of all opcodes to NULL */
FIRM_API void clear_irp_opcodes_generic_func(void);
/** Returns the graph for global constants of the current irp. /** Returns the graph for global constants of the current irp.
* *
* Returns an irgraph that only contains constant expressions for * Returns an irgraph that only contains constant expressions for
......
...@@ -175,7 +175,7 @@ static inline void set_emitter(ir_op *op, emit_func func) ...@@ -175,7 +175,7 @@ static inline void set_emitter(ir_op *op, emit_func func)
static void TEMPLATE_register_emitters(void) static void TEMPLATE_register_emitters(void)
{ {
/* first clear the generic function pointer for all ops */ /* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
/* register all emitter functions defined in spec */ /* register all emitter functions defined in spec */
TEMPLATE_register_spec_emitters(); TEMPLATE_register_spec_emitters();
......
...@@ -154,6 +154,11 @@ static void TEMPLATE_init(void) ...@@ -154,6 +154,11 @@ static void TEMPLATE_init(void)
TEMPLATE_create_opcodes(&TEMPLATE_irn_ops); TEMPLATE_create_opcodes(&TEMPLATE_irn_ops);
} }
static void TEMPLATE_finish(void)
{
TEMPLATE_free_opcodes();
}
static arch_env_t *TEMPLATE_begin_codegeneration(const be_main_env_t *env) static arch_env_t *TEMPLATE_begin_codegeneration(const be_main_env_t *env)
{ {
TEMPLATE_isa_t *isa = XMALLOC(TEMPLATE_isa_t); TEMPLATE_isa_t *isa = XMALLOC(TEMPLATE_isa_t);
...@@ -356,6 +361,7 @@ static int TEMPLATE_register_saved_by(const arch_register_t *reg, int callee) ...@@ -356,6 +361,7 @@ static int TEMPLATE_register_saved_by(const arch_register_t *reg, int callee)
const arch_isa_if_t TEMPLATE_isa_if = { const arch_isa_if_t TEMPLATE_isa_if = {
TEMPLATE_init, TEMPLATE_init,
TEMPLATE_finish,
TEMPLATE_get_backend_params, TEMPLATE_get_backend_params,
TEMPLATE_lower_for_target, TEMPLATE_lower_for_target,
TEMPLATE_parse_asm_constraint, TEMPLATE_parse_asm_constraint,
......
...@@ -486,7 +486,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node) ...@@ -486,7 +486,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node)
static void amd64_register_emitters(void) static void amd64_register_emitters(void)
{ {
/* first clear the generic function pointer for all ops */ /* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
/* register all emitter functions defined in spec */ /* register all emitter functions defined in spec */
amd64_register_spec_emitters(); amd64_register_spec_emitters();
......
...@@ -301,6 +301,11 @@ static void amd64_init(void) ...@@ -301,6 +301,11 @@ static void amd64_init(void)
amd64_create_opcodes(&amd64_irn_ops); amd64_create_opcodes(&amd64_irn_ops);
} }
static void amd64_finish(void)
{
amd64_free_opcodes();
}
static arch_env_t *amd64_begin_codegeneration(const be_main_env_t *env) static arch_env_t *amd64_begin_codegeneration(const be_main_env_t *env)
{ {
amd64_isa_t *isa = XMALLOC(amd64_isa_t); amd64_isa_t *isa = XMALLOC(amd64_isa_t);
...@@ -536,6 +541,7 @@ static int amd64_register_saved_by(const arch_register_t *reg, int callee) ...@@ -536,6 +541,7 @@ static int amd64_register_saved_by(const arch_register_t *reg, int callee)
const arch_isa_if_t amd64_isa_if = { const arch_isa_if_t amd64_isa_if = {
amd64_init, amd64_init,
amd64_finish,
amd64_get_backend_params, amd64_get_backend_params,
amd64_lower_for_target, amd64_lower_for_target,
amd64_parse_asm_constraint, amd64_parse_asm_constraint,
......
...@@ -794,7 +794,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node) ...@@ -794,7 +794,7 @@ static inline void set_emitter(ir_op *op, emit_func arm_emit_node)
static void arm_register_emitters(void) static void arm_register_emitters(void)
{ {
/* first clear the generic function pointer for all ops */ /* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
/* register all emitter functions defined in spec */ /* register all emitter functions defined in spec */
arm_register_spec_emitters(); arm_register_spec_emitters();
......
...@@ -267,7 +267,7 @@ static void register_peephole_optimisation(ir_op *op, peephole_opt_func func) ...@@ -267,7 +267,7 @@ static void register_peephole_optimisation(ir_op *op, peephole_opt_func func)
void arm_peephole_optimization(ir_graph *irg) void arm_peephole_optimization(ir_graph *irg)
{ {
/* register peephole optimizations */ /* register peephole optimizations */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
register_peephole_optimisation(op_arm_Str, peephole_arm_Str_Ldr); register_peephole_optimisation(op_arm_Str, peephole_arm_Str_Ldr);
register_peephole_optimisation(op_arm_Ldr, peephole_arm_Str_Ldr); register_peephole_optimisation(op_arm_Ldr, peephole_arm_Str_Ldr);
......
...@@ -433,6 +433,11 @@ static void arm_init(void) ...@@ -433,6 +433,11 @@ static void arm_init(void)
arm_create_opcodes(&arm_irn_ops); arm_create_opcodes(&arm_irn_ops);
} }
static void arm_finish(void)
{
arm_free_opcodes();
}
static arch_env_t *arm_begin_codegeneration(const be_main_env_t *env) static arch_env_t *arm_begin_codegeneration(const be_main_env_t *env)
{ {
arm_isa_t *isa = XMALLOC(arm_isa_t); arm_isa_t *isa = XMALLOC(arm_isa_t);
...@@ -564,6 +569,7 @@ static const lc_opt_table_entry_t arm_options[] = { ...@@ -564,6 +569,7 @@ static const lc_opt_table_entry_t arm_options[] = {
const arch_isa_if_t arm_isa_if = { const arch_isa_if_t arm_isa_if = {
arm_init, arm_init,
arm_finish,
arm_get_libfirm_params, arm_get_libfirm_params,
arm_lower_for_target, arm_lower_for_target,
arm_parse_asm_constraint, arm_parse_asm_constraint,
......
...@@ -437,6 +437,11 @@ struct arch_isa_if_t { ...@@ -437,6 +437,11 @@ struct arch_isa_if_t {
*/ */
void (*init)(void); void (*init)(void);
/**
* Fress resources allocated by this isa interface.
*/
void (*finish)(void);
/** /**
* Returns the frontend settings needed for this backend. * Returns the frontend settings needed for this backend.
*/ */
...@@ -547,7 +552,7 @@ struct arch_isa_if_t { ...@@ -547,7 +552,7 @@ struct arch_isa_if_t {
* Called directly before done is called. This should be the last place * Called directly before done is called. This should be the last place
* where the irg is modified. * where the irg is modified.
*/ */
void (*finish)(ir_graph *irg); void (*finish_graph)(ir_graph *irg);
/** /**
* Called after everything happened. This call should emit the final * Called after everything happened. This call should emit the final
......
...@@ -151,6 +151,15 @@ static void initialize_isa(void) ...@@ -151,6 +151,15 @@ static void initialize_isa(void)
if (isa_initialized) if (isa_initialized)
return; return;
isa_if->init(); isa_if->init();
isa_initialized = true;
}
static void finish_isa(void)
{
if (isa_initialized) {
isa_if->finish();
isa_initialized = false;
}
} }
void be_init_default_asm_constraint_flags(void) void be_init_default_asm_constraint_flags(void)
...@@ -341,6 +350,7 @@ void firm_be_init(void) ...@@ -341,6 +350,7 @@ void firm_be_init(void)
/* Finalize the Firm backend. */ /* Finalize the Firm backend. */
void firm_be_finish(void) void firm_be_finish(void)
{ {
finish_isa();
be_quit_modules(); be_quit_modules();
} }
...@@ -720,8 +730,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) ...@@ -720,8 +730,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
dump(DUMP_RA, irg, "ra"); dump(DUMP_RA, irg, "ra");
be_timer_push(T_FINISH); be_timer_push(T_FINISH);
if (arch_env->impl->finish != NULL) if (arch_env->impl->finish_graph != NULL)
arch_env->impl->finish(irg); arch_env->impl->finish_graph(irg);
be_timer_pop(T_FINISH); be_timer_pop(T_FINISH);
dump(DUMP_FINAL, irg, "finish"); dump(DUMP_FINAL, irg, "finish");
......
...@@ -1334,6 +1334,8 @@ void be_init_op(void) ...@@ -1334,6 +1334,8 @@ void be_init_op(void)
{ {
unsigned opc; unsigned opc;
assert(op_be_Spill == NULL);
/* Acquire all needed opcodes. */ /* Acquire all needed opcodes. */
op_be_Spill = new_ir_op(beo_Spill, "be_Spill", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops); op_be_Spill = new_ir_op(beo_Spill, "be_Spill", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
op_be_Reload = new_ir_op(beo_Reload, "be_Reload", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops); op_be_Reload = new_ir_op(beo_Reload, "be_Reload", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
...@@ -1369,10 +1371,28 @@ void be_init_op(void) ...@@ -1369,10 +1371,28 @@ void be_init_op(void)
/* attach out dummy_ops to middle end nodes */ /* attach out dummy_ops to middle end nodes */
for (opc = iro_First; opc <= iro_Last; ++opc) { for (opc = iro_First; opc <= iro_Last; ++opc) {
ir_op *op = get_irp_opcode(opc); ir_op *op = ir_get_opcode(opc);
assert(op->ops.be_ops == NULL); assert(op->ops.be_ops == NULL);
op->ops.be_ops = &dummy_be_irn_ops; op->ops.be_ops = &dummy_be_irn_ops;
} }
op_Phi->ops.be_ops = &phi_irn_ops; op_Phi->ops.be_ops = &phi_irn_ops;
} }
void be_finish_op(void)
{
free_ir_op(op_be_Spill); op_be_Spill = NULL;
free_ir_op(op_be_Reload); op_be_Reload = NULL;
free_ir_op(op_be_Perm); op_be_Perm = NULL;
free_ir_op(op_be_MemPerm); op_be_MemPerm = NULL;
free_ir_op(op_be_Copy); op_be_Copy = NULL;
free_ir_op(op_be_Keep); op_be_Keep = NULL;
free_ir_op(op_be_CopyKeep); op_be_CopyKeep = NULL;
free_ir_op(op_be_Call); op_be_Call = NULL;
free_ir_op(op_be_Return); op_be_Return = NULL;
free_ir_op(op_be_IncSP); op_be_IncSP = NULL;
free_ir_op(op_be_AddSP); op_be_AddSP = NULL;
free_ir_op(op_be_SubSP); op_be_SubSP = NULL;
free_ir_op(op_be_Start); op_be_Start = NULL;
free_ir_op(op_be_FrameAddr); op_be_FrameAddr = NULL;
}
...@@ -63,6 +63,8 @@ int is_be_node(const ir_node *irn); ...@@ -63,6 +63,8 @@ int is_be_node(const ir_node *irn);
*/ */
void be_init_op(void); void be_init_op(void);
void be_finish_op(void);
/** /**
* Position numbers for the be_Spill inputs. * Position numbers for the be_Spill inputs.
*/ */
......
...@@ -149,7 +149,7 @@ static ir_node *transform_end(ir_node *node) ...@@ -149,7 +149,7 @@ static ir_node *transform_end(ir_node *node)
void be_start_transform_setup(void) void be_start_transform_setup(void)
{ {
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
be_set_transform_function(op_Bad, be_duplicate_node); be_set_transform_function(op_Bad, be_duplicate_node);
be_set_transform_function(op_be_Copy, be_duplicate_node); be_set_transform_function(op_be_Copy, be_duplicate_node);
......
...@@ -1310,7 +1310,7 @@ static void introduce_prolog_epilog(ir_graph *irg) ...@@ -1310,7 +1310,7 @@ static void introduce_prolog_epilog(ir_graph *irg)
* virtual with real x87 instructions, creating a block schedule and peephole * virtual with real x87 instructions, creating a block schedule and peephole
* optimisations. * optimisations.
*/ */
static void ia32_finish(ir_graph *irg) static void ia32_finish_graph(ir_graph *irg)
{ {
ia32_irg_data_t *irg_data = ia32_get_irg_data(irg); ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg); be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg);
...@@ -1736,9 +1736,6 @@ static void ia32_init(void) ...@@ -1736,9 +1736,6 @@ static void ia32_init(void)
init_asm_constraints(); init_asm_constraints();
ia32_register_init();
ia32_create_opcodes(&ia32_irn_ops);
ia32_mode_fpcw = new_int_mode("Fpcw", irma_twos_complement, 16, 0, 0); ia32_mode_fpcw = new_int_mode("Fpcw", irma_twos_complement, 16, 0, 0);
/* note mantissa is 64bit but with explicitely encoded 1 so the really /* note mantissa is 64bit but with explicitely encoded 1 so the really
...@@ -1764,6 +1761,14 @@ static void ia32_init(void) ...@@ -1764,6 +1761,14 @@ static void ia32_init(void)
ia32_backend_params.mode_float_arithmetic = ia32_mode_E; ia32_backend_params.mode_float_arithmetic = ia32_mode_E;
ia32_backend_params.type_long_double = ia32_type_E; ia32_backend_params.type_long_double = ia32_type_E;
} }
ia32_register_init();
ia32_create_opcodes(&ia32_irn_ops);
}
static void ia32_finish(void)
{
ia32_free_opcodes();
} }
/** /**
...@@ -2042,8 +2047,6 @@ static void ia32_lower_for_target(void) ...@@ -2042,8 +2047,6 @@ static void ia32_lower_for_target(void)
&intrinsic_env, &intrinsic_env,
}; };
ia32_create_opcodes(&ia32_irn_ops);
/* lower compound param handling /* lower compound param handling
* Note: we lower compound arguments ourself, since on ia32 we don't * Note: we lower compound arguments ourself, since on ia32 we don't
* have hidden parameters but know where to find the structs on the stack. * have hidden parameters but know where to find the structs on the stack.
...@@ -2163,6 +2166,7 @@ static const lc_opt_table_entry_t ia32_options[] = { ...@@ -2163,6 +2166,7 @@ static const lc_opt_table_entry_t ia32_options[] = {
const arch_isa_if_t ia32_isa_if = { const arch_isa_if_t ia32_isa_if = {
ia32_init, ia32_init,
ia32_finish,
ia32_get_libfirm_params, ia32_get_libfirm_params,
ia32_lower_for_target, ia32_lower_for_target,
ia32_parse_asm_constraint, ia32_parse_asm_constraint,
...@@ -2182,7 +2186,7 @@ const arch_isa_if_t ia32_isa_if = { ...@@ -2182,7 +2186,7 @@ const arch_isa_if_t ia32_isa_if = {
ia32_before_abi, /* before abi introduce hook */ ia32_before_abi, /* before abi introduce hook */
ia32_prepare_graph, ia32_prepare_graph,
ia32_before_ra, /* before register allocation hook */ ia32_before_ra, /* before register allocation hook */
ia32_finish, /* called before codegen */ ia32_finish_graph, /* called before codegen */
ia32_emit, /* emit && done */ ia32_emit, /* emit && done */
}; };
......
...@@ -1560,7 +1560,7 @@ static void ia32_register_emitters(void) ...@@ -1560,7 +1560,7 @@ static void ia32_register_emitters(void)
#define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing #define BE_IGN(a) op_be_##a->ops.generic = (op_func)emit_Nothing
/* first clear the generic function pointer for all ops */ /* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
/* register all emitter functions defined in spec */ /* register all emitter functions defined in spec */
ia32_register_spec_emitters(); ia32_register_spec_emitters();
...@@ -3668,7 +3668,7 @@ static void register_emitter(ir_op *op, emit_func func) ...@@ -3668,7 +3668,7 @@ static void register_emitter(ir_op *op, emit_func func)
static void ia32_register_binary_emitters(void) static void ia32_register_binary_emitters(void)
{ {
/* first clear the generic function pointer for all ops */ /* first clear the generic function pointer for all ops */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
/* benode emitter */ /* benode emitter */
register_emitter(op_be_Copy, bemit_copy); register_emitter(op_be_Copy, bemit_copy);
......
...@@ -1278,7 +1278,7 @@ void ia32_peephole_optimization(ir_graph *irg) ...@@ -1278,7 +1278,7 @@ void ia32_peephole_optimization(ir_graph *irg)
*/ */
/* pass 1 */ /* pass 1 */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp); register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp);
register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp); register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp);
register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea); register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea);
...@@ -1291,7 +1291,7 @@ void ia32_peephole_optimization(ir_graph *irg) ...@@ -1291,7 +1291,7 @@ void ia32_peephole_optimization(ir_graph *irg)
be_peephole_opt(irg); be_peephole_opt(irg);
/* pass 2 */ /* pass 2 */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const); register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const);
register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test); register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test);
......
...@@ -2208,7 +2208,7 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg) ...@@ -2208,7 +2208,7 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg)
"x87 Simulator started for %+F\n", irg)); "x87 Simulator started for %+F\n", irg));
/* set the generic function pointer of instruction we must simulate */ /* set the generic function pointer of instruction we must simulate */
clear_irp_opcodes_generic_func(); ir_clear_opcodes_generic_func();
register_sim(op_ia32_Call, sim_Call); register_sim(op_ia32_Call, sim_Call);
register_sim(op_ia32_vfld, sim_fld); register_sim(op_ia32_vfld, sim_fld);
......
...@@ -116,6 +116,7 @@ my @obst_opvar; # stack for the "ir_op *op_<arch>_<op-name> = NULL;" state ...@@ -116,6 +116,7 @@ my @obst_opvar; # stack for the "ir_op *op_<arch>_<op-name> = NULL;" state
my @obst_get_opvar; # stack for the get_op_<arch>_<op-name>() functions my @obst_get_opvar; # stack for the get_op_<arch>_<op-name>() functions
my $obst_constructor; # stack for node constructor functions my $obst_constructor; # stack for node constructor functions
my @obst_new_irop; # stack for the new_ir_op calls my @obst_new_irop; # stack for the new_ir_op calls
my @obst_free_irop; # stack for free_ir_op calls
my @obst_enum_op; # stack for creating the <arch>_opcode enum my @obst_enum_op; # stack for creating the <arch>_opcode enum
my $obst_header; # stack for function prototypes my $obst_header; # stack for function prototypes
my @obst_is_archirn; # stack for the is_$arch_irn() function my @obst_is_archirn; # stack for the is_$arch_irn() function
...@@ -159,6 +160,7 @@ foreach my $class_name (keys(%reg_classes)) { ...@@ -159,6 +160,7 @@ foreach my $class_name (keys(%reg_classes)) {
$n_opcodes += $additional_opcodes if (defined($additional_opcodes)); $n_opcodes += $additional_opcodes if (defined($additional_opcodes));
$obst_header .= "void ${arch}_create_opcodes(const arch_irn_ops_t *be_ops);\n"; $obst_header .= "void ${arch}_create_opcodes(const arch_irn_ops_t *be_ops);\n";
$obst_header .= "void ${arch}_free_opcodes(void);\n";
sub create_constructor { sub create_constructor {
my $op = shift; my $op = shift;
...@@ -712,6 +714,8 @@ EOF ...@@ -712,6 +714,8 @@ EOF
push(@obst_new_irop, "\tset_op_attr(op_$op, attr);\n"); push(@obst_new_irop, "\tset_op_attr(op_$op, attr);\n");
} }
push(@obst_free_irop, "\tfree_ir_op(op_$op); op_$op = NULL;\n");
push(@obst_enum_op, "\tiro_$op,\n"); push(@obst_enum_op, "\tiro_$op,\n");
$obst_header .= "\n"; $obst_header .= "\n";
...@@ -817,10 +821,10 @@ $obst_constructor ...@@ -817,10 +821,10 @@ $obst_constructor
* Creates the $arch specific Firm machine operations * Creates the $arch specific Firm machine operations
* needed for the assembler irgs. * needed for the assembler irgs.
*/ */
void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) { void $arch\_create_opcodes(const arch_irn_ops_t *be_ops)
{
ir_op_ops ops; ir_op_ops ops;
int cur_opcode; int cur_opcode;
static int run_once = 0;
ENDOFMAIN ENDOFMAIN
if (defined($default_op_attr_type)) { if (defined($default_op_attr_type)) {
...@@ -829,10 +833,6 @@ ENDOFMAIN ...@@ -829,10 +833,6 @@ ENDOFMAIN
print OUT<<ENDOFMAIN; print OUT<<ENDOFMAIN;
if (run_once)
return;
run_once = 1;
cur_opcode = get_next_ir_opcodes(iro_$arch\_last); cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
$arch\_opcode_start = cur_opcode; $arch\_opcode_start = cur_opcode;
...@@ -848,7 +848,18 @@ print OUT "\t$arch\_register_additional_opcodes(cur_opcode);\n" if (defined($add ...@@ -848,7 +848,18 @@ print OUT "\t$arch\_register_additional_opcodes(cur_opcode);\n" if (defined($add
print OUT "\t$arch\_opcode_end = cur_opcode + iro_$arch\_last"; print OUT "\t$arch\_opcode_end = cur_opcode + iro_$arch\_last";
print OUT " + $additional_opcodes" if (defined($additional_opcodes)); print OUT " + $additional_opcodes" if (defined($additional_opcodes));
print OUT ";\n"; print OUT ";\n";
print OUT "}\n"; print OUT <<ENDOFMAIN;
}
void $arch\_free_opcodes(void)
{
ENDOFMAIN
print OUT @obst_free_irop;
print OUT <<ENDOFMAIN;
}
ENDOFMAIN
close(OUT); close(OUT);
......
...@@ -347,6 +347,11 @@ static void sparc_init(void) ...@@ -347,6 +347,11 @@ static void sparc_init(void)
sparc_cconv_init(); sparc_cconv_init();
} }