# Creation: 2006/02/13
# $Id$
-# This is a template specification for the Firm-Backend
-
-$new_emit_syntax = 1;
-
-# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
$arch = "sparc";
#
# ); # close the %nodes initializer
-# op_flags: flags for the operation, OPTIONAL (default is "N")
-# the op_flags correspond to the firm irop_flags:
-# N irop_flag_none
-# L irop_flag_labeled
-# C irop_flag_commutative
-# X irop_flag_cfopcode
-# I irop_flag_ip_cfopcode
-# F irop_flag_fragile
-# Y irop_flag_forking
-# H irop_flag_highlevel
-# c irop_flag_constlike
-# K irop_flag_keep
-#
-# irn_flags: special node flags, OPTIONAL (default is 0)
-# following irn_flags are supported:
-# R rematerializeable
-# N not spillable
-# I ignore for register allocation
-#
# state: state of the operation, OPTIONAL (default is "floats")
#
# arity: arity of the operation, MUST NOT BE OMITTED
{ name => "g7", realname => "g7", type => 4 }, # reserved by SPARC ABI
# window's out registers
- { name => "o0", realname => "o0", type => 0 }, # param 1 / return value from callee
- { name => "o1", realname => "o1", type => 0 }, # param 2
- { name => "o2", realname => "o2", type => 0 }, # param 3
- { name => "o3", realname => "o3", type => 0 }, # param 4
- { name => "o4", realname => "o4", type => 0 }, # param 5
- { name => "o5", realname => "o5", type => 0 }, # param 6
+ { name => "o0", realname => "o0", type => 1 }, # param 1 / return value from callee
+ { name => "o1", realname => "o1", type => 1 }, # param 2
+ { name => "o2", realname => "o2", type => 1 }, # param 3
+ { name => "o3", realname => "o3", type => 1 }, # param 4
+ { name => "o4", realname => "o4", type => 1 }, # param 5
+ { name => "o5", realname => "o5", type => 1 }, # param 6
{ name => "sp", realname => "sp", type => 4 }, # our stackpointer
{ name => "o7", realname => "o6", type => 4 }, # temp. value / address of CALL instr.
{ name => "l7", realname => "l7", type => 0 },
# window's in registers
- { name => "i0", realname => "i0", type => 1 }, # incoming param1 / return value to caller
- { name => "i1", realname => "i1", type => 1 }, # param 2
- { name => "i2", realname => "i2", type => 1 }, # param 3
- { name => "i3", realname => "i3", type => 1 }, # param 4
- { name => "i4", realname => "i4", type => 1 }, # param 5
- { name => "i5", realname => "i5", type => 1 }, # param 6
+ { 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 => "fp", realname => "fp", type => 4 }, # our framepointer
{ name => "i7", realname => "i7", type => 4 }, # return address - 8
{ mode => $mode_gp }
C => "${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);",
);
-#--------------------------------------------------#
-# _ #
-# (_) #
-# _ __ _____ __ _ _ __ ___ _ __ ___ #
-# | '_ \ / _ \ \ /\ / / | | '__| / _ \| '_ \/ __| #
-# | | | | __/\ V V / | | | | (_) | |_) \__ \ #
-# |_| |_|\___| \_/\_/ |_|_| \___/| .__/|___/ #
-# | | #
-# |_| #
-#--------------------------------------------------#
-
$default_attr_type = "sparc_attr_t";
$default_copy_attr = "sparc_copy_attr";
%nodes = (
-#-----------------------------------------------------------------#
-# _ _ _ #
-# (_) | | | | #
-# _ _ __ | |_ ___ __ _ ___ _ __ _ __ ___ __| | ___ ___ #
-# | | '_ \| __/ _ \/ _` |/ _ \ '__| | '_ \ / _ \ / _` |/ _ \/ __| #
-# | | | | | || __/ (_| | __/ | | | | | (_) | (_| | __/\__ \ #
-# |_|_| |_|\__\___|\__, |\___|_| |_| |_|\___/ \__,_|\___||___/ #
-# __/ | #
-# |___/ #
-#-----------------------------------------------------------------#
-
-# commutative operations
-
Add => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct Add: Add(a, b) = Add(b, a) = a + b",
mode => $mode_gp,
emit => '. add %S1, %R2I, %D1',
},
Sub => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct Sub: Sub(a, b) = a - b",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
# Load / Store
Load => {
- op_flags => "L|F",
+ op_flags => [ "labeled", "fragile" ],
comment => "construct Load: Load(ptr, mem) = LD ptr -> reg",
state => "exc_pinned",
ins => [ "ptr", "mem" ],
},
LoadHi => {
- op_flags => "L|F",
+ op_flags => [ "labeled", "fragile" ],
comment => "construct LoadHi: Load(ptr, mem) = sethi hi(ptr) -> reg",
state => "exc_pinned",
ins => [ "ptr", "mem" ],
},
HiImm => {
- op_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct LoadHi: Load(imm, mem) = sethi hi(imm) -> reg",
state => "exc_pinned",
outs => [ "res" ],
},
LoImm => {
- op_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct LoadHi: Load(imm, mem) = sethi hi(imm) -> reg",
state => "exc_pinned",
ins => [ "hireg" ],
},
LoadLo => {
- op_flags => "L|F",
+ op_flags => [ "labeled", "fragile" ],
comment => "construct LoadLo: Or(in, ptr, mem) = or in lo(ptr) -> reg",
state => "exc_pinned",
ins => [ "hireg", "ptr", "mem" ],
},
Store => {
- op_flags => "L|F",
+ op_flags => [ "labeled", "fragile" ],
comment => "construct Store: Store(ptr, val, mem) = ST ptr,val",
mode => "mode_M",
state => "exc_pinned",
},
Mov => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct Mov: Mov(src, dest) = MV src,dest",
arity => "variable",
emit => '. mov %R1I, %D1',
},
SymConst => {
- op_flags => "c",
- irn_flags => "R",
+ op_flags => [ "constlike" ],
+ irn_flags => [ "rematerializable" ],
attr => "ir_entity *entity",
reg_req => { out => [ "gp" ] },
attr_type => "sparc_symconst_attr_t",
},
FrameAddr => {
- op_flags => "c",
- irn_flags => "R",
+ op_flags => [ "constlike" ],
+ irn_flags => [ "rematerializable" ],
attr => "ir_entity *entity",
reg_req => { in => [ "gp" ], out => [ "gp" ] },
ins => [ "base" ],
},
Branch => {
- op_flags => "L|X|Y",
+ op_flags => [ "labeled", "cfopcode", "forking" ],
state => "pinned",
mode => "mode_T",
reg_req => { in => [ "flags" ], out => [ "none", "none" ] },
Jmp => {
state => "pinned",
- op_flags => "X",
- irn_flags => "J",
+ op_flags => [ "cfopcode" ],
+ irn_flags => [ "simple_jump" ],
reg_req => { out => [ "none" ] },
mode => "mode_X",
},
Cmp => {
- irn_flags => "R|F",
+ irn_flags => [ "rematerializable", "modify_flags" ],
emit => '. cmp %S1, %R2I',
mode => $mode_flags,
attr_type => "sparc_cmp_attr_t",
},
Tst => {
- irn_flags => "R|F",
+ irn_flags => [ "rematerializable", "modify_flags" ],
emit => '. tst %S1',
mode => $mode_flags,
attr_type => "sparc_cmp_attr_t",
},
SwitchJmp => {
- op_flags => "L|X|Y",
+ op_flags => [ "labeled", "cfopcode", "forking" ],
state => "pinned",
mode => "mode_T",
attr => "int n_projs, long def_proj_num",
},
ShiftLL => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct shift logical left",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
},
ShiftLR => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct shift logical right",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- emit => '. slr %S1, %R2I, %D1',
+ emit => '. srl %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
},
ShiftRA => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct shift right arithmetical",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
},
And => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct logical and",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
},
Or => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct logical or",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
},
Xor => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
comment => "construct logical xor",
mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
constructors => \%binop_operand_constructors,
},
-UMul => {
+Mul => {
state => "exc_pinned",
comment => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
reg_req => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] },
outs => [ "low", "high" ],
constructors => \%binop_operand_constructors,
- emit =>'. umul %S1, %R2I, %D1'
+# emit =>'. mul %S1, %R2I, %D1'
+},
+
+Mulh => {
+ state => "exc_pinned",
+ comment => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
+ reg_req => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
+ outs => [ "low", "high" ],
+ constructors => \%binop_operand_constructors,
+},
+
+Div => {
+ irn_flags => [ "rematerializable" ],
+ state => "exc_pinned",
+# mode => $mode_gp,
+ comment => "construct Div: Div(a, b) = a / b",
+ reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
+ outs => [ "res" ],
+ constructors => \%binop_operand_constructors,
+# emit =>'. div %S1, %R2I, %D1'
},
Minus => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
mode => $mode_gp,
comment => "construct Minus: Minus(a) = -a",
#reg_req => { in => [ "gp" ], out => [ "in_r1" ] },
},
Not => {
- irn_flags => "R",
+ irn_flags => [ "rematerializable" ],
mode => $mode_gp,
comment => "construct Not: Not(a) = !a",
reg_req => { in => [ "gp" ], out => [ "gp" ] },
emit => '. xnor %S1, %%g0, %D1'
},
+Nop => {
+ op_flags => [ "keep" ],
+ reg_req => { in => [], out => [ "none" ] },
+ emit => '. nop',
+},
+
#Mul_i => {
# irn_flags => "R",
# comment => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
# emit => '. not %S1, %D1'
#},
+fAdd => {
+ op_flags => [ "commutative" ],
+ irn_flags => [ "rematerializable" ],
+ comment => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
+ reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
+ emit => '. fadd%FPM %S1, %S2, %D1'
+},
+
+fMul => {
+ op_flags => [ "commutative" ],
+ comment => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
+ reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
+ emit =>'. fmul%FPM %S1, %S2, %D1'
+},
-#--------------------------------------------------------#
-# __ _ _ _ #
-# / _| | | | | | #
-# | |_| | ___ __ _| |_ _ __ ___ __| | ___ ___ #
-# | _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
-# | | | | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ #
-# |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
-#--------------------------------------------------------#
+fsMuld => {
+ op_flags => [ "commutative" ],
+ comment => "construct FP single to double precision Mul: Mul(a, b) = Mul(b, a) = a * b",
+ reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
+ emit =>'. fsmuld %S1, %S2, %D1'
+},
+
+FpSToFpD => {
+ irn_flags => [ "rematerializable" ],
+ comment => "convert FP (single) to FP (double)",
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ emit =>'. FsTOd %S1, %D1'
+},
+
+FpDToFpS => {
+ irn_flags => [ "rematerializable" ],
+ comment => "convert FP (double) to FP (single)",
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ emit =>'. FdTOs %S1, %D1'
+},
+
+FpSToInt => {
+ irn_flags => [ "rematerializable" ],
+ comment => "convert integer to FP",
+ reg_req => { in => [ "fp" ], out => [ "gp" ] },
+ emit =>'. FiTOs %S1, %D1'
+},
+
+FpDToInt => {
+ irn_flags => [ "rematerializable" ],
+ comment => "convert integer to FP",
+ reg_req => { in => [ "fp" ], out => [ "gp" ] },
+ emit =>'. FiTOd %S1, %D1'
+},
+
+IntToFpS => {
+ irn_flags => [ "rematerializable" ],
+ comment => "convert FP (single) to integer",
+ reg_req => { in => [ "gp" ], out => [ "fp" ] },
+ emit =>'. FsTOi %S1, %D1'
+},
+
+IntToFpD => {
+ irn_flags => [ "rematerializable" ],
+ comment => "convert FP (double) to integer",
+ reg_req => { in => [ "gp" ], out => [ "fp" ] },
+ emit =>'. FdTOi %S1, %D1'
+},
-# commutative operations
-#fAdd => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct FP Add: Add(a, b) = Add(b, a) = a + b",
-# reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
-# emit => '. fadd %S1, %S2, %D1'
-#},
-#
-#fMul => {
-# op_flags => "C",
-# comment => "construct FP Mul: Mul(a, b) = Mul(b, a) = a * b",
-# reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
-# emit =>'. fmul %S1, %S2, %D1'
-#},
#
#fMax => {
# op_flags => "C",
## Load / Store
#
#fLoad => {
-# op_flags => "L|F",
+# op_flags => [ "labeled", "fragile" ],
# irn_flags => "R",
# state => "exc_pinned",
# comment => "construct FP Load: Load(ptr, mem) = LD ptr",
#},
#
#fStore => {
-# op_flags => "L|F",
+# op_flags => [ "labeled", "fragile" ],
# irn_flags => "R",
# state => "exc_pinned",
# comment => "construct Store: Store(ptr, val, mem) = ST ptr,val",