summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Emont <guijemont@igalia.com>2012-10-24 19:03:47 +0200
committerGuillaume Emont <guijemont@igalia.com>2012-12-28 15:17:45 +0100
commit5ec705af310007a22b0208f0fee911a8cc6a8ce2 (patch)
treef99ae5a37c4ddb395290c6d3cf67c3a45e9487c5
parent756654d280446b03d5363784a79a3c1619923e09 (diff)
downloadorc-5ec705af310007a22b0208f0fee911a8cc6a8ce2.tar.gz
mips: factorised and mostly fixed load and store rules
Code is assuming that all data is correctly aligned for now.
-rw-r--r--orc/orcrules-mips.c106
1 files changed, 84 insertions, 22 deletions
diff --git a/orc/orcrules-mips.c b/orc/orcrules-mips.c
index 3e1280e..d89c5d2 100644
--- a/orc/orcrules-mips.c
+++ b/orc/orcrules-mips.c
@@ -1,53 +1,101 @@
#include <orc/orcmips.h>
+#include <orc/orcdebug.h>
#include <stdlib.h>
void
-mips_rule_loadl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+mips_rule_load (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
int src = compiler->vars[insn->src_args[0]].ptr_register;
int dest = compiler->vars[insn->dest_args[0]].alloc;
+ /* such that 2^total_shift is the amount to load at a time */
+ int total_shift = compiler->insn_shift + ORC_PTR_TO_INT (user);
+
+ ORC_DEBUG ("insn_shift=%d", compiler->insn_shift);
+ /* FIXME: Check alignment. We are assuming data is aligned here */
+ switch (total_shift) {
+ case 0:
+ orc_mips_emit_lb (compiler, dest, src, 0);
+ break;
+ case 1:
+ orc_mips_emit_lh (compiler, dest, src, 0);
+ break;
+ case 2:
+ orc_mips_emit_lw (compiler, dest, src, 0);
+ break;
+ default:
+ ORC_PROGRAM_ERROR(compiler, "Don't know how to handle that shift");
+ }
- orc_mips_emit_lw (compiler, dest, src, 0);
}
void
-mips_rule_loadb (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+mips_rule_store (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
- int src = compiler->vars[insn->src_args[0]].ptr_register;
- int dest = compiler->vars[insn->dest_args[0]].alloc;
-
- orc_mips_emit_lb (compiler, dest, src, 0);
+ int src = compiler->vars[insn->src_args[0]].alloc;
+ int dest = compiler->vars[insn->dest_args[0]].ptr_register;
+ int total_shift = compiler->insn_shift + ORC_PTR_TO_INT (user);
+
+ ORC_DEBUG ("insn_shift=%d", compiler->insn_shift);
+
+ /* FIXME: Check alignment. We are assuming data is aligned here */
+ switch (total_shift) {
+ case 0:
+ orc_mips_emit_sb (compiler, src, dest, 0);
+ break;
+ case 1:
+ orc_mips_emit_sh (compiler, src, dest, 0);
+ break;
+ case 2:
+ orc_mips_emit_sw (compiler, src, dest, 0);
+ break;
+ default:
+ ORC_PROGRAM_ERROR(compiler, "Don't know how to handle that shift");
+ }
}
+
void
-mips_rule_storel (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+mips_rule_addl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
- int src = compiler->vars[insn->src_args[0]].alloc;
- int dest = compiler->vars[insn->dest_args[0]].ptr_register;
+ int src1 = ORC_SRC_ARG (compiler, insn, 0);
+ int src2 = ORC_SRC_ARG (compiler, insn, 1);
+ int dest = ORC_DEST_ARG (compiler, insn, 0);
- orc_mips_emit_sw (compiler, src, dest, 0);
+ orc_mips_emit_add (compiler, dest, src1, src2);
}
void
-mips_rule_storeb (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+mips_rule_addw (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
- int src = compiler->vars[insn->src_args[0]].alloc;
- int dest = compiler->vars[insn->dest_args[0]].ptr_register;
+ int src1 = ORC_SRC_ARG (compiler, insn, 0);
+ int src2 = ORC_SRC_ARG (compiler, insn, 1);
+ int dest = ORC_DEST_ARG (compiler, insn, 0);
- orc_mips_emit_sb (compiler, src, dest, 0);
+ orc_mips_emit_add (compiler, dest, src1, src2);
}
-
void
-mips_rule_addl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+mips_rule_addb (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
int src1 = ORC_SRC_ARG (compiler, insn, 0);
int src2 = ORC_SRC_ARG (compiler, insn, 1);
int dest = ORC_DEST_ARG (compiler, insn, 0);
- orc_mips_emit_add (compiler, dest, src1, src2);
+ switch (compiler->insn_shift) {
+ case 0:
+ orc_mips_emit_addu (compiler, dest, src1, src2);
+ break;
+ case 1:
+ case 2:
+ orc_mips_emit_addu_qb (compiler, dest, src1, src2);
+ break;
+ default:
+ ORC_PROGRAM_ERROR (compiler, "Don't know how to handle that insn_shift");
+ }
+
}
+
void
mips_rule_copyl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
@@ -58,6 +106,15 @@ mips_rule_copyl (OrcCompiler *compiler, void *user, OrcInstruction *insn)
}
void
+mips_rule_copyw (OrcCompiler *compiler, void *user, OrcInstruction *insn)
+{
+ int src = ORC_SRC_ARG (compiler, insn, 0);
+ int dest = ORC_DEST_ARG (compiler, insn, 0);
+
+ orc_mips_emit_move (compiler, dest, src);
+}
+
+void
mips_rule_copyb (OrcCompiler *compiler, void *user, OrcInstruction *insn)
{
int src = ORC_SRC_ARG (compiler, insn, 0);
@@ -73,11 +130,16 @@ orc_compiler_orc_mips_register_rules (OrcTarget *target)
rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target, 0);
- orc_rule_register (rule_set, "loadl", mips_rule_loadl, NULL);
- orc_rule_register (rule_set, "loadb", mips_rule_loadb, NULL);
- orc_rule_register (rule_set, "storel", mips_rule_storeb, NULL);
- orc_rule_register (rule_set, "storeb", mips_rule_storel, NULL);
+ orc_rule_register (rule_set, "loadl", mips_rule_load, (void *) 2);
+ orc_rule_register (rule_set, "loadw", mips_rule_load, (void *) 1);
+ orc_rule_register (rule_set, "loadb", mips_rule_load, (void *) 0);
+ orc_rule_register (rule_set, "storel", mips_rule_store, (void *)2);
+ orc_rule_register (rule_set, "storew", mips_rule_store, (void *)1);
+ orc_rule_register (rule_set, "storeb", mips_rule_store, (void *)0);
orc_rule_register (rule_set, "addl", mips_rule_addl, NULL);
+ orc_rule_register (rule_set, "addw", mips_rule_addw, NULL);
+ orc_rule_register (rule_set, "addb", mips_rule_addb, NULL);
orc_rule_register (rule_set, "copyl", mips_rule_copyl, NULL);
+ orc_rule_register (rule_set, "copyw", mips_rule_copyw, NULL);
orc_rule_register (rule_set, "copyb", mips_rule_copyb, NULL);
}