+ mmx => [
+ { name => "mm0", type => 4 },
+ { name => "mm1", type => 4 },
+ { name => "mm2", type => 4 },
+ { name => "mm3", type => 4 },
+ { name => "mm4", type => 4 },
+ { name => "mm5", type => 4 },
+ { name => "mm6", type => 4 },
+ { name => "mm7", type => 4 },
+ { mode => "mode_E" }
+ ],
- S1 => "${arch}_emit_source_register(env, node, 0);",
- S2 => "${arch}_emit_source_register(env, node, 1);",
- S3 => "${arch}_emit_source_register(env, node, 2);",
- S4 => "${arch}_emit_source_register(env, node, 3);",
- S5 => "${arch}_emit_source_register(env, node, 4);",
- S6 => "${arch}_emit_source_register(env, node, 5);",
- D1 => "${arch}_emit_dest_register(env, node, 0);",
- D2 => "${arch}_emit_dest_register(env, node, 1);",
- D3 => "${arch}_emit_dest_register(env, node, 2);",
- D4 => "${arch}_emit_dest_register(env, node, 3);",
- D5 => "${arch}_emit_dest_register(env, node, 4);",
- D6 => "${arch}_emit_dest_register(env, node, 5);",
- X1 => "${arch}_emit_x87_name(env, node, 0);",
- X2 => "${arch}_emit_x87_name(env, node, 1);",
- X3 => "${arch}_emit_x87_name(env, node, 2);",
+ 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);",
+ S5 => "${arch}_emit_source_register(env, node, 5);",
+ D0 => "${arch}_emit_dest_register(env, node, 0);",
+ D1 => "${arch}_emit_dest_register(env, node, 1);",
+ D2 => "${arch}_emit_dest_register(env, node, 2);",
+ D3 => "${arch}_emit_dest_register(env, node, 3);",
+ D4 => "${arch}_emit_dest_register(env, node, 4);",
+ D5 => "${arch}_emit_dest_register(env, node, 5);",
+ X0 => "${arch}_emit_x87_name(env, node, 0);",
+ X1 => "${arch}_emit_x87_name(env, node, 1);",
+ X2 => "${arch}_emit_x87_name(env, node, 2);",
XM => "${arch}_emit_x87_mode_suffix(env, node);",
XXM => "${arch}_emit_xmm_mode_suffix(env, node);",
XSD => "${arch}_emit_xmm_mode_suffix_s(env, node);",
AM => "${arch}_emit_am(env, node);",
XM => "${arch}_emit_x87_mode_suffix(env, node);",
XXM => "${arch}_emit_xmm_mode_suffix(env, node);",
XSD => "${arch}_emit_xmm_mode_suffix_s(env, node);",
AM => "${arch}_emit_am(env, node);",
- unop => "${arch}_emit_unop(env, node);",
+ unop0 => "${arch}_emit_unop(env, node, 0);",
+ unop1 => "${arch}_emit_unop(env, node, 1);",
+ unop2 => "${arch}_emit_unop(env, node, 2);",
+ unop3 => "${arch}_emit_unop(env, node, 3);",
+ unop4 => "${arch}_emit_unop(env, node, 4);",
+ DAM0 => "${arch}_emit_am_or_dest_register(env, node, 0);",
+ DAM1 => "${arch}_emit_am_or_dest_register(env, node, 0);",
-$default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
+$default_attr_type = "ia32_attr_t";
+
+%init_attr = (
+ ia32_attr_t => "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
+ ia32_x87_attr_t =>
+ "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+ "\tinit_ia32_x87_attributes(res);",
+ ia32_asm_attr_t =>
+ "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+ "\tinit_ia32_x87_attributes(res);".
+ "\tinit_ia32_asm_attributes(res);",
+ ia32_immediate_attr_t =>
+ "\tinit_ia32_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n".
+ "\tinit_ia32_immediate_attributes(res, symconst, symconst_sign, offset);"
+);
+
+%compare_attr = (
+ ia32_attr_t => "ia32_compare_nodes_attr",
+ ia32_x87_attr_t => "ia32_compare_x87_attr",
+ ia32_asm_attr_t => "ia32_compare_asm_attr",
+ ia32_immediate_attr_t => "ia32_compare_immediate_attr",
+);
reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] },
attr => "ia32_op_flavour_t dm_flav",
init_attr => "attr->data.op_flav = dm_flav;",
reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] },
attr => "ia32_op_flavour_t dm_flav",
init_attr => "attr->data.op_flav = dm_flav;",
reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] },
attr => "ia32_op_flavour_t dm_flav",
init_attr => "attr->data.op_flav = dm_flav;",
reg_req => { in => [ "gp", "gp", "eax", "edx", "gp", "none" ], out => [ "eax", "edx", "none" ] },
attr => "ia32_op_flavour_t dm_flav",
init_attr => "attr->data.op_flav = dm_flav;",
- # this Shift and the only value dying is the ShiftCount. Then there would be a
- # register missing, as result must not be ecx and all other registers are
- # occupied. What we should write is "!in_r4 !in_r5", but this is not supported
- # (and probably never will). So we create artificial interferences of the result
- # with all inputs, so the spiller can always assure a free register.
+ # this Shift and the only value dying is the ShiftCount. Then there would be
+ # a register missing, as result must not be ecx and all other registers are
+ # occupied. What we should write is "!in_r4 !in_r5", but this is not
+ # supported (and probably never will). So we create artificial interferences
+ # of the result with all inputs, so the spiller can always assure a free
+ # register.
reg_req => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] },
emit =>
'
if (get_ia32_immop_type(node) == ia32_ImmNone) {
if (get_ia32_op_type(node) == ia32_AddrModeD) {
reg_req => { in => [ "gp", "gp", "gp", "gp", "ecx", "none" ], out => [ "!in" ] },
emit =>
'
if (get_ia32_immop_type(node) == ia32_ImmNone) {
if (get_ia32_op_type(node) == ia32_AddrModeD) {
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none" ] },
outs => [ "false", "true" ],
units => [ "BRANCH" ],
reg_req => { in => [ "gp", "gp", "gp", "gp", "none" ], out => [ "none", "none" ] },
outs => [ "false", "true" ],
units => [ "BRANCH" ],
reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
emit => '. addl %binop',
outs => [ "stack:S", "M" ],
reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
emit => '. addl %binop',
outs => [ "stack:S", "M" ],
reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
emit => '. subl %binop',
outs => [ "stack:S", "M" ],
reg_req => { in => [ "gp", "gp", "esp", "gp", "none" ], out => [ "in_r3", "none" ] },
emit => '. subl %binop',
outs => [ "stack:S", "M" ],
reg_req => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "none", "none" ] },
outs => [ "false", "true" ],
latency => 5,
reg_req => { in => [ "gp", "gp", "xmm", "xmm", "none" ], out => [ "none", "none" ] },
outs => [ "false", "true" ],
latency => 5,
- comment => "construct Store without index: Store(ptr, val, mem) = ST ptr,val",
- reg_req => { in => [ "gp", "xmm", "none" ] },
+ reg_req => { in => [ "gp", "gp", "xmm", "none" ] },
+ ins => [ "base", "index", "val", "mem" ],
- state => "exc_pinned",
- comment => "load ST0 from stack",
- reg_req => { in => [ "gp", "none" ], out => [ "vf0", "none" ] },
- emit => '. fld%M %AM',
+ state => "pinned",
+ reg_req => { in => [ "gp", "gp", "none" ], out => [ "vf0", "none" ] },
+ ins => [ "base", "index", "mem" ],
+ emit => '. fld%XM %AM',
reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
outs => [ "DST", "SRC", "CNT", "M" ],
units => [ "GP" ],
reg_req => { in => [ "edi", "esi", "ecx", "none" ], out => [ "edi", "esi", "ecx", "none" ] },
outs => [ "DST", "SRC", "CNT", "M" ],
units => [ "GP" ],
reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
outs => [ "DST", "SRC", "M" ],
units => [ "GP" ],
reg_req => { in => [ "edi", "esi", "none" ], out => [ "edi", "esi", "none" ] },
outs => [ "DST", "SRC", "M" ],
units => [ "GP" ],
- comment => "virtual fp Add: Add(a, b) = Add(b, a) = a + b",
- reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+ reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "left", "right", "mem", "fpcw" ],
- comment => "virtual fp Mul: Mul(a, b) = Mul(b, a) = a * b",
- reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+ reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "left", "right", "mem", "fpcw" ],
- comment => "virtual fp Sub: Sub(a, b) = a - b",
- reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+ reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "left", "right", "mem", "fpcw" ],
- comment => "virtual fp Div: Div(a, b) = a / b",
- reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+ reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp", "none" ] },
+ ins => [ "base", "index", "left", "right", "mem", "fpcw" ],
- comment => "virtual fp Rem: Rem(a, b) = a - Q * b (Q is integer)",
- reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "vfp" ] },
+ reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none", "fpcw" ], out => [ "vfp" ] },
+ ins => [ "base", "index", "left", "right", "mem", "fpcw" ],
-},
-
-vfsin => {
- irn_flags => "R",
- comment => "virtual fp Sin: Sin(a) = sin(a)",
- reg_req => { in => [ "vfp"], out => [ "vfp" ] },
- latency => 150,
- units => [ "VFP" ],
- mode => "mode_E",
-},
-
-vfcos => {
- irn_flags => "R",
- comment => "virtual fp Cos: Cos(a) = cos(a)",
- reg_req => { in => [ "vfp"], out => [ "vfp" ] },
- latency => 150,
- units => [ "VFP" ],
- mode => "mode_E",
-},
-
-vfsqrt => {
- irn_flags => "R",
- comment => "virtual fp Sqrt: Sqrt(a) = a ^ 0.5",
- reg_req => { in => [ "vfp"], out => [ "vfp" ] },
- latency => 30,
- units => [ "VFP" ],
- mode => "mode_E",
+ attr_type => "ia32_x87_attr_t",
reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "none", "none", "eax" ] },
outs => [ "false", "true", "temp_reg_eax" ],
latency => 10,
units => [ "VFP" ],
reg_req => { in => [ "gp", "gp", "vfp", "vfp", "none" ], out => [ "none", "none", "eax" ] },
outs => [ "false", "true", "temp_reg_eax" ],
latency => 10,
units => [ "VFP" ],