Skip to content

Commit

Permalink
Semantics for shift instruction.
Browse files Browse the repository at this point in the history
Includes semantics for the following instructions:
* LSL (register)
* LSLV
* LSR (register)
* LSRV
* ASR (register)
* ASRV
* ROR (register)
* RORV

Introduced method DispatcherARM64::ShiftReg that is utilized by the
semantics of all the above instructions and calls the appropriate shift
function under BaseSemantics::RiscOperators based on the shift type.

Introduced method DispatcherARM64::getShiftType that is again used by
the semantics code to determine the type of shift.
  • Loading branch information
ssunny7 committed Dec 20, 2016
1 parent cc98e05 commit 5c210a5
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 10 deletions.
159 changes: 150 additions & 9 deletions dataflowAPI/rose/semantics/DispatcherARM64.C
Expand Up @@ -4059,6 +4059,102 @@ namespace rose {
}
};

struct IP_asr_asrv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_asrv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_lsl_lslv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_lslv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_lsr_lsrv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_lsrv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_ror_rorv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

struct IP_rorv_execute : P {
void p(D d, Ops ops, I insn, A args, B raw) {
BaseSemantics::SValuePtr result;
BaseSemantics::SValuePtr operand2 = d->read(args[2]);
result = d->ShiftReg(d->read(args[1]), d->getShiftType(raw),
ops->unsignedModulo(d->UInt(operand2),
ops->number_(32, d->getDatasize(raw))));
d->write(args[0], result);

}
};

} // namespace

/*******************************************************************************************************************************
Expand Down Expand Up @@ -4179,6 +4275,14 @@ namespace rose {
iproc_set(rose_aarch64_op_sturb, new ARM64::IP_sturb_execute);
iproc_set(rose_aarch64_op_sturh, new ARM64::IP_sturh_execute);
iproc_set(rose_aarch64_op_stur_gen, new ARM64::IP_stur_gen_execute);
iproc_set(rose_aarch64_op_asr_asrv, new ARM64::IP_asr_asrv_execute);
iproc_set(rose_aarch64_op_asrv, new ARM64::IP_asrv_execute);
iproc_set(rose_aarch64_op_lsl_lslv, new ARM64::IP_lsl_lslv_execute);
iproc_set(rose_aarch64_op_lslv, new ARM64::IP_lslv_execute);
iproc_set(rose_aarch64_op_lsr_lsrv, new ARM64::IP_lsr_lsrv_execute);
iproc_set(rose_aarch64_op_lsrv, new ARM64::IP_lsrv_execute);
iproc_set(rose_aarch64_op_ror_rorv, new ARM64::IP_ror_rorv_execute);
iproc_set(rose_aarch64_op_rorv, new ARM64::IP_rorv_execute);
}

void
Expand Down Expand Up @@ -4527,18 +4631,33 @@ namespace rose {

int
DispatcherARM64::getDatasize(uint32_t raw) {
int v27_29 = IntegerOps::extract2<uint32_t>(27, 29, raw), v23_25 = IntegerOps::extract2<uint32_t>(23,
25,
raw);
int retval, v30_31 = IntegerOps::extract2<uint32_t>(30, 31, raw);;

if (v27_29 == 0x5 && v23_25 < 0x4) {
retval = 0x8 << (2 + (v30_31 & 0x1));
if(IntegerOps::extract2(25, 27, raw) == 0x5) {
return 32 * (1 + (IntegerOps::extract2(31, 31, raw) & 0x1));
} else {
retval = 0x8 << v30_31;
int v27_29 = IntegerOps::extract2<uint32_t>(27, 29, raw), v23_25 = IntegerOps::extract2<uint32_t>(23, 25, raw);
int retval, v30_31 = IntegerOps::extract2<uint32_t>(30, 31, raw);;

if (v27_29 == 0x5 && v23_25 < 0x4) {
retval = 0x8 << (2 + (v30_31 & 0x1));
} else {
retval = 0x8 << v30_31;
}

return retval * 8;
}
}

return retval * 8;
int
DispatcherARM64::getShiftType(uint32_t raw) {
int v10_11 = IntegerOps::extract2(10, 11, raw);

switch(v10_11) {
case 0: return static_cast<int>(ARM64::InsnProcessor::ShiftType_LSL);
case 1: return static_cast<int>(ARM64::InsnProcessor::ShiftType_LSR);
case 2: return static_cast<int>(ARM64::InsnProcessor::ShiftType_ASR);
case 3: return static_cast<int>(ARM64::InsnProcessor::ShiftType_ROR);
default: ASSERT_not_reachable("Cannot have a value greater than 3 for a 2-bit field (field: op2, bits: 10..11)!");
}
}

BaseSemantics::SValuePtr
Expand Down Expand Up @@ -4686,6 +4805,28 @@ namespace rose {
return retval;
}
}

/*Just returning the expression as-is, since there is no flag or variable in semantics indicating whether or not
a SValue should be treated as signed/unsigned. The signed-ness should be taken into account when performing an
operation on this value instead */
BaseSemantics::SValuePtr
DispatcherARM64::UInt(const BaseSemantics::SValuePtr &expr) {
ASSERT_not_null(expr);
return expr;
}

BaseSemantics::SValuePtr
DispatcherARM64::ShiftReg(const BaseSemantics::SValuePtr &src, int shiftType, const BaseSemantics::SValuePtr &amount) {
ASSERT_not_null(amount);

switch(static_cast<ARM64::InsnProcessor::ShiftType>(shiftType)) {
case ARM64::InsnProcessor::ShiftType_LSL: return operators->shiftLeft(src, amount);
case ARM64::InsnProcessor::ShiftType_LSR: return operators->shiftRight(src, amount);
case ARM64::InsnProcessor::ShiftType_ASR: return operators->shiftRightArithmetic(src, amount);
case ARM64::InsnProcessor::ShiftType_ROR: return operators->rotateRight(src, amount);
default: ASSERT_not_reachable("Found invalid shift type for shift instruction!");
}
}
} // namespace
} // namespace
} // namespace
Expand Down
16 changes: 15 additions & 1 deletion dataflowAPI/rose/semantics/DispatcherARM64.h
Expand Up @@ -9,7 +9,6 @@ namespace rose {
namespace BinaryAnalysis {
namespace InstructionSemantics2 {


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Dispatcher
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -225,6 +224,8 @@ namespace rose {

int getDatasize(uint32_t raw);

int getShiftType(uint32_t raw);

/** */
BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &addr, size_t readSize);

Expand All @@ -233,6 +234,12 @@ namespace rose {

/** */
SgAsmExpression *getWriteBackTarget(SgAsmExpression *expr);

/** */
BaseSemantics::SValuePtr UInt(const BaseSemantics::SValuePtr &expr);

/** */
BaseSemantics::SValuePtr ShiftReg(const BaseSemantics::SValuePtr &src, int shiftType, const BaseSemantics::SValuePtr &amount);
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -279,6 +286,13 @@ namespace rose {
LogicalOp_ORR,
LogicalOp_EOR
};

enum ShiftType {
ShiftType_LSL,
ShiftType_LSR,
ShiftType_ASR,
ShiftType_ROR
};
};

} // namespace
Expand Down

0 comments on commit 5c210a5

Please sign in to comment.