From 01535dcd5f6eed370e9699f6778af8382564c2ba Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 30 Jun 2010 18:41:00 -0700 Subject: [PATCH] arm: arm backend code gen fixes --- orc-test/orctest.c | 2 +- orc/orcarm.c | 22 ++++++++++------- orc/orcprogram-arm.c | 7 +++++- orc/orcrules-arm.c | 56 ++++++++++++++++++++++++++++++++++---------- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/orc-test/orctest.c b/orc-test/orctest.c index 2a1373a..cdcea6b 100644 --- a/orc-test/orctest.c +++ b/orc-test/orctest.c @@ -174,7 +174,7 @@ orc_test_gcc_compile_neon (OrcProgram *p) sprintf(dump_filename, "%s-dump.bin", base); sprintf(dump_dis_filename, "%s-dump.dis", base); - target = orc_target_get_by_name ("neon"); + target = orc_target_get_by_name ("arm"); flags = orc_target_get_default_flags (target); flags |= ORC_TARGET_NEON_CLEAN_COMPILE; diff --git a/orc/orcarm.c b/orc/orcarm.c index 6bfea2b..19968a1 100644 --- a/orc/orcarm.c +++ b/orc/orcarm.c @@ -389,19 +389,19 @@ orc_arm_emit_cmp_imm (OrcCompiler *compiler, int src1, int value) /* 1 * 1 0 9 8 7 6 5 4 3 2 1 0 * +-+-+-+-+-+-+-+-+-+-+-+-+ - * | Si | St |0| Rm | + * | Si | St|0| Rm | * +-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define arm_so_rsi(Si,St,Rm) ((((Si)&31)<<7)|(((St)&7)<<5)|((Rm)&7)) +#define arm_so_rsi(Si,St,Rm) ((((Si)&31)<<7)|(((St)&3)<<5)|((Rm)&15)) #define arm_so_rrx(Rm) arm_so_rsi(0,ORC_ARM_ROR,Rm) #define arm_so_r(Rm) ((Rm)&15) /* 1 * 1 0 9 8 7 6 5 4 3 2 1 0 * +-+-+-+-+-+-+-+-+-+-+-+-+ - * | Rs |0| St |1| Rm | + * | Rs |0| St|1| Rm | * +-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define arm_so_rsr(Rs,St,Rm) (0x008|(((Rs)&15)<<8)|(((St)&7)<<5)|((Rm)&7)) +#define arm_so_rsr(Rs,St,Rm) (0x010|(((Rs)&15)<<8)|(((St)&3)<<5)|((Rm)&15)) /* data processing instructions */ /* 3 2 2 2 2 2 2 2 1 1 1 1 1 @@ -523,7 +523,7 @@ orc_arm_emit_dp (OrcCompiler *p, int type, OrcArmCond cond, OrcArmDP opcode, * | cond | mode | Rn | Rd |0 0 0 0| op | Rm | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define arm_code_par(cond,mode,Rn,Rd,op,Rm) (((cond)<<28)|((mode)<<20)|((Rn)<<16)|((Rd)<<12)|((op)<<4)|(Rm)) +#define arm_code_par(cond,mode,Rn,Rd,op,Rm) (((cond)<<28)|((mode)<<20)|(((Rn)&0xf)<<16)|(((Rd)&0xf)<<12)|((op)<<4)|((Rm)&0xf)|0xf00) void orc_arm_emit_par (OrcCompiler *p, int op, int mode, OrcArmCond cond, @@ -559,7 +559,7 @@ orc_arm_emit_par (OrcCompiler *p, int op, int mode, OrcArmCond cond, * | cond |0 1 1 0 0 0 0 0| Rn | Rd |rot|0 0|0 1 1 1| Rm | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -#define arm_code_xt(op,cond,Rn,Rd,r8,Rm) (op|((cond)<<28)|((Rn)<<16)|((Rd)<<12)|(((r8)&0x18)<<7)|(Rm)) +#define arm_code_xt(op,cond,Rn,Rd,r8,Rm) (op|((cond)<<28)|(((Rn)&0xf)<<16)|(((Rd)&0xf)<<12)|((((r8)&0xf)&0x18)<<7)|((Rm)&0xf)) void orc_arm_emit_xt (OrcCompiler *p, int op, OrcArmCond cond, @@ -599,7 +599,7 @@ orc_arm_emit_xt (OrcCompiler *p, int op, OrcArmCond cond, orc_arm_emit (p, code); } -#define arm_code_pkh(op,cond,Rn,Rd,sh,Rm) (op|((cond)<<28)|((Rn)<<16)|((Rd)<<12)|((sh)<<7)|(Rm)) +#define arm_code_pkh(op,cond,Rn,Rd,sh,Rm) (op|((cond)<<28)|(((Rn)&0xf)<<16)|(((Rd)&0xf)<<12)|((sh)<<7)|((Rm)&0xf)) void orc_arm_emit_pkh (OrcCompiler *p, int op, OrcArmCond cond, int Rd, int Rn, int Rm, int sh) @@ -657,7 +657,11 @@ orc_arm_emit_sat (OrcCompiler *p, int op, OrcArmCond cond, if (op < 2) { code = arm_code_sat (sat_opcodes[op], cond, sat, Rd, sh, asr, Rm); } else { - code = arm_code_par (cond, par_mode[op], sat, Rd, par_op[op], Rm); + if (op == 3) { + code = arm_code_par (cond, par_mode[op], sat, Rd, par_op[op], Rm); + } else { + code = arm_code_par (cond, par_mode[op], sat - 1, Rd, par_op[op], Rm); + } } ORC_ASM_CODE(p," %s%s %s, #%d, %s%s\n", sat_insn_names[op], orc_arm_cond_name(cond), @@ -674,7 +678,7 @@ orc_arm_emit_rv (OrcCompiler *p, int op, OrcArmCond cond, int Rd, int Rm) { orc_uint32 code; - static const orc_uint32 rv_opcodes[] = { 0x06b00030, 0x06e000b0 }; + static const orc_uint32 rv_opcodes[] = { 0x06b00030, 0x06bf0fb0 }; static const char *rv_insn_names[] = { "rev", "rev16" }; code = arm_code_rv (rv_opcodes[op], cond, Rd, Rm); diff --git a/orc/orcprogram-arm.c b/orc/orcprogram-arm.c index 4573630..069612b 100644 --- a/orc/orcprogram-arm.c +++ b/orc/orcprogram-arm.c @@ -115,7 +115,6 @@ orc_compiler_orc_arm_init (OrcCompiler *compiler) for(i=ORC_GP_REG_BASE;ivalid_regs[i] = 1; } - compiler->valid_regs[ORC_ARM_A1] = 0; //compiler->valid_regs[ORC_ARM_SB] = 0; compiler->valid_regs[ORC_ARM_IP] = 0; compiler->valid_regs[ORC_ARM_SP] = 0; @@ -129,6 +128,12 @@ orc_compiler_orc_arm_init (OrcCompiler *compiler) compiler->alloc_regs[i] = 0; compiler->used_regs[i] = 0; } + compiler->exec_reg = ORC_ARM_A1; + compiler->valid_regs[compiler->exec_reg] = 0; + compiler->gp_tmpreg = ORC_ARM_A2; + compiler->valid_regs[compiler->gp_tmpreg] = 0; + compiler->tmpreg = ORC_ARM_A3; + compiler->valid_regs[compiler->tmpreg] = 0; compiler->loop_shift = 0; } diff --git a/orc/orcrules-arm.c b/orc/orcrules-arm.c index 8774f3b..4d2fcee 100644 --- a/orc/orcrules-arm.c +++ b/orc/orcrules-arm.c @@ -35,18 +35,48 @@ arm_rule_ ## opcode (OrcCompiler *p, void *user, OrcInstruction *insn) \ } /* multiplies */ -#define orc_arm_smulxy(cond,x,y,Rd,Rm,Rs) (0x01600080|((cond)<<28)|((Rd)<<16)|((Rs)<<8)|((y)<<6)|((x)<<5)|(Rm)) -#define orc_arm_emit_smulbb(p,cond,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_smulxy (cond,0,0,Rd,Rm,Rs)) -#define orc_arm_emit_smulbt(p,cond,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_smulxy (cond,0,1,Rd,Rm,Rs)) -#define orc_arm_emit_smultb(p,cond,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_smulxy (cond,1,0,Rd,Rm,Rs)) -#define orc_arm_emit_smultt(p,cond,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_smulxy (cond,1,1,Rd,Rm,Rs)) - -#define orc_arm_mul(cond,S,Rd,Rm,Rs) (0x00000090|((cond)<<28)|((S)<<20)|((Rd)<<16)|((Rs)<<8)|(Rm)) -#define orc_arm_emit_mul(p,cond,S,Rd,Rm,Rs) orc_arm_emit (p, orc_arm_mul (cond,S,Rd,Rm,Rs)) - -#define orc_arm_mull(op,cond,S,RdH,RdL,Rm,Rs) (op|((cond)<<28)|((S)<<20)|((RdH)<<16)|((RdL)<<12)|((Rs)<<8)|(Rm)) -#define orc_arm_emit_smull(p,cond,S,RdL,RdH,Rm,Rs) orc_arm_emit(p,orc_arm_mull (0x00c00090,cond,S,RdH,RdL,Rm,Rs)) -#define orc_arm_emit_umull(p,cond,S,RdL,RdH,Rm,Rs) orc_arm_emit(p,orc_arm_mull (0x00800090,cond,S,RdH,RdL,Rm,Rs)) +#define orc_arm_smulxy(cond,x,y,Rd,Rm,Rs) (0x01600080|((cond)<<28)|(((Rd)&15)<<16)|(((Rs)&15)<<8)|((y)<<6)|((x)<<5)|((Rm)&15)) +#define orc_arm_emit_smulbb(p,cond,Rd,Rm,Rs) do { \ + ORC_ASM_CODE (p, "smulbb %s, %s, %s\n", orc_arm_reg_name (Rd), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit (p, orc_arm_smulxy (cond,0,0,Rd,Rm,Rs)); \ +} while (0) +#define orc_arm_emit_smulbt(p,cond,Rd,Rm,Rs) do { \ + ORC_ASM_CODE (p, "smulbt %s, %s, %s\n", orc_arm_reg_name (Rd), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit (p, orc_arm_smulxy (cond,0,1,Rd,Rm,Rs)); \ +} while (0) +#define orc_arm_emit_smultb(p,cond,Rd,Rm,Rs) do { \ + ORC_ASM_CODE (p, "smultb %s, %s, %s\n", orc_arm_reg_name (Rd), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit (p, orc_arm_smulxy (cond,1,0,Rd,Rm,Rs)); \ +} while (0) +#define orc_arm_emit_smultt(p,cond,Rd,Rm,Rs) do { \ + ORC_ASM_CODE (p, "smultt %s, %s, %s\n", orc_arm_reg_name (Rd), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit (p, orc_arm_smulxy (cond,1,1,Rd,Rm,Rs)); \ +} while (0) + +#define orc_arm_mul(cond,S,Rd,Rm,Rs) (0x00000090|((cond)<<28)|((S)<<20)|(((Rd)&15)<<16)|(((Rs)&15)<<8)|((Rm)&15)) +#define orc_arm_emit_mul(p,cond,S,Rd,Rm,Rs) do { \ + ORC_ASM_CODE (p, "mul %s, %s, %s\n", orc_arm_reg_name (Rd), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit (p, orc_arm_mul (cond,S,Rd,Rm,Rs)); \ +} while (0) + +#define orc_arm_mull(op,cond,S,RdH,RdL,Rm,Rs) (op|((cond)<<28)|((S)<<20)|(((RdH)&15)<<16)|(((RdL)&15)<<12)|(((Rs)&15)<<8)|((Rm)&15)) +#define orc_arm_emit_smull(p,cond,S,RdL,RdH,Rm,Rs) do { \ + ORC_ASM_CODE (p, "mull %s, %s, %s, %s\n", orc_arm_reg_name (RdH), \ + orc_arm_reg_name (RdL), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit(p,orc_arm_mull (0x00c00090,cond,S,RdH,RdL,Rm,Rs)); \ +} while (0) +#define orc_arm_emit_umull(p,cond,S,RdL,RdH,Rm,Rs) do { \ + ORC_ASM_CODE (p, "umull %s, %s, %s, %s\n", orc_arm_reg_name (RdH), \ + orc_arm_reg_name (RdL), \ + orc_arm_reg_name (Rm), orc_arm_reg_name(Rs)); \ + orc_arm_emit(p,orc_arm_mull (0x00800090,cond,S,RdH,RdL,Rm,Rs)); \ +} while (0) void orc_arm_loadw (OrcCompiler *compiler, int dest, int src1, int offset) @@ -517,7 +547,7 @@ arm_rule_shrsX (OrcCompiler *p, void *user, OrcInstruction *insn) int src1 = ORC_SRC_ARG (p, insn, 0); int dest = ORC_DEST_ARG (p, insn, 0); int mask = p->tmpreg; - int tmp = ORC_ARM_IP; + int tmp = ORC_ARM_V8; int src2type = ORC_SRC_TYPE (p, insn, 1); int size = ORC_PTR_TO_INT(user); int loop = 4 / size; /* number of items in one register */ -- 2.34.1