target/arm_simulator: fix undefined behaviour
Shifting 32 bit unsigned variables by 32 bits is undefined behaviour Change-Id: I846619a522c747f9c3b11a814a1864d1d51cfe87 Signed-off-by: Mark O'Donovan <shiftee@posteo.net> Reviewed-on: https://review.openocd.org/c/openocd/+/9502 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
committed by
Antonio Borneo
parent
49e75c74d5
commit
231aa88ee5
@@ -27,25 +27,31 @@ static uint32_t arm_shift(uint8_t shift, uint32_t rm,
|
|||||||
shift_amount &= 0xff;
|
shift_amount &= 0xff;
|
||||||
|
|
||||||
if (shift == 0x0) { /* LSL */
|
if (shift == 0x0) { /* LSL */
|
||||||
if ((shift_amount > 0) && (shift_amount <= 32)) {
|
if (shift_amount > 0 && shift_amount < 32) {
|
||||||
return_value = rm << shift_amount;
|
return_value = rm << shift_amount;
|
||||||
*carry = rm >> (32 - shift_amount);
|
*carry = rm >> (32 - shift_amount);
|
||||||
|
} else if (shift_amount == 32) {
|
||||||
|
return_value = 0x0;
|
||||||
|
*carry = rm & 0x1;
|
||||||
} else if (shift_amount > 32) {
|
} else if (shift_amount > 32) {
|
||||||
return_value = 0x0;
|
return_value = 0x0;
|
||||||
*carry = 0x0;
|
*carry = 0x0;
|
||||||
} else /* (shift_amount == 0) */
|
} else /* (shift_amount == 0) */
|
||||||
return_value = rm;
|
return_value = rm;
|
||||||
} else if (shift == 0x1) { /* LSR */
|
} else if (shift == 0x1) { /* LSR */
|
||||||
if ((shift_amount > 0) && (shift_amount <= 32)) {
|
if (shift_amount > 0 && shift_amount < 32) {
|
||||||
return_value = rm >> shift_amount;
|
return_value = rm >> shift_amount;
|
||||||
*carry = (rm >> (shift_amount - 1)) & 1;
|
*carry = (rm >> (shift_amount - 1)) & 1;
|
||||||
|
} else if (shift_amount == 32) {
|
||||||
|
return_value = 0x0;
|
||||||
|
*carry = (rm >> 31) & 0x1;
|
||||||
} else if (shift_amount > 32) {
|
} else if (shift_amount > 32) {
|
||||||
return_value = 0x0;
|
return_value = 0x0;
|
||||||
*carry = 0x0;
|
*carry = 0x0;
|
||||||
} else /* (shift_amount == 0) */
|
} else /* (shift_amount == 0) */
|
||||||
return_value = rm;
|
return_value = rm;
|
||||||
} else if (shift == 0x2) { /* ASR */
|
} else if (shift == 0x2) { /* ASR */
|
||||||
if ((shift_amount > 0) && (shift_amount <= 32)) {
|
if (shift_amount > 0 && shift_amount < 32) {
|
||||||
/* C right shifts of unsigned values are guaranteed to
|
/* C right shifts of unsigned values are guaranteed to
|
||||||
* be logical (shift in zeroes); simulate an arithmetic
|
* be logical (shift in zeroes); simulate an arithmetic
|
||||||
* shift (shift in signed-bit) by adding the sign bit
|
* shift (shift in signed-bit) by adding the sign bit
|
||||||
@@ -54,7 +60,7 @@ static uint32_t arm_shift(uint8_t shift, uint32_t rm,
|
|||||||
return_value = rm >> shift_amount;
|
return_value = rm >> shift_amount;
|
||||||
if (rm & 0x80000000)
|
if (rm & 0x80000000)
|
||||||
return_value |= 0xffffffff << (32 - shift_amount);
|
return_value |= 0xffffffff << (32 - shift_amount);
|
||||||
} else if (shift_amount > 32) {
|
} else if (shift_amount >= 32) {
|
||||||
if (rm & 0x80000000) {
|
if (rm & 0x80000000) {
|
||||||
return_value = 0xffffffff;
|
return_value = 0xffffffff;
|
||||||
*carry = 0x1;
|
*carry = 0x1;
|
||||||
|
|||||||
Reference in New Issue
Block a user