be_emit_string(reg_name);
}
+/**
+ * emit a register, possible shortened by a mode
+ *
+ * @param reg the register
+ * @param mode the mode of the register or NULL for full register
+ */
static void emit_register(const arch_register_t *reg, const ir_mode *mode)
{
const char *reg_name;
emit_8bit_register_high(reg);
}
+void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos)
+{
+ const arch_register_t *reg;
+ const ir_node *in = get_irn_n(node, pos);
+ if (is_ia32_Immediate(in)) {
+ emit_ia32_Immediate(in);
+ return;
+ }
+
+ reg = get_in_reg(node, pos);
+ emit_16bit_register(reg);
+}
+
void ia32_emit_dest_register(const ir_node *node, int pos)
{
const arch_register_t *reg = get_out_reg(node, pos);
emit_register(reg, NULL);
}
+void ia32_emit_dest_register_size(const ir_node *node, int pos)
+{
+ const arch_register_t *reg = get_out_reg(node, pos);
+
+ emit_register(reg, get_ia32_ls_mode(node));
+}
+
void ia32_emit_8bit_dest_register(const ir_node *node, int pos)
{
const arch_register_t *reg = get_out_reg(node, pos);
void ia32_emit_source_register(const ir_node *node, int pos);
void ia32_emit_dest_register(const ir_node *node, int pos);
+void ia32_emit_dest_register_size(const ir_node *node, int pos);
void ia32_emit_8bit_dest_register(const ir_node *node, int pos);
void ia32_emit_x87_register(const ir_node *node, int pos);
void ia32_emit_source_register_or_immediate(const ir_node *node, int pos);
void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos);
void ia32_emit_8bit_high_source_register(const ir_node *node, int pos);
+void ia32_emit_16bit_source_register_or_immediate(const ir_node *node, int pos);
void ia32_emit_mode_suffix(const ir_node *node);
void ia32_emit_x87_mode_suffix(const ir_node *node);
void ia32_emit_xmm_mode_suffix(const ir_node *node);
SB2 => "${arch}_emit_8bit_source_register_or_immediate(node, 2);",
SB3 => "${arch}_emit_8bit_source_register_or_immediate(node, 3);",
SH0 => "${arch}_emit_8bit_high_source_register(node, 0);",
+ SS0 => "${arch}_emit_16bit_source_register_or_immediate(node, 0);",
+ SI0 => "${arch}_emit_source_register_or_immediate(node, 0);",
SI1 => "${arch}_emit_source_register_or_immediate(node, 1);",
SI3 => "${arch}_emit_source_register_or_immediate(node, 3);",
D0 => "${arch}_emit_dest_register(node, 0);",
D1 => "${arch}_emit_dest_register(node, 1);",
+ DS0 => "${arch}_emit_dest_register_size(node, 0);",
DB0 => "${arch}_emit_8bit_dest_register(node, 0);",
X0 => "${arch}_emit_x87_register(node, 0);",
X1 => "${arch}_emit_x87_register(node, 1);",
mode => mode_M,
},
+#
+# outport
+#
+Outport => {
+ irn_flags => "R",
+ state => "pinned",
+ reg_req => { in => [ "edx", "eax", "none" ], out => [ "none" ] },
+ ins => [ "port", "value", "mem" ],
+ emit => '. out%M %SS0, %SI1',
+ units => [ "GP" ],
+ latency => 1,
+ mode => mode_M,
+ modified_flags => $status_flags
+},
+
+#
+# inport
+#
+Inport => {
+ irn_flags => "R",
+ state => "pinned",
+ reg_req => { in => [ "edx", "none" ], out => [ "eax", "none" ] },
+ ins => [ "port", "mem" ],
+ outs => [ "res", "M" ],
+ emit => '. in%M %DS0, %SS0',
+ units => [ "GP" ],
+ latency => 1,
+ mode => mode_T,
+ modified_flags => $status_flags
+},
+
#
# Intel style prefetching
#
}
}
+/**
+ * Transform builtin outport.
+ */
+static ir_node *gen_outport(ir_node *node) {
+ ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
+ ir_node *oldv = get_Builtin_param(node, 1);
+ ir_mode *mode = get_irn_mode(oldv);
+ ir_node *value = be_transform_node(oldv);
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *mem = be_transform_node(get_Builtin_mem(node));
+ dbg_info *dbgi = get_irn_dbg_info(node);
+
+ ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
+ set_ia32_ls_mode(res, mode);
+ return res;
+}
+
+/**
+ * Transform builtin inport.
+ */
+static ir_node *gen_inport(ir_node *node) {
+ ir_type *tp = get_Builtin_type(node);
+ ir_type *rstp = get_method_res_type(tp, 0);
+ ir_mode *mode = get_type_mode(rstp);
+ ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *mem = be_transform_node(get_Builtin_mem(node));
+ dbg_info *dbgi = get_irn_dbg_info(node);
+
+ ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
+ set_ia32_ls_mode(res, mode);
+
+ /* check for missing Result Proj */
+ return res;
+}
+
/**
* Transform Builtin node.
*/
return gen_popcount(node);
case ir_bk_bswap:
return gen_bswap(node);
+ case ir_bk_outport:
+ return gen_outport(node);
+ case ir_bk_inport:
+ return gen_inport(node);
}
panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
}
* Transform Proj(Builtin) node.
*/
static ir_node *gen_Proj_Builtin(ir_node *proj) {
- ir_node *node = get_Proj_pred(proj);
+ ir_node *node = get_Proj_pred(proj);
ir_node *new_node = be_transform_node(node);
ir_builtin_kind kind = get_Builtin_kind(node);
case ir_bk_trap:
case ir_bk_debugbreak:
case ir_bk_prefetch:
+ case ir_bk_outport:
assert(get_Proj_proj(proj) == pn_Builtin_M);
return new_node;
+ case ir_bk_inport:
+ if (get_Proj_proj(proj) == pn_Builtin_1_result) {
+ return new_r_Proj(current_ir_graph, get_nodes_block(new_node),
+ new_node, get_irn_mode(proj), pn_ia32_Inport_res);
+ } else {
+ assert(get_Proj_proj(proj) == pn_Builtin_M);
+ return new_r_Proj(current_ir_graph, get_nodes_block(new_node),
+ new_node, mode_M, pn_ia32_Inport_M);
+ }
}
panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
}