From e9bc8926ab19ddf878d98f260e95ac5b2cdada9b Mon Sep 17 00:00:00 2001 From: Mihai Parparita Date: Thu, 7 Dec 2023 23:59:49 -0800 Subject: [PATCH] Avoid some undefined behavior The `SubOpcode31Grabber[1024] = { ppc_illegalop }` initializer only populates the first entry with ppc_illegalop (at least on some compilers), switch to explicitly initializing the entire array with std::fill_n. Also fix a couple of sign and overflow issues flagged by the Xcode undefined behavior sanitizer. --- cpu/ppc/ppcexec.cpp | 9 ++++++--- cpu/ppc/ppcopcodes.cpp | 11 ++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 032fa82..5cd3522 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -161,9 +161,9 @@ static PPCOpcode SubOpcode18Grabber[] = { /** Instructions decoding tables for integer, single floating-point, and double-floating point ops respectively */ -PPCOpcode SubOpcode31Grabber[1024] = { ppc_illegalop }; -PPCOpcode SubOpcode59Grabber[32] = { ppc_illegalop }; -PPCOpcode SubOpcode63Grabber[1024] = { ppc_illegalop }; +PPCOpcode SubOpcode31Grabber[1024]; +PPCOpcode SubOpcode59Grabber[32]; +PPCOpcode SubOpcode63Grabber[1024]; /** Exception helpers. */ @@ -575,6 +575,7 @@ void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size) } void initialize_ppc_opcode_tables() { + std::fill_n(SubOpcode31Grabber, 1024, ppc_illegalop); SubOpcode31Grabber[0] = ppc_cmp; SubOpcode31Grabber[4] = ppc_tw; SubOpcode31Grabber[32] = ppc_cmpl; @@ -709,6 +710,7 @@ void initialize_ppc_opcode_tables() { SubOpcode31Grabber[978] = ppc_tlbld; SubOpcode31Grabber[1010] = ppc_tlbli; + std::fill_n(SubOpcode59Grabber, 32, ppc_illegalop); SubOpcode59Grabber[18] = ppc_fdivs; SubOpcode59Grabber[20] = ppc_fsubs; SubOpcode59Grabber[21] = ppc_fadds; @@ -720,6 +722,7 @@ void initialize_ppc_opcode_tables() { SubOpcode59Grabber[30] = ppc_fnmsubs; SubOpcode59Grabber[31] = ppc_fnmadds; + std::fill_n(SubOpcode63Grabber, 1024, ppc_illegalop); SubOpcode63Grabber[0] = ppc_fcmpu; SubOpcode63Grabber[12] = ppc_frsp; SubOpcode63Grabber[14] = ppc_fctiw; diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index ad809cc..3731ee8 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -685,7 +685,7 @@ void dppc_interpreter::ppc_sraw() { ppc_state.spr[SPR::XER] |= (ppc_result_a & 1) << 29; } else { uint32_t shift = ppc_result_b & 0x1F; - uint32_t mask = (1 << shift) - 1; + uint32_t mask = (1U << shift) - 1; ppc_result_a = (int32_t)ppc_result_d >> shift; if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) { ppc_state.spr[SPR::XER] |= 0x20000000UL; @@ -703,7 +703,7 @@ void dppc_interpreter::ppc_sraw() { void dppc_interpreter::ppc_srawi() { ppc_grab_regssa(); unsigned shift = (ppc_cur_instruction >> 11) & 0x1F; - uint32_t mask = (1 << shift) - 1; + uint32_t mask = (1U << shift) - 1; ppc_result_a = (int32_t)ppc_result_d >> shift; if ((ppc_result_d & 0x80000000UL) && (ppc_result_d & mask)) { ppc_state.spr[SPR::XER] |= 0x20000000UL; @@ -730,7 +730,7 @@ void dppc_interpreter::ppc_rlwimi() { unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; unsigned rot_me = (ppc_cur_instruction >> 1) & 31; uint32_t mask = rot_mask(rot_mb, rot_me); - uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); + uint32_t r = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d; ppc_result_a = (ppc_result_a & ~mask) | (r & mask); if ((ppc_cur_instruction & 0x01) == 1) { ppc_changecrf0(ppc_result_a); @@ -744,7 +744,7 @@ void dppc_interpreter::ppc_rlwinm() { unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; unsigned rot_me = (ppc_cur_instruction >> 1) & 31; uint32_t mask = rot_mask(rot_mb, rot_me); - uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))); + uint32_t r = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d; ppc_result_a = r & mask; if ((ppc_cur_instruction & 0x01) == 1) { ppc_changecrf0(ppc_result_a); @@ -757,7 +757,8 @@ void dppc_interpreter::ppc_rlwnm() { unsigned rot_mb = (ppc_cur_instruction >> 6) & 31; unsigned rot_me = (ppc_cur_instruction >> 1) & 31; uint32_t mask = rot_mask(rot_mb, rot_me); - uint32_t r = ((ppc_result_d << ppc_result_b) | (ppc_result_d >> (32 - ppc_result_b))); + uint32_t rot = ppc_result_b & 0x1F; + uint32_t r = rot ? ((ppc_result_d << rot) | (ppc_result_d >> (32 - rot))) : ppc_result_d; ppc_result_a = r & mask; if ((ppc_cur_instruction & 0x01) == 1) { ppc_changecrf0(ppc_result_a);