- 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 => "R",
- 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",
- mode => $mode_gp,
- comment => "construct Minus: Minus(a) = -a",
- #reg_req => { in => [ "gp" ], out => [ "in_r1" ] },
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => ". sub %%g0, %S1, %D1"
-},
-
-Not => {
- irn_flags => "R",
- mode => $mode_gp,
- comment => "construct Not: Not(a) = !a",
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. xnor %S1, %%g0, %D1'
-},
-
-Nop => {
- op_flags => "K",
- reg_req => { in => [], out => [ "none" ] },
- emit => '. nop',
-},
-
-#Mul_i => {
-# irn_flags => "R",
-# comment => "construct Mul: Mul(a, const) = Mul(const, a) = a * const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. mul %S1, %C, %D1'
-#},
-#
-#And => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct And: And(a, b) = And(b, a) = a AND b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
-# emit => '. and %S1, %S2, %D1'
-#},
-#
-#And_i => {
-# irn_flags => "R",
-# comment => "construct And: And(a, const) = And(const, a) = a AND const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. and %S1, %C, %D1'
-#},
-#
-#Or => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct Or: Or(a, b) = Or(b, a) = a OR b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
-# emit => '. or %S1, %S2, %D1'
-#},
-#
-#Or_i => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct Or: Or(a, const) = Or(const, a) = a OR const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. or %S1, %C, %D1'
-#},
-#
-#Eor => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
-# emit => '. xor %S1, %S2, %D1'
-#},
-#
-#Eor_i => {
-# irn_flags => "R",
-# comment => "construct Eor: Eor(a, const) = Eor(const, a) = a EOR const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. xor %S1, %C, %D1'
-#},
-
-# not commutative operations
-#Shl => {
-# irn_flags => "R",
-# comment => "construct Shl: Shl(a, b) = a << b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
-# emit => '. shl %S1, %S2, %D1'
-#},
-#
-#Shl_i => {
-# irn_flags => "R",
-# comment => "construct Shl: Shl(a, const) = a << const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. shl %S1, %C, %D1'
-#},
-#
-#Shr => {
-# irn_flags => "R",
-# comment => "construct Shr: Shr(a, b) = a >> b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "in_r1" ] },
-# emit => '. shr %S2, %D1'
-#},
-#
-#Shr_i => {
-# irn_flags => "R",
-# comment => "construct Shr: Shr(a, const) = a >> const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. shr %S1, %C, %D1'
-#},
-#
-#RotR => {
-# irn_flags => "R",
-# comment => "construct RotR: RotR(a, b) = a ROTR b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
-# emit => '. ror %S1, %S2, %D1'
-#},
-#
-#RotL => {
-# irn_flags => "R",
-# comment => "construct RotL: RotL(a, b) = a ROTL b",
-# reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
-# emit => '. rol %S1, %S2, %D1'
-#},
-#
-#RotL_i => {
-# irn_flags => "R",
-# comment => "construct RotL: RotL(a, const) = a ROTL const",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. rol %S1, %C, %D1'
-#},
-#
-#Minus => {
-# irn_flags => "R",
-# comment => "construct Minus: Minus(a) = -a",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. neg %S1, %D1'
-#},
-#
-#Inc => {
-# irn_flags => "R",
-# comment => "construct Increment: Inc(a) = a++",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. inc %S1, %D1'
-#},
-#
-#Dec => {
-# irn_flags => "R",
-# comment => "construct Decrement: Dec(a) = a--",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. dec %S1, %D1'
-#},
-#
-#Not => {
-# arity => 1,
-# remat => 1,
-# comment => "construct Not: Not(a) = !a",
-# reg_req => { in => [ "gp" ], out => [ "gp" ] },
-# emit => '. not %S1, %D1'
-#},
-
-
-#--------------------------------------------------------#
-# __ _ _ _ #
-# / _| | | | | | #
-# | |_| | ___ __ _| |_ _ __ ___ __| | ___ ___ #
-# | _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
-# | | | | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ #
-# |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
-#--------------------------------------------------------#
-
-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%FPM %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%FPM %S1, %S2, %D1'
-},
-
-fsMuld => {
- op_flags => "C",
- 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 => "R",
- comment => "convert FP (single) to FP (double)",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit =>'. FsTOd %S1, %D1'
-},
-
-FpDToFpS => {
- irn_flags => "R",
- comment => "convert FP (double) to FP (single)",
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit =>'. FdTOs %S1, %D1'
-},
-
-FpSToInt => {
- irn_flags => "R",
- comment => "convert integer to FP",
- reg_req => { in => [ "fp" ], out => [ "gp" ] },
- emit =>'. FiTOs %S1, %D1'
-},
-
-FpDToInt => {
- irn_flags => "R",
- comment => "convert integer to FP",
- reg_req => { in => [ "fp" ], out => [ "gp" ] },
- emit =>'. FiTOd %S1, %D1'
-},
-
-IntToFpS => {
- irn_flags => "R",
- comment => "convert FP (single) to integer",
- reg_req => { in => [ "gp" ], out => [ "fp" ] },
- emit =>'. FsTOi %S1, %D1'
-},
-
-IntToFpD => {
- irn_flags => "R",
- comment => "convert FP (double) to integer",
- reg_req => { in => [ "gp" ], out => [ "fp" ] },
- emit =>'. FdTOi %S1, %D1'
-},
-
-
-#
-#fMax => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct FP Max: Max(a, b) = Max(b, a) = a > b ? a : b",
-# reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
-# emit =>'. fmax %S1, %S2, %D1'
-#},
-#
-#fMin => {
-# op_flags => "C",
-# irn_flags => "R",
-# comment => "construct FP Min: Min(a, b) = Min(b, a) = a < b ? a : b",
-# reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
-# emit =>'. fmin %S1, %S2, %D1'
-#},
-#
-## not commutative operations
-#
-#fSub => {
-# irn_flags => "R",
-# comment => "construct FP Sub: Sub(a, b) = a - b",
-# reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
-# emit => '. fsub %S1, %S2, %D1'
-#},
-#
-#fDiv => {
-# comment => "construct FP Div: Div(a, b) = a / b",
-# reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
-# emit => '. fdiv %S1, %S2, %D1'
-#},
-#
-#fMinus => {
-# irn_flags => "R",
-# comment => "construct FP Minus: Minus(a) = -a",
-# reg_req => { in => [ "fp" ], out => [ "fp" ] },
-# emit => '. fneg %S1, %D1'
-#},
-#
-## other operations
-#
-#fConst => {
-# op_flags => "c",
-# irn_flags => "R",
-# comment => "represents a FP constant",
-# reg_req => { out => [ "fp" ] },
-# emit => '. fmov %C, %D1',
-# cmp_attr =>
-#'
-# /* TODO: compare fConst attributes */
-# return 1;
-#'
-#},
-#
-## Load / Store
-#
-#fLoad => {
-# op_flags => "L|F",
-# irn_flags => "R",
-# state => "exc_pinned",
-# comment => "construct FP Load: Load(ptr, mem) = LD ptr",
-# reg_req => { in => [ "gp", "none" ], out => [ "fp" ] },
-# emit => '. fmov (%S1), %D1'
-#},
-#
-#fStore => {
-# op_flags => "L|F",
-# irn_flags => "R",
-# state => "exc_pinned",
-# comment => "construct Store: Store(ptr, val, mem) = ST ptr,val",
-# reg_req => { in => [ "gp", "fp", "none" ] },
-# emit => '. fmov %S2, (%S1)'
-#},
+ irn_flags => [ "rematerializable" ],
+ outs => [ "low", "high" ],
+ constructors => \%binop_operand_constructors,
+},
+
+SDiv => {
+ irn_flags => [ "rematerializable" ],
+ state => "exc_pinned",
+ ins => [ "dividend_high", "dividend_low", "divisor" ],
+ outs => [ "res", "M" ],
+ constructors => \%div_operand_constructors,
+},
+
+UDiv => {
+ irn_flags => [ "rematerializable" ],
+ state => "exc_pinned",
+ ins => [ "dividend_high", "dividend_low", "divisor" ],
+ outs => [ "res", "M" ],
+ constructors => \%div_operand_constructors,
+},
+
+fcmp => {
+ irn_flags => [ "rematerializable", "modifies_fp_flags" ],
+ emit => '. fcmp%FPM %S0, %S1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fpflags,
+ constructors => {
+ s => {
+ reg_req => { in => [ "fp", "fp" ], out => [ "fpflags" ] },
+ },
+ d => {
+ reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fpflags" ] },
+ },
+ q => {
+ reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fpflags" ] },
+ },
+ },
+},
+
+fadd => {
+ op_flags => [ "commutative" ],
+ irn_flags => [ "rematerializable" ],
+ emit => '. fadd%FPM %S0, %S1, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ ins => [ "left", "right" ],
+ constructors => \%float_binop_constructors,
+},
+
+fsub => {
+ irn_flags => [ "rematerializable" ],
+ emit => '. fsub%FPM %S0, %S1, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ ins => [ "left", "right" ],
+ constructors => \%float_binop_constructors,
+},
+
+fmul => {
+ irn_flags => [ "rematerializable" ],
+ op_flags => [ "commutative" ],
+ emit =>'. fmul%FPM %S0, %S1, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ ins => [ "left", "right" ],
+ constructors => \%float_binop_constructors,
+},
+
+fdiv => {
+ irn_flags => [ "rematerializable" ],
+ emit => '. fdiv%FPM %S0, %S1, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ ins => [ "left", "right" ],
+ outs => [ "res", "M" ],
+ constructors => {
+ s => {
+ reg_req => { in => [ "fp", "fp" ], out => [ "fp", "none" ] },
+ },
+ d => {
+ reg_req => { in => [ "fp:a|2", "fp:a|2" ], out => [ "fp:a|2", "none" ] },
+ },
+ q => {
+ reg_req => { in => [ "fp:a|4", "fp:a|4" ], out => [ "fp:a|4", "none" ] },
+ }
+ },
+},
+
+fneg => {
+ irn_flags => [ "rematerializable" ],
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ # note that we only need the first register even for wide-values
+ emit => '. fneg %S0, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ ins => [ "val" ],
+ constructors => \%float_unop_constructors,
+},
+
+"fabs" => {
+ irn_flags => [ "rematerializable" ],
+ # note that we only need the first register even for wide-values
+ emit => '. fabs %S0, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ ins => [ "val" ],
+ constructors => \%float_unop_constructors,
+},
+
+fftof => {
+ irn_flags => [ "rematerializable" ],
+ emit => '. f%FCONVS%.to%FCONVD %S0, %D0',
+ attr_type => "sparc_fp_conv_attr_t",
+ attr => "ir_mode *src_mode, ir_mode *dest_mode",
+ constructors => {
+ s_d => {
+ reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
+ mode => $mode_fp2,
+ },
+ s_q => {
+ reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
+ mode => $mode_fp4,
+ },
+ d_s => {
+ reg_req => { in => [ "fp:a|2" ], out => [ "fp" ] },
+ mode => $mode_fp,
+ },
+ d_q => {
+ reg_req => { in => [ "fp:a|2" ], out => [ "fp:a|4" ] },
+ mode => $mode_fp4,
+ },
+ q_s => {
+ reg_req => { in => [ "fp:a|4" ], out => [ "fp" ] },
+ mode => $mode_fp,
+ },
+ q_d => {
+ reg_req => { in => [ "fp:a|4" ], out => [ "fp:a|2" ] },
+ mode => $mode_fp2,
+ },
+ },
+},
+
+fitof => {
+ irn_flags => [ "rematerializable" ],
+ emit => '. fito%FPM %S0, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ constructors => {
+ s => {
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ mode => $mode_fp,
+ },
+ d => {
+ reg_req => { in => [ "fp" ], out => [ "fp:a|2" ] },
+ mode => $mode_fp2,
+ },
+ q => {
+ reg_req => { in => [ "fp" ], out => [ "fp:a|4" ] },
+ mode => $mode_fp4,
+ },
+ },
+},
+
+fftoi => {
+ irn_flags => [ "rematerializable" ],
+ emit => '. f%FPM%.toi %S0, %D0',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_gp,
+ constructors => {
+ s => {
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ },
+ d => {
+ reg_req => { in => [ "fp:a|2" ], out => [ "fp" ] },
+ },
+ q => {
+ reg_req => { in => [ "fp:a|4" ], out => [ "fp" ] },
+ },
+ },
+},
+
+Ldf => {
+ op_flags => [ "labeled", "fragile" ],
+ state => "exc_pinned",
+ constructors => {
+ s => {
+ reg_req => { in => [ "gp", "none" ], out => [ "fp", "none" ] },
+ },
+ d => {
+ reg_req => { in => [ "gp", "none" ], out => [ "fp:a|2", "none" ] },
+ },
+ q => {
+ reg_req => { in => [ "gp", "none" ], out => [ "fp:a|4", "none" ] },
+ },
+ },
+ ins => [ "ptr", "mem" ],
+ outs => [ "res", "M" ],
+ attr_type => "sparc_load_store_attr_t",
+ attr => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
+ custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
+ emit => '. ld%FLSM [%S0%O1], %D0'
+},
+
+Stf => {
+ op_flags => [ "labeled", "fragile" ],
+ state => "exc_pinned",
+ constructors => {
+ s => {
+ reg_req => { in => [ "fp", "gp", "none" ], out => [ "none" ] },
+ },
+ d => {
+ reg_req => { in => [ "fp:a|2", "gp", "none" ], out => [ "none" ] },
+ },
+ q => {
+ reg_req => { in => [ "fp:a|4", "gp", "none" ], out => [ "none" ] },
+ },
+ },
+ ins => [ "val", "ptr", "mem" ],
+ outs => [ "M" ],
+ attr_type => "sparc_load_store_attr_t",
+ attr => "ir_mode *ls_mode, ir_entity *entity, int32_t offset, bool is_frame_entity",
+ custominit => "init_sparc_load_store_attributes(res, ls_mode, entity, offset, is_frame_entity, false);",
+ emit => '. st%FLSM %S0, [%S1%O2]',
+ mode => 'mode_M',
+},