sse: Implement ldresnearl
authorDavid Schleef <ds@schleef.org>
Wed, 8 Sep 2010 04:11:23 +0000 (21:11 -0700)
committerDavid Schleef <ds@schleef.org>
Wed, 8 Sep 2010 04:11:23 +0000 (21:11 -0700)
orc/orccompiler.c
orc/orcprogram-sse.c
orc/orcprogram.h
orc/orcrules-sse.c
orc/orcsse.c
orc/orcsse.h
orc/orcx86.c
orc/orcx86.h

index 512bb46..16b4d76 100644 (file)
@@ -795,6 +795,9 @@ orc_compiler_global_reg_alloc (OrcCompiler *compiler)
           var->ptr_offset = orc_compiler_allocate_register (compiler, FALSE);
           var->aligned_data = orc_compiler_allocate_register (compiler, TRUE);
         }
+        if (var->need_offset_reg) {
+          var->ptr_offset = orc_compiler_allocate_register (compiler, FALSE);
+        }
         break;
       case ORC_VAR_TYPE_DEST:
         var->ptr_register = orc_compiler_allocate_register (compiler, FALSE);
index 435630e..89b3bbd 100644 (file)
@@ -254,6 +254,20 @@ orc_compiler_sse_init (OrcCompiler *compiler)
   }
   compiler->alloc_loop_counter = TRUE;
   compiler->allow_gp_on_stack = TRUE;
+
+  {
+    for(i=0;i<compiler->n_insns;i++){
+      OrcInstruction *insn = compiler->insns + i;
+      OrcStaticOpcode *opcode = insn->opcode;
+
+      if (strcmp (opcode->name, "ldreslinb") == 0 ||
+          strcmp (opcode->name, "ldreslinl") == 0 ||
+          strcmp (opcode->name, "ldresnearb") == 0 ||
+          strcmp (opcode->name, "ldresnearl") == 0) {
+        compiler->vars[insn->src_args[0]].need_offset_reg = TRUE;
+      }
+    }
+  }
 }
 
 void
@@ -465,6 +479,29 @@ sse_load_constants_outer (OrcCompiler *compiler)
       }
     }
   }
+
+  {
+    for(i=0;i<compiler->n_insns;i++){
+      OrcInstruction *insn = compiler->insns + i;
+      OrcStaticOpcode *opcode = insn->opcode;
+
+      if (strcmp (opcode->name, "ldreslinb") == 0 ||
+          strcmp (opcode->name, "ldreslinl") == 0 ||
+          strcmp (opcode->name, "ldresnearb") == 0 ||
+          strcmp (opcode->name, "ldresnearl") == 0) {
+        if (compiler->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) {
+          orc_x86_emit_mov_memoffset_reg (compiler, 4,
+              (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
+              compiler->exec_reg,
+              compiler->vars[insn->src_args[0]].ptr_offset);
+        } else {
+          orc_x86_emit_mov_imm_reg (compiler, 4,
+              compiler->vars[insn->src_args[1]].value.i,
+              compiler->vars[insn->src_args[0]].ptr_offset);
+        }
+      }
+    }
+  }
 }
 
 void
@@ -517,6 +554,10 @@ sse_add_strides (OrcCompiler *compiler)
         orc_x86_emit_add_reg_memoffset (compiler, compiler->is_64bit ? 8 : 4,
             compiler->gp_tmpreg,
             (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[i]), compiler->exec_reg);
+
+        if (compiler->vars[i].ptr_register == 0) {
+          ORC_COMPILER_ERROR(compiler, "unimplemented: stride on mem pointer");
+        }
         break;
       case ORC_VAR_TYPE_ACCUMULATOR:
         break;
@@ -955,18 +996,31 @@ orc_sse_emit_loop (OrcCompiler *compiler, int offset, int update)
 
   if (update) {
     for(k=0;k<ORC_N_COMPILER_VARIABLES;k++){
-      if (compiler->vars[k].name == NULL) continue;
-      if (compiler->vars[k].vartype == ORC_VAR_TYPE_SRC ||
-          compiler->vars[k].vartype == ORC_VAR_TYPE_DEST) {
-        if (compiler->vars[k].ptr_register) {
-          orc_x86_emit_add_imm_reg (compiler, compiler->is_64bit ? 8 : 4,
-              compiler->vars[k].size * update,
-              compiler->vars[k].ptr_register, FALSE);
+      OrcVariable *var = compiler->vars + k;
+
+      if (var->name == NULL) continue;
+      if (var->vartype == ORC_VAR_TYPE_SRC ||
+          var->vartype == ORC_VAR_TYPE_DEST) {
+        int offset;
+        if (var->update_type == 0) {
+          offset = 0;
+        } else if (var->update_type == 1) {
+          offset = (var->size * update) >> 1;
         } else {
-          orc_x86_emit_add_imm_memoffset (compiler, compiler->is_64bit ? 8 : 4,
-              compiler->vars[k].size * update,
-              (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k]),
-              compiler->exec_reg);
+          offset = var->size * update;
+        }
+
+        if (offset != 0) {
+          if (compiler->vars[k].ptr_register) {
+            orc_x86_emit_add_imm_reg (compiler, compiler->is_64bit ? 8 : 4,
+                offset,
+                compiler->vars[k].ptr_register, FALSE);
+          } else {
+            orc_x86_emit_add_imm_memoffset (compiler, compiler->is_64bit ? 8 : 4,
+                offset,
+                (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[k]),
+                compiler->exec_reg);
+          }
         }
       }
     }
index 634ea27..e46a53f 100644 (file)
@@ -231,6 +231,8 @@ struct _OrcVariable {
   int aligned_data;
   int param_type;
   int load_dest;
+  int update_type;
+  int need_offset_reg;
 };
 
 /**
index b9a3b9f..2b69b2d 100644 (file)
@@ -97,6 +97,8 @@ sse_rule_loadX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
           src->size << compiler->loop_shift);
       break;
   }
+
+  src->update_type = 2;
 }
 
 static void
@@ -150,6 +152,8 @@ sse_rule_loadoffX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
           src->size << compiler->loop_shift);
       break;
   }
+
+  src->update_type = 2;
 }
 
 static void
@@ -161,7 +165,7 @@ sse_rule_loadupib (OrcCompiler *compiler, void *user, OrcInstruction *insn)
   int offset = 0;
   int tmp = orc_compiler_get_temp_reg (compiler);
 
-  offset = compiler->offset * src->size;
+  offset = (compiler->offset * src->size) >> 1;
   if (src->ptr_register == 0) {
     int i = insn->src_args[0];
     orc_x86_emit_mov_memoffset_reg (compiler, compiler->is_64bit ? 8 : 4,
@@ -209,17 +213,7 @@ sse_rule_loadupib (OrcCompiler *compiler, void *user, OrcInstruction *insn)
   orc_sse_emit_pavgb (compiler, dest->alloc, tmp);
   orc_sse_emit_punpcklbw (compiler, tmp, dest->alloc);
 
-  /* FIXME hack */
-  if (src->ptr_register) {
-    orc_x86_emit_add_imm_reg (compiler, compiler->is_64bit ? 8 : 4,
-        -(src->size << compiler->loop_shift)>>1,
-        src->ptr_register, FALSE);
-  } else {
-    orc_x86_emit_add_imm_memoffset (compiler, compiler->is_64bit ? 8 : 4,
-        -(src->size << compiler->loop_shift)>>1,
-        (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[insn->src_args[0]]),
-        compiler->exec_reg);
-  }
+  src->update_type = 1;
 }
 
 static void
@@ -230,7 +224,7 @@ sse_rule_loadupdb (OrcCompiler *compiler, void *user, OrcInstruction *insn)
   int ptr_reg;
   int offset = 0;
 
-  offset = compiler->offset * src->size;
+  offset = (compiler->offset * src->size) >> 1;
   if (src->ptr_register == 0) {
     int i = insn->src_args[0];
     orc_x86_emit_mov_memoffset_reg (compiler, compiler->is_64bit ? 8 : 4,
@@ -278,17 +272,8 @@ sse_rule_loadupdb (OrcCompiler *compiler, void *user, OrcInstruction *insn)
       orc_sse_emit_punpckldq (compiler, dest->alloc, dest->alloc);
       break;
   }
-  /* FIXME hack */
-  if (src->ptr_register) {
-    orc_x86_emit_add_imm_reg (compiler, compiler->is_64bit ? 8 : 4,
-        -(src->size << compiler->loop_shift)>>1,
-        src->ptr_register, FALSE);
-  } else {
-    orc_x86_emit_add_imm_memoffset (compiler, compiler->is_64bit ? 8 : 4,
-        -(src->size << compiler->loop_shift)>>1,
-        (int)ORC_STRUCT_OFFSET(OrcExecutor, arrays[insn->src_args[0]]),
-        compiler->exec_reg);
-  }
+
+  src->update_type = 1;
 }
 
 static void
@@ -347,6 +332,110 @@ sse_rule_storeX (OrcCompiler *compiler, void *user, OrcInstruction *insn)
       ORC_COMPILER_ERROR(compiler,"bad size");
       break;
   }
+
+  dest->update_type = 2;
+}
+
+#if try1
+static void
+sse_rule_ldresnearl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+{
+  OrcVariable *src = compiler->vars + insn->src_args[0];
+  OrcVariable *dest = compiler->vars + insn->dest_args[0];
+  int tmp = orc_compiler_get_temp_reg (compiler);
+  int tmp2 = orc_compiler_get_temp_reg (compiler);
+  int tmpc;
+
+  orc_x86_emit_mov_sse_reg (compiler, X86_XMM6, compiler->gp_tmpreg);
+  orc_x86_emit_sar_imm_reg (compiler, 4, 16, compiler->gp_tmpreg);
+
+  ORC_ASM_CODE(compiler,"  movdqu 0(%%%s,%%%s,4), %%%s\n",
+      orc_x86_get_regname_ptr(compiler, src->ptr_register),
+      orc_x86_get_regname_ptr(compiler, compiler->gp_tmpreg),
+      orc_x86_get_regname_sse(dest->alloc));
+  *compiler->codeptr++ = 0xf3;
+  orc_x86_emit_rex(compiler, 0, dest->ptr_register, 0, dest->alloc);
+  *compiler->codeptr++ = 0x0f;
+  *compiler->codeptr++ = 0x6f;
+  orc_x86_emit_modrm_memindex (compiler, dest->alloc, 0,
+      src->ptr_register, compiler->gp_tmpreg, 2);
+
+#if 0
+  orc_sse_emit_movdqa (compiler, X86_XMM6, tmp);
+  orc_sse_emit_pslld (compiler, 10, tmp);
+  orc_sse_emit_psrld (compiler, 26, tmp);
+  orc_sse_emit_pslld (compiler, 2, tmp);
+
+  orc_sse_emit_movdqa (compiler, tmp, tmp2);
+  orc_sse_emit_pslld (compiler, 8, tmp2);
+  orc_sse_emit_por (compiler, tmp2, tmp);
+  orc_sse_emit_movdqa (compiler, tmp, tmp2);
+  orc_sse_emit_pslld (compiler, 16, tmp2);
+  orc_sse_emit_por (compiler, tmp2, tmp);
+#else
+  orc_sse_emit_movdqa (compiler, X86_XMM6, tmp);
+  tmpc = orc_compiler_get_constant_long (compiler, 0x02020202,
+      0x06060606, 0x0a0a0a0a, 0x0e0e0e0e);
+  orc_sse_emit_pshufb (compiler, tmpc, tmp);
+  orc_sse_emit_paddb (compiler, tmp, tmp);
+  orc_sse_emit_paddb (compiler, tmp, tmp);
+#endif
+
+  orc_sse_emit_pshufd (compiler, ORC_SSE_SHUF(0,0,0,0), tmp, tmp2);
+  orc_sse_emit_psubd (compiler, tmp2, tmp);
+  tmpc = orc_compiler_get_constant (compiler, 4, 0x03020100);
+  orc_sse_emit_paddd (compiler, tmpc, tmp);
+
+  orc_sse_emit_pshufb (compiler, tmp, dest->alloc);
+
+  orc_sse_emit_movdqa (compiler, X86_XMM7, tmp);
+  orc_sse_emit_pslld (compiler, compiler->loop_shift, tmp);
+
+  orc_sse_emit_paddd (compiler, tmp, X86_XMM6);
+
+  src->update_type = 0;
+}
+#endif
+
+static void
+sse_rule_ldresnearl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+{
+  OrcVariable *src = compiler->vars + insn->src_args[0];
+  int increment_var = insn->src_args[2];
+  OrcVariable *dest = compiler->vars + insn->dest_args[0];
+  int tmp = orc_compiler_get_temp_reg (compiler);
+  int i;
+
+  for(i=0;i<(1<<compiler->loop_shift);i++){
+    if (i == 0) {
+      orc_x86_emit_mov_memoffset_sse (compiler, 4, 0,
+          src->ptr_register, dest->alloc, FALSE);
+    } else {
+      orc_x86_emit_mov_memindex_sse (compiler, 4, 0,
+          src->ptr_register, compiler->gp_tmpreg, 2, tmp, FALSE);
+      orc_sse_emit_pslldq (compiler, 4*i, tmp);
+      orc_sse_emit_por (compiler, tmp, dest->alloc);
+    }
+
+    if (compiler->vars[increment_var].vartype == ORC_VAR_TYPE_PARAM) {
+      orc_x86_emit_add_memoffset_reg (compiler, 4,
+          (int)ORC_STRUCT_OFFSET(OrcExecutor, params[increment_var]),
+          compiler->exec_reg, src->ptr_offset);
+    } else {
+      orc_x86_emit_add_imm_reg (compiler, 4,
+          compiler->vars[increment_var].value.i,
+          src->ptr_offset, FALSE);
+    }
+
+    orc_x86_emit_mov_reg_reg (compiler, 4, src->ptr_offset, compiler->gp_tmpreg);
+    orc_x86_emit_sar_imm_reg (compiler, 4, 16, compiler->gp_tmpreg);
+  }
+
+  orc_x86_emit_add_reg_reg_shift (compiler, 4, compiler->gp_tmpreg,
+      src->ptr_register, 2);
+  orc_x86_emit_and_imm_reg (compiler, 4, 0xffff, src->ptr_offset);
+
+  src->update_type = 0;
 }
 
 static void
@@ -2194,6 +2283,7 @@ orc_compiler_sse_register_rules (OrcTarget *target)
   orc_rule_register (rule_set, "loadpw", sse_rule_loadpX, (void *)2);
   orc_rule_register (rule_set, "loadpl", sse_rule_loadpX, (void *)4);
   orc_rule_register (rule_set, "loadpq", sse_rule_loadpX, (void *)8);
+  orc_rule_register (rule_set, "ldresnearl", sse_rule_ldresnearl, NULL);
 
   orc_rule_register (rule_set, "storeb", sse_rule_storeX, NULL);
   orc_rule_register (rule_set, "storew", sse_rule_storeX, NULL);
index 725e04b..f812075 100644 (file)
@@ -244,6 +244,56 @@ orc_x86_emit_mov_memoffset_sse (OrcCompiler *compiler, int size, int offset,
 }
 
 void
+orc_x86_emit_mov_memindex_sse (OrcCompiler *compiler, int size, int offset,
+    int reg1, int regindex, int shift, int reg2, int is_aligned)
+{
+  switch (size) {
+    case 4:
+      ORC_ASM_CODE(compiler,"  movd %d(%%%s,%%%s,%d), %%%s\n", offset,
+          orc_x86_get_regname_ptr(compiler, reg1),
+          orc_x86_get_regname_ptr(compiler, regindex), 1<<shift,
+          orc_x86_get_regname_sse(reg2));
+      *compiler->codeptr++ = 0x66;
+      orc_x86_emit_rex(compiler, 0, reg2, 0, reg1);
+      *compiler->codeptr++ = 0x0f;
+      *compiler->codeptr++ = 0x6e;
+      break;
+    case 8:
+      ORC_ASM_CODE(compiler,"  movq %d(%%%s,%%%s,%d), %%%s\n", offset, orc_x86_get_regname_ptr(compiler, reg1),
+          orc_x86_get_regname_ptr(compiler, regindex), 1<<shift,
+          orc_x86_get_regname_sse(reg2));
+      *compiler->codeptr++ = 0xf3;
+      orc_x86_emit_rex(compiler, 0, reg2, 0, reg1);
+      *compiler->codeptr++ = 0x0f;
+      *compiler->codeptr++ = 0x7e;
+      break;
+    case 16:
+      if (is_aligned) {
+        ORC_ASM_CODE(compiler,"  movdqa %d(%%%s,%%%s,%d), %%%s\n", offset, orc_x86_get_regname_ptr(compiler, reg1),
+            orc_x86_get_regname_ptr(compiler, regindex), 1<<shift,
+            orc_x86_get_regname_sse(reg2));
+        *compiler->codeptr++ = 0x66;
+        orc_x86_emit_rex(compiler, 0, reg2, 0, reg1);
+        *compiler->codeptr++ = 0x0f;
+        *compiler->codeptr++ = 0x6f;
+      } else {
+        ORC_ASM_CODE(compiler,"  movdqu %d(%%%s,%%%s,%d), %%%s\n", offset, orc_x86_get_regname_ptr(compiler, reg1),
+            orc_x86_get_regname_ptr(compiler, regindex), 1<<shift,
+            orc_x86_get_regname_sse(reg2));
+        *compiler->codeptr++ = 0xf3;
+        orc_x86_emit_rex(compiler, 0, reg2, 0, reg1);
+        *compiler->codeptr++ = 0x0f;
+        *compiler->codeptr++ = 0x6f;
+      }
+      break;
+    default:
+      ORC_COMPILER_ERROR(compiler, "bad size");
+      break;
+  }
+  orc_x86_emit_modrm_memindex (compiler, reg2, offset, reg1, regindex, shift);
+}
+
+void
 orc_x86_emit_mov_sse_memoffset (OrcCompiler *compiler, int size, int reg1, int offset,
     int reg2, int aligned, int uncached)
 {
index 32a4593..e662824 100644 (file)
@@ -41,6 +41,8 @@ typedef enum {
 const char * orc_x86_get_regname_sse(int i);
 void orc_x86_emit_mov_memoffset_sse (OrcCompiler *compiler, int size, int offset,
     int reg1, int reg2, int is_aligned);
+void orc_x86_emit_mov_memindex_sse (OrcCompiler *compiler, int size, int offset,
+    int reg1, int regindex, int shift, int reg2, int is_aligned);
 void orc_x86_emit_mov_sse_memoffset (OrcCompiler *compiler, int size, int reg1, int offset,
     int reg2, int aligned, int uncached);
 void orc_x86_emit_mov_sse_reg_reg (OrcCompiler *compiler, int reg1, int reg2);
index 85a63b1..c857eb7 100644 (file)
@@ -168,6 +168,26 @@ orc_x86_emit_modrm_memoffset (OrcCompiler *compiler, int reg1, int offset, int r
   }
 }
 
+void orc_x86_emit_modrm_memindex (OrcCompiler *compiler, int reg1, int offset,
+    int reg2, int regindex, int shift)
+{
+  if (offset == 0) {
+    *compiler->codeptr++ = X86_MODRM(0, 4, reg1);
+    *compiler->codeptr++ = X86_SIB(shift, regindex, reg2);
+  } else if (offset >= -128 && offset < 128) {
+    *compiler->codeptr++ = X86_MODRM(1, 4, reg1);
+    *compiler->codeptr++ = X86_SIB(shift, regindex, reg2);
+    *compiler->codeptr++ = (offset & 0xff);
+  } else {
+    *compiler->codeptr++ = X86_MODRM(2, 4, reg1);
+    *compiler->codeptr++ = X86_SIB(shift, regindex, reg2);
+    *compiler->codeptr++ = (offset & 0xff);
+    *compiler->codeptr++ = ((offset>>8) & 0xff);
+    *compiler->codeptr++ = ((offset>>16) & 0xff);
+    *compiler->codeptr++ = ((offset>>24) & 0xff);
+  }
+}
+
 void
 orc_x86_emit_modrm_reg (OrcCompiler *compiler, int reg1, int reg2)
 {
@@ -475,7 +495,7 @@ orc_x86_emit_add_imm_reg (OrcCompiler *compiler, int size, int value, int reg, o
 {
   if (!record) {
     if (size == 4 && !compiler->is_64bit) {
-      ORC_ASM_CODE(compiler,"  lea %d(%%%s), %%%s\n", value,
+      ORC_ASM_CODE(compiler,"  leal %d(%%%s), %%%s\n", value,
           orc_x86_get_regname(reg), orc_x86_get_regname(reg));
       orc_x86_emit_rex(compiler, size, 0, 0, reg);
       *compiler->codeptr++ = 0x8d;
@@ -483,7 +503,7 @@ orc_x86_emit_add_imm_reg (OrcCompiler *compiler, int size, int value, int reg, o
       return;
     }
     if (size == 8 && compiler->is_64bit) {
-      ORC_ASM_CODE(compiler,"  lea %d(%%%s), %%%s\n", value,
+      ORC_ASM_CODE(compiler,"  leaq %d(%%%s), %%%s\n", value,
           orc_x86_get_regname_64(reg), orc_x86_get_regname_64(reg));
       orc_x86_emit_rex(compiler, size, reg, 0, reg);
       *compiler->codeptr++ = 0x8d;
@@ -519,6 +539,27 @@ orc_x86_emit_add_imm_reg (OrcCompiler *compiler, int size, int value, int reg, o
 }
 
 void
+orc_x86_emit_add_reg_reg_shift (OrcCompiler *compiler, int size, int reg1,
+    int reg2, int shift)
+{
+  if (size == 4) {
+    ORC_ASM_CODE(compiler,"  leal (%%%s, %%%s, %d), %%%s\n",
+        orc_x86_get_regname(reg2),
+        orc_x86_get_regname(reg1), 1<<shift,
+        orc_x86_get_regname(reg2));
+  } else {
+    ORC_ASM_CODE(compiler,"  leaq (%%%s, %%%s, %d), %%%s\n",
+        orc_x86_get_regname(reg2),
+        orc_x86_get_regname(reg1), 1<<shift,
+        orc_x86_get_regname(reg2));
+  }
+
+  orc_x86_emit_rex(compiler, size, reg2, 0, reg1);
+  *compiler->codeptr++ = 0x8d;
+  orc_x86_emit_modrm_memindex (compiler, reg2, 0, reg2, reg1, shift);
+}
+
+void
 orc_x86_emit_add_reg_reg (OrcCompiler *compiler, int size, int reg1, int reg2)
 {
   if (size == 2) {
@@ -573,6 +614,30 @@ orc_x86_emit_imul_memoffset_reg (OrcCompiler *compiler, int size,
 }
 
 void
+orc_x86_emit_add_memoffset_reg (OrcCompiler *compiler, int size,
+    int offset, int reg, int destreg)
+{
+  if (size == 2) {
+    ORC_ASM_CODE(compiler,"  addw %d(%%%s), %%%s\n", offset,
+        orc_x86_get_regname_ptr(compiler, reg),
+        orc_x86_get_regname_16(destreg));
+    *compiler->codeptr++ = 0x66;
+  } else if (size == 4) {
+    ORC_ASM_CODE(compiler,"  addl %d(%%%s), %%%s\n", offset,
+        orc_x86_get_regname_ptr(compiler, reg),
+        orc_x86_get_regname(destreg));
+  } else {
+    ORC_ASM_CODE(compiler,"  add %d(%%%s), %%%s\n", offset,
+        orc_x86_get_regname_ptr(compiler, reg),
+        orc_x86_get_regname_64(destreg));
+  }
+
+  orc_x86_emit_rex(compiler, size, 0, 0, reg);
+  *compiler->codeptr++ = 0x03;
+  orc_x86_emit_modrm_memoffset (compiler, destreg, offset, reg);
+}
+
+void
 orc_x86_emit_sub_memoffset_reg (OrcCompiler *compiler, int size,
     int offset, int reg, int destreg)
 {
index 3e3b48c..05b4f9f 100644 (file)
@@ -61,10 +61,13 @@ void orc_x86_emit_and_imm_memoffset (OrcCompiler *compiler, int size, int value,
 void orc_x86_emit_add_imm_reg (OrcCompiler *compiler, int size, int value, int reg, orc_bool record);
 void orc_x86_emit_and_imm_reg (OrcCompiler *compiler, int size, int value, int reg);
 void orc_x86_emit_or_imm_reg (OrcCompiler *compiler, int size, int value, int reg);
+void orc_x86_emit_add_reg_reg_shift (OrcCompiler *compiler, int size, int reg1, int reg2, int shift);
 void orc_x86_emit_add_reg_reg (OrcCompiler *compiler, int size, int reg1, int reg2);
 void orc_x86_emit_sub_reg_reg (OrcCompiler *compiler, int size, int reg1, int reg2);
 void orc_x86_emit_imul_memoffset_reg (OrcCompiler *compiler, int size,
     int offset, int reg, int destreg);
+void orc_x86_emit_add_memoffset_reg (OrcCompiler *compiler, int size,
+    int offset, int reg, int destreg);
 void orc_x86_emit_sub_memoffset_reg (OrcCompiler *compiler, int size,
     int offset, int reg, int destreg);
 void orc_x86_emit_cmp_reg_memoffset (OrcCompiler *compiler, int size, int reg1,
@@ -91,6 +94,8 @@ void orc_x86_emit_epilogue (OrcCompiler *compiler);
 void orc_x86_emit_rex (OrcCompiler *compiler, int size, int reg1, int reg2, int reg3);
 void orc_x86_emit_modrm_memoffset (OrcCompiler *compiler, int reg1, int offset, int reg2);
 void orc_x86_emit_modrm_reg (OrcCompiler *compiler, int reg1, int reg2);
+void orc_x86_emit_modrm_memindex (OrcCompiler *compiler, int reg1, int offset,
+    int reg2, int regindex, int shift);
 
 void orc_x86_do_fixups (OrcCompiler *compiler);