# <op-name> => {
# "op_flags" => "N|L|C|X|I|F|Y|H|c|K",
# "irn_flags" => "R|N|I"
-# "arity" => "0|1|2|3 ... |variable|dynamic|all",
-# "state" => "floats|pinned",
+# "arity" => "0|1|2|3 ... |variable|dynamic|any",
+# "state" => "floats|pinned|mem_pinned|exc_pinned",
# "args" => [
# { "type" => "type 1", "name" => "name 1" },
# { "type" => "type 2", "name" => "name 2" },
# ...
# ],
# "comment" => "any comment for constructor",
+# "reg_req" => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] },
+# "cmp_attr" => "c source code for comparing node attributes",
# "emit" => "emit code with templates",
# "rd_constructor" => "c source code which constructs an ir_node"
# },
# N not spillable
# I ignore for register allocation
#
-# state: state of the operation, OPTIONAL (default is "pinned")
+# state: state of the operation, OPTIONAL (default is "floats")
#
# arity: arity of the operation, MUST NOT BE OMITTED
#
# 1 - caller save (register must be saved by the caller of a function)
# 2 - callee save (register must be saved by the called function)
# 4 - ignore (do not assign this register)
-# 8 - this is the stack pointer
-# 16 - this is the base pointer
-# NOTE: Make sure to list the registers returning the call-result before all other
-# caller save registers and in the correct order, otherwise it will break
-# the magic!
-# Last entry of each class is the largest Firm-Mode a register can hold
+# NOTE: Last entry of each class is the largest Firm-Mode a register can hold
%reg_classes = (
"gp" => [
{ "name" => "eax", "type" => 1 },
{ "name" => "esi", "type" => 2 },
{ "name" => "edi", "type" => 2 },
{ "name" => "ebp", "type" => 2 },
- { "name" => "esp", "type" => 6 },
+ { "name" => "esp", "type" => 4 },
{ "name" => "xxx", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes
{ "mode" => "mode_P" }
],
{ "name" => "xmm5", "type" => 1 },
{ "name" => "xmm6", "type" => 1 },
{ "name" => "xmm7", "type" => 1 },
- { "name" => "xxxx", "type" => 4 }, # we need a dummy register for NoReg and Unknown nodes
+ { "name" => "xxxx", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes
{ "mode" => "mode_D" }
]
); # %reg_classes
"Add" => {
"irn_flags" => "R",
"comment" => "construct Add: Add(a, b) = Add(b, a) = a + b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. add %ia32_emit_binop\t\t\t/* Add(%A1, %A2) -> %D1 */'
},
"Mul" => {
"irn_flags" => "A",
"comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. imul %ia32_emit_binop\t\t\t/* Mul(%A1, %A2) -> %D1 */'
},
# Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
"Mulh" => {
"comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r1", "edx in_r2" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx in_r4" ] },
"emit" => '. imul %ia32_emit_unop\t\t\t/* Mulh(%A1, %A2) -> %D1 */ '
},
"And" => {
"irn_flags" => "R",
"comment" => "construct And: And(a, b) = And(b, a) = a AND b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. and %ia32_emit_binop\t\t\t/* And(%A1, %A2) -> %D1 */'
},
"Or" => {
"irn_flags" => "R",
"comment" => "construct Or: Or(a, b) = Or(b, a) = a OR b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. or %ia32_emit_binop\t\t\t/* Or(%A1, %A2) -> %D1 */'
},
"Eor" => {
"irn_flags" => "R",
"comment" => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. xor %ia32_emit_binop\t\t\t/* Xor(%A1, %A2) -> %D1 */'
},
'
},
+"CMov" => {
+ "irn_flags" => "R",
+ "comment" => "construct Mux: Mux(sel, a, b) == sel ? a : b",
+ "reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2" ] },
+ "emit" =>
+'. cmp %S1, 0\t\t\t/* compare Sel for CMov (%A2, %A3) */
+. cmovne %D1, %S3\t\t\t/* sel == true -> return %S3 */
+'
+},
+
# not commutative operations
"Sub" => {
"irn_flags" => "R",
"comment" => "construct Sub: Sub(a, b) = a - b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. sub %ia32_emit_binop\t\t\t/* Sub(%A1, %A2) -> %D1 */'
},
"Shl" => {
"irn_flags" => "R",
"comment" => "construct Shl: Shl(a, b) = a << b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3" ] },
"emit" => '. shl %ia32_emit_binop\t\t\t/* Shl(%A1, %A2) -> %D1 */'
},
"Shr" => {
"irn_flags" => "R",
"comment" => "construct Shr: Shr(a, b) = a >> b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3" ] },
"emit" => '. shr %ia32_emit_binop\t\t\t/* Shr(%A1, %A2) -> %D1 */'
},
"Shrs" => {
"irn_flags" => "R",
"comment" => "construct Shrs: Shrs(a, b) = a >> b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3" ] },
"emit" => '. sar %ia32_emit_binop\t\t\t/* Shrs(%A1, %A2) -> %D1 */'
},
"RotR" => {
"irn_flags" => "R",
"comment" => "construct RotR: RotR(a, b) = a ROTR b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3" ] },
"emit" => '. ror %ia32_emit_binop\t\t\t/* RotR(%A1, %A2) -> %D1 */'
},
"RotL" => {
"irn_flags" => "R",
"comment" => "construct RotL: RotL(a, b) = a ROTL b",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3" ] },
"emit" => '. rol %ia32_emit_binop\t\t\t/* RotL(%A1, %A2) -> %D1 */'
},
"Minus" => {
"irn_flags" => "R",
"comment" => "construct Minus: Minus(a) = -a",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. neg %ia32_emit_unop\t\t\t/* Neg(%A1) -> %D1, (%A1) */'
},
"Inc" => {
"irn_flags" => "R",
"comment" => "construct Increment: Inc(a) = a++",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. inc %ia32_emit_unop\t\t\t/* Inc(%S1) -> %D1, (%A1) */'
},
"Dec" => {
"irn_flags" => "R",
"comment" => "construct Decrement: Dec(a) = a--",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. dec %ia32_emit_unop\t\t\t/* Dec(%S1) -> %D1, (%A1) */'
},
"Not" => {
"irn_flags" => "R",
"comment" => "construct Not: Not(a) = !a",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. not %ia32_emit_unop\t\t\t/* Not(%S1) -> %D1, (%A1) */'
},
# other operations
"Conv" => {
- "arity" => 1,
"reg_req" => { "in" => [ "gp" ], "out" => [ "in_r1" ] },
"comment" => "construct Conv: Conv(a) = (conv)a"
},
"CondJmp" => {
"op_flags" => "L|X|Y",
"comment" => "construct conditional jump: CMP A, B && JMPxx LABEL",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "none", "none" ] },
},
"SwitchJmp" => {
"op_flags" => "L|X|Y",
"comment" => "construct switch",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp" ], "out" => [ "none" ] },
},
"Const" => {
"op_flags" => "c",
"irn_flags" => "R",
"comment" => "represents an integer constant",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "out" => [ "gp" ] },
- "emit" => '. mov %D1, %C\t\t\t/* Mov Const into register */',
- "cmp_attr" =>
-'
- if (attr_a->tp == attr_b->tp) {
- if (attr_a->tp == ia32_SymConst) {
- if (attr_a->sc == NULL || attr_b->sc == NULL)
- return 1;
- else
- return strcmp(attr_a->sc, attr_b->sc);
- }
- else {
- if (attr_a->tv == NULL || attr_b->tv == NULL)
- return 1;
-
- if (tarval_cmp(attr_a->tv, attr_b->tv) == pn_Cmp_Eq)
- return 0;
- else
- return 1;
- }
+ "emit" =>
+' if (get_ia32_Immop_tarval(n) == get_tarval_null(get_irn_mode(n))) {
+4. sub %D1, %D1\t\t\t/* optimized mov 0 to register */
}
- else
- return 1;
-'
+ else {
+4. mov %D1, %C\t\t\t/* Mov Const into register */
+ }
+',
},
"Cdq" => {
"irn_flags" => "R",
"state" => "exc_pinned",
"comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
"emit" => '. mov %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */'
},
"op_flags" => "L|F",
"state" => "exc_pinned",
"comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "gp", "none" ] },
- "emit" => '. mov %ia32_emit_am, %S3\t\t\t/* Store(%A2) -> (%A1) */'
+ "emit" => '. mov %ia32_emit_binop\t\t\t/* Store(%A3) -> (%A1) */'
},
"Lea" => {
"irn_flags" => "R",
"comment" => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
- "emit" => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << %C + %O, (%A1, %A2) */'
-},
-
-"StackParam" => {
- "arity" => 1,
- "remat" => 1,
- "comment" => "constructs a Stack Parameter to retrieve a parameter from Stack",
- "reg_req" => { "in" => [ "none" ], "out" => [ "gp" ] },
- "cmp_attr" =>
-'
- return (attr_a->pn_code != attr_b->pn_code);
-'
-},
-
-"StackArg" => {
- "arity" => 2,
- "comment" => "constructs a Stack Argument to pass an argument on Stack",
- "reg_req" => { "in" => [ "none", "gp" ], "out" => [ "none" ] },
- "cmp_attr" =>
-'
- return (attr_a->pn_code != attr_b->pn_code);
-'
+ "emit" => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << scale + %O, (%A1, %A2) */'
},
#--------------------------------------------------------#
"fAdd" => {
"irn_flags" => "R",
"comment" => "construct SSE Add: Add(a, b) = Add(b, a) = a + b",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. adds%M %ia32_emit_binop\t\t\t/* SSE Add(%A1, %A2) -> %D1 */'
},
"fMul" => {
"irn_flags" => "R",
"comment" => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. muls%M %ia32_emit_binop\t\t\t/* SSE Mul(%A1, %A2) -> %D1 */'
},
"fMax" => {
"irn_flags" => "R",
"comment" => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. maxs%M %ia32_emit_binop\t\t\t/* SSE Max(%A1, %A2) -> %D1 */'
},
"fMin" => {
"irn_flags" => "R",
"comment" => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. mins%M %ia32_emit_binop\t\t\t/* SSE Min(%A1, %A2) -> %D1 */'
},
"fAnd" => {
"irn_flags" => "R",
"comment" => "construct SSE And: And(a, b) = a AND b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. andp%M %ia32_emit_binop\t\t\t/* SSE And(%A3, %A4) -> %D1 */'
},
"fOr" => {
"irn_flags" => "R",
"comment" => "construct SSE Or: Or(a, b) = a OR b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. orp%M %ia32_emit_binop\t\t\t/* SSE Or(%A3, %A4) -> %D1 */'
},
"fEor" => {
"irn_flags" => "R",
"comment" => "construct SSE Eor: Eor(a, b) = a XOR b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. xorp%M %ia32_emit_binop\t\t\t/* SSE Xor(%A3, %A4) -> %D1 */'
},
"fSub" => {
"irn_flags" => "R",
"comment" => "construct SSE Sub: Sub(a, b) = a - b",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. subs%M %ia32_emit_binop\t\t\t/* SSE Sub(%A1, %A2) -> %D1 */'
},
"fDiv" => {
"irn_flags" => "R",
"comment" => "construct SSE Div: Div(a, b) = a / b",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. divs%M %ia32_emit_binop\t\t\t/* SSE Div(%A1, %A2) -> %D1 */'
},
# other operations
"fConv" => {
- "arity" => 1,
"reg_req" => { "in" => [ "fp" ], "out" => [ "gp" ] },
"comment" => "construct Conv: Conv(a) = (conv)a"
},
"fCondJmp" => {
"op_flags" => "L|X|Y",
"comment" => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "none", "none" ] },
},
"op_flags" => "c",
"irn_flags" => "R",
"comment" => "represents a SSE constant",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "out" => [ "fp" ] },
"emit" => '. mov%M %D1, %C\t\t\t/* Load fConst into register */',
- "cmp_attr" =>
-'
- if (attr_a->tp == attr_b->tp) {
- if (attr_a->tp == ia32_SymConst) {
- if (attr_a->sc == NULL || attr_b->sc == NULL)
- return 1;
- else
- return strcmp(attr_a->sc, attr_b->sc);
- }
- else {
- if (attr_a->tv == NULL || attr_b->tv == NULL)
- return 1;
-
- if (tarval_cmp(attr_a->tv, attr_b->tv) == pn_Cmp_Eq)
- return 0;
- else
- return 1;
- }
- }
- else
- return 1;
-'
},
# Load / Store
"irn_flags" => "R",
"state" => "exc_pinned",
"comment" => "construct SSE Load: Load(ptr, mem) = LD ptr",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "fp" ] },
"emit" => '. movs%M %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */'
},
"op_flags" => "L|F",
"state" => "exc_pinned",
"comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "fp", "none" ] },
"emit" => '. movs%M %ia32_emit_am, %S3\t\t\t/* Store(%S3) -> (%A1) */'
},
-"fStackParam" => {
- "arity" => 1,
- "remat" => 1,
- "comment" => "constructs a Stack Parameter to retrieve a SSE parameter from Stack",
- "reg_req" => { "in" => [ "none" ], "out" => [ "fp" ] },
- "cmp_attr" =>
-'
- return (attr_a->pn_code != attr_b->pn_code);
-'
-},
+# CopyB
-"fStackArg" => {
- "arity" => 2,
- "comment" => "constructs a Stack Argument to pass an argument on Stack",
- "reg_req" => { "in" => [ "none", "fp" ], "out" => [ "none" ] },
- "cmp_attr" =>
-'
- return (attr_a->pn_code != attr_b->pn_code);
-'
-},
-
-# Call
-
-"Call" => {
- "op_flags" => "L|F",
- "state" => "mem_pinned",
- "arity" => "variable",
- "comment" => "construct Call: Call(...)",
- "args" => [
- { "type" => "int", "name" => "n" },
- { "type" => "ir_node **", "name" => "in" }
- ],
- "rd_constructor" =>
-" if (!op_ia32_Call) assert(0);
- return new_ir_node(db, irg, block, op_ia32_Call, mode_T, n, in);
-"
-},
-
-# Return
-
-"Return" => {
- "op_flags" => "L|X",
+"CopyB" => {
+ "op_flags" => "F|H",
"state" => "pinned",
- "arity" => "variable",
- "comment" => "construct Return: Return(...)",
- "args" => [
- { "type" => "int", "name" => "n" },
- { "type" => "ir_node **", "name" => "in" }
- ],
- "rd_constructor" =>
-" if (!op_ia32_Return) assert(0);
- return new_ir_node(db, irg, block, op_ia32_Return, mode_X, n, in);
-"
+ "comment" => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
+ "reg_req" => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "none" ] },
},
-# M/Alloc
-
-"Alloca" => {
- "op_flags" => "L|F",
+"CopyB_i" => {
+ "op_flags" => "F|H",
"state" => "pinned",
- "arity" => "2",
- "comment" => "construct Alloca: allocate memory on Stack",
- "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] }
+ "comment" => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] },
},
); # end of %nodes