diff --git a/tcg/tcg.c b/tcg/tcg.c
index 93066e2..7a48057 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1678,6 +1678,78 @@ static void tcg_reg_alloc_op(TCGContext *s,
     }
 }
 
+static void tcg_reg_alloc_const(TCGContext *s,
+                                const TCGOpDef *def, int opc,
+                                const TCGArg *args,
+                                unsigned int dead_iargs)
+{
+    TCGTemp *its1, *its2;
+    its1 = &s->temps[args[1]];
+    its2 = &s->temps[args[2]];
+
+    if (its1->val_type != TEMP_VAL_CONST || its2->val_type != TEMP_VAL_CONST) {
+        tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
+    } else {
+        TCGTemp *ots;
+        tcg_target_ulong val;
+
+        switch(opc) {
+        case INDEX_op_add_i32:
+            val = (uint32_t)(its1->val + its2->val);
+            break;
+        case INDEX_op_sub_i32:
+            val = (uint32_t)(its1->val - its2->val);
+            break;
+
+        case INDEX_op_and_i32:
+            val = (uint32_t)(its1->val & its2->val);
+            break;
+        case INDEX_op_or_i32:
+            val = (uint32_t)(its1->val | its2->val);
+            break;
+        case INDEX_op_xor_i32:
+            val = (uint32_t)(its1->val ^ its2->val);
+            break;
+
+#if TCG_TARGET_REG_BITS == 64
+        case INDEX_op_add_i64:
+            val = its1->val + its2->val;
+            break;
+        case INDEX_op_sub_i64:
+            val = its1->val - its2->val;
+            break;
+
+        case INDEX_op_and_i64:
+            val = its1->val & its2->val;
+            break;
+        case INDEX_op_or_i64:
+            val = its1->val | its2->val;
+            break;
+        case INDEX_op_xor_i64:
+            val = its1->val ^ its2->val;
+            break;
+#endif
+        default:
+            val = 0;
+            break;
+        }
+
+        ots = &s->temps[args[0]];
+
+        if (ots->fixed_reg) {
+            /* for fixed registers, we do not do any constant
+               propagation */
+            tcg_out_movi(s, ots->type, ots->reg, val);
+        } else {
+            /* The movi is not explicitly generated here */
+            if (ots->val_type == TEMP_VAL_REG)
+                s->reg_to_temp[ots->reg] = -1;
+            ots->val_type = TEMP_VAL_CONST;
+            ots->val = val;
+        }
+    }
+}
+
 #ifdef TCG_TARGET_STACK_GROWSUP
 #define STACK_DIR(x) (-(x))
 #else
@@ -1977,6 +2049,21 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
             goto next;
         case INDEX_op_end:
             goto the_end;
+        case INDEX_op_add_i32:
+        case INDEX_op_and_i32:
+        case INDEX_op_sub_i32:
+        case INDEX_op_or_i32:
+        case INDEX_op_xor_i32:
+#if TCG_TARGET_REG_BITS == 64
+        case INDEX_op_add_i64:
+        case INDEX_op_sub_i64:
+        case INDEX_op_and_i64:
+        case INDEX_op_or_i64:
+        case INDEX_op_xor_i64:
+#endif
+            dead_iargs = s->op_dead_iargs[op_index];
+            tcg_reg_alloc_const(s, def, opc, args, dead_iargs);
+            break;
         default:
             /* Note: in order to speed up the code, it would be much
                faster to have specialized register allocator functions for

