From f28cee651175bd9119a863babf28ce8bde138b33 Mon Sep 17 00:00:00 2001 From: Guillaume Emont Date: Fri, 7 Dec 2012 13:45:01 +0100 Subject: [PATCH] mips: implement loadupdb --- orc/orcprogram-mips.c | 3 ++- orc/orcrules-mips.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/orc/orcprogram-mips.c b/orc/orcprogram-mips.c index 555b215..0656fbf 100644 --- a/orc/orcprogram-mips.c +++ b/orc/orcprogram-mips.c @@ -123,7 +123,8 @@ orc_compiler_orc_mips_init (OrcCompiler *compiler) OrcInstruction *insn = compiler->insns + i; OrcStaticOpcode *opcode = insn->opcode; - if (strcmp (opcode->name, "loadupib") == 0) { + if ((strcmp (opcode->name, "loadupib") == 0) + || (strcmp (opcode->name, "loadupdb") == 0)) { compiler->vars[insn->src_args[0]].need_offset_reg = TRUE; } } diff --git a/orc/orcrules-mips.c b/orc/orcrules-mips.c index b64ac0f..dd45429 100644 --- a/orc/orcrules-mips.c +++ b/orc/orcrules-mips.c @@ -389,6 +389,50 @@ mips_rule_loadupib (OrcCompiler *compiler, void *user, OrcInstruction *insn) src->update_type = 1; } +void +mips_rule_loadupdb (OrcCompiler *compiler, void *user, OrcInstruction *insn) +{ + OrcVariable *src = compiler->vars + insn->src_args[0]; + OrcVariable *dest = compiler->vars + insn->dest_args[0]; + OrcMipsRegister tmp = orc_compiler_get_temp_reg (compiler); + + if (compiler->vars[insn->src_args[0]].vartype == ORC_VAR_TYPE_CONST) { + ORC_PROGRAM_ERROR (compiler, "not implemented"); + return; + } + + switch (compiler->insn_shift) { + case 0: + orc_mips_emit_andi (compiler, tmp, src->ptr_offset, 1); + orc_mips_emit_conditional_branch_with_offset (compiler, + ORC_MIPS_BEQ, + tmp, + ORC_MIPS_ZERO, + 8); + /* this is always done: in branch delay slot*/ + orc_mips_emit_lb (compiler, dest->alloc, src->ptr_register, 0); + /* In the case where there is no insn_shift, src->ptr_register needs to be + * incremented only when ptr_offset is odd, _emit_loop() doesn't update it + * in that case, and therefore we do it here */ + orc_mips_emit_addiu (compiler, src->ptr_register, src->ptr_register, 1); + orc_mips_emit_append (compiler, dest->alloc, dest->alloc, 8); + + orc_mips_emit_addiu (compiler, src->ptr_offset, src->ptr_offset, 1); + break; + case 2: + orc_mips_emit_lb (compiler, tmp, src->ptr_register, 0); + orc_mips_emit_lb (compiler, dest->alloc, src->ptr_register, 1); + orc_mips_emit_replv_qb (compiler, tmp, tmp); + orc_mips_emit_replv_qb (compiler, dest->alloc, dest->alloc); + orc_mips_emit_packrl_ph (compiler, dest->alloc, tmp, dest->alloc); + /* FIXME: should we remove that as we only use ptr_offset for parity? */ + orc_mips_emit_addiu (compiler, src->ptr_offset, src->ptr_offset, 4); + break; + default: + ORC_PROGRAM_ERROR (compiler, "unimplemented"); + } + src->update_type = 1; +} void mips_rule_loadp (OrcCompiler *compiler, void *user, OrcInstruction *insn) @@ -463,5 +507,6 @@ orc_compiler_orc_mips_register_rules (OrcTarget *target) orc_rule_register (rule_set, "addssw", mips_rule_addssw, NULL); orc_rule_register (rule_set, "subssw", mips_rule_subssw, NULL); orc_rule_register (rule_set, "loadupib", mips_rule_loadupib, NULL); + orc_rule_register (rule_set, "loadupdb", mips_rule_loadupdb, NULL); orc_rule_register (rule_set, "shrsw", mips_rule_shrsw, NULL); } -- 2.7.4