X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Farm%2Farm_spec.pl;h=10d956d183af95ebd0b3d0c35ffa18c8f6621250;hb=ede86ffb1270f07437edcc8ea3dd5d46530f93eb;hp=659c86f3f40b6ea6665414c40fea8b22b079a45f;hpb=bc9cdc9fc86b6886fe5004374bfaa37b2c382a49;p=libfirm diff --git a/ir/be/arm/arm_spec.pl b/ir/be/arm/arm_spec.pl index 659c86f3f..10d956d18 100644 --- a/ir/be/arm/arm_spec.pl +++ b/ir/be/arm/arm_spec.pl @@ -99,6 +99,12 @@ $new_emit_syntax = 1; # latency: the latency of the operation, default is 1 # +# +# Modes +# +$mode_gp = "mode_Iu"; +$mode_fpa = "mode_E"; + # register types: # 0 - no special type # 1 - caller save (register must be saved by the caller of a function) @@ -109,51 +115,53 @@ $new_emit_syntax = 1; # 32 - register represents a state # NOTE: Last entry of each class is the largest Firm-Mode a register can hold %reg_classes = ( - gp => [ - { "name" => "r0", "type" => 1 }, - { "name" => "r1", "type" => 1 }, - { "name" => "r2", "type" => 1 }, - { "name" => "r3", "type" => 1 }, - { "name" => "r4", "type" => 2 }, - { "name" => "r5", "type" => 2 }, - { "name" => "r6", "type" => 2 }, - { "name" => "r7", "type" => 2 }, - { "name" => "r8", "type" => 2 }, - { "name" => "r9", "type" => 2 }, - { "name" => "r10", "type" => 2 }, - { "name" => "r11", "type" => 2 }, - { "name" => "r12", "type" => 6 }, # reserved for linker - { "name" => "sp", "type" => 6 }, # this is our stack pointer - { "name" => "lr", "type" => 3 }, # this is our return address - { "name" => "pc", "type" => 6 }, # this is our program counter - { "mode" => "mode_Iu" } - ], - fpa => [ - { "name" => "f0", "type" => 1 }, - { "name" => "f1", "type" => 1 }, - { "name" => "f2", "type" => 1 }, - { "name" => "f3", "type" => 1 }, - { "name" => "f4", "type" => 1 }, - { "name" => "f5", "type" => 1 }, - { "name" => "f6", "type" => 1 }, - { "name" => "f7", "type" => 1 }, - { "mode" => "mode_E" } - ] + gp => [ + { "name" => "r0", "type" => 1 }, + { "name" => "r1", "type" => 1 }, + { "name" => "r2", "type" => 1 }, + { "name" => "r3", "type" => 1 }, + { "name" => "r4", "type" => 2 }, + { "name" => "r5", "type" => 2 }, + { "name" => "r6", "type" => 2 }, + { "name" => "r7", "type" => 2 }, + { "name" => "r8", "type" => 2 }, + { "name" => "r9", "type" => 2 }, + { "name" => "r10", "type" => 2 }, + { "name" => "r11", "type" => 2 }, + { "name" => "r12", "type" => 4 | 2 }, # reserved for linker + { "name" => "sp", "type" => 4 | 2 }, # this is our stack pointer + { "name" => "lr", "type" => 2 | 1 }, # this is our return address + { "name" => "pc", "type" => 4 | 2 }, # this is our program counter + { name => "gp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes + { "mode" => $mode_gp } + ], + fpa => [ + { "name" => "f0", "type" => 1 }, + { "name" => "f1", "type" => 1 }, + { "name" => "f2", "type" => 1 }, + { "name" => "f3", "type" => 1 }, + { "name" => "f4", "type" => 1 }, + { "name" => "f5", "type" => 1 }, + { "name" => "f6", "type" => 1 }, + { "name" => "f7", "type" => 1 }, + { name => "fpa_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes + { "mode" => $mode_fpa } + ] ); # %reg_classes %emit_templates = ( - M => "${arch}_emit_mode(env, node);", - X => "${arch}_emit_shift(env, node);", - S0 => "${arch}_emit_source_register(env, node, 0);", - S1 => "${arch}_emit_source_register(env, node, 1);", - S2 => "${arch}_emit_source_register(env, node, 2);", - S3 => "${arch}_emit_source_register(env, node, 3);", - S4 => "${arch}_emit_source_register(env, node, 4);", - D0 => "${arch}_emit_dest_register(env, node, 0);", - D1 => "${arch}_emit_dest_register(env, node, 1);", - D2 => "${arch}_emit_dest_register(env, node, 2);", - C => "${arch}_emit_immediate(env, node);", - O => "${arch}_emit_offset(env, mode);", + M => "${arch}_emit_mode(node);", + X => "${arch}_emit_shift(node);", + S0 => "${arch}_emit_source_register(node, 0);", + S1 => "${arch}_emit_source_register(node, 1);", + S2 => "${arch}_emit_source_register(node, 2);", + S3 => "${arch}_emit_source_register(node, 3);", + S4 => "${arch}_emit_source_register(node, 4);", + D0 => "${arch}_emit_dest_register(node, 0);", + D1 => "${arch}_emit_dest_register(node, 1);", + D2 => "${arch}_emit_dest_register(node, 2);", + C => "${arch}_emit_immediate(node);", + O => "${arch}_emit_offset(mode);", ); #--------------------------------------------------# @@ -168,12 +176,14 @@ $new_emit_syntax = 1; #--------------------------------------------------# $default_attr_type = "arm_attr_t"; +$default_copy_attr = "arm_copy_attr"; %init_attr = ( - arm_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", - arm_SymConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", - arm_CondJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", - arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);", + arm_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", + arm_SymConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", + arm_CondJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", + arm_SwitchJmp_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", + arm_fpaConst_attr_t => "\tinit_arm_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res);", ); %compare_attr = ( @@ -181,10 +191,58 @@ $default_attr_type = "arm_attr_t"; arm_SymConst_attr_t => "cmp_attr_arm_SymConst", arm_CondJmp_attr_t => "cmp_attr_arm_CondJmp", arm_SwitchJmp_attr_t => "cmp_attr_arm_SwitchJmp", + arm_fpaConst_attr_t => "cmp_attr_arm_fpaConst", ); +#%operands = ( +# +#Immediate => { +# comment => "blup di dup", +# irn_flags => "R", +# emit => ". [%S0]-10", +# reg_req => { }, +# attr => "tarval *tv", +# init_attr => "(void) attri;", +# # op_flags => O +# # cmp => "return 1;" +#}, +# +#ShfOp_I => { +# irn_flags => "R", +# emit => ". ...", +# reg_req => { in => [ "gp" ] }, +# attr => "tarval *tv", +# init_attr => "(void) tv;", +#}, +# +#ShfOp => { +# irn_flags => "R", +# emit => ". ...", +# reg_req => { in => [ "gp", "gp" ] }, +#}, +# +#); + %nodes = ( +Unknown_GP => { + state => "pinned", + op_flags => "c", + irn_flags => "I", + reg_req => { out => [ "gp_UKNWN" ] }, + emit => "", + mode => $mode_gp, +}, + +Unknown_FPA => { + state => "pinned", + op_flags => "c", + irn_flags => "I", + reg_req => { out => [ "fpa_UKNWN" ] }, + emit => "", + mode => $mode_fpa, +}, + #-----------------------------------------------------------------# # _ _ _ # # (_) | | | | # @@ -199,212 +257,212 @@ $default_attr_type = "arm_attr_t"; # commutative operations Add => { - op_flags => "C", - irn_flags => "R", - comment => "construct Add: Add(a, b) = Add(b, a) = a + b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. add %D0, %S0, %S1%X' + op_flags => "C", + irn_flags => "R", + comment => "construct Add: Add(a, b) = Add(b, a) = a + b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. add %D0, %S0, %S1%X' }, Add_i => { - irn_flags => "R", - comment => "construct Add: Add(a, const) = Add(const, a) = a + const", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - cmp_attr => 'return attr_a->value != attr_b->value;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. add %D0, %S0, %C' + irn_flags => "R", + comment => "construct Add: Add(a, const) = Add(const, a) = a + const", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. add %D0, %S0, %C' }, Mul => { - #op_flags => "C", - irn_flags => "R", - comment => "construct Mul: Mul(a, b) = Mul(b, a) = a * b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] }, - emit =>'. mul %D0, %S0, %S1' + #op_flags => "C", + irn_flags => "R", + comment => "construct Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "!in_r1" ] }, + emit =>'. mul %D0, %S0, %S1' }, Smull => { - #op_flags => "C", - irn_flags => "R", - comment => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, - emit =>'. smull %D0, %D1, %S0, %S1', - outs => [ "low", "high" ], + #op_flags => "C", + irn_flags => "R", + comment => "construct signed 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, + emit =>'. smull %D0, %D1, %S0, %S1', + outs => [ "low", "high" ], }, Umull => { - #op_flags => "C", - irn_flags => "R", - comment => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, - emit =>'. umull %D0, %D1, %S0, %S1', - outs => [ "low", "high" ], + #op_flags => "C", + irn_flags => "R", + comment => "construct unsigned 64bit Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp", "gp" ] }, + emit =>'. umull %D0, %D1, %S0, %S1', + outs => [ "low", "high" ], }, Mla => { - #op_flags => "C", - irn_flags => "R", - comment => "construct Mla: Mla(a, b, c) = a * b + c", - reg_req => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] }, - emit =>'. mla %D0, %S0, %S1, %S2' + #op_flags => "C", + irn_flags => "R", + comment => "construct Mla: Mla(a, b, c) = a * b + c", + reg_req => { "in" => [ "gp", "gp", "gp" ], "out" => [ "!in_r1" ] }, + emit =>'. mla %D0, %S0, %S1, %S2' }, And => { - op_flags => "C", - irn_flags => "R", - comment => "construct And: And(a, b) = And(b, a) = a AND b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. and %D0, %S0, %S1%X' + op_flags => "C", + irn_flags => "R", + comment => "construct And: And(a, b) = And(b, a) = a AND b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. and %D0, %S0, %S1%X' }, And_i => { - irn_flags => "R", - comment => "construct And: And(a, const) = And(const, a) = a AND const", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. and %D0, %S0, %C', - cmp_attr => 'return attr_a->value != attr_b->value;' + irn_flags => "R", + comment => "construct And: And(a, const) = And(const, a) = a AND const", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. and %D0, %S0, %C', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' }, Or => { - op_flags => "C", - irn_flags => "R", - comment => "construct Or: Or(a, b) = Or(b, a) = a OR b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. orr %D0, %S0, %S1%X' + op_flags => "C", + irn_flags => "R", + comment => "construct Or: Or(a, b) = Or(b, a) = a OR b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. orr %D0, %S0, %S1%X' }, Or_i => { - irn_flags => "R", - comment => "construct Or: Or(a, const) = Or(const, a) = a OR const", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - cmp_attr => 'return attr_a->value != attr_b->value;', - emit => '. orr %D0, %S0, %C' + irn_flags => "R", + comment => "construct Or: Or(a, const) = Or(const, a) = a OR const", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + emit => '. orr %D0, %S0, %C' }, Eor => { - op_flags => "C", - irn_flags => "R", - comment => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. eor %D0, %S0, %S1%X' + op_flags => "C", + irn_flags => "R", + comment => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. eor %D0, %S0, %S1%X' }, Eor_i => { - irn_flags => "R", - comment => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - cmp_attr => 'return attr_a->value != attr_b->value;', - emit => '. eor %D0, %S0, %C' + irn_flags => "R", + comment => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + emit => '. eor %D0, %S0, %C' }, # not commutative operations Bic => { - irn_flags => "R", - comment => "construct Bic: Bic(a, b) = a AND ~b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. bic %D0, %S0, %S1%X' + irn_flags => "R", + comment => "construct Bic: Bic(a, b) = a AND ~b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. bic %D0, %S0, %S1%X' }, Bic_i => { - irn_flags => "R", - comment => "construct Bic: Bic(a, const) = a AND ~const", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. bic %D0, %S0, %C', - cmp_attr => 'return attr_a->value != attr_b->value;' + irn_flags => "R", + comment => "construct Bic: Bic(a, const) = a AND ~const", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. bic %D0, %S0, %C', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' }, Sub => { - irn_flags => "R", - comment => "construct Sub: Sub(a, b) = a - b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. sub %D0, %S0, %S1%X' + irn_flags => "R", + comment => "construct Sub: Sub(a, b) = a - b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. sub %D0, %S0, %S1%X' }, Sub_i => { - irn_flags => "R", - comment => "construct Sub: Sub(a, const) = a - const", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - cmp_attr => 'return attr_a->value != attr_b->value;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. sub %D0, %S0, %C', + irn_flags => "R", + comment => "construct Sub: Sub(a, const) = a - const", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. sub %D0, %S0, %C', }, Rsb => { - irn_flags => "R", - comment => "construct Rsb: Rsb(a, b) = b - a", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. rsb %D0, %S0, %S1%X' + irn_flags => "R", + comment => "construct Rsb: Rsb(a, b) = b - a", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. rsb %D0, %S0, %S1%X' }, Rsb_i => { - irn_flags => "R", - comment => "construct Rsb: Rsb(a, const) = const - a", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. rsb %D0, %S0, %C', - cmp_attr => 'return attr_a->value != attr_b->value;' + irn_flags => "R", + comment => "construct Rsb: Rsb(a, const) = const - a", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. rsb %D0, %S0, %C', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' }, Shl => { - irn_flags => "R", - comment => "construct Shl: Shl(a, b) = a << b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, - emit => '. mov %D0, %S0, lsl %S1' + irn_flags => "R", + comment => "construct Shl: Shl(a, b) = a << b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. mov %D0, %S0, lsl %S1' }, Shr => { - irn_flags => "R", - comment => "construct Shr: Shr(a, b) = a >> b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, - emit => '. mov %D0, %S0, lsr %S1' + irn_flags => "R", + comment => "construct Shr: Shr(a, b) = a >> b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, + emit => '. mov %D0, %S0, lsr %S1' }, Shrs => { - irn_flags => "R", - comment => "construct Shrs: Shrs(a, b) = a >> b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, - emit => '. mov %D0, %S0, asr %S1' + irn_flags => "R", + comment => "construct Shrs: Shrs(a, b) = a >> b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, + emit => '. mov %D0, %S0, asr %S1' }, #RotR => { -# irn_flags => "R", -# comment => "construct RotR: RotR(a, b) = a ROTR b", -# reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, -# emit => '. mov %D0, %S0, ror %S1 /* RotR(%S0, %S1) -> %D0, (%A1, %A2) */' -## emit => '. ror %S0, %S1, %D0' +# irn_flags => "R", +# comment => "construct RotR: RotR(a, b) = a ROTR b", +# reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, +# emit => '. mov %D0, %S0, ror %S1 /* RotR(%S0, %S1) -> %D0, (%A1, %A2) */' +## emit => '. ror %S0, %S1, %D0' #}, #RotL => { @@ -415,57 +473,57 @@ Shrs => { #}, #RotL_i => { -# irn_flags => "R", -# comment => "construct RotL: RotL(a, const) = a ROTL const", -# reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, -# emit => '. rol %S0, %C, %D0' +# irn_flags => "R", +# comment => "construct RotL: RotL(a, const) = a ROTL const", +# reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, +# emit => '. rol %S0, %C, %D0' #}, Mov => { - irn_flags => "R", - comment => "construct Mov: a = b", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. mov %D0, %S0%X' + irn_flags => "R", + comment => "construct Mov: a = b", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. mov %D0, %S0%X' }, Mov_i => { - irn_flags => "R", - comment => "represents an integer constant", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - reg_req => { "out" => [ "gp" ] }, - emit => '. mov %D0, %C', - cmp_attr => 'return attr_a->value != attr_b->value;' + irn_flags => "R", + comment => "represents an integer constant", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + reg_req => { "out" => [ "gp" ] }, + emit => '. mov %D0, %C', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' }, Mvn => { - irn_flags => "R", - comment => "construct Not: Not(a) = !a", - attr => "arm_shift_modifier mod, tarval *shf", - init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->value = shf;', - cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);', - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => '. mvn %D0, %S0%X' + irn_flags => "R", + comment => "construct Not: Not(a) = !a", + attr => "arm_shift_modifier mod, long shf", + init_attr => 'ARM_SET_SHF_MOD(attr, mod); attr->imm_value = shf;', + cmp_attr => 'return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);', + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. mvn %D0, %S0%X' }, Mvn_i => { - irn_flags => "R", - comment => "represents a negated integer constant", - attr => "tarval *tv", - init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->value = tv;', - cmp_attr => 'return attr_a->value != attr_b->value;', - reg_req => { "out" => [ "gp" ] }, - emit => '. mvn %D0, %C', + irn_flags => "R", + comment => "represents a negated integer constant", + attr => "long imm", + init_attr => 'ARM_SET_SHF_MOD(attr, ARM_SHF_IMM); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "out" => [ "gp" ] }, + emit => '. mvn %D0, %C', }, Abs => { - irn_flags => "R", - comment => "construct Abs: Abs(a) = |a|", - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, - emit => + irn_flags => "R", + comment => "construct Abs: Abs(a) = |a|", + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + emit => '. movs %S0, %S0, #0 . rsbmi %D0, %S0, #0' }, @@ -476,160 +534,163 @@ Abs => { # this node produces ALWAYS an empty (tempary) gp reg and cannot be CSE'd # EmptyReg => { - op_flags => "c", - irn_flags => "R", - comment => "allocate an empty register for calculations", - reg_req => { "out" => [ "gp" ] }, - emit => '. /* %D0 now available for calculations */', - cmp_attr => 'return 1;' + op_flags => "c", + irn_flags => "R", + comment => "allocate an empty register for calculations", + reg_req => { "out" => [ "gp" ] }, + emit => '. /* %D0 now available for calculations */', + cmp_attr => 'return 1;' }, Copy => { - comment => "implements a register copy", - reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, + comment => "implements a register copy", + reg_req => { "in" => [ "gp" ], "out" => [ "gp" ] }, }, CopyB => { - op_flags => "F|H", - state => "pinned", - comment => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)", - attr => "tarval *tv", - init_attr => 'attr->value = tv;', - reg_req => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] }, - outs => [ "M" ], + op_flags => "F|H", + state => "pinned", + comment => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)", + attr => "long imm", + init_attr => 'attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "!sp", "!sp", "gp", "gp", "gp", "none" ], "out" => [ "none" ] }, + outs => [ "M" ], }, SymConst => { - op_flags => "c", - irn_flags => "R", - comment => "represents a symbolic constant", - attr => "ident *id", - init_attr => "\tset_arm_symconst_id(res, id);", - reg_req => { "out" => [ "gp" ] }, - attr_type => "arm_SymConst_attr_t", -}, - -CondJmp => { - op_flags => "L|X|Y", - comment => "construct conditional jump: CMP A, B && JMPxx LABEL", - mode => "mode_T", - attr => "int proj_num", - init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] }, - attr_type => "arm_CondJmp_attr_t", + op_flags => "c", + irn_flags => "R", + comment => "represents a symbolic constant", + attr => "ident *id", + init_attr => "\tset_arm_symconst_id(res, id);", + reg_req => { "out" => [ "gp" ] }, + attr_type => "arm_SymConst_attr_t", +}, + +CmpBra => { + op_flags => "L|X|Y", + state => "pinned", + comment => "construct conditional branch: CMP A, B && JMPxx LABEL", + mode => "mode_T", + attr => "int proj_num", + init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "none", "none"] }, + attr_type => "arm_CondJmp_attr_t", }, SwitchJmp => { - op_flags => "L|X|Y", - comment => "construct switch", - mode => "mode_T", - attr => "int n_projs, long def_proj_num", - init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n". - "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);", - reg_req => { "in" => [ "gp" ], "out" => [ "none" ] }, - attr_type => "arm_SwitchJmp_attr_t", + op_flags => "L|X|Y", + state => "pinned", + comment => "construct switch", + mode => "mode_T", + attr => "int n_projs, long def_proj_num", + init_attr => "\tset_arm_SwitchJmp_n_projs(res, n_projs);\n". + "\tset_arm_SwitchJmp_default_proj_num(res, def_proj_num);", + reg_req => { "in" => [ "gp" ], "out" => [ "none" ] }, + attr_type => "arm_SwitchJmp_attr_t", }, # Load / Store Load => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", - reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - emit => '. ldr %D0, [%S0, #0]', - outs => [ "res", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldr %D0, [%S0, #0]', + outs => [ "res", "M" ], }, Loadb => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", - reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - emit => '. ldrb %D0, [%S0, #0]', - outs => [ "res", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrb %D0, [%S0, #0]', + outs => [ "res", "M" ], }, Loadbs => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", - reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - emit => '. ldrsb %D0, [%S0, #0]', - outs => [ "res", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrsb %D0, [%S0, #0]', + outs => [ "res", "M" ], }, Loadh => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", - reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - emit => '. ldrh %D0, [%S0, #0]', - outs => [ "res", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrh %D0, [%S0, #0]', + outs => [ "res", "M" ], }, Loadhs => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", - reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, - emit => '. ldrsh %D0, [%S0, #0]', - outs => [ "res", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. ldrsh %D0, [%S0, #0]', + outs => [ "res", "M" ], }, Storeb => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", - reg_req => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] }, - emit => '. strb %S1, [%S0, #0]', - mode => "mode_M", + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], "out" => [ "none" ] }, + emit => '. strb %S1, [%S0, #0]', + mode => "mode_M", }, Storeh => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", - reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, - emit => '. strh %S1, [%S0, #0]', - mode => "mode_M", + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, + emit => '. strh %S1, [%S0, #0]', + mode => "mode_M", }, Store => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", - reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, - emit => '. str %S1, [%S0, #0]', - mode => "mode_M", + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "gp", "gp", "none" ], out => [ "none" ] }, + emit => '. str %S1, [%S0, #0]', + mode => "mode_M", }, StoreStackM4Inc => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", - reg_req => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] }, - emit => '. stmfd %S0!, {%S1, %S2, %S3, %S4}', - outs => [ "ptr", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + reg_req => { "in" => [ "sp", "gp", "gp", "gp", "gp", "none" ], "out" => [ "gp", "none" ] }, + emit => '. stmfd %S0!, {%S1, %S2, %S3, %S4}', + outs => [ "ptr", "M" ], }, LoadStackM3 => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", - reg_req => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] }, - emit => '. ldmfd %S0, {%D0, %D1, %D2}', - outs => [ "res0", "res1", "res2", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Load: Load(ptr, mem) = LD ptr -> reg", + reg_req => { "in" => [ "sp", "none" ], "out" => [ "gp", "gp", "gp", "none" ] }, + emit => '. ldmfd %S0, {%D0, %D1, %D2}', + outs => [ "res0", "res1", "res2", "M" ], }, @@ -646,187 +707,337 @@ LoadStackM3 => { # commutative operations -fpaAdd => { - op_flags => "C", - irn_flags => "R", - comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit => '. adf%M %D0, %S0, %S1', -}, - -fpaMul => { - op_flags => "C", - comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit =>'. muf%M %D0, %S0, %S1', -}, - -fpaFMul => { - op_flags => "C", - comment => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit =>'. fml%M %D0, %S0, %S1', -}, - -fpaMax => { - op_flags => "C", - irn_flags => "R", - comment => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit =>'. fmax %S0, %S1, %D0', -}, - -fpaMin => { - op_flags => "C", - irn_flags => "R", - comment => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit =>'. fmin %S0, %S1, %D0', +fpaAdf => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit => '. adf%M %D0, %S0, %S1', }, -# not commutative operations - -fpaSub => { - irn_flags => "R", - comment => "construct FPA Sub: Sub(a, b) = a - b", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit => '. suf%M %D0, %S0, %S1' +fpaAdf_i => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", + attr => "long imm", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. adf%M %D0, %S0, %C', }, -fpaRsb => { - irn_flags => "R", - comment => "construct FPA reverse Sub: Sub(a, b) = b - a", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, - emit => '. rsf%M %D0, %S0, %S1' +fpaMuf => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. muf%M %D0, %S0, %S1', }, -fpaDiv => { - comment => "construct FPA Div: Div(a, b) = a / b", - attr => "ir_mode *op_mode", - init_attr => "attr->op_mode = op_mode;", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, - emit =>'. dvf%M %D0, %S0, %S1', - outs => [ "res", "M" ], +fpaMuf_i => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Mul: Mul(a, b) = Mul(b, a) = a * b", + attr => "long imm", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. muf%M %D0, %S0, %C', }, -fpaRdv => { - comment => "construct FPA reverse Div: Div(a, b) = b / a", - attr => "ir_mode *op_mode", - init_attr => "attr->op_mode = op_mode;", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, - emit =>'. rdf%M %D0, %S0, %S1', - outs => [ "res", "M" ], +fpaFml => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Fast Mul: Mul(a, b) = Mul(b, a) = a * b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fml%M %D0, %S0, %S1', }, -fpaFDiv => { - comment => "construct FPA Fast Div: Div(a, b) = a / b", - attr => "ir_mode *op_mode", - init_attr => "attr->op_mode = op_mode;", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, - emit =>'. fdv%M %D0, %S0, %S1', - outs => [ "res", "M" ], +fpaMax => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Max: Max(a, b) = Max(b, a) = a > b ? a : b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fmax %S0, %S1, %D0', }, -fpaFRdv => { - comment => "construct FPA Fast reverse Div: Div(a, b) = b / a", - attr => "ir_mode *op_mode", - init_attr => "attr->op_mode = op_mode;", - reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, - emit =>'. frd%M %D0, %S0, %S1', - outs => [ "res", "M" ], +fpaMin => { + op_flags => "C", + irn_flags => "R", + comment => "construct FPA Min: Min(a, b) = Min(b, a) = a < b ? a : b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit =>'. fmin %S0, %S1, %D0', }, -fpaMov => { - irn_flags => "R", - comment => "construct FPA Move: b = a", - reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - emit => '. mvf%M %S0, %D0', -}, +# not commutative operations -fpaMnv => { - irn_flags => "R", - comment => "construct FPA Move Negated: b = -a", - reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - emit => '. mnf%M %S0, %D0', +fpaSuf => { + irn_flags => "R", + comment => "construct FPA Sub: Sub(a, b) = a - b", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit => '. suf%M %D0, %S0, %S1' +}, + +fpaSuf_i => { + irn_flags => "R", + comment => "construct FPA Sub: Sub(a, b) = a - b", + attr => "long imm", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. suf%M %D0, %S0, %C' +}, + +fpaRsf => { + irn_flags => "R", + comment => "construct FPA reverse Sub: Sub(a, b) = b - a", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa" ] }, + emit => '. rsf%M %D0, %S0, %S1' +}, + +fpaRsf_i => { + irn_flags => "R", + comment => "construct FPA reverse Sub: Sub(a, b) = b - a", + attr => "long imm", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. rsf%M %D0, %S0, %C' +}, + +fpaDvf => { + comment => "construct FPA Div: Div(a, b) = a / b", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. dvf%M %D0, %S0, %S1', + outs => [ "res", "M" ], +}, + +fpaDvf_i => { + comment => "construct FPA Div: Div(a, b) = a / b", + attr => "ir_mode *op_mode, long imm", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. dvf%M %D0, %S0, %C', + outs => [ "res", "M" ], +}, + +fpaRdf => { + comment => "construct FPA reverse Div: Div(a, b) = b / a", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. rdf%M %D0, %S0, %S1', + outs => [ "res", "M" ], +}, + +fpaRdf_i => { + comment => "construct FPA reverse Div: Div(a, b) = b / a", + attr => "ir_mode *op_mode, long imm", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. rdf%M %D0, %S0, %S1', + outs => [ "res", "M" ], +}, + +fpaFdv => { + comment => "construct FPA Fast Div: Div(a, b) = a / b", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. fdv%M %D0, %S0, %S1', + outs => [ "res", "M" ], +}, + +fpaFdv_i => { + comment => "construct FPA Fast Div: Div(a, b) = a / b", + attr => "ir_mode *op_mode, long imm", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. fdv%M %D0, %S0, %C', + outs => [ "res", "M" ], +}, + +fpaFrd => { + comment => "construct FPA Fast reverse Div: Div(a, b) = b / a", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. frd%M %D0, %S0, %S1', + outs => [ "res", "M" ], +}, + +fpaFrd_i => { + comment => "construct FPA Fast reverse Div: Div(a, b) = b / a", + attr => "ir_mode *op_mode, long imm", + init_attr => 'attr->op_mode = op_mode; ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa", "none" ] }, + emit =>'. frd%M %D0, %S0, %C', + outs => [ "res", "M" ], +}, + +fpaMvf => { + irn_flags => "R", + comment => "construct FPA Move: b = a", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. mvf%M %S0, %D0', +}, + +fpaMvf_i => { + irn_flags => "R", + comment => "represents a float constant", + attr => "long imm", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + reg_req => { "out" => [ "fpa" ] }, + emit => '. mvf %D0, %C', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' +}, + +fpaMnf => { + irn_flags => "R", + comment => "construct FPA Move Negated: b = -a", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. mnf%M %S0, %D0', +}, + +fpaMnf_i => { + irn_flags => "R", + comment => "represents a float constant", + attr => "long imm", + init_attr => 'ARM_SET_FPA_IMM(attr); attr->imm_value = imm;', + reg_req => { "out" => [ "fpa" ] }, + emit => '. mnf %D0, %C', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' }, fpaAbs => { - irn_flags => "R", - comment => "construct FPA Absolute value: fAbsd(a) = |a|", - reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - emit => '. abs%M %D0, %S0', + irn_flags => "R", + comment => "construct FPA Absolute value: fAbsd(a) = |a|", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. abs%M %D0, %S0', }, # other operations fpaFlt => { - irn_flags => "R", - comment => "construct a FPA integer->float conversion", - reg_req => { "in" => ["gp"], "out" => [ "fpa" ] }, - emit => '. flt%M %D0, %S0', + irn_flags => "R", + comment => "construct a FPA integer->float conversion", + reg_req => { "in" => ["gp"], "out" => [ "fpa" ] }, + emit => '. flt%M %D0, %S0', }, fpaFix => { - irn_flags => "R", - comment => "construct a FPA float->integer conversion", - reg_req => { "in" => ["fpa"], "out" => [ "gp" ] }, - emit => '. fix %D0, %S0', + irn_flags => "R", + comment => "construct a FPA float->integer conversion", + reg_req => { "in" => ["fpa"], "out" => [ "gp" ] }, + emit => '. fix %D0, %S0', +}, + +fpaCmfBra => { + op_flags => "L|X|Y", + state => "pinned", + comment => "construct floating point Compare and Branch: CMF A, B && JMPxx LABEL", + mode => "mode_T", + attr => "int proj_num", + init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] }, + attr_type => "arm_CondJmp_attr_t", +}, + +fpaCnfBra => { + op_flags => "L|X|Y", + state => "pinned", + comment => "construct floating point Compare negative and Branch: CMF A, -B && JMPxx LABEL", + mode => "mode_T", + attr => "int proj_num", + init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] }, + attr_type => "arm_CondJmp_attr_t", +}, + +fpaCmfeBra => { + op_flags => "L|X|Y", + state => "pinned", + comment => "construct floating point Compare and Branch: CMF A, -B && JMPxx LABEL", + mode => "mode_T", + attr => "int proj_num", + init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] }, + attr_type => "arm_CondJmp_attr_t", +}, + +fpaCnfeBra => { + op_flags => "L|X|Y", + state => "pinned", + comment => "construct floating point Compare and Branch: CMF A, -B && JMPxx LABEL", + mode => "mode_T", + attr => "int proj_num", + init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", + reg_req => { "in" => [ "fpa", "fpa" ], "out" => [ "none", "none"] }, + attr_type => "arm_CondJmp_attr_t", }, # Load / Store fpaLdf => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct FPA Load: Load(ptr, mem) = LD ptr", - attr => "ir_mode *op_mode", - init_attr => "attr->op_mode = op_mode;", - reg_req => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] }, - emit => '. ldf%M %D0, [%S0, #0]', - outs => [ "res", "M" ], + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct FPA Load: Load(ptr, mem) = LD ptr", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "gp", "none" ], "out" => [ "fpa", "none" ] }, + emit => '. ldf%M %D0, [%S0]', + outs => [ "res", "M" ], }, fpaStf => { - op_flags => "L|F", - irn_flags => "R", - state => "exc_pinned", - comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", - attr => "ir_mode *op_mode", - init_attr => "attr->op_mode = op_mode;", - reg_req => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] }, - emit => '. stf%M [%S1, #0], %S0', - mode => "mode_M", + op_flags => "L|F", + irn_flags => "R", + state => "exc_pinned", + comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + attr => "ir_mode *op_mode", + init_attr => "attr->op_mode = op_mode;", + reg_req => { "in" => [ "gp", "fpa", "none" ], "out" => [ "none" ] }, + emit => '. stf%M %S1, [%S0]', + mode => "mode_M", }, fpaDbl2GP => { - op_flags => "L|F", - irn_flags => "R", - comment => "construct fp double to 2 gp register transfer", - reg_req => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] }, - outs => [ "low", "high", "M" ], + op_flags => "L|F", + irn_flags => "R", + comment => "construct fp double to 2 gp register transfer", + reg_req => { "in" => [ "fpa", "none" ], "out" => [ "gp", "gp", "none" ] }, + outs => [ "low", "high", "M" ], }, AddSP => { - irn_flags => "I", - comment => "construct Add to stack pointer", - reg_req => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "none" ] }, - emit => '. add %D0, %S0, %S1', - outs => [ "stack:S", "M" ], + irn_flags => "I", + comment => "construct Add to stack pointer", + reg_req => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "none" ] }, + emit => '. add %D0, %S0, %S1', + outs => [ "stack:I|S", "M" ], }, SubSP => { - irn_flags => "I", - comment => "construct Sub from stack pointer", - reg_req => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "none" ] }, - emit => '. sub %D0, %S0, %S1', - outs => [ "stack:S", "M" ], +#irn_flags => "I", + comment => "construct Sub from stack pointer", + reg_req => { in => [ "sp", "gp", "none" ], out => [ "in_r1", "gp", "none" ] }, + ins => [ "stack", "size", "mem" ], + emit => ". sub %D0, %S0, %S1\n". + ". mov sp, %D1", + outs => [ "stack:I|S", "addr", "M" ], }, LdTls => { - irn_flags => "R", - comment => "load the TLS address", - reg_req => { out => [ "gp" ] }, + irn_flags => "R", + comment => "load the TLS address", + reg_req => { out => [ "gp" ] }, }, @@ -834,13 +1045,14 @@ LdTls => { # floating point constants # fpaConst => { - op_flags => "c", - irn_flags => "R", - comment => "construct a floating point constant", - attr => "tarval *tv", - init_attr => "attr->value = tv;", - mode => "get_tarval_mode(tv)", - reg_req => { "out" => [ "fpa" ] }, + op_flags => "c", + irn_flags => "R", + comment => "construct a floating point constant", + attr => "tarval *tv", + init_attr => "attr->tv = tv;", + mode => "get_tarval_mode(tv)", + reg_req => { "out" => [ "fpa" ] }, + attr_type => "arm_fpaConst_attr_t", } #---------------------------------------------------#