X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Farm%2Farm_spec.pl;h=3adff66079a647db0a526722eb3da8baeef9a9a1;hb=fc2759fa267ba4b074c2ac570c1b9d47cc943612;hp=9b923ff2618b248db0bbcd5d2a82344b623f5570;hpb=986820750066ef571994af26528e2668841e32dc;p=libfirm diff --git a/ir/be/arm/arm_spec.pl b/ir/be/arm/arm_spec.pl index 9b923ff26..3adff6607 100644 --- a/ir/be/arm/arm_spec.pl +++ b/ir/be/arm/arm_spec.pl @@ -28,10 +28,14 @@ $new_emit_syntax = 1; # comment => "any comment for constructor", # reg_req => { in => [ "reg_class|register" ], out => [ "reg_class|register|in_rX" ] }, # cmp_attr => "c source code for comparing node attributes", +# outs => { "out1", "out2" } # optional, creates pn_op_out1, ... consts +# ins => { "in1", "in2" } # optional, creates n_op_in1, ... consts +# mode => "mode_Iu" # optional, predefines the mode # emit => "emit code with templates", -# attr => "attitional attribute arguments for constructor" -# init_attr => "emit attribute initialization template" +# attr => "attitional attribute arguments for constructor", +# init_attr => "emit attribute initialization template", # rd_constructor => "c source code which constructs an ir_node" +# hash_func => "name of the hash function for this operation", # latency => "latency of this operation (can be float)" # attr_type => "name of the attribute struct", # }, @@ -106,33 +110,33 @@ $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) -# 2 - callee save (register must be saved by the called function) -# 4 - ignore (do not assign this register) -# 8 - emitter can choose an arbitrary register of this class -# 16 - the register is a virtual one -# 32 - register represents a state +$normal = 0; # no special type +$caller_save = 1; # caller save (register must be saved by the caller of a function) +$callee_save = 2; # callee save (register must be saved by the called function) +$ignore = 4; # ignore (do not assign this register) +$arbitrary = 8; # emitter can choose an arbitrary register of this class +$virtual = 16; # the register is a virtual one +$state = 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 - { name => "gp_UKNWN", type => 4 | 8 | 16 }, # we need a dummy register for Unknown nodes + { "name" => "r0", "type" => $caller_save }, + { "name" => "r1", "type" => $caller_save }, + { "name" => "r2", "type" => $caller_save }, + { "name" => "r3", "type" => $caller_save }, + { "name" => "r4", "type" => $callee_save }, + { "name" => "r5", "type" => $callee_save }, + { "name" => "r6", "type" => $callee_save }, + { "name" => "r7", "type" => $callee_save }, + { "name" => "r8", "type" => $callee_save }, + { "name" => "r9", "type" => $callee_save }, + { "name" => "r10", "type" => $callee_save }, + { "name" => "r11", "type" => $callee_save }, + { "name" => "r12", "type" => $ignore | $callee_save }, # reserved for linker + { "name" => "sp", "type" => $ignore | $callee_save }, # this is our stack pointer + { "name" => "lr", "type" => $callee_save | $caller_save }, # this is our return address + { "name" => "pc", "type" => $ignore | $callee_save }, # this is our program counter + { name => "gp_UKNWN", type => $ignore | $arbitrary | $virtual }, # we need a dummy register for Unknown nodes { "mode" => $mode_gp } ], fpa => [ @@ -150,18 +154,18 @@ $mode_fpa = "mode_E"; ); # %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);", ); #--------------------------------------------------# @@ -176,12 +180,14 @@ $mode_fpa = "mode_E"; #--------------------------------------------------# $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 = ( @@ -189,6 +195,7 @@ $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 = ( @@ -257,9 +264,9 @@ 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);', + 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' }, @@ -267,9 +274,9 @@ Add => { 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;', + 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' }, @@ -312,9 +319,9 @@ 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);', + 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' }, @@ -322,20 +329,20 @@ And => { 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;', + 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->value != attr_b->value;' + 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);', + 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' }, @@ -343,10 +350,10 @@ Or => { 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;', + 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->value != attr_b->value;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', emit => '. orr %D0, %S0, %C' }, @@ -354,9 +361,9 @@ 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);', + 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' }, @@ -364,10 +371,10 @@ Eor => { 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;', + 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->value != attr_b->value;', + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;', emit => '. eor %D0, %S0, %C' }, @@ -376,9 +383,9 @@ Eor_i => { 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);', + 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' }, @@ -386,19 +393,19 @@ Bic => { 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;', + 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->value != attr_b->value;' + 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);', + 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' }, @@ -406,9 +413,9 @@ Sub => { 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;', + 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', }, @@ -416,9 +423,9 @@ Sub_i => { 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);', + 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' }, @@ -426,11 +433,11 @@ Rsb => { 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;', + 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->value != attr_b->value;' + cmp_attr => 'return attr_a->imm_value != attr_b->imm_value;' }, Shl => { @@ -442,25 +449,24 @@ Shl => { Shr => { irn_flags => "R", - comment => "construct Shr: Shr(a, b) = a >> b", - reg_req => { "in" => [ "gp", "gp" ], "out" => [ "in_r1" ] }, + comment => "construct Shr: Shr(a, b) = a >>u b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, 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" ] }, + comment => "construct Shrs: Shrs(a, b) = a >>s b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, 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' -#}, +Ror => { + irn_flags => "R", + comment => "construct Ror: Ror(a, b) = a <> b", + reg_req => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] }, + emit => '. mov %D0, %S0, ror %S1' +}, #RotL => { # irn_flags => "R", @@ -479,9 +485,9 @@ Shrs => { 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);', + 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' }, @@ -489,19 +495,19 @@ Mov => { 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;', + 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->value != attr_b->value;' + 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);', + 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' }, @@ -509,9 +515,9 @@ Mvn => { 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;', + 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', }, @@ -548,8 +554,9 @@ 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;', + 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" ], }, @@ -564,10 +571,21 @@ SymConst => { attr_type => "arm_SymConst_attr_t", }, -CondJmp => { +CmpBra => { op_flags => "L|X|Y", state => "pinned", - comment => "construct conditional jump: CMP A, B && JMPxx LABEL", + 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", +}, + +TstBra => { + op_flags => "L|X|Y", + state => "pinned", + comment => "construct conditional branch: TST A, B && JMPxx LABEL", mode => "mode_T", attr => "int proj_num", init_attr => "\tset_arm_CondJmp_proj_num(res, proj_num);", @@ -673,7 +691,7 @@ StoreStackM4Inc => { op_flags => "L|F", irn_flags => "R", state => "exc_pinned", - comment => "construct Store: Store(ptr, val, mem) = ST ptr,val", + comment => "construct Store: Push 4 Registers = 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" ], @@ -703,7 +721,7 @@ LoadStackM3 => { # commutative operations -fpaAdd => { +fpaAdf => { op_flags => "C", irn_flags => "R", comment => "construct FPA Add: Add(a, b) = Add(b, a) = a + b", @@ -711,15 +729,37 @@ fpaAdd => { emit => '. adf%M %D0, %S0, %S1', }, -fpaMul => { +fpaAdf_i => { + 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', +}, + +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', }, -fpaFMul => { +fpaMuf_i => { + 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', +}, + +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', @@ -743,21 +783,41 @@ fpaMin => { # not commutative operations -fpaSub => { +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' }, -fpaRsb => { +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' }, -fpaDiv => { +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;", @@ -766,7 +826,17 @@ fpaDiv => { outs => [ "res", "M" ], }, -fpaRdv => { +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;", @@ -775,7 +845,17 @@ fpaRdv => { outs => [ "res", "M" ], }, -fpaFDiv => { +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;", @@ -784,7 +864,17 @@ fpaFDiv => { outs => [ "res", "M" ], }, -fpaFRdv => { +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;", @@ -793,20 +883,50 @@ fpaFRdv => { outs => [ "res", "M" ], }, -fpaMov => { +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', }, -fpaMnv => { +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%M %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%M %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|", @@ -830,6 +950,50 @@ fpaFix => { 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 => { @@ -869,15 +1033,17 @@ AddSP => { 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" ], + 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" ], +SubSPandCopy => { +#irn_flags => "I", + comment => "construct Sub from stack pointer and copy to Register", + 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 => { @@ -895,9 +1061,10 @@ fpaConst => { irn_flags => "R", comment => "construct a floating point constant", attr => "tarval *tv", - init_attr => "attr->value = tv;", + init_attr => "attr->tv = tv;", mode => "get_tarval_mode(tv)", reg_req => { "out" => [ "fpa" ] }, + attr_type => "arm_fpaConst_attr_t", } #---------------------------------------------------#