summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-12-14 14:17:16 +0100
committerWim Taymans <wtaymans@redhat.com>2014-12-14 14:17:16 +0100
commit093a04aa9bc097b6594f96d90ab315cdac582aa9 (patch)
tree4fdf6c5976651b430399e2300d2f9d105529941c
parent98f3b33241fcdfe8ede33685f6418d87343b5a44 (diff)
llvm: beginnings of llvm backend
-rw-r--r--configure.ac9
-rw-r--r--orc/Makefile.am3
-rw-r--r--orc/orc.c4
-rw-r--r--orc/orcinternal.h1
-rw-r--r--orc/orcprogram-llvm.c3017
5 files changed, 3032 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index a7aaf1e..8916a58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,7 +141,7 @@ AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_LIBS)
AC_ARG_ENABLE(backend,
- AC_HELP_STRING([--enable-backend],[sse,mmx,neon,mips,all (default all)]),
+ AC_HELP_STRING([--enable-backend],[sse,mmx,neon,mips,llvm,all (default all)]),
[], [enable_backend=all])
case "${enable_backend}" in
sse)
@@ -173,6 +173,10 @@ case "${enable_backend}" in
ENABLE_BACKEND_MIPS=yes
AC_DEFINE(ENABLE_BACKEND_MIPS, 1, [Enable MIPS backend])
;;
+ llvm)
+ ENABLE_BACKEND_LLVM=yes
+ AC_DEFINE(ENABLE_BACKEND_LLVM, 1, [Enable LLVM backend])
+ ;;
all|auto)
ENABLE_BACKEND_SSE=yes
AC_DEFINE(ENABLE_BACKEND_SSE, 1, [Enable SSE backend])
@@ -188,6 +192,8 @@ case "${enable_backend}" in
AC_DEFINE(ENABLE_BACKEND_C64X, 1, [Enable c64x backend])
ENABLE_BACKEND_MIPS=yes
AC_DEFINE(ENABLE_BACKEND_MIPS, 1, [Enable MIPS backend])
+ ENABLE_BACKEND_LLVM=yes
+ AC_DEFINE(ENABLE_BACKEND_LLVM, 1, [Enable LLVM backend])
;;
esac
AM_CONDITIONAL(ENABLE_BACKEND_SSE, test "x$ENABLE_BACKEND_SSE" = "xyes")
@@ -197,6 +203,7 @@ AM_CONDITIONAL(ENABLE_BACKEND_NEON, test "x$ENABLE_BACKEND_NEON" = "xyes")
AM_CONDITIONAL(ENABLE_BACKEND_ARM, test "x$ENABLE_BACKEND_ARM" = "xyes")
AM_CONDITIONAL(ENABLE_BACKEND_C64X, test "x$ENABLE_BACKEND_C64X" = "xyes")
AM_CONDITIONAL(ENABLE_BACKEND_MIPS, test "x$ENABLE_BACKEND_MIPS" = "xyes")
+AM_CONDITIONAL(ENABLE_BACKEND_LLVM, test "x$ENABLE_BACKEND_LLVM" = "xyes")
dnl Check for -Bsymbolic-functions linker flag used to avoid
dnl intra-library PLT jumps, if available.
diff --git a/orc/Makefile.am b/orc/Makefile.am
index 84c36cd..67b8362 100644
--- a/orc/Makefile.am
+++ b/orc/Makefile.am
@@ -59,6 +59,9 @@ endif
if ENABLE_BACKEND_MIPS
liborc_@ORC_MAJORMINOR@_la_SOURCES += orcmips.c orcprogram-mips.c orcrules-mips.c
endif
+if ENABLE_BACKEND_LLVM
+liborc_@ORC_MAJORMINOR@_la_SOURCES += orcprogram-llvm.c
+endif
if HAVE_I386
liborc_@ORC_MAJORMINOR@_la_SOURCES += orccpu-x86.c
diff --git a/orc/orc.c b/orc/orc.c
index 55ac934..8ab9556 100644
--- a/orc/orc.c
+++ b/orc/orc.c
@@ -63,7 +63,9 @@ orc_init (void)
#ifdef ENABLE_BACKEND_MIPS
orc_mips_init();
#endif
-
+#ifdef ENABLE_BACKEND_LLVM
+ orc_llvm_init();
+#endif
inited = TRUE;
}
orc_global_mutex_unlock ();
diff --git a/orc/orcinternal.h b/orc/orcinternal.h
index a60838b..15b75e5 100644
--- a/orc/orcinternal.h
+++ b/orc/orcinternal.h
@@ -18,6 +18,7 @@ void orc_neon_init (void);
void orc_c64x_init (void);
void orc_c64x_c_init (void);
void orc_mips_init (void);
+void orc_llvm_init (void);
extern int _orc_data_cache_size_level1;
extern int _orc_data_cache_size_level2;
diff --git a/orc/orcprogram-llvm.c b/orc/orcprogram-llvm.c
new file mode 100644
index 0000000..e30b493
--- /dev/null
+++ b/orc/orcprogram-llvm.c
@@ -0,0 +1,3017 @@
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <orc/orc.h>
+#include <orc/orcprogram.h>
+#include <orc/orcdebug.h>
+
+static void llvm_get_name_int (char *name, OrcCompiler *p, OrcInstruction *insn, int var, int src);
+
+void orc_llvm_init (void);
+
+static void
+get_temp (char *name, OrcCompiler *compiler)
+{
+ static int count;
+
+ sprintf(name, "%%tmp%d", count++);
+}
+
+void
+orc_compiler_llvm_init (OrcCompiler *compiler)
+{
+ int i;
+
+ for(i=ORC_GP_REG_BASE;i<ORC_GP_REG_BASE+32;i++){
+ compiler->valid_regs[i] = 1;
+ }
+ compiler->loop_shift = 0;
+}
+
+const char *
+orc_target_llvm_get_typedefs (void)
+{
+ return "\n";
+}
+
+const char *
+orc_target_llvm_get_asm_preamble (void)
+{
+ return "\n";
+}
+
+unsigned int
+orc_compiler_llvm_get_default_flags (void)
+{
+ return 0;
+}
+
+static const char *varnames[] = {
+ "%%d1", "%%d2", "%%d3", "%%d4",
+ "%%s1", "%%s2", "%%s3", "%%s4",
+ "%%s5", "%%s6", "%%s7", "%%s8",
+ "%%a1", "%%a2", "%%a3", "%%d4",
+ "%%c1", "%%c2", "%%c3", "%%c4",
+ "%%c5", "%%c6", "%%c7", "%%c8",
+ "%%p1", "%%p2", "%%p3", "%%p4",
+ "%%p5", "%%p6", "%%p7", "%%p8",
+ "%%t1", "%%t2", "%%t3", "%%t4",
+ "%%t5", "%%t6", "%%t7", "%%t8",
+ "%%t9", "%%t10", "%%t11", "%%t12",
+ "%%t13", "%%t14", "%%t15", "%%t16",
+};
+
+static void
+get_varname (char *s, OrcCompiler *compiler, int var)
+{
+ if (compiler->target_flags & ORC_TARGET_C_NOEXEC) {
+ if (var < 48) {
+ strcpy (s, varnames[var]);
+ } else {
+ sprintf(s, "%%tmp%d", var-32);
+ }
+ } else if (compiler->target_flags & ORC_TARGET_C_OPCODE) {
+ if (var < ORC_VAR_S1) {
+ sprintf(s, "ex->dest_ptrs[%d]", var-ORC_VAR_D1);
+ } else {
+ sprintf(s, "ex->src_ptrs[%d]", var-ORC_VAR_S1);
+ }
+ } else {
+ sprintf(s, "ex->arrays[%d]", var);
+ }
+}
+
+static void
+get_varname_stride (char *s, OrcCompiler *compiler, int var)
+{
+ if (compiler->target_flags & ORC_TARGET_C_NOEXEC) {
+ sprintf(s, "%s_stride", varnames[var]);
+ } else {
+ sprintf(s, "ex->params[%d]", var);
+ }
+}
+
+void
+orc_compiler_llvm_assemble (OrcCompiler *compiler)
+{
+ int i;
+ int j;
+ OrcInstruction *insn;
+ OrcStaticOpcode *opcode;
+ OrcRule *rule;
+ int prefix = 0;
+
+ if (!(compiler->target_flags & ORC_TARGET_C_BARE)) {
+ ORC_ASM_CODE(compiler,"void\n");
+ ORC_ASM_CODE(compiler,"%s (OrcExecutor *ex)\n", compiler->program->name);
+ ORC_ASM_CODE(compiler,"{\n");
+ }
+
+ ORC_ASM_CODE(compiler,"%*s int i;\n", prefix, "");
+ if (compiler->program->is_2d) {
+ ORC_ASM_CODE(compiler," int j;\n");
+ }
+ if (compiler->program->constant_n == 0) {
+ if (!(compiler->target_flags & ORC_TARGET_C_NOEXEC) &&
+ !(compiler->target_flags & ORC_TARGET_C_OPCODE)) {
+ ORC_ASM_CODE(compiler," int n = ex->n;\n");
+ }
+ } else {
+ ORC_ASM_CODE(compiler," int n = %d;\n", compiler->program->constant_n);
+ }
+ if (compiler->program->is_2d) {
+ if (compiler->program->constant_m == 0) {
+ if (!(compiler->target_flags & ORC_TARGET_C_NOEXEC)) {
+ ORC_ASM_CODE(compiler," int m = ex->params[ORC_VAR_A1];\n");
+ }
+ } else {
+ ORC_ASM_CODE(compiler," int m = %d;\n", compiler->program->constant_m);
+ }
+ }
+
+ ORC_ASM_CODE(compiler,"\n");
+ if (compiler->program->is_2d) {
+ ORC_ASM_CODE(compiler," for (j = 0; j < m; j++) {\n");
+ prefix = 2;
+
+ for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
+ OrcVariable *var = compiler->vars + i;
+ if (var->name == NULL) continue;
+ switch (var->vartype) {
+ case ORC_VAR_TYPE_SRC:
+ {
+ char s1[40], s2[40];
+ get_varname(s1, compiler, i);
+ get_varname_stride(s2, compiler, i);
+ ORC_ASM_CODE(compiler,
+ " ptr%d = ORC_PTR_OFFSET(%s, %s * j);\n",
+ i, s1, s2);
+ }
+ break;
+ case ORC_VAR_TYPE_DEST:
+ {
+ char s1[40], s2[40];
+ get_varname(s1, compiler, i),
+ get_varname_stride(s2, compiler, i),
+ ORC_ASM_CODE(compiler,
+ " ptr%d = ORC_PTR_OFFSET(%s, %s * j);\n",
+ i, s1, s2);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
+ OrcVariable *var = compiler->vars + i;
+ char s[40],tn[40];
+ if (var->name == NULL) continue;
+ get_varname(s, compiler, i);
+ switch (var->vartype) {
+ case ORC_VAR_TYPE_SRC:
+ ORC_ASM_CODE(compiler," ptr%d = (%s *)%s;\n", i, tn, s);
+ break;
+ case ORC_VAR_TYPE_DEST:
+ ORC_ASM_CODE(compiler," ptr%d = (%s *)%s;\n", i, tn, s);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ ORC_ASM_CODE(compiler,"\n");
+ for(j=0;j<compiler->n_insns;j++){
+ insn = compiler->insns + j;
+ opcode = insn->opcode;
+
+ if (!(insn->flags & ORC_INSN_FLAG_INVARIANT)) continue;
+
+ ORC_ASM_CODE(compiler,"%*s /* %d: %s */\n", prefix, "",
+ j, insn->opcode->name);
+
+ rule = insn->rule;
+ if (!rule) {
+ ORC_COMPILER_ERROR(compiler, "No rule for: %s on target %s", opcode->name,
+ compiler->target->name);
+ continue;
+ }
+ ORC_ASM_CODE(compiler,"%*s", prefix, "");
+ ORC_ASM_CODE(compiler,"%*s", prefix, "");
+ rule->emit (compiler, rule->emit_user, insn);
+ }
+
+ ORC_ASM_CODE(compiler,"\n");
+ ORC_ASM_CODE(compiler,"%*s for (i = 0; i < n; i++) {\n", prefix, "");
+
+ /* Emit instructions */
+ for(j=0;j<compiler->n_insns;j++){
+ insn = compiler->insns + j;
+ opcode = insn->opcode;
+
+ if (insn->flags & ORC_INSN_FLAG_INVARIANT) continue;
+
+ ORC_ASM_CODE(compiler,"%*s /* %d: %s */\n", prefix, "",
+ j, insn->opcode->name);
+
+ rule = insn->rule;
+ if (!rule) {
+ ORC_COMPILER_ERROR(compiler, "No rule for: %s on target %s", opcode->name,
+ compiler->target->name);
+ continue;
+ }
+
+ ORC_ASM_CODE(compiler,"%*s", prefix, "");
+ rule->emit (compiler, rule->emit_user, insn);
+ }
+ ORC_ASM_CODE(compiler,"%*s }\n", prefix, "");
+ if (compiler->program->is_2d) {
+ ORC_ASM_CODE(compiler," }\n");
+ }
+
+ for(i=0;i<ORC_N_COMPILER_VARIABLES;i++){
+ char varname[40];
+ OrcVariable *var = compiler->vars + i;
+ if (var->name == NULL) continue;
+ switch (var->vartype) {
+ case ORC_VAR_TYPE_ACCUMULATOR:
+ llvm_get_name_int (varname, compiler, NULL, i, 0);
+ if (var->size == 2) {
+ if (compiler->target_flags & ORC_TARGET_C_NOEXEC) {
+ ORC_ASM_CODE(compiler," *%s = (%s & 0xffff);\n",
+ varnames[i], varname);
+ } else if (compiler->target_flags & ORC_TARGET_C_OPCODE) {
+ ORC_ASM_CODE(compiler," ((orc_union32 *)ex->dest_ptrs[%d])->i = "
+ "(%s + ((orc_union32 *)ex->dest_ptrs[%d])->i) & 0xffff;\n",
+ i - ORC_VAR_A1, varname, i - ORC_VAR_A1);
+ } else {
+ ORC_ASM_CODE(compiler," ex->accumulators[%d] = (%s & 0xffff);\n",
+ i - ORC_VAR_A1, varname);
+ }
+ } else {
+ if (compiler->target_flags & ORC_TARGET_C_NOEXEC) {
+ ORC_ASM_CODE(compiler," *%s = %s;\n",
+ varnames[i], varname);
+ } else if (compiler->target_flags & ORC_TARGET_C_OPCODE) {
+ ORC_ASM_CODE(compiler," ((orc_union32 *)ex->dest_ptrs[%d])->i += (orc_uint%d)%s;\n",
+ i - ORC_VAR_A1, var->size * 8, varname);
+ } else {
+ ORC_ASM_CODE(compiler," ex->accumulators[%d] = %s;\n",
+ i - ORC_VAR_A1, varname);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!(compiler->target_flags & ORC_TARGET_C_BARE)) {
+ ORC_ASM_CODE(compiler,"}\n");
+ ORC_ASM_CODE(compiler,"\n");
+ }
+}
+
+
+/* rules */
+
+static void
+llvm_get_name_int (char *name, OrcCompiler *p, OrcInstruction *insn, int var, int src)
+{
+ if (p->vars[var].vartype == ORC_VAR_TYPE_PARAM) {
+ if (p->target_flags & ORC_TARGET_C_NOEXEC) {
+ sprintf(name,"%%%s", varnames[var]);
+ } else if (p->target_flags & ORC_TARGET_C_OPCODE) {
+ sprintf(name,"((orc_union64 *)(ex->src_ptrs[%d]))->i",
+ var - ORC_VAR_P1 + p->program->n_src_vars);
+ } else {
+ switch (p->vars[var].param_type) {
+ case ORC_PARAM_TYPE_INT:
+ sprintf(name,"ex->params[%d]", var);
+ break;
+ case ORC_PARAM_TYPE_FLOAT:
+ sprintf(name,"((orc_union32 *)(ex->params+%d))->i", var);
+ break;
+ case ORC_PARAM_TYPE_INT64:
+ /* FIXME */
+ sprintf(name,"((orc_union32 *)(ex->params+%d))->i", var);
+ break;
+ case ORC_PARAM_TYPE_DOUBLE:
+ /* FIXME */
+ sprintf(name,"((orc_union32 *)(ex->params+%d))->i", var);
+ break;
+ default:
+ ORC_ASSERT(0);
+ }
+ }
+ } else if (p->vars[var].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[var].value.i == 0x80000000) {
+ sprintf(name,"0x80000000");
+ } else {
+ if (p->vars[var].value.i == (int)p->vars[var].value.i) {
+ sprintf(name, "%d", (int)p->vars[var].value.i);
+ } else {
+ ORC_ASSERT(0);
+ }
+ }
+ } else {
+ if (insn && (insn->flags & (ORC_INSTRUCTION_FLAG_X2|ORC_INSTRUCTION_FLAG_X4))) {
+ int bits = p->vars[var].size * 8;
+ int multiplier;
+
+ get_temp (name, p);
+
+ if (insn->flags & ORC_INSTRUCTION_FLAG_X4)
+ multiplier = 4;
+ else
+ multiplier = 2;
+
+ if (src)
+ ORC_ASM_CODE (p, " %s = bitcast <1 x i%d> %%var%d to <%d x i%d>\n",
+ name, bits, var, multiplier, bits / multiplier);
+ } else {
+ sprintf(name, "%%var%d", var);
+ }
+ }
+}
+
+static void
+llvm_get_name_float (char *name, OrcCompiler *p, OrcInstruction *insn, int var)
+{
+ sprintf(name, "%%var%d", var);
+}
+
+static void
+llvm_get_src_int (char *name, OrcCompiler *p, OrcInstruction *insn, int var)
+{
+ llvm_get_name_int (name, p, insn, var, 1);
+}
+
+static void
+llvm_get_dst_int (char *name, OrcCompiler *p, OrcInstruction *insn, int var)
+{
+ llvm_get_name_int (name, p, insn, var, 0);
+}
+
+static void
+llvm_store_dst_int (char *name, OrcCompiler *p, OrcInstruction *insn, int var)
+{
+ if (insn && !(insn->flags & (ORC_INSTRUCTION_FLAG_X2|ORC_INSTRUCTION_FLAG_X4)))
+ return;
+
+ int bits = p->vars[var].size * 8;
+ int multiplier;
+
+ if (insn->flags & ORC_INSTRUCTION_FLAG_X4)
+ multiplier = 4;
+ else
+ multiplier = 2;
+
+ ORC_ASM_CODE (p, " %%var%d = bitcast <%d x i%d> %s to <1 x i%d>\n",
+ var, multiplier, bits / multiplier, name, bits);
+}
+
+static int
+get_shift (OrcCompiler *p, OrcInstruction *insn)
+{
+ int res;;
+ if (insn && (insn->flags & ORC_INSTRUCTION_FLAG_X2)) {
+ res = 2;
+ } else if (insn && (insn->flags & ORC_INSTRUCTION_FLAG_X4)) {
+ res = 4;
+ } else {
+ res = 1;
+ }
+ return res;
+}
+
+static void
+llvm_rule_absb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40], t1[40], t2[40];
+ int sh = get_shift (p, insn);
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i8> zeroinitializer, %s\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = icmp slt <%d x i8> %s, zeroinitializer\n", t2, sh, src);
+ ORC_ASM_CODE (p, " %s = select <%d x i1> %s, <%d x i8> %s, <%d x i8> %s\n",
+ dest, sh, t2, sh, src, sh, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addssb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add nsw <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addusb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add nuw <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = and <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andnb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40], t1[40];
+ int sh = get_shift (p, insn);
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i8> %s, 255\n", t1, sh, src2);
+ ORC_ASM_CODE (p, " %s = and <%d x i8> %s, %s\n", dest, sh, src1, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_avgsb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+}
+static void
+llvm_rule_avgub (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpeqb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpgtsb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_copyb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = %s\n", dest, src);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_loadb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], t1[40];
+ int sh = get_shift (p, insn);
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+
+ ORC_ASM_CODE (p, " %s = getelementptr <%d x i8*> %%ptr%d, <%d x i64> %%i\n",
+ t1, sh, insn->src_args[0], sh);
+ ORC_ASM_CODE (p, " %s = load <%d x i8*> %s\n", dest, sh, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_loadoffb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadupdb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadupib (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadpb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_ldresnearb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_ldresnearl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_ldreslinb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_ldreslinl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_maxsb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_maxub (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minsb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minub (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_mullb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = mul <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulhsb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i8> %s to <%d x i16>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = sext <%d x i8> %s to <%d x i16>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i16> %s, %s\n", t3, sh, t1, t2);
+ ORC_ASM_CODE (p, " %s = ashr <%d x i16> %s, 8\n", t4, sh, t3);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulhub (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40], t1[40], t2[40], t3[40], t4[40];
+ int sh = get_shift (p, insn);
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i8> %s to <%d x i16>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = zext <%d x i8> %s to <%d x i16>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i16> %s, %s\n", t3, sh, t1, t2);
+ ORC_ASM_CODE (p, " %s = lshr <%d x i16> %s, 8\n", t4, sh, t3);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_orb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = or <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shlb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = shl <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shrsb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = ashr <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shrub (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = lshr <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_signb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_storeb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char src[40], t1[40];
+ int sh = get_shift (p, insn);
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = getelementptr <%d x i8*> %%ptr%d, <%d x i64> %%i\n",
+ t1, sh, insn->dest_args[0], sh);
+ ORC_ASM_CODE (p, " store <%d x i8*> %s, %s\n", sh, src, t1);
+}
+
+static void
+llvm_rule_subb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subssb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub nsw <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subusb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub nuw <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_xorb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i8> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_absw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i16> zeroinitializer, %s\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = icmp slt <%d x i16> %s, zeroinitializer\n", t2, sh, src);
+ ORC_ASM_CODE (p, " %s = select i1 %s, <%d x i16> %s, <%d x i16> %s\n", dest, t2, sh, src, sh, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addssw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add nsw <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addusw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add nuw <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = and <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andnw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i16> %s, 65535\n", t1, sh, src2);
+ ORC_ASM_CODE (p, " %s = and <%d x i16> %s, %s\n", dest, sh, src1, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_avgsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_avguw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpeqw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpgtsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_copyw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = %s\n", dest, src);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_div255w (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_divluw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_loadw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadoffw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadpw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_maxsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_maxuw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minuw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = mul <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulhsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i16> %s to <%d x i32>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = sext <%d x i16> %s to <%d x i32>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i32> %s, %s\n", t3, sh, t1, t2);
+ ORC_ASM_CODE (p, " %s = ashr <%d x i32> %s, 16\n", t4, sh, t3);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i32> %s to <%d x i16>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulhuw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i16> %s to <%d x i32>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = zext <%d x i16> %s to <%d x i32>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i32> %s, %s\n", t3, sh, t1, t2);
+ ORC_ASM_CODE (p, " %s = ashr <%d x i32> %s, 16\n", t4, sh, t3);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i32> %s to <%d x i16>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_orw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = or <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = shl <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shrsw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = ashr <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shruw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = lshr <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_signw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_storew (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_subw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subssw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub nsw <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subusw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub nuw <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_xorw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i16> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_absl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i32> zeroinitializer, %s\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = icmp slt <%d x i32> %s, zeroinitializer\n", t2, sh, src);
+ ORC_ASM_CODE (p, " %s = select i1 %s, <%d x i32> %s, <%d x i32> %s\n", dest, t2, sh, src, sh, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addssl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add nsw <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addusl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add nuw <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = and <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andnl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i32> %s, 0xffffffff\n", t1, sh, src2);
+ ORC_ASM_CODE (p, " %s = and <%d x i32> %s, %s\n", dest, sh, src1, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_avgsl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_avgul (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpeql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpgtsl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_copyl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = %s\n", dest, src);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_loadl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadoffl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadpl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_maxsl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_maxul (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minsl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minul (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_mulll (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = mul <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulhsl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i32> %s to <%d x i64>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = sext <%d x i32> %s to <%d x i64>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i64> %s, %s\n", t3, sh, t1, t2);
+ ORC_ASM_CODE (p, " %s = ashr <%d x i64> %s, 32\n", t4, sh, t3);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i64> %s to <%d x i32>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulhul (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i32> %s to <%d x i64>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = zext <%d x i32> %s to <%d x i64>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i64> %s, %s\n", t3, sh, t1, t2);
+ ORC_ASM_CODE (p, " %s = ashr <%d x i64> %s, 32\n", t4, sh, t3);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i64> %s to <%d x i32>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_orl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = or <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shll (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = shl <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shrsl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = ashr <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shrul (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = lshr <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_signl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_storel (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_subl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subssl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub nsw <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subusl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub nuw <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_xorl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i32> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_loadq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_loadpq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_storeq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_splatw3q (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_copyq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = %s\n", dest, src);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_cmpeqq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpgtsq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_andq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = and <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_andnq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i64> %s, 0xffffffffffffffff\n", t1, sh, src2);
+ ORC_ASM_CODE (p, " %s = and <%d x i64> %s, %s\n", dest, sh, src1, t1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_orq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = or <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_xorq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = xor <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_addq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = add <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_subq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sub <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shlq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = shl <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shrsq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = ashr <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_shruq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = lshr <%d x i64> %s, %s\n", dest, sh, src1, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_convsbw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i8> %s to <%d x i16>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convubw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i8> %s to <%d x i16>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_splatbw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ const char *mask;
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ if (sh == 1)
+ mask = "<2 x i32> <i32 0, i32 0>";
+ else if (sh == 2)
+ mask = "<4 x i32> <i32 0, i32 0, i32 0, i32 0>";
+ else if (sh == 4)
+ mask = "<8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>";
+ else
+ mask = "ERROR";
+
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i8> %s, <%d x i8> %s, %s\n",
+ dest, sh, src, sh, src, mask);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_splatbl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ const char *mask;
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ if (sh == 1)
+ mask = "<4 x i32> <i32 0, i32 0, i32 0, i32 0>";
+ else if (sh == 2)
+ mask = "<8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>";
+ else
+ mask = "ERROR";
+
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i8> %s, <%d x i8> %s, %s\n",
+ dest, sh, src, sh, src, mask);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_convswl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i16> %s to <%d x i32>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convuwl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i16> %s to <%d x i32>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convslq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i32> %s to <%d x i64>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convulq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i32> %s to <%d x i64>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_convwb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convhwb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = asr <%d x i16> %s, 8\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n", dest, sh, t1, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convssswb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+ const char *mask1, *mask2;
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ if (sh == 1) {
+ mask1 = "<1 x i16> <i16 127>";
+ mask2 = "<1 x i16> <i16 -128>";
+ } else if (sh == 2) {
+ mask1 = "<2 x i16> <i16 127, i16 127>";
+ mask2 = "<2 x i16> <i16 -128, i16 -128>";
+ } else if (sh == 4) {
+ mask1 = "<4 x i16> <i16 127, i16 127, i16 127, i16 127>";
+ mask2 = "<4 x i16> <i16 -128, i16 -128, i16 -128, i16 -128>";
+ } else {
+ mask1 = "ERROR";
+ mask2 = "ERROR";
+ }
+
+ ORC_ASM_CODE (p, " %s = icmp sgt <%d x i16> %s, %s\n", t1, sh, src, mask1);
+ ORC_ASM_CODE (p, " %s = select <%d x i1> %s, %s, <%d x i16> %s\n", t2, sh, t1, mask1, sh, src);
+ ORC_ASM_CODE (p, " %s = icmp sle <%d x i16> %s, %s\n", t3, sh, src, mask2);
+ ORC_ASM_CODE (p, " %s = select <%d x i1> %s, %s, <%d x i16> %s\n", t4, sh, t3, mask2, sh, t2);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_convsuswb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40], t3[40], t4[40];
+ const char *mask1, *mask2;
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+ get_temp (t3, p);
+ get_temp (t4, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ if (sh == 1) {
+ mask1 = "<1 x i16> <i16 255>";
+ mask2 = "<1 x i16> <i16 0>";
+ } else if (sh == 2) {
+ mask1 = "<2 x i16> <i16 255, i16 255>";
+ mask2 = "<2 x i16> <i16 0, i16 0>";
+ } else if (sh == 4) {
+ mask1 = "<4 x i16> <i16 255, i16 255, i16 255, i16 255>";
+ mask2 = "<4 x i16> <i16 0, i16 0, i16 0, i16 0>";
+ } else {
+ mask1 = "ERROR";
+ mask2 = "ERROR";
+ }
+ ORC_ASM_CODE (p, " %s = icmp sgt <%d x i16> %s, %s\n", t1, sh, src, mask1);
+ ORC_ASM_CODE (p, " %s = select <%d x i1> %s, %s, <%d x i16> %s\n", t2, sh, t1, mask1, sh, src);
+ ORC_ASM_CODE (p, " %s = icmp sle <%d x i16> %s, %s\n", t3, sh, src, mask2);
+ ORC_ASM_CODE (p, " %s = select <%d x i1> %s, %s, <%d x i16> %s\n", t4, sh, t3, mask2, sh, t2);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n", dest, sh, t4, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convusswb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convuuswb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_convlw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = trunc <%d x i32> %s to <%d x i16>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convhlw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = asr <%d x i32> %s, 16\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i32> %s to <%d x i16>\n", dest, sh, t1, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convssslw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convsuslw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convusslw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convuuslw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_convql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = trunc <%d x i64> %s to <%d x i32>\n", dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_convsssql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convsusql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convussql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convuusql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_mulsbw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i8> %s to <%d x i16>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = sext <%d x i8> %s to <%d x i16>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i16> %s, %s\n", dest, sh, t1, t2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulubw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i8> %s to <%d x i16>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = zext <%d x i8> %s to <%d x i16>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i16> %s, %s\n", dest, sh, t1, t2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulswl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i16> %s to <%d x i32>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = sext <%d x i16> %s to <%d x i32>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i32> %s, %s\n", dest, sh, t1, t2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_muluwl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i16> %s to <%d x i32>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = zext <%d x i16> %s to <%d x i32>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i32> %s, %s\n", dest, sh, t1, t2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mulslq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = sext <%d x i32> %s to <%d x i64>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = sext <%d x i32> %s to <%d x i64>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i64> %s, %s\n", dest, sh, t1, t2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+static void
+llvm_rule_mululq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ char t1[40], t2[40];
+
+ get_temp (t1, p);
+ get_temp (t2, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE (p, " %s = zext <%d x i32> %s to <%d x i64>\n", t1, sh, src1, sh);
+ ORC_ASM_CODE (p, " %s = zext <%d x i32> %s to <%d x i64>\n", t2, sh, src2, sh);
+ ORC_ASM_CODE (p, " %s = mul <%d x i64> %s, %s\n", dest, sh, t1, t2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_accw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE(p," %s = add <%d x i16> %s, %s\n", dest, sh, dest, src1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_accl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE(p," %s = add <%d x i32> %s, %s\n", dest, sh, dest, src1);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_accsadubl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ ORC_ASM_CODE(p," %s = add <%d x i32> %s, %s\n", dest, sh, dest, src1);
+ ORC_ASM_CODE(p," %s = sub <%d x i32> %s, %s\n", dest, sh, dest, src2);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_swapw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_swapl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_swapwl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_swapq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_swaplq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+}
+
+
+static void
+llvm_rule_select0wb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n",
+ dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_select1wb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = asr <%d x i16> %s, 8\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i16> %s to <%d x i8>\n",
+ dest, sh, t1, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_select0lw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = trunc <%d x i32> %s to <%d x i16>\n",
+ dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_select1lw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = asr <%d x i32> %s, 16\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i32> %s to <%d x i16>\n",
+ dest, sh, t1, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+
+static void
+llvm_rule_select0ql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = trunc <%d x i64> %s to <%d x i32>\n",
+ dest, sh, src, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_select1ql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40];
+ int sh = get_shift (p, insn);
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ ORC_ASM_CODE (p, " %s = asr <%d x i64> %s, 32\n", t1, sh, src);
+ ORC_ASM_CODE (p, " %s = trunc <%d x i64> %s to <%d x i32>\n",
+ dest, sh, t1, sh);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static const char *
+get_merge_mask (OrcCompiler *p, int sh)
+{
+ const char *mask;
+
+ if (sh == 1)
+ mask = "<2 x i32> <i32 0, i32 1>";
+ else if (sh == 2)
+ mask = "<4 x i32> <i32 0, i32 1, i32 0, i32 1>";
+ else if (sh == 4)
+ mask = "<8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>";
+ else
+ mask = "ERROR";
+
+ return mask;
+}
+
+static const char *
+get_split_mask1 (OrcCompiler *p, int sh)
+{
+ const char *mask;
+
+ if (sh == 1)
+ mask = "<1 x i32> <i32 0>";
+ else if (sh == 2)
+ mask = "<2 x i32> <i32 0, i32 2>";
+ else if (sh == 4)
+ mask = "<4 x i32> <i32 0, i32 2, i32 4, i32 6>";
+ else
+ mask = "ERROR";
+
+ return mask;
+}
+
+static const char *
+get_split_mask2 (OrcCompiler *p, int sh)
+{
+ const char *mask;
+
+ if (sh == 1)
+ mask = "<1 x i32> <i32 1>";
+ else if (sh == 2)
+ mask = "<2 x i32> <i32 1, i32 3>";
+ else if (sh == 4)
+ mask = "<4 x i32> <i32 1, i32 3, i32 5, i32 7>";
+ else
+ mask = "ERROR";
+
+ return mask;
+}
+
+static void
+llvm_rule_mergelq (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ const char *mask;
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ mask = get_merge_mask (p, sh);
+
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i32> %s, <%d x i32> %s, %s\n",
+ dest, sh, src1, sh, src2, mask);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_mergewl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ const char *mask;
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ mask = get_merge_mask (p, sh);
+
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i16> %s, <%d x i16> %s, %s\n",
+ dest, sh, src1, sh, src2, mask);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+static void
+llvm_rule_mergebw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+ int sh = get_shift (p, insn);
+ const char *mask;
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+
+ mask = get_merge_mask (p, sh);
+
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i8> %s, <%d x i8> %s, %s\n",
+ dest, sh, src1, sh, src2, mask);
+
+ llvm_store_dst_int (dest, p, insn, insn->dest_args[0]);
+}
+
+
+static void
+llvm_rule_splitql (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest1[40], dest2[40], src[40];
+ int sh = get_shift (p, insn);
+ const char *mask1, *mask2;
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest1, p, insn, insn->dest_args[0]);
+ llvm_get_dst_int (dest2, p, insn, insn->dest_args[1]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ mask1 = get_split_mask1 (p, sh);
+ mask2 = get_split_mask2 (p, sh);
+
+ ORC_ASM_CODE (p, " %s = bitcast <%d x i64> %s to <%d x i32>\n",
+ t1, sh, src, sh * 2);
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i32> %s, <%d x i32> %s, %s\n",
+ dest1, sh * 2, t1, sh * 2, t1, mask1);
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i32> %s, <%d x i32> %s, %s\n",
+ dest2, sh * 2, t1, sh * 2, t1, mask2);
+
+ llvm_store_dst_int (dest1, p, insn, insn->dest_args[0]);
+ llvm_store_dst_int (dest2, p, insn, insn->dest_args[1]);
+}
+
+static void
+llvm_rule_splitlw (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest1[40], dest2[40], src[40];
+ int sh = get_shift (p, insn);
+ const char *mask1, *mask2;
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest1, p, insn, insn->dest_args[0]);
+ llvm_get_dst_int (dest2, p, insn, insn->dest_args[1]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ mask1 = get_split_mask1 (p, sh);
+ mask2 = get_split_mask2 (p, sh);
+
+ ORC_ASM_CODE (p, " %s = bitcast <%d x i32> %s to <%d x i16>\n",
+ t1, sh, src, sh * 2);
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i16> %s, <%d x i16> %s, %s\n",
+ dest1, sh * 2, t1, sh * 2, t1, mask1);
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i16> %s, <%d x i16> %s, %s\n",
+ dest2, sh * 2, t1, sh * 2, t1, mask2);
+
+ llvm_store_dst_int (dest1, p, insn, insn->dest_args[0]);
+ llvm_store_dst_int (dest2, p, insn, insn->dest_args[1]);
+}
+
+static void
+llvm_rule_splitwb (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest1[40], dest2[40], src[40];
+ int sh = get_shift (p, insn);
+ const char *mask1, *mask2;
+ char t1[40];
+
+ get_temp (t1, p);
+
+ llvm_get_dst_int (dest1, p, insn, insn->dest_args[0]);
+ llvm_get_dst_int (dest2, p, insn, insn->dest_args[1]);
+ llvm_get_src_int (src, p, insn, insn->src_args[0]);
+
+ mask1 = get_split_mask1 (p, sh);
+ mask2 = get_split_mask2 (p, sh);
+
+ ORC_ASM_CODE (p, " %s = bitcast <%d x i16> %s to <%d x i8>\n",
+ t1, sh, src, sh * 2);
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i8> %s, <%d x i8> %s, %s\n",
+ dest1, sh * 2, t1, sh * 2, t1, mask1);
+ ORC_ASM_CODE (p, " %s = shufflevector <%d x i8> %s, <%d x i8> %s, %s\n",
+ dest2, sh * 2, t1, sh * 2, t1, mask2);
+
+ llvm_store_dst_int (dest1, p, insn, insn->dest_args[0]);
+ llvm_store_dst_int (dest2, p, insn, insn->dest_args[1]);
+}
+
+static void
+llvm_rule_addf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_subf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_mulf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_divf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_sqrtf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+
+static void
+llvm_rule_maxf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_minf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+
+static void
+llvm_rule_cmpeqf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_cmpltf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_cmplef (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_convfl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40], src_i[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_name_float (src, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src_i, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_convlf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40];
+
+ llvm_get_name_float (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_addd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_subd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_muld (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_divd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_sqrtd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_maxd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_mind (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40], src2[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src2, p, insn, insn->src_args[1]);
+}
+static void
+llvm_rule_cmpeqd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_cmpltd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_cmpled (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+}
+static void
+llvm_rule_convdl (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src[40], src_i[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_name_float (src, p, insn, insn->src_args[0]);
+ llvm_get_src_int (src_i, p, insn, insn->src_args[0]);
+}
+static void
+llvm_rule_convld (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40];
+
+ llvm_get_name_float (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_convfd (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40];
+
+ llvm_get_name_float (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+}
+
+static void
+llvm_rule_convdf (OrcCompiler *p, void *user, OrcInstruction *insn)
+{
+ char dest[40], src1[40];
+
+ llvm_get_dst_int (dest, p, insn, insn->dest_args[0]);
+ llvm_get_src_int (src1, p, insn, insn->src_args[0]);
+}
+
+
+static OrcTarget llvm_target = {
+ "llvm",
+ FALSE,
+ ORC_GP_REG_BASE,
+ orc_compiler_llvm_get_default_flags,
+ orc_compiler_llvm_init,
+ orc_compiler_llvm_assemble,
+ { { 0 } },
+ 0,
+ orc_target_llvm_get_asm_preamble,
+};
+
+
+void
+orc_llvm_init (void)
+{
+ OrcRuleSet *rule_set;
+
+ orc_target_register (&llvm_target);
+
+ rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), &llvm_target, 0);
+
+#define REG(a) orc_rule_register (rule_set, #a , llvm_rule_ ## a, NULL);
+
+ /* byte ops */
+ REG(absb);
+ REG(addb);
+ REG(addssb);
+ REG(addusb);
+ REG(andb);
+ REG(andnb);
+ REG(avgsb);
+ REG(avgub);
+ REG(cmpeqb);
+ REG(cmpgtsb);
+ REG(copyb);
+ REG(loadb);
+ REG(loadoffb);
+ REG(loadupdb);
+ REG(loadupib);
+ REG(loadpb);
+ REG(ldresnearb);
+ REG(ldresnearl);
+ REG(ldreslinb);
+ REG(ldreslinl);
+ REG(maxsb);
+ REG(maxub);
+ REG(minsb);
+ REG(minub);
+ REG(mullb);
+ REG(mulhsb);
+ REG(mulhub);
+ REG(orb);
+ REG(shlb);
+ REG(shrsb);
+ REG(shrub);
+ REG(signb);
+ REG(storeb);
+ REG(subb);
+ REG(subssb);
+ REG(subusb);
+ REG(xorb);
+
+ /* word ops */
+ REG(absw);
+ REG(addw);
+ REG(addssw);
+ REG(addusw);
+ REG(andw);
+ REG(andnw);
+ REG(avgsw);
+ REG(avguw);
+ REG(cmpeqw);
+ REG(cmpgtsw);
+ REG(copyw);
+ REG(div255w);
+ REG(divluw);
+ REG(loadw);
+ REG(loadoffw);
+ REG(loadpw);
+ REG(maxsw);
+ REG(maxuw);
+ REG(minsw);
+ REG(minuw);
+ REG(mullw);
+ REG(mulhsw);
+ REG(mulhuw);
+ REG(orw);
+ REG(shlw);
+ REG(shrsw);
+ REG(shruw);
+ REG(signw);
+ REG(storew);
+ REG(subw);
+ REG(subssw);
+ REG(subusw);
+ REG(xorw);
+
+ /* long ops */
+ REG(absl);
+ REG(addl);
+ REG(addssl);
+ REG(addusl);
+ REG(andl);
+ REG(andnl);
+ REG(avgsl);
+ REG(avgul);
+ REG(cmpeql);
+ REG(cmpgtsl);
+ REG(copyl);
+ REG(loadl);
+ REG(loadoffl);
+ REG(loadpl);
+ REG(maxsl);
+ REG(maxul);
+ REG(minsl);
+ REG(minul);
+ REG(mulll);
+ REG(mulhsl);
+ REG(mulhul);
+ REG(orl);
+ REG(shll);
+ REG(shrsl);
+ REG(shrul);
+ REG(signl);
+ REG(storel);
+ REG(subl);
+ REG(subssl);
+ REG(subusl);
+ REG(xorl);
+
+ REG(loadq);
+ REG(loadpq);
+ REG(storeq);
+ REG(splatw3q);
+ REG(copyq);
+ REG(cmpeqq);
+ REG(cmpgtsq);
+ REG(andq);
+ REG(andnq);
+ REG(orq);
+ REG(xorq);
+ REG(addq);
+ REG(subq);
+ REG(shlq);
+ REG(shrsq);
+ REG(shruq);
+
+ REG(convsbw);
+ REG(convubw);
+ REG(splatbw);
+ REG(splatbl);
+
+ REG(convswl);
+ REG(convuwl);
+ REG(convslq);
+ REG(convulq);
+
+ REG(convwb);
+ REG(convhwb);
+ REG(convssswb);
+ REG(convsuswb);
+ REG(convusswb);
+ REG(convuuswb);
+
+ REG(convlw);
+ REG(convhlw);
+ REG(convssslw);
+ REG(convsuslw);
+ REG(convusslw);
+ REG(convuuslw);
+
+ REG(convql);
+ REG(convsssql);
+ REG(convsusql);
+ REG(convussql);
+ REG(convuusql);
+
+ REG(mulsbw);
+ REG(mulubw);
+ REG(mulswl);
+ REG(muluwl);
+ REG(mulslq);
+ REG(mululq);
+
+ /* accumulators */
+ REG(accw);
+ REG(accl);
+ REG(accsadubl);
+
+ REG(swapw);
+ REG(swapl);
+ REG(swapwl);
+ REG(swapq);
+ REG(swaplq);
+ REG(select0wb);
+ REG(select1wb);
+ REG(select0lw);
+ REG(select1lw);
+ REG(select0ql);
+ REG(select1ql);
+ REG(mergelq);
+ REG(mergewl);
+ REG(mergebw);
+ REG(splitql);
+ REG(splitlw);
+ REG(splitwb);
+
+ /* float ops */
+ REG(addf);
+ REG(subf);
+ REG(mulf);
+ REG(divf);
+ REG(sqrtf);
+ REG(maxf);
+ REG(minf);
+ REG(cmpeqf);
+ REG(cmpltf);
+ REG(cmplef);
+ REG(convfl);
+ REG(convlf);
+
+ /* double ops */
+ REG(addd);
+ REG(subd);
+ REG(muld);
+ REG(divd);
+ REG(sqrtd);
+ REG(maxd);
+ REG(mind);
+ REG(cmpeqd);
+ REG(cmpltd);
+ REG(cmpled);
+ REG(convdl);
+ REG(convld);
+ REG(convfd);
+ REG(convdf);
+}
+