X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fsparc%2Fsparc_spec.pl;h=6733e6dba323f99ed30f3409465a84926013bf7c;hb=035c482fe704a0f976727e4f7f0e3d2763bdc3f3;hp=1f3713c911c7d75d9f61c4d4add4221809c56e38;hpb=637450acaf2ef255b2841785a6c6e6b809c9ac27;p=libfirm diff --git a/ir/be/sparc/sparc_spec.pl b/ir/be/sparc/sparc_spec.pl index 1f3713c91..6733e6dba 100644 --- a/ir/be/sparc/sparc_spec.pl +++ b/ir/be/sparc/sparc_spec.pl @@ -5,6 +5,7 @@ $arch = "sparc"; $mode_gp = "mode_Iu"; $mode_flags = "mode_Bu"; +$mode_fpflags = "mode_Bu"; $mode_fp = "mode_D"; $normal = 0; # no special type @@ -18,50 +19,58 @@ $state = 32; # register represents a state # available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals) %reg_classes = ( gp => [ - { name => "g0", realname => "g0", type => $ignore }, # hardwired 0, behaves like /dev/null - { name => "g1", realname => "g1", type => $caller_save }, # temp. value - { name => "g2", realname => "g2", type => $caller_save }, - { name => "g3", realname => "g3", type => $caller_save }, - { name => "g4", realname => "g4", type => $caller_save }, - { name => "g5", realname => "g5", type => $ignore }, # reserved by SPARC ABI - { name => "g6", realname => "g6", type => $ignore }, # reserved by SPARC ABI - { name => "g7", realname => "g7", type => $ignore }, # reserved by SPARC ABI + { name => "g0", type => $ignore }, # hardwired 0, behaves like /dev/null + { name => "g1", type => $caller_save }, # temp. value + { name => "g2", type => $caller_save }, + { name => "g3", type => $caller_save }, + { name => "g4", type => $caller_save }, + { name => "g5", type => $ignore }, # reserved by SPARC ABI + { name => "g6", type => $ignore }, # reserved by SPARC ABI + { name => "g7", type => $ignore }, # reserved by SPARC ABI # window's out registers - { name => "o0", realname => "o0", type => $caller_save }, # param 1 / return value from callee - { name => "o1", realname => "o1", type => $caller_save }, # param 2 - { name => "o2", realname => "o2", type => $caller_save }, # param 3 - { name => "o3", realname => "o3", type => $caller_save }, # param 4 - { name => "o4", realname => "o4", type => $caller_save }, # param 5 - { name => "o5", realname => "o5", type => $caller_save }, # param 6 - { name => "sp", realname => "sp", type => $ignore }, # our stackpointer - { name => "o7", realname => "o6", type => $ignore }, # temp. value / address of CALL instr. + { name => "o0", type => $caller_save }, # param 1 / return value from callee + { name => "o1", type => $caller_save }, # param 2 + { name => "o2", type => $caller_save }, # param 3 + { name => "o3", type => $caller_save }, # param 4 + { name => "o4", type => $caller_save }, # param 5 + { name => "o5", type => $caller_save }, # param 6 + { name => "sp", type => $ignore }, # our stackpointer + { name => "o7", type => $ignore }, # temp. value / address of CALL instr. # window's local registers - { name => "l0", realname => "l0", type => 0 }, - { name => "l1", realname => "l1", type => 0 }, - { name => "l2", realname => "l2", type => 0 }, - { name => "l3", realname => "l3", type => 0 }, - { name => "l4", realname => "l4", type => 0 }, - { name => "l5", realname => "l5", type => 0 }, - { name => "l6", realname => "l6", type => 0 }, - { name => "l7", realname => "l7", type => 0 }, + { name => "l0", type => 0 }, + { name => "l1", type => 0 }, + { name => "l2", type => 0 }, + { name => "l3", type => 0 }, + { name => "l4", type => 0 }, + { name => "l5", type => 0 }, + { name => "l6", type => 0 }, + { name => "l7", type => 0 }, # window's in registers - { name => "i0", realname => "i0", type => 0 }, # incoming param1 / return value to caller - { name => "i1", realname => "i1", type => 0 }, # param 2 - { name => "i2", realname => "i2", type => 0 }, # param 3 - { name => "i3", realname => "i3", type => 0 }, # param 4 - { name => "i4", realname => "i4", type => 0 }, # param 5 - { name => "i5", realname => "i5", type => 0 }, # param 6 + { name => "i0", type => 0 }, # incoming param1 / return value to caller + { name => "i1", type => 0 }, # param 2 + { name => "i2", type => 0 }, # param 3 + { name => "i3", type => 0 }, # param 4 + { name => "i4", type => 0 }, # param 5 + { name => "i5", type => 0 }, # param 6 { name => "frame_pointer", realname => "fp", type => $ignore }, # our framepointer - { name => "i7", realname => "i7", type => $ignore }, # return address - 8 + { name => "i7", type => $ignore }, # return address - 8 { mode => $mode_gp } ], - flags => [ - { name => "y", realname => "y", type => $ignore }, # the multiply/divide state register + fp_flags => [ + { name => "fpflags", type => $ignore }, + { mode => $mode_fpflags, flags => "manual_ra" } + ], + flags_class => [ + { name => "flags", type => $ignore }, { mode => $mode_flags, flags => "manual_ra" } ], + mul_div_high_res => [ + { name => "y", type => $ignore }, + { mode => $mode_gp, flags => "manual_ra" } + ], # fp registers can be accessed any time fp => [ { name => "f0", type => $caller_save }, @@ -121,11 +130,10 @@ $state = 32; # register represents a state IM => "${arch}_emit_immediate(node);", LM => "${arch}_emit_load_mode(node);", SM => "${arch}_emit_store_mode(node);", - EXTPREF => "${arch}_emit_mode_sign_prefix(node);", FPM => "${arch}_emit_fp_mode_suffix(node);", - FPLM => "${arch}_emit_fp_load_mode(node);", - FPSM => "${arch}_emit_fp_store_mode(node);", - O => "${arch}_emit_offset(node);", + FCONVS => "${arch}_emit_fp_conv_source(node);", + FCONVD => "${arch}_emit_fp_conv_destination(node);", + O => "${arch}_emit_offset(node);", ); $default_attr_type = "sparc_attr_t"; @@ -141,7 +149,10 @@ $default_copy_attr = "sparc_copy_attr"; sparc_jmp_cond_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);", sparc_jmp_switch_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);", sparc_save_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);", - + sparc_fp_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n". + "\tinit_sparc_fp_attributes(res, fp_mode);\n", + sparc_fp_conv_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);". + "\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n", ); %compare_attr = ( @@ -151,6 +162,8 @@ $default_copy_attr = "sparc_copy_attr"; sparc_jmp_cond_attr_t => "cmp_attr_sparc_jmp_cond", sparc_jmp_switch_attr_t => "cmp_attr_sparc_jmp_switch", sparc_save_attr_t => "cmp_attr_sparc_save", + sparc_fp_attr_t => "cmp_attr_sparc_fp", + sparc_fp_conv_attr_t => "cmp_attr_sparc_fp_conv", ); # addressing modes: imm, reg, reg +/- imm, reg + reg @@ -273,7 +286,7 @@ Save => { outs => [ "stack", "frame", "mem" ], attr => "int initial_stacksize", attr_type => "sparc_save_attr_t", - init_attr => "\tinit_sparc_save_attr(res, initial_stacksize);", + init_attr => "\tinit_sparc_save_attributes(res, initial_stacksize);", }, SubSP => { @@ -349,6 +362,8 @@ Call => { Cmp => { irn_flags => [ "rematerializable", "modify_flags" ], emit => '. cmp %S1, %R2I', + reg_req => { in => [ "gp", "gp" ], out => [ "flags" ] }, + ins => [ "left", "right" ], mode => $mode_flags, constructors => \%cmp_operand_constructors, }, @@ -374,7 +389,7 @@ SwitchJmp => { Sll => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, emit => '. sll %S1, %R2I, %D1', constructors => \%binop_operand_constructors, @@ -382,7 +397,7 @@ Sll => { Slr => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, emit => '. srl %S1, %R2I, %D1', constructors => \%binop_operand_constructors, @@ -390,7 +405,7 @@ Slr => { Sra => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, emit => '. sra %S1, %R2I, %D1', constructors => \%binop_operand_constructors, @@ -398,7 +413,7 @@ Sra => { And => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, emit => '. and %S1, %R2I, %D1', constructors => \%binop_operand_constructors, @@ -406,7 +421,7 @@ And => { Or => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, emit => '. or %S1, %R2I, %D1', constructors => \%binop_operand_constructors, @@ -414,49 +429,59 @@ Or => { Xor => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, emit => '. xor %S1, %R2I, %D1', constructors => \%binop_operand_constructors, }, Mul => { - state => "exc_pinned", - reg_req => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] }, - outs => [ "low", "high" ], + reg_req => { in => [ "gp", "gp" ], out => [ "gp", "y" ] }, constructors => \%binop_operand_constructors, - #emit =>'. mul %S1, %R2I, %D1' + emit => '. mul %S1, %R2I, %D1', + mode => $mode_gp, }, Mulh => { - state => "exc_pinned", reg_req => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] }, outs => [ "low", "high" ], constructors => \%binop_operand_constructors, }, -Div => { +# The div instructions are kinda hacky. Things to improve: +# * Make high-value input explicitely. Either as a gp at first or ideally +# as an explicit y-register + +SDiv => { irn_flags => [ "rematerializable" ], state => "exc_pinned", - reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] }, - outs => [ "res" ], + reg_req => { in => [ "gp", "gp" ], out => [ "gp", "none" ] }, + ins => [ "dividend_low", "divisor" ], + outs => [ "res", "M" ], + constructors => \%binop_operand_constructors, +}, + +UDiv => { + irn_flags => [ "rematerializable" ], + state => "exc_pinned", + reg_req => { in => [ "gp", "gp" ], out => [ "gp", "none" ] }, + ins => [ "dividend_low", "divisor" ], + outs => [ "res", "M" ], constructors => \%binop_operand_constructors, - #mode => $mode_gp, - #emit =>'. div %S1, %R2I, %D1' }, Minus => { irn_flags => [ "rematerializable" ], - mode => $mode_gp, + mode => $mode_gp, reg_req => { in => [ "gp" ], out => [ "gp" ] }, emit => ". sub %%g0, %S1, %D1" }, Not => { - irn_flags => [ "rematerializable" ], - mode => $mode_gp, - reg_req => { in => [ "gp" ], out => [ "gp" ] }, - emit => '. xnor %S1, %%g0, %D1' + irn_flags => [ "rematerializable" ], + mode => $mode_gp, + reg_req => { in => [ "gp" ], out => [ "gp" ] }, + emit => '. xnor %S1, %%g0, %D1' }, Nop => { @@ -465,59 +490,87 @@ Nop => { emit => '. nop', }, -fAdd => { +fadd => { op_flags => [ "commutative" ], irn_flags => [ "rematerializable" ], reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] }, - emit => '. fadd%FPM %S1, %S2, %D1' + emit => '. fadd%FPM %S1, %S2, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_fp, }, -fMul => { - op_flags => [ "commutative" ], +fsub => { + irn_flags => [ "rematerializable" ], reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] }, - emit =>'. fmul%FPM %S1, %S2, %D1' + emit => '. fsub%FPM %S1, %S2, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_fp, }, -fsMuld => { +fmul => { + irn_flags => [ "rematerializable" ], op_flags => [ "commutative" ], reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] }, - emit =>'. fsmuld %S1, %S2, %D1' + emit =>'. fmul%FPM %S1, %S2, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_fp, }, -FsTOd => { +fdiv => { irn_flags => [ "rematerializable" ], - reg_req => { in => [ "fp" ], out => [ "fp" ] }, - emit =>'. FsTOd %S1, %D1' + reg_req => { in => [ "fp", "fp" ], out => [ "fp", "none" ] }, + emit => '. fdiv%FPM %S1, %S2, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + outs => [ "res", "M" ], }, -FdTOs => { +fneg => { irn_flags => [ "rematerializable" ], reg_req => { in => [ "fp" ], out => [ "fp" ] }, - emit =>'. FdTOs %S1, %D1' + emit => '. fneg%FPM %S1, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_fp, }, -FiTOs => { +"fabs" => { irn_flags => [ "rematerializable" ], - reg_req => { in => [ "gp" ], out => [ "fp" ] }, - emit =>'. FiTOs %S1, %D1' + reg_req => { in => [ "fp" ], out => [ "fp" ] }, + emit => '. fabs%FPM %S1, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_fp, }, -FiTOd => { +fftof => { irn_flags => [ "rematerializable" ], - reg_req => { in => [ "gp" ], out => [ "fp" ] }, - emit =>'. FiTOd %S1, %D1' + reg_req => { in => [ "fp" ], out => [ "fp" ] }, + emit => '. f%FCONVS.to%FCONVD %S1, %D1', + attr_type => "sparc_fp_conv_attr_t", + attr => "ir_mode *src_mode, ir_mode *dest_mode", + mode => $mode_fp, }, -FsTOi => { +fitof => { irn_flags => [ "rematerializable" ], - reg_req => { in => [ "fp" ], out => [ "gp" ] }, - emit =>'. FsTOi %S1, %D1' + reg_req => { in => [ "gp" ], out => [ "fp" ] }, + emit => '. fito%FPM %S1, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_fp, }, -FdTOi => { +fftoi => { irn_flags => [ "rematerializable" ], reg_req => { in => [ "fp" ], out => [ "gp" ] }, - emit =>'. FdTOi %S1, %D1' + emit => '. f%FPM.toi %S1, %D1', + attr_type => "sparc_fp_attr_t", + attr => "ir_mode *fp_mode", + mode => $mode_gp, }, Ldf => {