- implemented ia32 inport, outport for ir_bk_(in|out)port
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 29 Dec 2008 02:16:45 +0000 (02:16 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Mon, 29 Dec 2008 02:16:45 +0000 (02:16 +0000)
[r24938]

ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_emitter.h
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c

index 2555b57..a550082 100644 (file)
@@ -243,6 +243,12 @@ static void emit_16bit_register(const arch_register_t *reg)
        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;
@@ -335,6 +341,19 @@ void ia32_emit_8bit_high_source_register(const ir_node *node, int pos)
        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);
@@ -342,6 +361,13 @@ void ia32_emit_dest_register(const ir_node *node, int 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);
index fc16668..f490c46 100644 (file)
 
 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);
index 5685063..709e1db 100644 (file)
@@ -202,10 +202,13 @@ $arch = "ia32";
        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);",
@@ -1624,6 +1627,37 @@ UD2 => {
        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
 #
index d7b25cb..6a585ec 100644 (file)
@@ -4990,6 +4990,42 @@ static ir_node *gen_bswap(ir_node *node) {
        }
 }
 
+/**
+ * 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.
  */
@@ -5019,6 +5055,10 @@ static ir_node *gen_Builtin(ir_node *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));
 }
@@ -5027,7 +5067,7 @@ static ir_node *gen_Builtin(ir_node *node) {
  * 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);
 
@@ -5045,8 +5085,18 @@ static ir_node *gen_Proj_Builtin(ir_node *proj) {
        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));
 }