C#: Support for unsigned shift right in the experimental intermediate representation.

This commit is contained in:
Michael Nebel
2023-01-09 15:06:32 +01:00
parent f74c7c28ae
commit 5bb8f8ed5c
5 changed files with 40 additions and 1 deletions

View File

@@ -30,6 +30,7 @@ private newtype TOpcode =
TNegate() or
TShiftLeft() or
TShiftRight() or
TUnsignedShiftRight() or
TBitAnd() or
TBitOr() or
TBitXor() or
@@ -652,6 +653,15 @@ module Opcode {
final override string toString() { result = "ShiftRight" }
}
/**
* The `Opcode` for a `UnsignedShiftRightInstruction`.
*
* See the `UnsignedShiftRightInstruction` documentation for more details.
*/
class UnsignedShiftRight extends BinaryBitwiseOpcode, TUnsignedShiftRight {
final override string toString() { result = "UnsignedShiftRight" }
}
/**
* The `Opcode` for a `BitAndInstruction`.
*

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -1095,6 +1095,8 @@ private Opcode binaryBitwiseOpcode(BinaryBitwiseOperation expr) {
or
expr instanceof RightShiftExpr and result instanceof Opcode::ShiftRight
or
expr instanceof UnsignedRightShiftExpr and result instanceof Opcode::UnsignedShiftRight
or
expr instanceof BitwiseAndExpr and result instanceof Opcode::BitAnd
or
expr instanceof BitwiseOrExpr and result instanceof Opcode::BitOr
@@ -1378,7 +1380,8 @@ class TranslatedAssignOperation extends TranslatedAssignment {
private Type getConvertedLeftOperandType() {
if
expr instanceof AssignLeftShiftExpr or
expr instanceof AssignRightShiftExpr
expr instanceof AssignRightShiftExpr or
expr instanceof AssignUnsighedRightShiftExpr
then result = this.getLeftOperand().getResultType()
else
// The right operand has already been converted to the type of the op.
@@ -1419,6 +1422,8 @@ class TranslatedAssignOperation extends TranslatedAssignment {
expr instanceof AssignLeftShiftExpr and result instanceof Opcode::ShiftLeft
or
expr instanceof AssignRightShiftExpr and result instanceof Opcode::ShiftRight
or
expr instanceof AssignUnsighedRightShiftExpr and result instanceof Opcode::UnsignedShiftRight
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CSharpType resultType) {

View File

@@ -1204,6 +1204,17 @@ class ShiftRightInstruction extends BinaryBitwiseInstruction {
ShiftRightInstruction() { this.getOpcode() instanceof Opcode::ShiftRight }
}
/**
* An instruction that shifts its left operand to the right by the number of bits specified by its
* right operand.
*
* Both operands must have an integer type. The result has the same type as the left operand.
* The leftmost bits are zero-filled.
*/
class UnsignedShiftRightInstruction extends BinaryBitwiseInstruction {
UnsignedShiftRightInstruction() { this.getOpcode() instanceof Opcode::UnsignedShiftRight }
}
/**
* An instruction that performs a binary arithmetic operation involving at least one pointer
* operand.

View File

@@ -522,6 +522,8 @@ module SignAnalysisCached {
i instanceof ShiftRightInstruction and
not i.getResultType().(IntegralType) instanceof SignedIntegralType and
result = s1.urshift(s2)
or
i instanceof UnsignedShiftRightInstruction and result = s1.urshift(s2)
)
or
// use hasGuard here?