From a69a7e6a9d55e4f24e4f4c1bfce0bb7041413f4f Mon Sep 17 00:00:00 2001 From: David Schleef Date: Mon, 2 Aug 2010 17:59:54 -0700 Subject: [PATCH] arm: Add load/store opcodes --- orc/orcprogram-arm.c | 39 +++++++++++++++++++--- orc/orcrules-arm.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/orc/orcprogram-arm.c b/orc/orcprogram-arm.c index 6518a54..3f5054a 100644 --- a/orc/orcprogram-arm.c +++ b/orc/orcprogram-arm.c @@ -97,6 +97,10 @@ static OrcTarget orc_arm_target = { void orc_arm_init (void) { +#if defined(HAVE_ARM) + orc_arm_get_cpu_flags (); +#endif + orc_target_register (&orc_arm_target); orc_compiler_orc_arm_register_rules (&orc_arm_target); @@ -105,7 +109,11 @@ orc_arm_init (void) unsigned int orc_compiler_orc_arm_get_default_flags (void) { - return 0; +#if defined(HAVE_ARM) + return orc_arm_get_cpu_flags (); +#else + return ORC_TARGET_ARM_EDSP; +#endif } void @@ -147,8 +155,8 @@ orc_arm_load_constants_outer (OrcCompiler *compiler) if (compiler->vars[i].name == NULL) continue; switch (compiler->vars[i].vartype) { case ORC_VAR_TYPE_CONST: - orc_arm_emit_load_imm (compiler, compiler->vars[i].alloc, - (int)compiler->vars[i].value); + //orc_arm_emit_load_imm (compiler, compiler->vars[i].alloc, + // (int)compiler->vars[i].value); break; case ORC_VAR_TYPE_PARAM: ORC_PROGRAM_ERROR(compiler,"unimplemented"); @@ -165,6 +173,23 @@ orc_arm_load_constants_outer (OrcCompiler *compiler) break; } } + + for(i=0;in_insns;i++){ + OrcInstruction *insn = compiler->insns + i; + OrcStaticOpcode *opcode = insn->opcode; + OrcRule *rule; + + if (!(compiler->insn_flags[i] & ORC_INSN_FLAG_INVARIANT)) continue; + + ORC_ASM_CODE(compiler,"# %d: %s\n", i, insn->opcode->name); + + rule = insn->rule; + if (rule && rule->emit) { + rule->emit (compiler, rule->emit_user, insn); + } else { + ORC_COMPILER_ERROR(compiler,"No rule for: %s", opcode->name); + } + } } void @@ -189,6 +214,7 @@ orc_arm_load_constants_inner (OrcCompiler *compiler) } } +#if 0 void orc_arm_emit_load_src (OrcCompiler *compiler, OrcVariable *var) { @@ -268,6 +294,7 @@ orc_arm_emit_store_dest (OrcCompiler *compiler, OrcVariable *var) ORC_COMPILER_ERROR(compiler, "bad size %d", var->size << compiler->loop_shift); } } +#endif void orc_compiler_orc_arm_assemble (OrcCompiler *compiler) @@ -341,6 +368,8 @@ orc_arm_emit_loop (OrcCompiler *compiler) insn = compiler->insns + j; opcode = insn->opcode; + if (compiler->insn_flags[j] & ORC_INSN_FLAG_INVARIANT) continue; + orc_compiler_append_code(compiler,"# %d: %s", j, insn->opcode->name); /* set up args */ @@ -361,7 +390,7 @@ orc_arm_emit_loop (OrcCompiler *compiler) switch (compiler->vars[insn->src_args[k]].vartype) { case ORC_VAR_TYPE_SRC: case ORC_VAR_TYPE_DEST: - orc_arm_emit_load_src (compiler, &compiler->vars[insn->src_args[k]]); + //orc_arm_emit_load_src (compiler, &compiler->vars[insn->src_args[k]]); break; case ORC_VAR_TYPE_CONST: break; @@ -392,7 +421,7 @@ orc_arm_emit_loop (OrcCompiler *compiler) switch (compiler->vars[insn->dest_args[k]].vartype) { case ORC_VAR_TYPE_DEST: - orc_arm_emit_store_dest (compiler, &compiler->vars[insn->dest_args[k]]); + //orc_arm_emit_store_dest (compiler, &compiler->vars[insn->dest_args[k]]); break; case ORC_VAR_TYPE_TEMP: break; diff --git a/orc/orcrules-arm.c b/orc/orcrules-arm.c index 53b335c..fcc8353 100644 --- a/orc/orcrules-arm.c +++ b/orc/orcrules-arm.c @@ -78,6 +78,87 @@ arm_rule_ ## opcode (OrcCompiler *p, void *user, OrcInstruction *insn) \ orc_arm_emit(p,orc_arm_mull (0x00800090,cond,S,RdL,RdH,Rn,Rm)); \ } while (0) +static void +arm_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn) +{ + if (compiler->vars[insn->src_args[0]].vartype == ORC_VAR_TYPE_CONST) { + orc_arm_emit_load_imm (compiler, compiler->vars[insn->dest_args[0]].alloc, + (int)compiler->vars[insn->src_args[0]].value); + } else { + orc_arm_loadw (compiler, compiler->vars[insn->dest_args[0]].alloc, + compiler->exec_reg, + (int)ORC_STRUCT_OFFSET(OrcExecutor, params[insn->src_args[0]])); + } +} + +static void +arm_rule_loadX (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; + int size; + orc_uint32 code; + int offset = 0; + + size = (compiler->vars[insn->src_args[0]].size << compiler->loop_shift); + + if (size == 4) { + code = 0xe5900000; + ORC_ASM_CODE(compiler," ldr %s, [%s, #%d]\n", + orc_arm_reg_name (dest), + orc_arm_reg_name (src), offset); + } else if (size == 2) { + code = 0xe1d000b0; + ORC_ASM_CODE(compiler," ldrh %s, [%s, #%d]\n", + orc_arm_reg_name (dest), + orc_arm_reg_name (src), offset); + } else { + code = 0xe5d00000; + ORC_ASM_CODE(compiler," ldrb %s, [%s, #%d]\n", + orc_arm_reg_name (dest), + orc_arm_reg_name (src), offset); + } + code |= (src&0xf) << 16; + code |= (dest&0xf) << 12; + code |= (offset&0xf0) << 4; + code |= offset&0x0f; + orc_arm_emit (compiler, code); +} + +static void +arm_rule_storeX (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 size; + orc_uint32 code; + int offset = 0; + + size = (compiler->vars[insn->src_args[0]].size << compiler->loop_shift); + + if (size == 4) { + code = 0xe5800000; + ORC_ASM_CODE(compiler," str %s, [%s, #%d]\n", + orc_arm_reg_name (src), + orc_arm_reg_name (dest), offset); + } else if (size == 2) { + code = 0xe1c000b0; + ORC_ASM_CODE(compiler," strh %s, [%s, #%d]\n", + orc_arm_reg_name (src), + orc_arm_reg_name (dest), offset); + } else { + code = 0xe5c00000; + ORC_ASM_CODE(compiler," strb %s, [%s, #%d]\n", + orc_arm_reg_name (src), + orc_arm_reg_name (dest), offset); + } + code |= (dest&0xf) << 16; + code |= (src&0xf) << 12; + code |= (offset&0xf0) << 4; + code |= offset&0x0f; + orc_arm_emit (compiler, code); +} + void orc_arm_loadb (OrcCompiler *compiler, int dest, int src1, int offset) { @@ -1499,6 +1580,16 @@ orc_compiler_orc_arm_register_rules (OrcTarget *target) rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target, 0); + orc_rule_register (rule_set, "loadpb", arm_rule_loadpX, NULL); + orc_rule_register (rule_set, "loadpw", arm_rule_loadpX, NULL); + orc_rule_register (rule_set, "loadpl", arm_rule_loadpX, NULL); + orc_rule_register (rule_set, "loadb", arm_rule_loadX, NULL); + orc_rule_register (rule_set, "loadw", arm_rule_loadX, NULL); + orc_rule_register (rule_set, "loadl", arm_rule_loadX, NULL); + orc_rule_register (rule_set, "storeb", arm_rule_storeX, NULL); + orc_rule_register (rule_set, "storew", arm_rule_storeX, NULL); + orc_rule_register (rule_set, "storel", arm_rule_storeX, NULL); + orc_rule_register (rule_set, "andb", arm_rule_andX, NULL); orc_rule_register (rule_set, "andnb", arm_rule_andnX, NULL); orc_rule_register (rule_set, "avgsb", arm_rule_avgX, (void *)3); @@ -1550,7 +1641,7 @@ orc_compiler_orc_arm_register_rules (OrcTarget *target) FAIL orc_rule_register (rule_set, "muluwl", arm_rule_muluwl, NULL); rule_set = orc_rule_set_new (orc_opcode_set_get("sys"), target, - ORC_TARGET_ARM_ARMV6); + ORC_TARGET_ARM_EDSP); FAIL orc_rule_register (rule_set, "absb", arm_rule_absX, (void *)0); orc_rule_register (rule_set, "addb", arm_rule_addb, NULL); -- 2.7.4