Commit 99ba6c29 authored by Matthias Braun's avatar Matthias Braun
Browse files

- use flags handling code for ia32 Compares (including Cmov, Set, Jcc)

- Allow Source/DestAM with 8/16bit modes where this is profitable

[r15906]
parent 4b24a35d
......@@ -497,12 +497,11 @@ static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_
ir_mode *mode_bp = env->isa->bp->reg_class->mode;
ir_graph *irg = current_ir_graph;
/* gcc always emits a leave at the end of a routine */
if (ARCH_AMD(isa->opt_arch)) {
ir_node *leave;
/* leave */
leave = new_rd_ia32_Leave(NULL, env->irg, bl, curr_sp, curr_bp);
leave = new_rd_ia32_Leave(NULL, irg, bl, curr_sp, curr_bp);
set_ia32_flags(leave, arch_irn_flags_ignore);
curr_bp = new_r_Proj(irg, bl, leave, mode_bp, pn_ia32_Leave_frame);
curr_sp = new_r_Proj(irg, bl, leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
......@@ -968,7 +967,7 @@ static void ia32_prepare_graph(void *self) {
if (cg->dump)
be_dump(cg->irg, "-am", dump_ir_block_graph_sched);
/* do code placement, (optimize position of constants and argument loads) */
/* do code placement, to optimize the position of constants */
place_code(cg->irg);
if (cg->dump)
......@@ -990,6 +989,7 @@ static void turn_back_am(ir_node *node)
ir_node *base = get_irn_n(node, n_ia32_base);
ir_node *index = get_irn_n(node, n_ia32_index);
ir_node *mem = get_irn_n(node, n_ia32_mem);
ir_node *noreg = ia32_new_NoReg_gp(ia32_current_cg);
ir_node *load;
ir_node *load_res;
ir_node *mem_proj;
......@@ -1006,10 +1006,22 @@ static void turn_back_am(ir_node *node)
if(get_ia32_am_arity(node) == ia32_am_unary) {
set_irn_n(node, n_ia32_unary_op, load_res);
} else if(get_ia32_am_arity(node) == ia32_am_binary) {
set_irn_n(node, n_ia32_binary_right, load_res);
if(is_ia32_Immediate(get_irn_n(node, n_ia32_Cmp_right))) {
assert(is_ia32_Cmp(node) || is_ia32_Cmp8Bit(node)
|| is_ia32_Test(node) || is_ia32_Test8Bit(node));
set_irn_n(node, n_ia32_binary_left, load_res);
} else {
set_irn_n(node, n_ia32_binary_right, load_res);
}
} else if(get_ia32_am_arity(node) == ia32_am_ternary) {
set_irn_n(node, n_ia32_binary_right, load_res);
}
set_irn_n(node, n_ia32_base, noreg);
set_irn_n(node, n_ia32_index, noreg);
set_ia32_am_offs_int(node, 0);
set_ia32_am_sc(node, NULL);
set_ia32_am_scale(node, 0);
clear_ia32_am_sc_sign(node);
/* rewire mem-proj */
if(get_irn_mode(node) == mode_T) {
......@@ -1036,9 +1048,16 @@ static void turn_back_am(ir_node *node)
static ir_node *flags_remat(ir_node *node, ir_node *after)
{
/* we should turn back source address mode when rematerializing nodes */
ia32_op_type_t type = get_ia32_op_type(node);
ia32_op_type_t type = get_ia32_op_type(node);
ir_node *block;
ir_node *copy;
if(is_Block(after)) {
block = after;
} else {
block = get_nodes_block(after);
}
if (type == ia32_AddrModeS) {
turn_back_am(node);
} else if (type == ia32_AddrModeD) {
......@@ -1049,6 +1068,8 @@ static ir_node *flags_remat(ir_node *node, ir_node *after)
}
copy = exact_copy(node);
ir_fprintf(stderr, "Remated: %+F\n", copy);
set_nodes_block(copy, block);
sched_add_after(after, copy);
return copy;
......
This diff is collapsed.
......@@ -45,6 +45,7 @@ struct ia32_emit_env_t {
void ia32_emit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos);
void ia32_emit_8bit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos);
void ia32_emit_16bit_source_register(ia32_emit_env_t *env, const ir_node *node, int pos);
void ia32_emit_8bit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos);
void ia32_emit_dest_register(ia32_emit_env_t *env, const ir_node *node, int pos);
void ia32_emit_x87_name(ia32_emit_env_t *env, const ir_node *node, int pos);
void ia32_emit_immediate(ia32_emit_env_t *env, const ir_node *node);
......@@ -55,7 +56,9 @@ void ia32_emit_x87_mode_suffix(ia32_emit_env_t *env, const ir_node *node);
void ia32_emit_xmm_mode_suffix(ia32_emit_env_t *env, const ir_node *node);
void ia32_emit_xmm_mode_suffix_s(ia32_emit_env_t *env, const ir_node *node);
void ia32_emit_extend_suffix(ia32_emit_env_t *env, const ir_mode *mode);
void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node);
void ia32_emit_cmp_suffix_node(ia32_emit_env_t *env, const ir_node *node,
int flags_pos);
void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node, int produces_result);
void ia32_emit_am_or_dest_register(ia32_emit_env_t *env, const ir_node *node,
int pos);
void ia32_emit_unop(ia32_emit_env_t *env, const ir_node *node, int pos);
......
......@@ -353,8 +353,7 @@ static INLINE int need_constraint_copy(ir_node *irn) {
return ! is_ia32_Lea(irn) &&
! is_ia32_Conv_I2I(irn) &&
! is_ia32_Conv_I2I8Bit(irn) &&
! is_ia32_TestCMov(irn) &&
! is_ia32_CmpCMov(irn);
! is_ia32_CMov(irn);
}
/**
......@@ -501,33 +500,6 @@ static void assure_should_be_same_requirements(ia32_code_gen_t *cg,
}
}
}
/* check xCmp: try to avoid unordered cmp */
if ((is_ia32_xCmp(node) || is_ia32_xCmpCMov(node) || is_ia32_xCmpSet(node)) &&
op_tp == ia32_Normal)
{
long pnc = get_ia32_pncode(node);
if (pnc & pn_Cmp_Uo) {
ir_node *tmp;
int idx1 = n_ia32_binary_left;
int idx2 = n_ia32_binary_right;
if (is_ia32_xCmpCMov(node)) {
idx1 = 0;
idx2 = 1;
}
/** Matze: TODO this looks wrong, I assume we should exchange
* the proj numbers and not the inputs... */
tmp = get_irn_n(node, idx1);
set_irn_n(node, idx1, get_irn_n(node, idx2));
set_irn_n(node, idx2, tmp);
set_ia32_pncode(node, get_negated_pnc(pnc, mode_E));
}
}
}
/**
......
......@@ -279,14 +279,8 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
if(is_ia32_SwitchJmp(n) || is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
fprintf(F, "pn_code = %ld\n", get_ia32_pncode(n));
} else {
if(get_ia32_pncode(n) & ia32_pn_Cmp_Unsigned) {
long pnc = get_ia32_pncode(n);
fprintf(F, "pn_code = %ld (%s, unsigned)\n",
pnc, get_pnc_string(pnc & ~ia32_pn_Cmp_Unsigned));
} else {
fprintf(F, "pn_code = %ld (%s)\n", get_ia32_pncode(n),
get_pnc_string(get_ia32_pncode(n)));
}
fprintf(F, "pn_code = %ld (%s)\n", get_ia32_pncode(n),
get_pnc_string(get_ia32_pncode(n)));
}
/* dump n_res */
......@@ -986,8 +980,11 @@ int get_ia32_out_regnr(const ir_node *node, int pos) {
void ia32_swap_left_right(ir_node *node)
{
ir_node *left = get_irn_n(node, n_ia32_binary_left);
ir_node *right = get_irn_n(node, n_ia32_binary_right);
ia32_attr_t *attr = get_ia32_attr(node);
ir_node *left = get_irn_n(node, n_ia32_binary_left);
ir_node *right = get_irn_n(node, n_ia32_binary_right);
attr->data.cmp_flipped = !attr->data.cmp_flipped;
assert(is_ia32_commutative(node));
set_irn_n(node, n_ia32_binary_left, right);
set_irn_n(node, n_ia32_binary_right, left);
......@@ -1126,6 +1123,10 @@ int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b) {
if (a->data.except_label != b->data.except_label)
return 1;
if (a->data.cmp_flipped != b->data.cmp_flipped
|| a->data.cmp_unsigned != b->data.cmp_unsigned)
return 1;
return 0;
}
......
......@@ -70,10 +70,6 @@ enum {
ia32_S = (1 << 3) /**< S - Scale is set */
};
enum {
ia32_pn_Cmp_Unsigned = 0x100 /**< set this flag in a pnc to indicate an unsigned compare operation */
};
#ifndef NDEBUG
typedef enum {
IA32_ATTR_INVALID = 0,
......@@ -107,6 +103,8 @@ struct ia32_attr_t {
unsigned need_stackent:1; /**< Set to 1 if node need space on stack. */
unsigned need_64bit_stackent:1; /**< needs a 64bit stack entity (see double->unsigned int conv) */
unsigned need_32bit_stackent:1; /**< needs a 32bit stack entity */
unsigned cmp_flipped : 1;
unsigned cmp_unsigned : 1;
} data;
int *out_flags; /**< flags for each produced value */
......
......@@ -131,7 +131,7 @@ $arch = "ia32";
{ name => "mm5", type => 4 },
{ name => "mm6", type => 4 },
{ name => "mm7", type => 4 },
{ mode => "mode_E", flags => "manual_ra" }
{ mode => "mode_E", flags => "manual_ra" }
],
xmm => [
{ name => "xmm0", type => 1 },
......@@ -168,15 +168,15 @@ $arch = "ia32";
{ name => "st5", realname => "st(5)", type => 4 },
{ name => "st6", realname => "st(6)", type => 4 },
{ name => "st7", realname => "st(7)", type => 4 },
{ mode => "mode_E", flags => "manual_ra" }
{ mode => "mode_E", flags => "manual_ra" }
],
fp_cw => [ # the floating point control word
{ name => "fpcw", type => 4 | 32},
{ mode => "mode_fpcw", flags => "manual_ra|state" }
{ name => "fpcw", type => 4|32 },
{ mode => "mode_fpcw", flags => "manual_ra|state" }
],
flags => [
{ name => "eflags", type => 4 },
{ mode => "mode_Iu", flags => "manual_ra" }
{ name => "eflags", type => 0 },
{ mode => "mode_Iu", flags => "manual_ra" }
],
); # %reg_classes
......@@ -213,6 +213,7 @@ $arch = "ia32";
D3 => "${arch}_emit_dest_register(env, node, 3);",
D4 => "${arch}_emit_dest_register(env, node, 4);",
D5 => "${arch}_emit_dest_register(env, node, 5);",
DB0 => "${arch}_emit_8bit_dest_register(env, node, 0);",
X0 => "${arch}_emit_x87_name(env, node, 0);",
X1 => "${arch}_emit_x87_name(env, node, 1);",
X2 => "${arch}_emit_x87_name(env, node, 2);",
......@@ -232,8 +233,10 @@ $arch = "ia32";
unop5 => "${arch}_emit_unop(env, node, 5);",
DAM0 => "${arch}_emit_am_or_dest_register(env, node, 0);",
DAM1 => "${arch}_emit_am_or_dest_register(env, node, 1);",
binop => "${arch}_emit_binop(env, node);",
binop => "${arch}_emit_binop(env, node, 1);",
binop_nores => "${arch}_emit_binop(env, node, 0);",
x87_binop => "${arch}_emit_x87_binop(env, node);",
CMP0 => "${arch}_emit_cmp_suffix_node(env, node, 0);",
);
#--------------------------------------------------#
......@@ -309,6 +312,7 @@ $custom_init_attr_func = \&ia32_custom_init_attr;
$mode_xmm = "mode_E";
$mode_gp = "mode_Iu";
$mode_flags = "mode_Iu";
$mode_fpcw = "mode_fpcw";
$status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
......@@ -380,6 +384,16 @@ AddMem => {
modified_flags => $status_flags
},
AddMem8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
ins => [ "base", "index", "mem", "val" ],
emit => ". add%M %SB3, %AM",
units => [ "GP" ],
mode => "mode_M",
modified_flags => $status_flags
},
Adc => {
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ], out => [ "in_r4" ] },
ins => [ "base", "index", "mem", "left", "right", "eflags" ],
......@@ -492,6 +506,16 @@ AndMem => {
modified_flags => $status_flags
},
AndMem8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
ins => [ "base", "index", "mem", "val" ],
emit => '. and%M %SB3, %AM',
units => [ "GP" ],
mode => "mode_M",
modified_flags => $status_flags
},
Or => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
......@@ -513,6 +537,16 @@ OrMem => {
modified_flags => $status_flags
},
OrMem8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
ins => [ "base", "index", "mem", "val" ],
emit => '. or%M %SB3, %AM',
units => [ "GP" ],
mode => "mode_M",
modified_flags => $status_flags
},
Xor => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4" ] },
......@@ -534,6 +568,16 @@ XorMem => {
modified_flags => $status_flags
},
XorMem8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
ins => [ "base", "index", "mem", "val" ],
emit => '. xor%M %SB3, %AM',
units => [ "GP" ],
mode => "mode_M",
modified_flags => $status_flags
},
# not commutative operations
Sub => {
......@@ -557,6 +601,16 @@ SubMem => {
modified_flags => $status_flags
},
SubMem8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
ins => [ "base", "index", "mem", "val" ],
emit => '. sub%M %SB3, %AM',
units => [ "GP" ],
mode => 'mode_M',
modified_flags => $status_flags
},
Sbb => {
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 !in_r5" ] },
ins => [ "base", "index", "mem", "left", "right" ],
......@@ -897,55 +951,106 @@ NotMem => {
# other operations
CmpJmp => {
state => "pinned",
op_flags => "L|X|Y",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "none", "none"] },
Cmp => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] , out => [ "flags" ] },
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "false", "true" ],
attr => "long pnc",
outs => [ "eflags" ],
am => "source,binary",
init_attr => "attr->pn_code = pnc;",
latency => 3,
units => [ "BRANCH" ],
emit => '. cmp%M %binop_nores',
attr => "int flipped, int cmp_unsigned",
init_attr => "attr->data.cmp_flipped = flipped;\n".
"\tattr->data.cmp_unsigned = cmp_unsigned;\n",
latency => 1,
units => [ "GP" ],
mode => $mode_flags,
modified_flags => $status_flags
},
CmpJmp8Bit => {
state => "pinned",
op_flags => "L|X|Y",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ], out => [ "none", "none"] },
Cmp8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags" ] },
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "false", "true" ],
attr => "long pnc",
outs => [ "eflags" ],
am => "source,binary",
init_attr => "attr->pn_code = pnc;",
latency => 3,
units => [ "BRANCH" ],
emit => '. cmpb %binop_nores',
attr => "int flipped, int cmp_unsigned",
init_attr => "attr->data.cmp_flipped = flipped;\n".
"\tattr->data.cmp_unsigned = cmp_unsigned;\n",
latency => 1,
units => [ "GP" ],
mode => $mode_flags,
modified_flags => $status_flags
},
TestJmp => {
state => "pinned",
op_flags => "L|X|Y",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "none", "none" ] },
Test => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ] , out => [ "flags" ] },
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "false", "true" ],
attr => "long pnc",
outs => [ "eflags" ],
am => "source,binary",
emit => '. test%M %binop_nores',
attr => "int flipped, int cmp_unsigned",
init_attr => "attr->data.cmp_flipped = flipped;\n".
"\tattr->data.cmp_unsigned = cmp_unsigned;\n",
latency => 1,
units => [ "GP" ],
mode => $mode_flags,
modified_flags => $status_flags
},
Test8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ] , out => [ "flags" ] },
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "eflags" ],
am => "source,binary",
emit => '. testb %binop_nores',
attr => "int flipped, int cmp_unsigned",
init_attr => "attr->data.cmp_flipped = flipped;\n".
"\tattr->data.cmp_unsigned = cmp_unsigned;\n",
latency => 1,
units => [ "GP" ],
mode => $mode_flags,
modified_flags => $status_flags
},
Set => {
#irn_flags => "R",
reg_req => { in => [ "eflags" ], out => [ "eax ebx ecx edx" ] },
ins => [ "eflags" ],
am => "dest,unary",
attr => "pn_Cmp pnc",
init_attr => "attr->pn_code = pnc;",
latency => 3,
units => [ "BRANCH" ],
emit => '. set%CMP0 %DB0',
latency => 1,
units => [ "GP" ],
mode => $mode_gp,
},
CMov => {
#irn_flags => "R",
# (note: leave the false,true order intact to make it compatible with other
# ia32_binary ops)
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "eflags" ], out => [ "in_r4" ] },
ins => [ "base", "index", "mem", "val_false", "val_true", "eflags" ],
am => "source,binary",
attr => "pn_Cmp pn_code",
init_attr => "attr->pn_code = pn_code;",
latency => 1,
units => [ "GP" ],
mode => $mode_gp,
},
TestJmp8Bit => {
Jcc => {
state => "pinned",
op_flags => "L|X|Y",
reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx", "eax ebx ecx edx" ], out => [ "none", "none" ] },
ins => [ "base", "index", "mem", "left", "right" ],
reg_req => { in => [ "eflags" ], out => [ "none", "none" ] },
ins => [ "eflags" ],
outs => [ "false", "true" ],
attr => "long pnc",
am => "source,binary",
attr => "pn_Cmp pnc",
init_attr => "attr->pn_code = pnc;",
latency => 3,
latency => 2,
units => [ "BRANCH" ],
},
......@@ -956,6 +1061,7 @@ SwitchJmp => {
latency => 3,
units => [ "BRANCH" ],
mode => "mode_T",
modified_flags => $status_flags
},
IJmp => {
......@@ -975,6 +1081,8 @@ Const => {
attr => "ir_entity *symconst, int symconst_sign, long offset",
attr_type => "ia32_immediate_attr_t",
mode => $mode_gp,
# depends on the const and is set in ia32_transform
# modified_flags => $status_flags
},
Unknown_GP => {
......@@ -1144,6 +1252,9 @@ Lea => {
latency => 2,
units => [ "GP" ],
mode => $mode_gp,
# well this isn't true for Lea, but we often transform Lea back to Add, Inc
# or Dec, so we set the flag
modified_flags => 1,
},
Push => {
......@@ -1346,25 +1457,19 @@ xDiv => {
# other operations
xCmp => {
Ucomi => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "in_r4 !in_r5" ] },
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "eflags" ] },
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "flags" ],
am => "source,binary",
attr => "int flipped",
init_attr => "attr->data.cmp_flipped = flipped;",
emit => ' .ucomi%XXM %binop_nores',
latency => 3,
units => [ "SSE" ],
mode => "mode_E",
},
xCmpJmp => {
state => "pinned",
op_flags => "L|X|Y",
reg_req => { in => [ "gp", "gp", "none", "xmm", "xmm" ], out => [ "none", "none" ] },
ins => [ "base", "index", "mem", "left", "right" ],
outs => [ "false", "true" ],
attr => "long pnc",
init_attr => "attr->pn_code = pnc;",
latency => 5,
units => [ "SSE" ],
mode => $mode_flags,
modified_flags => 1,
},
# Load / Store
......@@ -1469,7 +1574,6 @@ Conv_I2I => {
attr => "ir_mode *smaller_mode",
init_attr => "attr->ls_mode = smaller_mode;",
mode => $mode_gp,
modified_flags => $status_flags
},
Conv_I2I8Bit => {
......@@ -1480,7 +1584,6 @@ Conv_I2I8Bit => {
attr => "ir_mode *smaller_mode",
init_attr => "attr->ls_mode = smaller_mode;",
mode => $mode_gp,
modified_flags => $status_flags
},
Conv_I2FP => {
......@@ -1507,140 +1610,6 @@ Conv_FP2FP => {
mode => "mode_E",
},
CmpCMov => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "gp", "gp" ], out => [ "in_r7" ] },
ins => [ "base", "index", "mem", "cmp_left", "cmp_right", "val_true", "val_false" ],
attr => "pn_Cmp pn_code",
init_attr => "attr->pn_code = pn_code;",
latency => 2,
units => [ "GP" ],
mode => $mode_gp,
},
CmpCMov8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "gp", "gp" ], out => [ "in_r7" ] },
ins => [ "base", "index", "mem", "cmp_left", "cmp_right", "val_true", "val_false" ],
attr => "pn_Cmp pn_code",
init_attr => "attr->pn_code = pn_code;",
latency => 2,
units => [ "GP" ],
mode => $mode_gp,
},
TestCMov => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "gp", "gp" ], out => [ "in_r7" ] },
ins => [ "base", "index", "mem", "cmp_left", "cmp_right", "val_true", "val_false" ],
attr => "pn_Cmp pn_code",
init_attr => "attr->pn_code = pn_code;",
latency => 2,
units => [ "GP" ],
mode => $mode_gp,
},
TestCMov8Bit => {
irn_flags => "R",
reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "gp", "gp" ], out => [ "in_r7" ] },
ins => [ "base", "index", "mem", "cmp_left", "cmp_right", "val_true", "val_false" ],
attr => "pn_Cmp pn_code",