From 78a7ccdf4f405f1bd41e82f60b6e996a75f631fb Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Fri, 22 Jun 2007 22:29:02 +0000 Subject: [PATCH] Implemented Unknown [r14731] --- ir/be/arm/arm_emitter.c | 18 + ir/be/arm/arm_spec.pl | 914 ++++++++++++++++++++------------------ ir/be/arm/arm_transform.c | 47 +- ir/be/arm/bearch_arm.c | 9 +- ir/be/arm/bearch_arm_t.h | 4 +- 5 files changed, 535 insertions(+), 457 deletions(-) diff --git a/ir/be/arm/arm_emitter.c b/ir/be/arm/arm_emitter.c index 4b731e055..f2c4de560 100644 --- a/ir/be/arm/arm_emitter.c +++ b/ir/be/arm/arm_emitter.c @@ -42,6 +42,7 @@ #include "irprog_t.h" #include "irargs_t.h" #include "error.h" +#include "raw_bitset.h" #include "../besched.h" #include "../beblocksched.h" @@ -77,6 +78,23 @@ static const arch_register_t *get_in_reg(const arch_env_t *arch_env, const ir_no reg = arch_get_irn_register(arch_env, op); assert(reg && "no in register found"); + + /* in case of a joker register: just return a valid register */ + if (arch_register_type_is(reg, joker)) { + const arch_register_req_t *req; + + /* ask for the requirements */ + req = arch_get_register_req(arch_env, irn, pos); + + if (arch_register_req_is(req, limited)) { + /* in case of limited requirements: get the first allowed register */ + unsigned idx = rbitset_next(req->limited, 0, 1); + reg = arch_register_for_index(req->cls, idx); + } else { + /* otherwise get first register in class */ + reg = arch_register_for_index(req->cls, 0); + } + } return reg; } diff --git a/ir/be/arm/arm_spec.pl b/ir/be/arm/arm_spec.pl index d311bb8f5..919b4a24a 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,49 +115,51 @@ $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" => 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 + { "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);", + 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);", ); @@ -214,6 +222,24 @@ $default_attr_type = "arm_attr_t"; %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, +}, + #-----------------------------------------------------------------# # _ _ _ # # (_) | | | | # @@ -228,212 +254,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, 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' }, 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 => "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' }, 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, 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' }, 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 => "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;' }, 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, 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' }, 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 => "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' }, 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, 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' }, 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 => "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' }, # 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, 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' }, 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 => "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;' }, 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, 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' }, 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 => "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', }, 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, 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' }, 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 => "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;' }, 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 => { @@ -444,57 +470,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, 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' }, 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 => "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;' }, 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, 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' }, 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 => "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', }, 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' }, @@ -505,162 +531,162 @@ 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 => "tarval *tv", + init_attr => 'attr->value = tv;', + 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", + 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", - state => "pinned", - 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 => "L|X|Y", + state => "pinned", + 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", }, SwitchJmp => { - 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", + 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" ], }, @@ -678,186 +704,186 @@ 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', + 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', + 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', + 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', + 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', + 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', }, # 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' + 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 => { - 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' + 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 => { - 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" ], + 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" ], }, 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" ], + 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" ], }, 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" ], + 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" ], }, 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" ], + 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" ], }, fpaMov => { - irn_flags => "R", - comment => "construct FPA Move: b = a", - reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - emit => '. mvf%M %S0, %D0', + irn_flags => "R", + comment => "construct FPA Move: b = a", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. mvf%M %S0, %D0', }, fpaMnv => { - irn_flags => "R", - comment => "construct FPA Move Negated: b = -a", - reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, - emit => '. mnf%M %S0, %D0', + irn_flags => "R", + comment => "construct FPA Move Negated: b = -a", + reg_req => { "in" => [ "fpa" ], "out" => [ "fpa" ] }, + emit => '. mnf%M %S0, %D0', }, 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', }, # 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, #0]', + 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, #0], %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: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", "none" ] }, + emit => '. sub %D0, %S0, %S1', + outs => [ "stack:S", "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" ] }, }, @@ -865,13 +891,13 @@ 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->value = tv;", + mode => "get_tarval_mode(tv)", + reg_req => { "out" => [ "fpa" ] }, } #---------------------------------------------------# diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index abd17bc00..17fbcccbf 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -1450,29 +1450,56 @@ static ir_node *gen_Proj(ir_node *node) { return be_duplicate_node(node); } +typedef ir_node *(*create_const_node_func)(dbg_info *db, ir_graph *irg, ir_node *block); + +static INLINE ir_node *create_const(ir_node **place, + create_const_node_func func, + const arch_register_t* reg) +{ + ir_node *block, *res; + + if (*place != NULL) + return *place; + + block = get_irg_start_block(env_cg->irg); + res = func(NULL, env_cg->irg, block); + arch_set_irn_register(env_cg->arch_env, res, reg); + *place = res; + + add_irn_dep(get_irg_end(env_cg->irg), res); + return res; +} + +static ir_node *arm_new_Unknown_gp(void) { + return create_const(&env_cg->unknown_gp, new_rd_arm_Unknown_GP, + &arm_gp_regs[REG_GP_UKNWN]); +} + +static ir_node *arm_new_Unknown_fpa(void) { + return create_const(&env_cg->unknown_fpa, new_rd_arm_Unknown_FPA, + &arm_fpa_regs[REG_FPA_UKNWN]); +} + /** * This function just sets the register for the Unknown node * as this is not done during register allocation because Unknown * is an "ignore" node. */ static ir_node *gen_Unknown(ir_node *node) { - (void) node; - /* ir_mode *mode = get_irn_mode(node); if (mode_is_float(mode)) { if (USE_FPA(env_cg->isa)) - return arm_new_Unknown_fpa(env_cg); + return arm_new_Unknown_fpa(); else if (USE_VFP(env_cg->isa)) - return arm_new_Unknown_vfp(env_cg); + panic("VFP not supported yet"); else panic("Softfloat not supported yet"); } else if (mode_needs_gp_reg(mode)) { - return ia32_new_Unknown_gp(env_cg); + return arm_new_Unknown_gp(); } else { assert(0 && "unsupported Unknown-Mode"); } -*/ - panic("Unknown NYI\n"); + return NULL; } @@ -1624,11 +1651,13 @@ static void arm_register_transformers(void) { } /** - * Pre-transform all unknown and noreg nodes. + * Pre-transform all unknown nodes. */ static void arm_pretransform_node(void *arch_cg) { arm_code_gen_t *cg = arch_cg; - (void) cg; + + cg->unknown_gp = be_pre_transform_node(cg->unknown_gp); + cg->unknown_fpa = be_pre_transform_node(cg->unknown_fpa); } /** diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 45e807f50..e4a350e18 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -92,7 +92,7 @@ arch_register_req_t *arm_get_irn_reg_req(const void *self, const ir_node *node, ir_mode *mode = get_irn_mode(node); (void) self; - if (is_Block(node) || mode == mode_X || mode == mode_M) { + if (is_Block(node) || mode == mode_X) { return arch_no_register_req; } @@ -101,8 +101,9 @@ arch_register_req_t *arm_get_irn_reg_req(const void *self, const ir_node *node, } if (is_Proj(node)) { - /* in case of a proj, we need to get the correct OUT slot */ - /* of the node corresponding to the proj number */ + if(mode == mode_M) + return arch_no_register_req; + if(pos >= 0) { return arch_no_register_req; } @@ -597,6 +598,8 @@ static void *arm_cg_init(be_irg_t *birg) { cg->birg = birg; cg->int_tp = int_tp; cg->have_fp_insn = 0; + cg->unknown_gp = NULL; + cg->unknown_fpa = NULL; cg->dump = (birg->main_env->options->dump_flags & DUMP_BE) ? 1 : 0; FIRM_DBG_REGISTER(cg->mod, "firm.be.arm.cg"); diff --git a/ir/be/arm/bearch_arm_t.h b/ir/be/arm/bearch_arm_t.h index 33187a32e..4bebbfede 100644 --- a/ir/be/arm/bearch_arm_t.h +++ b/ir/be/arm/bearch_arm_t.h @@ -142,7 +142,9 @@ typedef struct _arm_code_gen_t { arm_isa_t *isa; /**< the isa instance */ be_irg_t *birg; /**< The be-irg (contains additional information about the irg) */ ir_type *int_tp; /**< the int type, needed for Call conversion */ - int have_fp_insn; /**< non-zero, if fp hardware instructions are emitted */ + ir_node *unknown_gp; /**< unique Unknown_GP node */ + ir_node *unknown_fpa; /**< unique Unknown_FPA node */ + char have_fp_insn; /**< non-zero, if fp hardware instructions are emitted */ char dump; /**< set to 1 if graphs should be dumped */ DEBUG_ONLY(firm_dbg_module_t *mod;) /**< debugging module */ } arm_code_gen_t; -- 2.20.1