summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2015-11-05 14:32:37 +0100
committerIlia Mirkin <imirkin@alum.mit.edu>2015-11-06 18:13:31 -0500
commit9f2f8bda6e060cb85f6e099a4ad65c58cde36ba0 (patch)
treefc4264f2e5ed1822070f553398c5a8216f2a3025
parent428506ece2c7627392d0f02c7f83021caa46bb4f (diff)
nvc0/ir: Teach insnCanLoad about double immediates
Teach insnCanLoad about double immediates, together with the "Add support for merge-s to the ConstantFolding pass" This turns the following (nvc0) code: 1: mov u32 $r2 0x00000000 (8) 2: mov u32 $r3 0x3fe00000 (8) 3: add f64 $r0d $r0d $r2d (8) Into: 1: add f64 $r0d $r0d 0.500000 (8) Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
index 27df0eba66b..8f59d86a72f 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
@@ -338,17 +338,30 @@ TargetNVC0::insnCanLoad(const Instruction *i, int s,
if (sf == FILE_IMMEDIATE) {
Storage &reg = ld->getSrc(0)->asImm()->reg;
- if (typeSizeof(i->sType) > 4)
- return false;
- if (opInfo[i->op].immdBits != 0xffffffff) {
- if (i->sType == TYPE_F32) {
+ if (opInfo[i->op].immdBits != 0xffffffff || typeSizeof(i->sType) > 4) {
+ switch (i->sType) {
+ case TYPE_F64:
+ if (reg.data.u64 & 0x00000fffffffffffULL)
+ return false;
+ break;
+ case TYPE_F32:
if (reg.data.u32 & 0xfff)
return false;
- } else
- if (i->sType == TYPE_S32 || i->sType == TYPE_U32) {
+ break;
+ case TYPE_S32:
+ case TYPE_U32:
// with u32, 0xfffff counts as 0xffffffff as well
if (reg.data.s32 > 0x7ffff || reg.data.s32 < -0x80000)
return false;
+ break;
+ case TYPE_U8:
+ case TYPE_S8:
+ case TYPE_U16:
+ case TYPE_S16:
+ case TYPE_F16:
+ break;
+ default:
+ return false;
}
} else
if (i->op == OP_MAD || i->op == OP_FMA) {