diff options
author | Guillaume Emont <guijemont@igalia.com> | 2012-10-24 19:03:47 +0200 |
---|---|---|
committer | Guillaume Emont <guijemont@igalia.com> | 2012-12-28 15:17:45 +0100 |
commit | 5ec705af310007a22b0208f0fee911a8cc6a8ce2 (patch) | |
tree | f99ae5a37c4ddb395290c6d3cf67c3a45e9487c5 | |
parent | 756654d280446b03d5363784a79a3c1619923e09 (diff) | |
download | orc-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.c | 106 |
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); } |