From 00e1d0e38f85a7c687b068414a3fdb9c61e74b07 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Thu, 28 Apr 2011 00:27:44 -0700 Subject: [PATCH] altivec: Fix rules for shift ops with parameters --- orc/orccompiler.c | 7 +++++-- orc/orcpowerpc.c | 28 ++++++++++++++++++++++------ orc/orcpowerpc.h | 2 ++ orc/orcprogram-altivec.c | 1 + orc/orcprogram.h | 1 + orc/orcrules-altivec.c | 19 ++++++++++++------- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/orc/orccompiler.c b/orc/orccompiler.c index a3b6cbf..d65fe40 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -528,9 +528,12 @@ orc_compiler_rewrite_insns (OrcCompiler *compiler) OrcVariable *var; if (opcode->src_size[i] == 0) continue; - if (i > 0 && (opcode->flags & ORC_STATIC_OPCODE_SCALAR)) continue; - var = compiler->vars + insn.src_args[i]; + + if (i > 0 && (opcode->flags & ORC_STATIC_OPCODE_SCALAR) && + (!compiler->load_params || var->vartype != ORC_VAR_TYPE_PARAM)) + continue; + if (var->vartype == ORC_VAR_TYPE_SRC || var->vartype == ORC_VAR_TYPE_DEST) { OrcInstruction *cinsn; diff --git a/orc/orcpowerpc.c b/orc/orcpowerpc.c index 982020d..1d9c6c8 100644 --- a/orc/orcpowerpc.c +++ b/orc/orcpowerpc.c @@ -399,8 +399,6 @@ powerpc_load_constant (OrcCompiler *p, int i, int reg) { int j; int value = p->constants[i].value; - int greg = p->gp_tmpreg; - int label_skip, label_data; switch (p->constants[i].type) { case ORC_CONST_ZERO: @@ -467,6 +465,20 @@ powerpc_load_constant (OrcCompiler *p, int i, int reg) break; } + powerpc_load_long_constant (p, reg, + p->constants[i].full_value[0], + p->constants[i].full_value[1], + p->constants[i].full_value[2], + p->constants[i].full_value[3]); +} + +void +powerpc_load_long_constant (OrcCompiler *p, int reg, orc_uint32 a, + orc_uint32 b, orc_uint32 c, orc_uint32 d) +{ + int label_skip, label_data; + int greg = p->gp_tmpreg; + label_skip = orc_compiler_label_new (p); label_data = orc_compiler_label_new (p); @@ -478,10 +490,14 @@ powerpc_load_constant (OrcCompiler *p, int i, int reg) } powerpc_emit_label (p, label_data); - for(j=0;j<4;j++){ - ORC_ASM_CODE(p," .long 0x%08x\n", p->constants[i].full_value[j]); - powerpc_emit (p, p->constants[i].full_value[j]); - } + ORC_ASM_CODE(p," .long 0x%08x\n", a); + powerpc_emit (p, a); + ORC_ASM_CODE(p," .long 0x%08x\n", b); + powerpc_emit (p, b); + ORC_ASM_CODE(p," .long 0x%08x\n", c); + powerpc_emit (p, c); + ORC_ASM_CODE(p," .long 0x%08x\n", d); + powerpc_emit (p, d); powerpc_emit_label (p, label_skip); powerpc_emit_lwz (p, diff --git a/orc/orcpowerpc.h b/orc/orcpowerpc.h index 285f8ca..947a833 100644 --- a/orc/orcpowerpc.h +++ b/orc/orcpowerpc.h @@ -125,6 +125,8 @@ void powerpc_emit_VX_4 (OrcCompiler *p, const char *name, unsigned int insn, int d, int a); int powerpc_get_constant (OrcCompiler *p, int type, int value); int powerpc_get_constant_full (OrcCompiler *p, int value0, int value1, int value2, int value3); +void powerpc_load_long_constant (OrcCompiler *p, int reg, orc_uint32 a, + orc_uint32 b, orc_uint32 c, orc_uint32 d); /* instructions */ #define powerpc_emit_vand(p,a,b,c) powerpc_emit_VX_2 (p, "vand", 0x10000404, a, b, c) diff --git a/orc/orcprogram-altivec.c b/orc/orcprogram-altivec.c index 903c6f5..84f46b9 100644 --- a/orc/orcprogram-altivec.c +++ b/orc/orcprogram-altivec.c @@ -113,6 +113,7 @@ orc_compiler_powerpc_init (OrcCompiler *compiler) } compiler->loop_shift = 0; + compiler->load_params = TRUE; } void diff --git a/orc/orcprogram.h b/orc/orcprogram.h index 8aebccb..23f275b 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -483,6 +483,7 @@ struct _OrcCompiler { int insn_shift; /* used when emitting rules */ int max_var_size; /* size of largest var */ + int load_params; }; #define ORC_SRC_ARG(p,i,n) ((p)->vars[(i)->src_args[(n)]].alloc) diff --git a/orc/orcrules-altivec.c b/orc/orcrules-altivec.c index a405bed..69876e3 100644 --- a/orc/orcrules-altivec.c +++ b/orc/orcrules-altivec.c @@ -76,7 +76,11 @@ powerpc_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn) powerpc_emit_VX(compiler, 0x1000030c, powerpc_regnum(dest->alloc), value & 0x1f, 0); } else { - ORC_COMPILER_ERROR(compiler,"can't load constant"); + value &= 0xff; + value |= value << 8; + value |= value << 16; + powerpc_load_long_constant (compiler, dest->alloc, value, value, + value, value); } break; case 2: @@ -86,7 +90,10 @@ powerpc_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn) powerpc_emit_VX(compiler, 0x1000034c, powerpc_regnum(dest->alloc), value & 0x1f, 0); } else { - ORC_COMPILER_ERROR(compiler,"can't load constant"); + value &= 0xffff; + value |= value << 16; + powerpc_load_long_constant (compiler, dest->alloc, value, value, + value, value); } break; case 4: @@ -96,7 +103,8 @@ powerpc_rule_loadpX (OrcCompiler *compiler, void *user, OrcInstruction *insn) powerpc_emit_VX(compiler, 0x1000038c, powerpc_regnum(dest->alloc), value & 0x1f, 0); } else { - ORC_COMPILER_ERROR(compiler,"can't load constant"); + powerpc_load_long_constant (compiler, dest->alloc, value, value, + value, value); } break; } @@ -326,11 +334,8 @@ powerpc_rule_ ## name (OrcCompiler *p, void *user, OrcInstruction *insn) \ powerpc_emit_VX(p, 0x1000030c, \ powerpc_regnum(p->tmpreg), (int)p->vars[insn->src_args[1]].value.i, 0); \ powerpc_emit_VX_2 (p, opcode, code , dest, src1, p->tmpreg);\ - } else if (p->vars[insn->src_args[1]].vartype == ORC_VAR_TYPE_PARAM) { \ - ORC_COMPILER_ERROR(p,"rule only works with constants"); \ - powerpc_emit_VX_2 (p, opcode, code , dest, src1, src2);\ } else { \ - ORC_COMPILER_ERROR(p,"rule only works with constants or params"); \ + powerpc_emit_VX_2 (p, opcode, code , dest, src1, src2);\ } \ } -- 2.7.4