diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-12-14 14:17:16 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-12-14 14:17:16 +0100 |
commit | 093a04aa9bc097b6594f96d90ab315cdac582aa9 (patch) | |
tree | 4fdf6c5976651b430399e2300d2f9d105529941c | |
parent | 98f3b33241fcdfe8ede33685f6418d87343b5a44 (diff) |
llvm: beginnings of llvm backend
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | orc/Makefile.am | 3 | ||||
-rw-r--r-- | orc/orc.c | 4 | ||||
-rw-r--r-- | orc/orcinternal.h | 1 | ||||
-rw-r--r-- | orc/orcprogram-llvm.c | 3017 |
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 @@ -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); +} + |