ubsan: spu: left shift of negative value

Also fixes a real bug.  The DECODE_INSN_I9a and DECODE_INSN_I9b both
use UNSIGNED_EXTRACT for 7 low bits of the result, but this was an
unsigned value due to "insn" being unsigned.  DECODE_INSN_I9* is
therefore unsigned too, leading to a zero extension in an expression
using a bfd_vma if bfd_vma is 64 bits.

	* opcode/spu.h: Formatting.
	(UNSIGNED_EXTRACT): Use 1u.
	(SIGNED_EXTRACT): Don't sign extend with shifts.
	(DECODE_INSN_I9a, DECODE_INSN_I9b): Avoid left shift of signed value.
	Keep result signed.
	(DECODE_INSN_U9a, DECODE_INSN_U9b): Delete.
This commit is contained in:
Alan Modra
2020-01-09 06:44:16 +10:30
parent 71780f455f
commit 8948cc6971
2 changed files with 29 additions and 17 deletions

View File

@ -1,3 +1,12 @@
2020-01-10 Alan Modra <amodra@gmail.com>
* opcode/spu.h: Formatting.
(UNSIGNED_EXTRACT): Use 1u.
(SIGNED_EXTRACT): Don't sign extend with shifts.
(DECODE_INSN_I9a, DECODE_INSN_I9b): Avoid left shift of signed value.
Keep result signed.
(DECODE_INSN_U9a, DECODE_INSN_U9b): Delete.
2020-01-07 Shahab Vahedi <shahab@synopsys.com> 2020-01-07 Shahab Vahedi <shahab@synopsys.com>
* opcode/arc.h (insn_class_t): Add 'LLOCK' and 'SCOND'. * opcode/arc.h (insn_class_t): Add 'LLOCK' and 'SCOND'.

View File

@ -87,39 +87,42 @@ struct spu_opcode
int arg[5]; int arg[5];
}; };
#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size)) #define UNSIGNED_EXTRACT(insn, size, pos) \
#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1)) (((insn) >> (pos)) & ((1u << (size)) - 1))
#define SIGNED_EXTRACT(insn, size, pos) \
(((int) UNSIGNED_EXTRACT(insn, size, pos) \
^ (1 << ((size) - 1))) - (1 << ((size) - 1)))
#define DECODE_INSN_RT(insn) (insn & 0x7f) #define DECODE_INSN_RT(insn) (insn & 0x7f)
#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f) #define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f) #define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f) #define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14) #define DECODE_INSN_I10(insn) SIGNED_EXTRACT (insn, 10, 14)
#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14) #define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT (insn, 10, 14)
/* For branching, immediate loads, hbr and lqa/stqa. */ /* For branching, immediate loads, hbr and lqa/stqa. */
#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7) #define DECODE_INSN_I16(insn) SIGNED_EXTRACT (insn, 16, 7)
#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7) #define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT (insn, 16, 7)
/* for stop */ /* for stop */
#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0) #define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT (insn, 14, 0)
/* For ila */ /* For ila */
#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7) #define DECODE_INSN_I18(insn) SIGNED_EXTRACT (insn, 18, 7)
#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7) #define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT (insn, 18, 7)
/* For rotate and shift and generate control mask */ /* For rotate and shift and generate control mask */
#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14) #define DECODE_INSN_I7(insn) SIGNED_EXTRACT (insn, 7, 14)
#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14) #define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT (insn, 7, 14)
/* For float <-> int conversion */ /* For float <-> int conversion */
#define DECODE_INSN_I8(insn) SIGNED_EXTRACT(insn,8,14) #define DECODE_INSN_I8(insn) SIGNED_EXTRACT (insn, 8, 14)
#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14) #define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT (insn, 8, 14)
/* For hbr */ /* For hbr */
#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0)) #define DECODE_INSN_I9a(insn) \
#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0)) ((SIGNED_EXTRACT (insn, 2, 23) * 128) | (int) UNSIGNED_EXTRACT (insn, 7, 0))
#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0)) #define DECODE_INSN_I9b(insn) \
#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0)) ((SIGNED_EXTRACT (insn, 2, 14) * 128) | (int) UNSIGNED_EXTRACT (insn, 7, 0))