changeset 96c81efdd3be in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=96c81efdd3be
description:
        hsail: fix unsigned offset bug in address calculation

        it's possible for the offset provided to an HSAIL mem inst to be a 
negative
        value, however the variable we use to hold the offset is an unsigned 
type.
        this can lead to excessively large offset values when the offset is 
negative,
        which will almost certainly cause the access to go out of bounds.

diffstat:

 src/arch/hsail/operand.hh |  14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

diffs (38 lines):

diff -r e15e445c21a6 -r 96c81efdd3be src/arch/hsail/operand.hh
--- a/src/arch/hsail/operand.hh Fri Dec 02 11:40:40 2016 -0500
+++ b/src/arch/hsail/operand.hh Fri Dec 02 11:40:52 2016 -0500
@@ -591,7 +591,7 @@
     virtual void calcVector(Wavefront *w, std::vector<Addr> &addrVec) = 0;
     virtual uint64_t calcLane(Wavefront *w, int lane=0) = 0;
 
-    uint64_t offset;
+    int64_t offset;
     const char *name = nullptr;
     StorageElement *storageElement;
 };
@@ -627,14 +627,24 @@
             const BrigOperandAddress *op = (BrigOperandAddress*)baseOp;
             storageElement = nullptr;
 
-            offset = (uint64_t(op->offset.hi) << 32) | uint64_t(op->offset.lo);
             reg.init(op->reg, obj);
 
             if (reg.regFileChar == 's') {
+                // if the address expression is 32b, then the hi
+                // bits of the offset must be set to 0 in the BRIG
+                assert(!op->offset.hi);
+                /**
+                 * the offset field of an HSAIL instruction may be negative
+                 * so here we cast the raw bits we get from the BRIG file to
+                 * a signed type to avoid address calculation errors
+                 */
+                offset = (int32_t)(op->offset.lo);
                 reg.regOperandSize = sizeof(uint32_t);
                 registerType = Enums::RT_VECTOR;
             }
             else if (reg.regFileChar == 'd') {
+                offset = (int64_t)(((uint64_t)(op->offset.hi) << 32)
+                    | (uint64_t)(op->offset.lo));
                 reg.regOperandSize = sizeof(uint64_t);
                 registerType = Enums::RT_VECTOR;
             }
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to