orc_init (void)
{
orc_opcode_init();
+ orc_c_init();
orc_mmx_init();
orc_sse_init();
orc_powerpc_init();
- orc_c_init();
orc_arm_init();
}
void orc_compiler_do_regs (OrcCompiler *compiler);
int orc_compiler_dup_temporary (OrcCompiler *compiler, int var, int j);
-#if defined(HAVE_I386)
-int _orc_default_target = ORC_TARGET_SSE;
-#elif defined(HAVE_AMD64)
-int _orc_default_target = ORC_TARGET_SSE;
-#elif defined(HAVE_ARM)
-int _orc_default_target = ORC_TARGET_ARM;
-#elif defined(HAVE_POWERPC)
-int _orc_default_target = ORC_TARGET_ALTIVEC;
-#else
-int _orc_default_target = ORC_TARGET_C;
-#endif
-
int
orc_compiler_allocate_register (OrcCompiler *compiler, int data_reg)
int offset;
if (data_reg) {
- if (compiler->target == ORC_TARGET_ARM ||
- compiler->target == ORC_TARGET_C) {
- offset = ORC_GP_REG_BASE;
- } else {
- offset = ORC_VEC_REG_BASE;
- }
+ offset = compiler->target->data_register_offset;
} else {
offset = ORC_GP_REG_BASE;
}
orc_bool
orc_program_compile (OrcProgram *program)
{
- return orc_program_compile_for_target (program, _orc_default_target);
+ return orc_program_compile_for_target (program, orc_target_get_default());
}
orc_bool
-orc_program_compile_for_target (OrcProgram *program, int target)
+orc_program_compile_for_target (OrcProgram *program, OrcTarget *target)
{
OrcCompiler *compiler;
int i;
compiler->valid_regs[i] = 1;
}
- switch (compiler->target) {
- case ORC_TARGET_C:
- orc_compiler_c_init (compiler);
- break;
- case ORC_TARGET_ALTIVEC:
- orc_compiler_powerpc_init (compiler);
- break;
- case ORC_TARGET_SSE:
- orc_compiler_sse_init (compiler);
- break;
- case ORC_TARGET_MMX:
- orc_compiler_mmx_init (compiler);
- break;
- case ORC_TARGET_ARM:
- orc_compiler_arm_init (compiler);
- break;
- default:
- break;
- }
+ compiler->target->compiler_init (compiler);
orc_compiler_assign_rules (compiler);
if (compiler->error) goto error;
orc_compiler_rewrite_vars (compiler);
if (compiler->error) goto error;
- if (compiler->target != ORC_TARGET_C) {
+ //if (compiler->target != ORC_TARGET_C) {
orc_compiler_global_reg_alloc (compiler);
orc_compiler_do_regs (compiler);
- }
+ //}
orc_compiler_rewrite_vars2 (compiler);
if (compiler->error) goto error;
- if (compiler->target != ORC_TARGET_C) {
+ //if (compiler->target != ORC_TARGET_C) {
orc_compiler_allocate_codemem (compiler);
- }
+ //}
- switch (compiler->target) {
- case ORC_TARGET_C:
- orc_compiler_assemble_c (compiler);
- break;
- case ORC_TARGET_ALTIVEC:
- orc_compiler_assemble_powerpc (compiler);
- break;
- case ORC_TARGET_MMX:
- orc_compiler_mmx_assemble (compiler);
- break;
- case ORC_TARGET_SSE:
- orc_compiler_sse_assemble (compiler);
- break;
- case ORC_TARGET_ARM:
- orc_compiler_arm_assemble (compiler);
- break;
- default:
- break;
- }
+ compiler->target->compile (compiler);
if (compiler->error) goto error;
program->asm_code = compiler->asm_code;
for(i=0;i<compiler->n_insns;i++) {
OrcInstruction *insn = compiler->insns + i;
- insn->rule = insn->opcode->rules + compiler->target;
+ insn->rule = orc_target_get_rule (compiler->target, insn->opcode);
if (insn->rule == NULL || insn->rule->emit == NULL) {
ORC_PROGRAM_ERROR(compiler, "No rule for: %s", insn->opcode->name);
int j;
int k;
OrcInstruction *insn;
- OrcOpcode *opcode;
+ OrcStaticOpcode *opcode;
int var;
int actual_var;
opcode = insn->opcode;
/* set up args */
- for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
- var = insn->args[k];
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ if (opcode->src_size[k] == 0) continue;
+
+ var = insn->src_args[k];
if (compiler->vars[var].vartype == ORC_VAR_TYPE_DEST) {
ORC_PROGRAM_ERROR(compiler, "using dest var as source");
}
actual_var = var;
if (compiler->vars[var].replaced) {
actual_var = compiler->vars[var].replacement;
- insn->args[k] = actual_var;
+ insn->src_args[k] = actual_var;
}
if (!compiler->vars[var].used) {
compiler->vars[actual_var].last_use = j;
}
- for(k=0;k<opcode->n_dest;k++){
- var = insn->args[k];
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ if (opcode->dest_size[k] == 0) continue;
+
+ var = insn->dest_args[k];
if (compiler->vars[var].vartype == ORC_VAR_TYPE_SRC) {
ORC_PROGRAM_ERROR(compiler,"using src var as dest");
actual_var = var;
if (compiler->vars[var].replaced) {
actual_var = compiler->vars[var].replacement;
- insn->args[k] = actual_var;
+ insn->dest_args[k] = actual_var;
}
if (!compiler->vars[var].used) {
actual_var = orc_compiler_dup_temporary (compiler, var, j);
compiler->vars[var].replaced = TRUE;
compiler->vars[var].replacement = actual_var;
- insn->args[k] = actual_var;
+ insn->dest_args[k] = actual_var;
compiler->vars[actual_var].used = TRUE;
compiler->vars[actual_var].first_use = j;
}
int k;
int var;
OrcInstruction *insn;
- OrcOpcode *opcode;
+ OrcStaticOpcode *opcode;
for(i=0;i<compiler->n_insns;i++){
insn = compiler->insns + i;
opcode = insn->opcode;
- for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
- var = insn->args[k];
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ if (opcode->src_size[k] == 0) continue;
+ var = insn->src_args[k];
}
- for(k=0;k<opcode->n_dest;k++){
- var = insn->args[k];
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ if (opcode->dest_size[k] == 0) continue;
+
+ var = insn->dest_args[k];
}
}
}
* - src1 must be last_use
*/
if (1) {
- int src1 = compiler->insns[j].args[1];
- int dest = compiler->insns[j].args[0];
+ int src1 = compiler->insns[j].src_args[0];
+ int dest = compiler->insns[j].dest_args[0];
if (compiler->vars[src1].last_use == j) {
if (compiler->vars[src1].first_use == j) {
k = orc_compiler_allocate_register (compiler, TRUE);
if (0) {
/* immediate operand, don't load */
- int src2 = compiler->insns[j].args[2];
+ int src2 = compiler->insns[j].src_args[1];
compiler->vars[src2].alloc = 1;
} else {
- int src2 = compiler->insns[j].args[2];
+ int src2 = compiler->insns[j].src_args[1];
if (compiler->vars[src2].alloc == 1) {
compiler->vars[src2].alloc = 0;
}
orc_debug_print((level), __FILE__, ORC_FUNCTION, __LINE__, __VA_ARGS__); \
}while(0)
+#define ORC_ASSERT(test) do { \
+ if (!(test)) { \
+ ORC_ERROR("assertion failed: " #test ); \
+ abort(); \
+ } \
+} while(0)
+
void orc_debug_set_print_function (OrcDebugPrintFunc func);
int orc_debug_get_level (void);
void orc_debug_set_level (int level);
int k;
OrcProgram *program = ex->program;
OrcInstruction *insn;
- OrcOpcode *opcode;
+ OrcStaticOpcode *opcode;
OrcOpcodeExecutor opcode_ex;
for(i=0;i<ex->n;i++){
opcode = insn->opcode;
/* set up args */
- for(k=0;k<opcode->n_src + opcode->n_dest;k++){
-
- if (program->vars[insn->args[k]].vartype == ORC_VAR_TYPE_SRC) {
- void *ptr = ex->arrays[insn->args[k]] +
- program->vars[insn->args[k]].size*i;
-
- switch (program->vars[insn->args[k]].size) {
- case 1:
- opcode_ex.values[k] = *(int8_t *)ptr;
- break;
- case 2:
- opcode_ex.values[k] = *(int16_t *)ptr;
- break;
- case 4:
- opcode_ex.values[k] = *(int32_t *)ptr;
- break;
- default:
- ORC_ERROR("ack");
- }
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ void *ptr = ex->arrays[insn->src_args[k]] +
+ program->vars[insn->src_args[k]].size*i;
+
+ switch (program->vars[insn->src_args[k]].size) {
+ case 1:
+ opcode_ex.values[k] = *(int8_t *)ptr;
+ break;
+ case 2:
+ opcode_ex.values[k] = *(int16_t *)ptr;
+ break;
+ case 4:
+ opcode_ex.values[k] = *(int32_t *)ptr;
+ break;
+ default:
+ ORC_ERROR("ack");
}
}
opcode->emulate (&opcode_ex, opcode->emulate_user);
- for(k=0;k<opcode->n_src + opcode->n_dest;k++){
- if (program->vars[insn->args[k]].vartype == ORC_VAR_TYPE_DEST) {
- void *ptr = ex->arrays[insn->args[k]] +
- program->vars[insn->args[k]].size*i;
-
- switch (program->vars[insn->args[k]].size) {
- case 1:
- *(int8_t *)ptr = opcode_ex.values[k];
- break;
- case 2:
- *(int16_t *)ptr = opcode_ex.values[k];
- break;
- case 4:
- *(int32_t *)ptr = opcode_ex.values[k];
- break;
- default:
- ORC_ERROR("ack");
- }
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ void *ptr = ex->arrays[insn->dest_args[k]] +
+ program->vars[insn->dest_args[k]].size*i;
+
+ switch (program->vars[insn->dest_args[k]].size) {
+ case 1:
+ *(int8_t *)ptr = opcode_ex.values[k];
+ break;
+ case 2:
+ *(int16_t *)ptr = opcode_ex.values[k];
+ break;
+ case 4:
+ *(int32_t *)ptr = opcode_ex.values[k];
+ break;
+ default:
+ ORC_ERROR("ack");
}
}
}
#include <stdlib.h>
#include <orc/orcprogram.h>
+#include <orc/orcdebug.h>
-static OrcOpcode *opcode_list;
-static int n_opcodes;
-static int n_opcodes_alloc;
+static OrcOpcodeSet *opcode_sets;
+static int n_opcode_sets;
+
+static OrcTarget *targets[ORC_N_TARGETS];
+static int n_targets;
+
+static OrcTarget *default_target;
#define ORC_SB_MAX 127
#define ORC_SB_MIN (-1-ORC_SB_MAX)
#define ORC_CLAMP_UL(x) CLAMP(x,ORC_UL_MIN,ORC_UL_MAX)
+void
+orc_target_register (OrcTarget *target)
+{
+ targets[n_targets] = target;
+ n_targets++;
+
+ if (target->executable) {
+ default_target = target;
+ }
+}
+
+OrcTarget *
+orc_target_get_by_name (const char *name)
+{
+ int i;
+
+ for(i=0;i<n_targets;i++){
+ if (strcmp (name, targets[i]->name) == 0) {
+ return targets[i];
+ }
+ }
+
+ return NULL;
+}
+
+OrcTarget *
+orc_target_get_default (void)
+{
+ return default_target;
+}
+
+#if 0
int
orc_opcode_get_list (OrcOpcode **list)
{
(*list) = opcode_list;
return n_opcodes;
}
+#endif
+#if 0
void
orc_opcode_register (const char *name, int n_dest, int n_src,
OrcOpcodeEmulateFunc emulate, void *user)
n_opcodes++;
}
+#endif
-void
-orc_opcode_register_static (OrcStaticOpcode *sopcode)
+OrcRuleSet *
+orc_rule_set_new (OrcOpcodeSet *opcode_set, OrcTarget *target)
{
- while (sopcode->name[0]) {
- OrcOpcode *opcode;
- int i;
+ OrcRuleSet *rule_set;
- if (n_opcodes == n_opcodes_alloc) {
- n_opcodes_alloc += 100;
- opcode_list = realloc(opcode_list, sizeof(OrcOpcode) * n_opcodes_alloc);
- }
+ rule_set = target->rule_sets + target->n_rule_sets;
+ target->n_rule_sets++;
- opcode = opcode_list + n_opcodes;
+ memset (rule_set, 0, sizeof(OrcRuleSet));
- memset (opcode, 0, sizeof(OrcOpcode));
+ rule_set->opcode_set = opcode_set;
- opcode->name = sopcode->name;
- for(i=0;i<ORC_STATIC_OPCODE_N_DEST;i++){
- opcode->dest_size[i] = sopcode->dest_size[i];
- if (sopcode->dest_size[i]) opcode->n_dest = i + 1;
- }
- for(i=0;i<ORC_STATIC_OPCODE_N_SRC;i++){
- opcode->src_size[i] = sopcode->src_size[i];
- if (sopcode->src_size[i]) opcode->n_src = i + 1;
- }
- opcode->emulate = sopcode->emulate;
- opcode->emulate_user = sopcode->emulate_user;
+ rule_set->rules = malloc (sizeof(OrcRule) * opcode_set->n_opcodes);
+ memset (rule_set->rules, 0, sizeof(OrcRule) * opcode_set->n_opcodes);
+
+ return rule_set;
+}
+
+OrcRule *
+orc_target_get_rule (OrcTarget *target, OrcStaticOpcode *opcode)
+{
+ OrcRule *rule;
+ int i;
+ int j;
+
+ /* FIXME */
+ ORC_ASSERT(n_opcode_sets == 1);
+
+ j = opcode - opcode_sets[0].opcodes;
+
+ for(i=0;i<target->n_rule_sets;i++){
+ rule = target->rule_sets[i].rules + j;
+ if (rule) return rule;
+ }
+
+ return NULL;
+}
+
+int
+orc_opcode_register_static (OrcStaticOpcode *sopcode, char *prefix)
+{
+ int n;
+ int major;
+
+ n = 0;
+ while (sopcode[n].name[0]) {
+ n++;
+ }
+
+ major = n_opcode_sets;
+
+ n_opcode_sets++;
+ opcode_sets = realloc (opcode_sets, sizeof(OrcOpcodeSet)*n_opcode_sets);
+
+ memset (opcode_sets + major, 0, sizeof(OrcOpcodeSet));
+ strncpy(opcode_sets[major].prefix, prefix, sizeof(opcode_sets[major].prefix)-1);
+ opcode_sets[major].n_opcodes = n;
+ opcode_sets[major].opcodes = sopcode;
+ opcode_sets[major].opcode_major = major;
- n_opcodes++;
- sopcode++;
+ return major;
+}
+
+OrcOpcodeSet *
+orc_opcode_set_get (const char *name)
+{
+ int i;
+
+ for(i=0;i<n_opcode_sets;i++){
+ if (strcmp (opcode_sets[i].prefix, name) == 0) {
+ return opcode_sets + i;
+ }
}
+
+ return NULL;
}
+int
+orc_opcode_set_find_by_name (OrcOpcodeSet *opcode_set, const char *name)
+{
+ int j;
+
+ for(j=0;j<opcode_set->n_opcodes;j++){
+ if (strcmp (name, opcode_set->opcodes[j].name) == 0) {
+ return j;
+ }
+ }
+
+ return -1;
+}
-OrcOpcode *
+OrcStaticOpcode *
orc_opcode_find_by_name (const char *name)
{
int i;
+ int j;
- for(i=0;i<n_opcodes;i++){
- if (!strcmp (name, opcode_list[i].name)) {
- return opcode_list + i;
+ for(i=0;i<n_opcode_sets;i++){
+ j = orc_opcode_set_find_by_name (opcode_sets + i, name);
+ if (j >= 0) {
+ return &opcode_sets[i].opcodes[j];
}
}
{ "shlb", shlb, NULL, { 1 }, { 1, 1 } },
{ "shrsb", shrsb, NULL, { 1 }, { 1, 1 } },
{ "shrub", shrub, NULL, { 1 }, { 1, 1 } },
- { "signb", signb, NULL, { 1 }, { 1, 1 } },
+ { "signb", signb, NULL, { 1 }, { 1 } },
{ "subb", subb, NULL, { 1 }, { 1, 1 } },
{ "subssb", subssb, NULL, { 1 }, { 1, 1 } },
{ "subusb", subusb, NULL, { 1 }, { 1, 1 } },
{ "shlw", shlw, NULL, { 2 }, { 2, 2 } },
{ "shrsw", shrsw, NULL, { 2 }, { 2, 2 } },
{ "shruw", shruw, NULL, { 2 }, { 2, 2 } },
- { "signw", signw, NULL, { 2 }, { 2, 2 } },
+ { "signw", signw, NULL, { 2 }, { 2 } },
{ "subw", subw, NULL, { 2 }, { 2, 2 } },
{ "subssw", subssw, NULL, { 2 }, { 2, 2 } },
{ "subusw", subusw, NULL, { 2 }, { 2, 2 } },
{ "shll", shll, NULL, { 4 }, { 4, 4 } },
{ "shrsl", shrsl, NULL, { 4 }, { 4, 4 } },
{ "shrul", shrul, NULL, { 4 }, { 4, 4 } },
- { "signl", signl, NULL, { 4 }, { 4, 4 } },
+ { "signl", signl, NULL, { 4 }, { 4 } },
{ "subl", subl, NULL, { 4 }, { 4, 4 } },
{ "subssl", subssl, NULL, { 4 }, { 4, 4 } },
{ "subusl", subusl, NULL, { 4 }, { 4, 4 } },
void
orc_opcode_init (void)
{
- orc_opcode_register_static (opcodes);
+ orc_opcode_register_static (opcodes, "sys");
}
void arm_emit_loop (OrcCompiler *compiler);
-void orc_compiler_arm_register_rules (void);
+void orc_compiler_arm_register_rules (OrcTarget *target);
+void orc_compiler_arm_init (OrcCompiler *compiler);
+void orc_compiler_arm_assemble (OrcCompiler *compiler);
void orc_compiler_rewrite_vars (OrcCompiler *compiler);
void orc_compiler_dump (OrcCompiler *compiler);
//arm_dump_insns (compiler);
}
+static OrcTarget arm_target = {
+ "arm",
+#ifdef HAVE_ARM
+ TRUE,
+#else
+ FALSE,
+#endif
+ ORC_GP_REG_BASE,
+ orc_compiler_arm_init,
+ orc_compiler_arm_assemble
+};
+
void
orc_arm_init (void)
{
- orc_compiler_arm_register_rules ();
+ orc_target_register (&arm_target);
+
+ orc_compiler_arm_register_rules (&arm_target);
}
void
int j;
int k;
OrcInstruction *insn;
- OrcOpcode *opcode;
- OrcVariable *args[10];
+ OrcStaticOpcode *opcode;
OrcRule *rule;
for(j=0;j<compiler->n_insns;j++){
orc_compiler_append_code(compiler,"# %d: %s", j, insn->opcode->name);
/* set up args */
+#if 0
for(k=0;k<opcode->n_src + opcode->n_dest;k++){
args[k] = compiler->vars + insn->args[k];
orc_compiler_append_code(compiler," %d", args[k]->alloc);
orc_compiler_append_code(compiler," (chained)");
}
}
+#endif
orc_compiler_append_code(compiler,"\n");
- for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ if (opcode->src_size[k] == 0) continue;
+
+ switch (compiler->vars[insn->src_args[k]].vartype) {
case ORC_VAR_TYPE_SRC:
- arm_emit_load_src (compiler, args[k]);
+ arm_emit_load_src (compiler, &compiler->vars[insn->src_args[k]]);
break;
case ORC_VAR_TYPE_CONST:
break;
rule = insn->rule;
if (rule && rule->emit) {
- if (args[0]->alloc != args[1]->alloc) {
- arm_emit_mov (compiler, args[1]->alloc, args[0]->alloc);
+ if (compiler->vars[insn->dest_args[0]].alloc !=
+ compiler->vars[insn->src_args[0]].alloc) {
+ arm_emit_mov (compiler, compiler->vars[insn->src_args[0]].alloc,
+ compiler->vars[insn->dest_args[0]].alloc);
}
rule->emit (compiler, rule->emit_user, insn);
} else {
orc_compiler_append_code(compiler,"No rule for: %s\n", opcode->name);
}
- for(k=0;k<opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ if (opcode->dest_size[k] == 0) continue;
+
+ switch (compiler->vars[insn->dest_args[k]].vartype) {
case ORC_VAR_TYPE_DEST:
- arm_emit_store_dest (compiler, args[k]);
+ arm_emit_store_dest (compiler, &compiler->vars[insn->dest_args[k]]);
break;
case ORC_VAR_TYPE_TEMP:
break;
}
const char *
-orc_target_get_asm_preamble (int target)
+orc_target_get_asm_preamble (const char *target)
{
return "\n"
"/* begin Orc C target preamble */\n"
}
void
-orc_compiler_assemble_c (OrcCompiler *compiler)
+orc_compiler_c_assemble (OrcCompiler *compiler)
{
int i;
int j;
OrcInstruction *insn;
- OrcOpcode *opcode;
+ OrcStaticOpcode *opcode;
OrcRule *rule;
ORC_ASM_CODE(compiler,"void\n");
{ \
char dest[20], src1[20], src2[20]; \
\
- c_get_name (dest, p, insn->args[0]); \
- c_get_name (src1, p, insn->args[1]); \
- c_get_name (src2, p, insn->args[2]); \
+ c_get_name (dest, p, insn->dest_args[0]); \
+ c_get_name (src1, p, insn->src_args[0]); \
+ c_get_name (src2, p, insn->src_args[1]); \
\
ORC_ASM_CODE(p," %s = " op ";\n", dest, src1, src2); \
}
#undef BINARY_LW
#undef BINARY_WB
+static OrcTarget c_target = {
+ "c",
+ TRUE,
+ ORC_GP_REG_BASE,
+ orc_compiler_c_init,
+ orc_compiler_c_assemble
+};
+
void
orc_c_init (void)
{
-#define BINARY_SB(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_UB(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_SW(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_UW(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_SL(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_UL(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define UNARY_SB(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define UNARY_UB(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define UNARY_SW(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define UNARY_UW(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define UNARY_SL(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define UNARY_UL(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_BW(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_WL(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_LW(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
-#define BINARY_WB(a,b) orc_rule_register ( #a , ORC_TARGET_C, c_rule_ ## a, NULL);
+ OrcRuleSet *rule_set;
+
+ orc_target_register (&c_target);
+
+ rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), &c_target);
+
+#define BINARY_SB(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_UB(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_SW(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_UW(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_SL(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_UL(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define UNARY_SB(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define UNARY_UB(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define UNARY_SW(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define UNARY_UW(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define UNARY_SL(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define UNARY_UL(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_BW(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_WL(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_LW(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
+#define BINARY_WB(a,b) orc_rule_register (rule_set, #a , c_rule_ ## a, NULL);
#include "opcodes.h"
void mmx_emit_loop (OrcCompiler *compiler);
+void orc_compiler_mmx_init (OrcCompiler *compiler);
+void orc_compiler_mmx_assemble (OrcCompiler *compiler);
-void orc_compiler_mmx_register_rules (void);
+void orc_compiler_mmx_register_rules (OrcTarget *target);
void orc_compiler_rewrite_vars (OrcCompiler *compiler);
void orc_compiler_dump (OrcCompiler *compiler);
+static OrcTarget mmx_target = {
+ "mmx",
+#if defined(HAVE_I386) || defined(HAVE_AMD64)
+ TRUE,
+#else
+ FALSE,
+#endif
+ ORC_VEC_REG_BASE,
+ orc_compiler_mmx_init,
+ orc_compiler_mmx_assemble
+};
+
void
orc_mmx_init (void)
{
- orc_compiler_mmx_register_rules ();
+ orc_target_register (&mmx_target);
+
+ orc_compiler_mmx_register_rules (&mmx_target);
}
void
int j;
int k;
OrcInstruction *insn;
- OrcOpcode *opcode;
- OrcVariable *args[10];
+ OrcStaticOpcode *opcode;
+ //OrcVariable *args[10];
OrcRule *rule;
for(j=0;j<compiler->n_insns;j++){
insn = compiler->insns + j;
opcode = insn->opcode;
- orc_compiler_append_code(compiler,"# %d: %s", j, insn->opcode->name);
+ orc_compiler_append_code(compiler,"# %d: %s\n", j, insn->opcode->name);
+#if 0
/* set up args */
for(k=0;k<opcode->n_src + opcode->n_dest;k++){
args[k] = compiler->vars + insn->args[k];
}
}
orc_compiler_append_code(compiler,"\n");
+#endif
+
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ OrcVariable *var = compiler->vars + insn->src_args[k];
- for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ if (opcode->src_size[k] == 0) continue;
+
+ switch (var->vartype) {
case ORC_VAR_TYPE_SRC:
- mmx_emit_load_src (compiler, args[k]);
+ mmx_emit_load_src (compiler, var);
break;
case ORC_VAR_TYPE_CONST:
break;
rule = insn->rule;
if (rule) {
- if (args[0]->alloc != args[1]->alloc) {
- x86_emit_mov_mmx_reg_reg (compiler, args[1]->alloc, args[0]->alloc);
+ if (compiler->vars[insn->dest_args[0]].alloc !=
+ compiler->vars[insn->src_args[0]].alloc) {
+ x86_emit_mov_mmx_reg_reg (compiler,
+ compiler->vars[insn->src_args[0]].alloc,
+ compiler->vars[insn->dest_args[0]].alloc);
}
rule->emit (compiler, rule->emit_user, insn);
} else {
orc_compiler_append_code(compiler,"No rule for: %s\n", opcode->name);
}
- for(k=0;k<opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ OrcVariable *var = compiler->vars + insn->dest_args[k];
+
+ if (opcode->dest_size[k] == 0) continue;
+
+ switch (var->vartype) {
case ORC_VAR_TYPE_DEST:
- mmx_emit_store_dest (compiler, args[k]);
+ mmx_emit_store_dest (compiler, var);
break;
case ORC_VAR_TYPE_TEMP:
break;
void powerpc_emit_bne (OrcCompiler *compiler, int label);
void powerpc_emit_label (OrcCompiler *compiler, int label);
-void orc_compiler_powerpc_register_rules (void);
+void orc_compiler_powerpc_init (OrcCompiler *compiler);
+void orc_compiler_powerpc_assemble (OrcCompiler *compiler);
+void orc_compiler_powerpc_register_rules (OrcTarget *target);
enum {
POWERPC_R0 = ORC_GP_REG_BASE,
#endif
}
+static OrcTarget powerpc_target = {
+ "powerpc",
+#ifdef HAVE_POWERPC
+ TRUE,
+#else
+ FALSE,
+#endif
+ ORC_VEC_REG_BASE,
+ orc_compiler_powerpc_init,
+ orc_compiler_powerpc_assemble
+};
+
void
orc_powerpc_init (void)
{
- orc_compiler_powerpc_register_rules ();
+ orc_target_register (&powerpc_target);
+
+ orc_compiler_powerpc_register_rules (&powerpc_target);
}
void
}
void
-orc_compiler_assemble_powerpc (OrcCompiler *compiler)
+orc_compiler_powerpc_assemble (OrcCompiler *compiler)
{
int j;
int k;
OrcInstruction *insn;
- OrcOpcode *opcode;
- OrcVariable *args[10];
+ OrcStaticOpcode *opcode;
+ //OrcVariable *args[10];
OrcRule *rule;
powerpc_emit_prologue (compiler);
ORC_ASM_CODE(compiler,"# %d: %s", j, insn->opcode->name);
+#if 0
/* set up args */
for(k=0;k<opcode->n_src + opcode->n_dest;k++){
args[k] = compiler->vars + insn->args[k];
}
}
ORC_ASM_CODE(compiler,"\n");
+#endif
- for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ OrcVariable *var = compiler->vars + insn->src_args[k];
+
+ if (opcode->src_size[k] == 0) continue;
+
+ switch (var->vartype) {
case ORC_VAR_TYPE_SRC:
- powerpc_emit_load_src (compiler, args[k]);
+ powerpc_emit_load_src (compiler, var);
break;
case ORC_VAR_TYPE_CONST:
break;
ORC_ASM_CODE(compiler,"No rule for: %s\n", opcode->name);
}
- for(k=0;k<opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ OrcVariable *var = compiler->vars + insn->dest_args[k];
+
+ if (opcode->dest_size[k] == 0) continue;
+
+ switch (var->vartype) {
case ORC_VAR_TYPE_DEST:
- powerpc_emit_store_dest (compiler, args[k]);
+ powerpc_emit_store_dest (compiler, var);
break;
case ORC_VAR_TYPE_TEMP:
break;
unsigned int x;
ORC_ASM_CODE(p," vadduhm %s, %s, %s\n",
- powerpc_get_regname(p->vars[insn->args[0]].alloc),
- powerpc_get_regname(p->vars[insn->args[1]].alloc),
- powerpc_get_regname(p->vars[insn->args[2]].alloc));
+ powerpc_get_regname(p->vars[insn->dest_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[1]].alloc));
x = (4<<26);
- x |= (powerpc_regnum (p->vars[insn->args[0]].alloc)<<21);
- x |= (powerpc_regnum (p->vars[insn->args[1]].alloc)<<16);
- x |= (powerpc_regnum (p->vars[insn->args[2]].alloc)<<11);
+ x |= (powerpc_regnum (p->vars[insn->dest_args[0]].alloc)<<21);
+ x |= (powerpc_regnum (p->vars[insn->src_args[0]].alloc)<<16);
+ x |= (powerpc_regnum (p->vars[insn->src_args[1]].alloc)<<11);
x |= 64;
powerpc_emit (p, x);
powerpc_rule_subw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," vsubuhm %s, %s, %s\n",
- powerpc_get_regname(p->vars[insn->args[0]].alloc),
- powerpc_get_regname(p->vars[insn->args[1]].alloc),
- powerpc_get_regname(p->vars[insn->args[2]].alloc));
+ powerpc_get_regname(p->vars[insn->dest_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[1]].alloc));
}
static void
powerpc_regnum(POWERPC_V0), 1220);
ORC_ASM_CODE(p," vmladduhm %s, %s, %s, %s\n",
- powerpc_get_regname(p->vars[insn->args[0]].alloc),
- powerpc_get_regname(p->vars[insn->args[1]].alloc),
- powerpc_get_regname(p->vars[insn->args[2]].alloc),
+ powerpc_get_regname(p->vars[insn->dest_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[1]].alloc),
powerpc_get_regname(POWERPC_V0));
powerpc_emit_VA(p, 4,
- powerpc_regnum(p->vars[insn->args[0]].alloc),
- powerpc_regnum(p->vars[insn->args[1]].alloc),
- powerpc_regnum(p->vars[insn->args[2]].alloc),
+ powerpc_regnum(p->vars[insn->dest_args[0]].alloc),
+ powerpc_regnum(p->vars[insn->src_args[0]].alloc),
+ powerpc_regnum(p->vars[insn->src_args[1]].alloc),
powerpc_regnum(POWERPC_V0), 34);
}
powerpc_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," vrlh %s, %s, %s\n",
- powerpc_get_regname(p->vars[insn->args[0]].alloc),
- powerpc_get_regname(p->vars[insn->args[1]].alloc),
- powerpc_get_regname(p->vars[insn->args[2]].alloc));
+ powerpc_get_regname(p->vars[insn->dest_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[1]].alloc));
powerpc_emit_VX(p, 4,
- powerpc_regnum(p->vars[insn->args[0]].alloc),
- powerpc_regnum(p->vars[insn->args[1]].alloc),
- powerpc_regnum(p->vars[insn->args[2]].alloc), 68);
+ powerpc_regnum(p->vars[insn->dest_args[0]].alloc),
+ powerpc_regnum(p->vars[insn->src_args[0]].alloc),
+ powerpc_regnum(p->vars[insn->src_args[1]].alloc), 68);
}
static void
unsigned int x;
ORC_ASM_CODE(p," vsrah %s, %s, %s\n",
- powerpc_get_regname(p->vars[insn->args[0]].alloc),
- powerpc_get_regname(p->vars[insn->args[1]].alloc),
- powerpc_get_regname(p->vars[insn->args[2]].alloc));
+ powerpc_get_regname(p->vars[insn->dest_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[0]].alloc),
+ powerpc_get_regname(p->vars[insn->src_args[1]].alloc));
x = (4<<26);
- x |= (powerpc_regnum (p->vars[insn->args[0]].alloc)<<21);
- x |= (powerpc_regnum (p->vars[insn->args[1]].alloc)<<16);
- x |= (powerpc_regnum (p->vars[insn->args[2]].alloc)<<11);
+ x |= (powerpc_regnum (p->vars[insn->dest_args[0]].alloc)<<21);
+ x |= (powerpc_regnum (p->vars[insn->src_args[0]].alloc)<<16);
+ x |= (powerpc_regnum (p->vars[insn->src_args[1]].alloc)<<11);
x |= 836;
powerpc_emit (p, x);
void
-orc_compiler_powerpc_register_rules (void)
+orc_compiler_powerpc_register_rules (OrcTarget *target)
{
- orc_rule_register ("addw", ORC_TARGET_ALTIVEC, powerpc_rule_addw, NULL);
- orc_rule_register ("subw", ORC_TARGET_ALTIVEC, powerpc_rule_subw, NULL);
- orc_rule_register ("mullw", ORC_TARGET_ALTIVEC, powerpc_rule_mullw, NULL);
- orc_rule_register ("shlw", ORC_TARGET_ALTIVEC, powerpc_rule_shlw, NULL);
- orc_rule_register ("shrsw", ORC_TARGET_ALTIVEC, powerpc_rule_shrsw, NULL);
+ OrcRuleSet *rule_set;
+
+ rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target);
+
+ orc_rule_register (rule_set, "addw", powerpc_rule_addw, NULL);
+ orc_rule_register (rule_set, "subw", powerpc_rule_subw, NULL);
+ orc_rule_register (rule_set, "mullw", powerpc_rule_mullw, NULL);
+ orc_rule_register (rule_set, "shlw", powerpc_rule_shlw, NULL);
+ orc_rule_register (rule_set, "shrsw", powerpc_rule_shrsw, NULL);
}
/* code generation */
void sse_emit_loop (OrcCompiler *compiler);
-void orc_compiler_sse_register_rules (void);
+void orc_compiler_sse_init (OrcCompiler *compiler);
+void orc_compiler_sse_assemble (OrcCompiler *compiler);
+void orc_compiler_sse_register_rules (OrcTarget *target);
void orc_compiler_rewrite_vars (OrcCompiler *compiler);
void orc_compiler_dump (OrcCompiler *compiler);
+static OrcTarget sse_target = {
+ "sse",
+#if defined(HAVE_I386) || defined(HAVE_AMD64)
+ TRUE,
+#else
+ FALSE,
+#endif
+ ORC_VEC_REG_BASE,
+ orc_compiler_sse_init,
+ orc_compiler_sse_assemble
+};
+
+
void
orc_sse_init (void)
{
- orc_compiler_sse_register_rules ();
+ orc_target_register (&sse_target);
+
+ orc_compiler_sse_register_rules (&sse_target);
}
void
int j;
int k;
OrcInstruction *insn;
- OrcOpcode *opcode;
- OrcVariable *args[10];
+ OrcStaticOpcode *opcode;
+ //OrcVariable *args[10];
OrcRule *rule;
for(j=0;j<compiler->n_insns;j++){
insn = compiler->insns + j;
opcode = insn->opcode;
- ORC_ASM_CODE(compiler,"# %d: %s", j, insn->opcode->name);
+ ORC_ASM_CODE(compiler,"# %d: %s\n", j, insn->opcode->name);
+#if 0
/* set up args */
for(k=0;k<opcode->n_src + opcode->n_dest;k++){
args[k] = compiler->vars + insn->args[k];
}
}
ORC_ASM_CODE(compiler,"\n");
+#endif
+
+ for(k=0;k<ORC_STATIC_OPCODE_N_SRC;k++){
+ OrcVariable *var = compiler->vars + insn->src_args[k];
- for(k=opcode->n_dest;k<opcode->n_src + opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ if (opcode->src_size[k] == 0) continue;
+
+ switch (var->vartype) {
case ORC_VAR_TYPE_SRC:
- sse_emit_load_src (compiler, args[k]);
+ sse_emit_load_src (compiler, var);
break;
case ORC_VAR_TYPE_CONST:
break;
rule = insn->rule;
if (rule && rule->emit) {
- if (args[0]->alloc != args[1]->alloc) {
- x86_emit_mov_sse_reg_reg (compiler, args[1]->alloc, args[0]->alloc);
+ if (compiler->vars[insn->dest_args[0]].alloc !=
+ compiler->vars[insn->src_args[0]].alloc) {
+ x86_emit_mov_sse_reg_reg (compiler,
+ compiler->vars[insn->src_args[0]].alloc,
+ compiler->vars[insn->dest_args[0]].alloc);
}
rule->emit (compiler, rule->emit_user, insn);
} else {
ORC_PROGRAM_ERROR(compiler,"No rule for: %s", opcode->name);
}
- for(k=0;k<opcode->n_dest;k++){
- switch (args[k]->vartype) {
+ for(k=0;k<ORC_STATIC_OPCODE_N_DEST;k++){
+ OrcVariable *var = compiler->vars + insn->dest_args[k];
+
+ if (opcode->dest_size[k] == 0) continue;
+
+ switch (var->vartype) {
case ORC_VAR_TYPE_DEST:
- sse_emit_store_dest (compiler, args[k]);
+ sse_emit_store_dest (compiler, var);
break;
case ORC_VAR_TYPE_TEMP:
break;
if (!insn->opcode) {
ORC_ERROR ("unknown opcode: %s", name);
}
- insn->args[0] = arg0;
- insn->args[1] = arg1;
+ insn->dest_args[0] = arg0;
+ insn->src_args[0] = arg1;
program->n_insns++;
}
if (!insn->opcode) {
ORC_ERROR ("unknown opcode: %s", name);
}
- insn->args[0] = arg0;
- insn->args[1] = arg1;
- insn->args[2] = arg2;
+ insn->dest_args[0] = arg0;
+ insn->src_args[0] = arg1;
+ insn->src_args[1] = arg2;
program->n_insns++;
}
if (!insn->opcode) {
ORC_ERROR ("unknown opcode: %s", name);
}
- insn->args[0] = orc_program_find_var_by_name (program, arg1);
- insn->args[1] = orc_program_find_var_by_name (program, arg2);
- insn->args[2] = orc_program_find_var_by_name (program, arg3);
+ insn->dest_args[0] = orc_program_find_var_by_name (program, arg1);
+ insn->src_args[0] = orc_program_find_var_by_name (program, arg2);
+ insn->src_args[1] = orc_program_find_var_by_name (program, arg3);
program->n_insns++;
}
if (!insn->opcode) {
ORC_ERROR ("unknown opcode: %s", name);
}
- insn->args[0] = orc_program_find_var_by_name (program, arg1);
- insn->args[1] = orc_program_find_var_by_name (program, arg2);
+ insn->dest_args[0] = orc_program_find_var_by_name (program, arg1);
+ insn->src_args[0] = orc_program_find_var_by_name (program, arg2);
program->n_insns++;
}
typedef struct _OrcExecutor OrcExecutor;
typedef struct _OrcVariable OrcVariable;
typedef struct _OrcOpcode OrcOpcode;
+typedef struct _OrcOpcodeSet OrcOpcodeSet;
typedef struct _OrcStaticOpcode OrcStaticOpcode;
typedef struct _OrcInstruction OrcInstruction;
typedef struct _OrcProgram OrcProgram;
typedef struct _OrcCompiler OrcCompiler;
typedef struct _OrcRule OrcRule;
+typedef struct _OrcRuleSet OrcRuleSet;
typedef struct _OrcFixup OrcFixup;
+typedef struct _OrcTarget OrcTarget;
typedef void (*OrcOpcodeEmulateFunc)(OrcOpcodeExecutor *ex, void *user);
typedef void (*OrcRuleEmitFunc)(OrcCompiler *p, void *user, OrcInstruction *insn);
#define ORC_OPCODE_N_DEST 4
#define ORC_OPCODE_N_ARGS 4
-#define ORC_OPCODE_N_TARGETS 10
+#define ORC_N_TARGETS 10
+#define ORC_N_RULE_SETS 10
#define ORC_STRUCT_OFFSET(struct_type, member) \
((long) ((unsigned int *) &((struct_type*) 0)->member))
orc_debug_print(ORC_DEBUG_ERROR, __FILE__, ORC_FUNCTION, __LINE__, __VA_ARGS__); \
} while (0)
+#if 0
enum {
ORC_TARGET_C = 0,
ORC_TARGET_ALTIVEC = 1,
ORC_TARGET_SSE = 3,
ORC_TARGET_ARM = 4
};
+#endif
typedef enum {
ORC_VAR_TYPE_TEMP,
void *emit_user;
};
+struct _OrcRuleSet {
+ OrcOpcodeSet *opcode_set;
+
+ OrcRule *rules;
+ int n_rules;
+};
+
struct _OrcOpcode {
char *name;
int n_src;
int dest_size[ORC_OPCODE_N_DEST];
int src_size[ORC_OPCODE_N_SRC];
- OrcRule rules[ORC_OPCODE_N_TARGETS];
+ OrcRule rules[ORC_N_TARGETS];
OrcOpcodeEmulateFunc emulate;
void *emulate_user;
};
+struct _OrcOpcodeSet {
+ int opcode_major;
+ char prefix[8];
+
+ int n_opcodes;
+ OrcStaticOpcode *opcodes;
+};
+
struct _OrcStaticOpcode {
char name[16];
OrcOpcodeEmulateFunc emulate;
};
struct _OrcInstruction {
- OrcOpcode *opcode;
- int args[3];
+ OrcStaticOpcode *opcode;
+ int dest_args[ORC_STATIC_OPCODE_N_DEST];
+ int src_args[ORC_STATIC_OPCODE_N_SRC];
OrcRule *rule;
};
struct _OrcCompiler {
OrcProgram *program;
- int target;
+ OrcTarget *target;
OrcInstruction insns[ORC_N_INSNS];
int n_insns;
int params[ORC_N_VARIABLES];
};
+struct _OrcTarget {
+ const char *name;
+ orc_bool executable;
+ int data_register_offset;
+
+ void (*compiler_init)(OrcCompiler *compiler);
+ void (*compile)(OrcCompiler *compiler);
+
+ OrcRuleSet rule_sets[ORC_N_RULE_SETS];
+ int n_rule_sets;
+};
+
void orc_init (void);
OrcProgram * orc_program_new (void);
OrcProgram * orc_program_new_ds (int size1, int size2);
OrcProgram * orc_program_new_dss (int size1, int size2, int size3);
-OrcOpcode * orc_opcode_find_by_name (const char *name);
+OrcStaticOpcode * orc_opcode_find_by_name (const char *name);
int orc_opcode_get_list (OrcOpcode **list);
void orc_opcode_init (void);
void orc_c_init (void);
orc_bool orc_program_compile (OrcProgram *p);
-orc_bool orc_program_compile_for_target (OrcProgram *p, int target);
-void orc_compiler_c_init (OrcCompiler *compiler);
-void orc_compiler_mmx_init (OrcCompiler *compiler);
-void orc_compiler_sse_init (OrcCompiler *compiler);
-void orc_compiler_arm_init (OrcCompiler *compiler);
-void orc_compiler_powerpc_init (OrcCompiler *compiler);
-void orc_compiler_mmx_assemble (OrcCompiler *compiler);
-void orc_compiler_sse_assemble (OrcCompiler *compiler);
-void orc_compiler_arm_assemble (OrcCompiler *compiler);
-void orc_compiler_assemble_powerpc (OrcCompiler *compiler);
-void orc_compiler_assemble_c (OrcCompiler *compiler);
+orc_bool orc_program_compile_for_target (OrcProgram *p, OrcTarget *target);
void orc_program_free (OrcProgram *program);
int orc_program_find_var_by_name (OrcProgram *program, const char *name);
void orc_executor_emulate (OrcExecutor *ex);
void orc_executor_run (OrcExecutor *ex);
-void orc_rule_register (const char *opcode_name, unsigned int mode,
+OrcOpcodeSet *orc_opcode_set_get (const char *name);
+int orc_opcode_set_find_by_name (OrcOpcodeSet *opcode_set, const char *name);
+
+OrcRuleSet * orc_rule_set_new (OrcOpcodeSet *opcode_set, OrcTarget *target);
+void orc_rule_register (OrcRuleSet *rule_set, const char *opcode_name,
OrcRuleEmitFunc emit, void *emit_user);
+OrcRule * orc_target_get_rule (OrcTarget *target, OrcStaticOpcode *opcode);
+OrcTarget * orc_target_get_default (void);
int orc_program_allocate_register (OrcProgram *program, int is_data);
int orc_program_x86_allocate_register (OrcProgram *program, int is_data);
const char *orc_program_get_asm_code (OrcProgram *program);
void orc_program_dump_asm (OrcProgram *program);
-const char *orc_target_get_asm_preamble (int target);
+const char *orc_target_get_asm_preamble (const char *target);
void orc_compiler_append_code (OrcCompiler *p, const char *fmt, ...);
+void orc_target_register (OrcTarget *target);
+OrcTarget *orc_target_get_by_name (const char *target_name);
+
#endif
void
-orc_rule_register (const char *opcode_name, unsigned int mode,
+orc_rule_register (OrcRuleSet *rule_set,
+ const char *opcode_name,
OrcRuleEmitFunc emit, void *emit_user)
{
- OrcOpcode *opcode;
+ int i;
- opcode = orc_opcode_find_by_name (opcode_name);
- if (opcode == NULL) {
+ i = orc_opcode_set_find_by_name (rule_set->opcode_set, opcode_name);
+ if (i == -1) {
ORC_ERROR("failed to find opcode \"%s\"", opcode_name);
return;
}
- opcode->rules[mode].emit = emit;
- opcode->rules[mode].emit_user = emit_user;
+ rule_set->rules[i].emit = emit;
+ rule_set->rules[i].emit_user = emit_user;
}
uint32_t code;
code = 0xe0800000;
- code |= (p->vars[insn->args[1]].alloc&0xf) << 16;
- code |= (p->vars[insn->args[0]].alloc&0xf) << 12;
- code |= (p->vars[insn->args[2]].alloc&0xf) << 0;
+ code |= (p->vars[insn->src_args[0]].alloc&0xf) << 16;
+ code |= (p->vars[insn->dest_args[0]].alloc&0xf) << 12;
+ code |= (p->vars[insn->src_args[1]].alloc&0xf) << 0;
ORC_ASM_CODE(p," add %s, %s, %s\n",
- arm_reg_name (p->vars[insn->args[0]].alloc),
- arm_reg_name (p->vars[insn->args[1]].alloc),
- arm_reg_name (p->vars[insn->args[2]].alloc));
+ arm_reg_name (p->vars[insn->dest_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[1]].alloc));
arm_emit (p, code);
}
uint32_t code;
code = 0xe0400000;
- code |= (p->vars[insn->args[1]].alloc&0xf) << 16;
- code |= (p->vars[insn->args[0]].alloc&0xf) << 12;
- code |= (p->vars[insn->args[2]].alloc&0xf) << 0;
+ code |= (p->vars[insn->src_args[0]].alloc&0xf) << 16;
+ code |= (p->vars[insn->dest_args[0]].alloc&0xf) << 12;
+ code |= (p->vars[insn->src_args[1]].alloc&0xf) << 0;
ORC_ASM_CODE(p," sub %s, %s, %s\n",
- arm_reg_name (p->vars[insn->args[0]].alloc),
- arm_reg_name (p->vars[insn->args[1]].alloc),
- arm_reg_name (p->vars[insn->args[2]].alloc));
+ arm_reg_name (p->vars[insn->dest_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[1]].alloc));
arm_emit (p, code);
}
uint32_t code;
code = 0xe0000090;
- code |= (p->vars[insn->args[0]].alloc&0xf) << 16;
- code |= (p->vars[insn->args[1]].alloc&0xf) << 0;
- code |= (p->vars[insn->args[2]].alloc&0xf) << 8;
+ code |= (p->vars[insn->dest_args[0]].alloc&0xf) << 16;
+ code |= (p->vars[insn->src_args[0]].alloc&0xf) << 0;
+ code |= (p->vars[insn->src_args[1]].alloc&0xf) << 8;
ORC_ASM_CODE(p," mul %s, %s, %s\n",
- arm_reg_name (p->vars[insn->args[0]].alloc),
- arm_reg_name (p->vars[insn->args[1]].alloc),
- arm_reg_name (p->vars[insn->args[2]].alloc));
+ arm_reg_name (p->vars[insn->dest_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[1]].alloc));
arm_emit (p, code);
}
uint32_t code;
code = 0xe1a00050;
- code |= (p->vars[insn->args[0]].alloc&0xf) << 12;
- code |= (p->vars[insn->args[1]].alloc&0xf) << 0;
- code |= (p->vars[insn->args[2]].alloc&0xf) << 8;
+ code |= (p->vars[insn->dest_args[0]].alloc&0xf) << 12;
+ code |= (p->vars[insn->src_args[0]].alloc&0xf) << 0;
+ code |= (p->vars[insn->src_args[1]].alloc&0xf) << 8;
ORC_ASM_CODE(p," asr %s, %s, %s\n",
- arm_reg_name (p->vars[insn->args[0]].alloc),
- arm_reg_name (p->vars[insn->args[1]].alloc),
- arm_reg_name (p->vars[insn->args[2]].alloc));
+ arm_reg_name (p->vars[insn->dest_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[0]].alloc),
+ arm_reg_name (p->vars[insn->src_args[1]].alloc));
arm_emit (p, code);
}
arm_rule_copyx (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(compiler," movdqa %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
- x86_emit_rex (p, 0, p->vars[insn->args[1]].alloc, 0,
- p->vars[insn->args[0]].alloc);
+ x86_emit_rex (p, 0, p->vars[insn->src_args[0]].alloc, 0,
+ p->vars[insn->dest_args[0]].alloc);
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x6f;
- x86_emit_modrm_reg (p, p->vars[insn->args[1]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[0]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
static void
const char *insn_name)
{
ORC_ASM_CODE(compiler," %s %%%s, %%%s\n", insn_name,
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
} else {
*p->codeptr++ = code;
}
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
#if 0
static void
arm_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
ORC_ASM_CODE(compiler," psllw $%d, %%%s\n",
- p->vars[insn->args[2]].value,
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
- *p->codeptr++ = p->vars[insn->args[2]].value;
- } else if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_PARAM) {
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
+ } else if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) {
/* FIXME this is a gross hack to reload the register with a
* 64-bit version of the parameter. */
ORC_ASM_CODE(compiler," movd %d(%%%s), %%%s\n",
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_get_regname_ptr(x86_exec_ptr),
- x86_get_regname_sse(p->vars[insn->args[2]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x6e;
x86_emit_modrm_memoffset (p,
- p->vars[insn->args[2]].alloc,
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ p->vars[insn->src_args[1]].alloc,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_exec_ptr);
ORC_ASM_CODE(compiler," psllw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xf1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
} else {
ORC_ASM_CODE(compiler,"ERROR\n");
}
static void
arm_rule_shrsw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
ORC_ASM_CODE(compiler," psraw $%d, %%%s\n",
- p->vars[insn->args[2]].value,
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
- *p->codeptr++ = p->vars[insn->args[2]].value;
- } else if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_PARAM) {
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
+ } else if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) {
/* FIXME this is a gross hack to reload the register with a
* 64-bit version of the parameter. */
ORC_ASM_CODE(compiler," movd %d(%%%s), %%%s\n",
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_get_regname_ptr(x86_exec_ptr),
- x86_get_regname_sse(p->vars[insn->args[2]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x6e;
x86_emit_modrm_memoffset (p,
- p->vars[insn->args[2]].alloc,
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ p->vars[insn->src_args[1]].alloc,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_exec_ptr);
ORC_ASM_CODE(compiler," psraw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xe1;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
} else {
ORC_ASM_CODE(compiler,"ERROR\n");
}
arm_rule_convsbw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(compiler," punpcklbw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x60;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[1]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[0]].alloc);
ORC_ASM_CODE(compiler," psraw $8, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 4);
*p->codeptr++ = 8;
}
/* FIXME should do this by unpacking with a zero reg */
ORC_ASM_CODE(compiler," punpcklbw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x60;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[1]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[0]].alloc);
ORC_ASM_CODE(compiler," psrlw $8, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 2);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 2);
*p->codeptr++ = 8;
}
arm_rule_convsuswb (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(compiler," packuswb %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[0]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x67;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[1]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[0]].alloc);
}
#endif
void
-orc_compiler_arm_register_rules (void)
+orc_compiler_arm_register_rules (OrcTarget *target)
{
+ OrcRuleSet *rule_set;
+
+ rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target);
+
#if 0
#define REG(x) \
- orc_rule_register ( #x , ORC_TARGET_SSE, arm_rule_ ## x, NULL)
+ orc_rule_register (rule_set, #x , arm_rule_ ## x, NULL)
REG(absb);
REG(addb);
//REG(subusl);
REG(xorl);
- orc_rule_register ("copyb", ORC_TARGET_SSE, arm_rule_copyx, NULL);
- orc_rule_register ("copyw", ORC_TARGET_SSE, arm_rule_copyx, NULL);
- orc_rule_register ("copyl", ORC_TARGET_SSE, arm_rule_copyx, NULL);
+ orc_rule_register (rule_set, "copyb", arm_rule_copyx, NULL);
+ orc_rule_register (rule_set, "copyw", arm_rule_copyx, NULL);
+ orc_rule_register (rule_set, "copyl", arm_rule_copyx, NULL);
- orc_rule_register ("shlw", ORC_TARGET_SSE, arm_rule_shlw, NULL);
- orc_rule_register ("shrsw", ORC_TARGET_SSE, arm_rule_shrsw, NULL);
+ orc_rule_register (rule_set, "shlw", arm_rule_shlw, NULL);
+ orc_rule_register (rule_set, "shrsw", arm_rule_shrsw, NULL);
- orc_rule_register ("convsbw", ORC_TARGET_SSE, arm_rule_convsbw, NULL);
- orc_rule_register ("convubw", ORC_TARGET_SSE, arm_rule_convubw, NULL);
- orc_rule_register ("convsuswb", ORC_TARGET_SSE, arm_rule_convsuswb, NULL);
+ orc_rule_register (rule_set, "convsbw", arm_rule_convsbw, NULL);
+ orc_rule_register (rule_set, "convubw", arm_rule_convubw, NULL);
+ orc_rule_register (rule_set, "convsuswb", arm_rule_convsuswb, NULL);
#endif
- orc_rule_register ("addw", ORC_TARGET_ARM, arm_rule_addw, NULL);
- orc_rule_register ("subw", ORC_TARGET_ARM, arm_rule_subw, NULL);
- orc_rule_register ("mullw", ORC_TARGET_ARM, arm_rule_mullw, NULL);
- orc_rule_register ("shrsw", ORC_TARGET_ARM, arm_rule_shrsw, NULL);
+ orc_rule_register (rule_set, "addw", arm_rule_addw, NULL);
+ orc_rule_register (rule_set, "subw", arm_rule_subw, NULL);
+ orc_rule_register (rule_set, "mullw", arm_rule_mullw, NULL);
+ orc_rule_register (rule_set, "shrsw", arm_rule_shrsw, NULL);
}
mmx_rule_addw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," paddw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ x86_get_regname_mmx(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xfd;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
static void
mmx_rule_subw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," psubw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ x86_get_regname_mmx(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xf9;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
static void
mmx_rule_mullw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," pmullw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ x86_get_regname_mmx(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xd5;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
static void
mmx_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
ORC_ASM_CODE(p," psllw $%d, %%%s\n",
- p->vars[insn->args[2]].value,
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
- *p->codeptr++ = p->vars[insn->args[2]].value;
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
} else {
/* FIXME this doesn't work quite right */
ORC_ASM_CODE(p," psllw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ x86_get_regname_mmx(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xf1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
}
}
static void
mmx_rule_shrsw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
ORC_ASM_CODE(p," psraw $%d, %%%s\n",
- p->vars[insn->args[2]].value,
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
- *p->codeptr++ = p->vars[insn->args[2]].value;
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
} else {
/* FIXME this doesn't work quite right */
ORC_ASM_CODE(p," psraw %%%s, %%%s\n",
- x86_get_regname_mmx(p->vars[insn->args[2]].alloc),
- x86_get_regname_mmx(p->vars[insn->args[0]].alloc));
+ x86_get_regname_mmx(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_mmx(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xe1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
}
}
void
-orc_compiler_mmx_register_rules (void)
+orc_compiler_mmx_register_rules (OrcTarget *target)
{
- orc_rule_register ("addw", ORC_TARGET_MMX, mmx_rule_addw, NULL);
- orc_rule_register ("subw", ORC_TARGET_MMX, mmx_rule_subw, NULL);
- orc_rule_register ("mullw", ORC_TARGET_MMX, mmx_rule_mullw, NULL);
- orc_rule_register ("shlw", ORC_TARGET_MMX, mmx_rule_shlw, NULL);
- orc_rule_register ("shrsw", ORC_TARGET_MMX, mmx_rule_shrsw, NULL);
+ OrcRuleSet *rule_set;
+
+ rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target);
+
+ orc_rule_register (rule_set, "addw", mmx_rule_addw, NULL);
+ orc_rule_register (rule_set, "subw", mmx_rule_subw, NULL);
+ orc_rule_register (rule_set, "mullw", mmx_rule_mullw, NULL);
+ orc_rule_register (rule_set, "shlw", mmx_rule_shlw, NULL);
+ orc_rule_register (rule_set, "shrsw", mmx_rule_shrsw, NULL);
}
sse_rule_copyx (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," movdqa %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
- x86_emit_rex (p, 0, p->vars[insn->args[1]].alloc, 0,
- p->vars[insn->args[0]].alloc);
+ x86_emit_rex (p, 0, p->vars[insn->src_args[1]].alloc, 0,
+ p->vars[insn->dest_args[0]].alloc);
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x6f;
- x86_emit_modrm_reg (p, p->vars[insn->args[1]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
static void
const char *insn_name)
{
ORC_ASM_CODE(p," %s %%%s, %%%s\n", insn_name,
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
} else {
*p->codeptr++ = code;
}
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
}
#define UNARY(opcode,insn_name,code) \
static void
sse_rule_shlw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
ORC_ASM_CODE(p," psllw $%d, %%%s\n",
- p->vars[insn->args[2]].value,
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 6);
- *p->codeptr++ = p->vars[insn->args[2]].value;
- } else if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_PARAM) {
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 6);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
+ } else if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) {
/* FIXME this is a gross hack to reload the register with a
* 64-bit version of the parameter. */
ORC_ASM_CODE(p," movd %d(%%%s), %%%s\n",
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_get_regname_ptr(x86_exec_ptr),
- x86_get_regname_sse(p->vars[insn->args[2]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x6e;
x86_emit_modrm_memoffset (p,
- p->vars[insn->args[2]].alloc,
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ p->vars[insn->src_args[1]].alloc,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_exec_ptr);
ORC_ASM_CODE(p," psllw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xf1;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[2]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
} else {
ORC_PROGRAM_ERROR(p,"rule only works with constants or params");
}
static void
sse_rule_shrsw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
- if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_CONST) {
+ if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_CONST) {
ORC_ASM_CODE(p," psraw $%d, %%%s\n",
- p->vars[insn->args[2]].value,
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ p->vars[insn->src_args[1]].value,
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
- *p->codeptr++ = p->vars[insn->args[2]].value;
- } else if (p->vars[insn->args[2]].vartype == ORC_VAR_TYPE_PARAM) {
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 4);
+ *p->codeptr++ = p->vars[insn->src_args[1]].value;
+ } else if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) {
/* FIXME this is a gross hack to reload the register with a
* 64-bit version of the parameter. */
ORC_ASM_CODE(p," movd %d(%%%s), %%%s\n",
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_get_regname_ptr(x86_exec_ptr),
- x86_get_regname_sse(p->vars[insn->args[2]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x6e;
x86_emit_modrm_memoffset (p,
- p->vars[insn->args[2]].alloc,
- (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->args[2]]),
+ p->vars[insn->src_args[1]].alloc,
+ (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[1]]),
x86_exec_ptr);
ORC_ASM_CODE(p," psraw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[2]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0xe1;
- x86_emit_modrm_reg (p, p->vars[insn->args[2]].alloc,
- p->vars[insn->args[0]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->src_args[1]].alloc,
+ p->vars[insn->dest_args[0]].alloc);
} else {
ORC_PROGRAM_ERROR(p,"rule only works with constants or params");
}
sse_rule_convsbw (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," punpcklbw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x60;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[1]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
ORC_ASM_CODE(p," psraw $8, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 4);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 4);
*p->codeptr++ = 8;
}
/* FIXME should do this by unpacking with a zero reg */
ORC_ASM_CODE(p," punpcklbw %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x60;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[1]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
ORC_ASM_CODE(p," psrlw $8, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x71;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc, 2);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc, 2);
*p->codeptr++ = 8;
}
sse_rule_convsuswb (OrcCompiler *p, void *user, OrcInstruction *insn)
{
ORC_ASM_CODE(p," packuswb %%%s, %%%s\n",
- x86_get_regname_sse(p->vars[insn->args[1]].alloc),
- x86_get_regname_sse(p->vars[insn->args[0]].alloc));
+ x86_get_regname_sse(p->vars[insn->src_args[1]].alloc),
+ x86_get_regname_sse(p->vars[insn->dest_args[0]].alloc));
*p->codeptr++ = 0x66;
*p->codeptr++ = 0x0f;
*p->codeptr++ = 0x67;
- x86_emit_modrm_reg (p, p->vars[insn->args[0]].alloc,
- p->vars[insn->args[1]].alloc);
+ x86_emit_modrm_reg (p, p->vars[insn->dest_args[0]].alloc,
+ p->vars[insn->src_args[1]].alloc);
}
void
-orc_compiler_sse_register_rules (void)
+orc_compiler_sse_register_rules (OrcTarget *target)
{
+ OrcRuleSet *rule_set;
+
+ rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target);
+
#define REG(x) \
- orc_rule_register ( #x , ORC_TARGET_SSE, sse_rule_ ## x, NULL)
+ orc_rule_register (rule_set, #x , sse_rule_ ## x, NULL)
REG(absb);
REG(addb);
//REG(subusl);
REG(xorl);
- orc_rule_register ("copyb", ORC_TARGET_SSE, sse_rule_copyx, NULL);
- orc_rule_register ("copyw", ORC_TARGET_SSE, sse_rule_copyx, NULL);
- orc_rule_register ("copyl", ORC_TARGET_SSE, sse_rule_copyx, NULL);
+ orc_rule_register (rule_set, "copyb", sse_rule_copyx, NULL);
+ orc_rule_register (rule_set, "copyw", sse_rule_copyx, NULL);
+ orc_rule_register (rule_set, "copyl", sse_rule_copyx, NULL);
- orc_rule_register ("shlw", ORC_TARGET_SSE, sse_rule_shlw, NULL);
- orc_rule_register ("shrsw", ORC_TARGET_SSE, sse_rule_shrsw, NULL);
+ orc_rule_register (rule_set, "shlw", sse_rule_shlw, NULL);
+ orc_rule_register (rule_set, "shrsw", sse_rule_shrsw, NULL);
- orc_rule_register ("convsbw", ORC_TARGET_SSE, sse_rule_convsbw, NULL);
- orc_rule_register ("convubw", ORC_TARGET_SSE, sse_rule_convubw, NULL);
- orc_rule_register ("convsuswb", ORC_TARGET_SSE, sse_rule_convsuswb, NULL);
+ orc_rule_register (rule_set, "convsbw", sse_rule_convsbw, NULL);
+ orc_rule_register (rule_set, "convubw", sse_rule_convubw, NULL);
+ orc_rule_register (rule_set, "convsuswb", sse_rule_convsuswb, NULL);
}
int error = FALSE;
-void test_opcode (const char *name);
+void test_opcode (OrcStaticOpcode *opcode);
int
main (int argc, char *argv[])
{
int i;
- OrcOpcode *opcode_list;
- int n_opcodes;
+ OrcOpcodeSet *opcode_set;
orc_init();
- n_opcodes = orc_opcode_get_list (&opcode_list);
+ opcode_set = orc_opcode_set_get ("sys");
- printf("%s", orc_target_get_asm_preamble (ORC_TARGET_C));
+ printf("%s", orc_target_get_asm_preamble ("c"));
- for(i=0;i<n_opcodes;i++){
- printf("/* %s %d %d %p */\n",
- opcode_list[i].name,
- opcode_list[i].n_src,
- opcode_list[i].n_dest,
- opcode_list[i].emulate
- );
- test_opcode (opcode_list[i].name);
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("/* %s %d,%d,%d %p */\n",
+ opcode_set->opcodes[i].name,
+ opcode_set->opcodes[i].dest_size[0],
+ opcode_set->opcodes[i].src_size[0],
+ opcode_set->opcodes[i].src_size[1],
+ opcode_set->opcodes[i].emulate);
+ test_opcode (opcode_set->opcodes + i);
}
if (error) return 1;
}
void
-test_opcode (const char *name)
+test_opcode (OrcStaticOpcode *opcode)
{
OrcProgram *p;
char s[40];
int ret;
- p = orc_program_new_dss (2,2,2);
+ if (opcode->src_size[1] == 0) {
+ p = orc_program_new_ds (opcode->dest_size[0], opcode->src_size[0]);
+ } else {
+ p = orc_program_new_dss (opcode->dest_size[0], opcode->src_size[0],
+ opcode->src_size[1]);
+ }
- sprintf(s, "test_%s", name);
+ sprintf(s, "test_%s", opcode->name);
orc_program_set_name (p, s);
- orc_program_append_str (p, name, "d1", "s1", "s2");
+ orc_program_append_str (p, opcode->name, "d1", "s1", "s2");
- ret = orc_program_compile_for_target (p, ORC_TARGET_C);
+ ret = orc_program_compile_for_target (p, orc_target_get_by_name("c"));
if (!ret) {
error = TRUE;
}
main (int argc, char *argv[])
{
int i;
- OrcOpcode *opcode_list;
- int n_opcodes;
+ OrcOpcodeSet *opcode_set;
orc_init();
- n_opcodes = orc_opcode_get_list (&opcode_list);
+ opcode_set = orc_opcode_set_get ("sys");
- for(i=0;i<n_opcodes;i++){
- printf("%s %d %d %p\n",
- opcode_list[i].name,
- opcode_list[i].n_src,
- opcode_list[i].n_dest,
- opcode_list[i].emulate
- );
- test_opcode (opcode_list[i].name);
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("%s %d,%d,%d %p\n",
+ opcode_set->opcodes[i].name,
+ opcode_set->opcodes[i].dest_size[0],
+ opcode_set->opcodes[i].src_size[0],
+ opcode_set->opcodes[i].src_size[1],
+ opcode_set->opcodes[i].emulate);
+ test_opcode (opcode_set->opcodes[i].name);
}
if (error) return 1;
orc_program_append_str (p, name, "d1", "s1", "s2");
- ret = orc_program_compile_for_target (p, ORC_TARGET_C);
+ ret = orc_program_compile_for_target (p, orc_target_get_by_name("c"));
if (!ret) {
error = TRUE;
}
main (int argc, char *argv[])
{
int i;
- OrcOpcode *opcode_list;
- int n_opcodes;
+ OrcOpcodeSet *opcode_set;
orc_init();
- n_opcodes = orc_opcode_get_list (&opcode_list);
+ opcode_set = orc_opcode_set_get ("sys");
- //printf("%s", orc_target_get_asm_preamble (ORC_TARGET_C));
-
- for(i=0;i<n_opcodes;i++){
- printf("/* %s %d %d %p */\n",
- opcode_list[i].name,
- opcode_list[i].n_src,
- opcode_list[i].n_dest,
- opcode_list[i].emulate
- );
- test_opcode (opcode_list[i].name);
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("/* %s %d,%d,%d %p */\n",
+ opcode_set->opcodes[i].name,
+ opcode_set->opcodes[i].dest_size[0],
+ opcode_set->opcodes[i].src_size[0],
+ opcode_set->opcodes[i].src_size[1],
+ opcode_set->opcodes[i].emulate);
+ test_opcode (opcode_set->opcodes[i].name);
}
if (error) return 1;
main (int argc, char *argv[])
{
int i;
- OrcOpcode *opcode_list;
- int n_opcodes;
+ OrcOpcodeSet *opcode_set;
orc_init();
- n_opcodes = orc_opcode_get_list (&opcode_list);
+ opcode_set = orc_opcode_set_get ("sys");
- //printf("%s", orc_target_get_asm_preamble (ORC_TARGET_C));
-
- for(i=0;i<n_opcodes;i++){
- printf("/* %s %d %d %p */\n",
- opcode_list[i].name,
- opcode_list[i].n_src,
- opcode_list[i].n_dest,
- opcode_list[i].emulate
- );
- test_opcode (opcode_list[i].name);
+ for(i=0;i<opcode_set->n_opcodes;i++){
+ printf("/* %s %d,%d,%d %p */\n",
+ opcode_set->opcodes[i].name,
+ opcode_set->opcodes[i].dest_size[0],
+ opcode_set->opcodes[i].src_size[0],
+ opcode_set->opcodes[i].src_size[1],
+ opcode_set->opcodes[i].emulate);
+ test_opcode (opcode_set->opcodes[i].name);
}
if (error) return 1;
orc_program_append_str (p, name, "d1", "s1", "s2");
- ret = orc_program_compile_for_target (p, ORC_TARGET_ARM);
+ ret = orc_program_compile_for_target (p, orc_target_get_by_name("arm"));
if (!ret) {
error = TRUE;
goto out;