PPC/S390 [simulator] Use bit_cast instead of reinterpret_cast

The following bit casting method using reinterpret_cast
has undefined behaviour:
```
int a = 1;
float b = *reinterpret_cast<float*>(&a);
```
Above breaks the strict aliasing rule which indicates:
> dereferencing pointers to objects of different types will
never refer to the same memory location.

More information can be found under src/base/macros.h.

`bit_cast` here is implemented with `memcpy` behind the scenes.
C++20 will have this feature included by default.

Change-Id: I69ffdbeba6db64e24b268d838ea1d863fcd9121d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2889331
Reviewed-by: Junliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#74513}
This commit is contained in:
Milad Fa 2021-05-11 16:15:04 -04:00 committed by V8 LUCI CQ
parent f64bd67f82
commit dfe7aca109
2 changed files with 26 additions and 29 deletions

View File

@ -1138,7 +1138,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
SimulatorRuntimeDirectGetterCall target =
reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
if (!ABI_PASSES_HANDLES_IN_REGS) {
arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
arg[0] = bit_cast<intptr_t>(arg[0]);
}
target(arg[0], arg[1]);
} else if (redirection->type() ==
@ -1157,7 +1157,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
if (!ABI_PASSES_HANDLES_IN_REGS) {
arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
arg[0] = bit_cast<intptr_t>(arg[0]);
}
target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
} else {
@ -3913,8 +3913,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
case STVX: {
DECODE_VX_INSTRUCTION(vrs, ra, rb, S)
GET_ADDRESS(ra, rb, ra_val, rb_val)
__int128 vrs_val =
*(reinterpret_cast<__int128*>(get_simd_register(vrs).int8));
__int128 vrs_val = bit_cast<__int128>(get_simd_register(vrs).int8);
WriteQW((ra_val + rb_val) & 0xFFFFFFFFFFFFFFF0, vrs_val);
break;
}
@ -3946,8 +3945,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
DECODE_VX_INSTRUCTION(vrs, ra, rb, S)
GET_ADDRESS(ra, rb, ra_val, rb_val)
intptr_t addr = ra_val + rb_val;
__int128 vrs_val =
*(reinterpret_cast<__int128*>(get_simd_register(vrs).int8));
__int128 vrs_val = bit_cast<__int128>(get_simd_register(vrs).int8);
WriteQW(addr, vrs_val);
break;
}
@ -4002,9 +4000,9 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
case XXBRQ: {
int t = instr->RTValue();
int b = instr->RBValue();
__int128 xb_val = *reinterpret_cast<__int128*>(get_simd_register(b).int8);
__int128 xb_val = bit_cast<__int128>(get_simd_register(b).int8);
__int128 xb_val_reversed = __builtin_bswap128(xb_val);
simdr_t simdr_xb = *reinterpret_cast<simdr_t*>(&xb_val_reversed);
simdr_t simdr_xb = bit_cast<simdr_t>(xb_val_reversed);
set_simd_register(t, simdr_xb);
break;
}
@ -4775,7 +4773,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
DECODE_VX_INSTRUCTION(t, a, b, T)
uint16_t result_bits = 0;
unsigned __int128 src_bits =
*(reinterpret_cast<__int128*>(get_simd_register(a).int8));
bit_cast<__int128>(get_simd_register(a).int8);
for (int i = 0; i < kSimd128Size; i++) {
result_bits <<= 1;
uint8_t selected_bit_index = get_simd_register_by_lane<uint8_t>(b, i);
@ -5007,7 +5005,7 @@ void Simulator::CallInternal(Address entry) {
// Prepare to execute the code at entry
if (ABI_USES_FUNCTION_DESCRIPTORS) {
// entry is the function descriptor
set_pc(*(reinterpret_cast<intptr_t*>(entry)));
set_pc(*(bit_cast<intptr_t*>(entry)));
} else {
// entry is the instruction address
set_pc(static_cast<intptr_t>(entry));

View File

@ -2002,8 +2002,8 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
(redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
// Place the return address on the stack, making the call GC safe.
*reinterpret_cast<intptr_t*>(get_register(sp) +
kStackFrameRASlot * kSystemPointerSize) =
*bit_cast<intptr_t*>(get_register(sp) +
kStackFrameRASlot * kSystemPointerSize) =
get_register(r14);
intptr_t external =
@ -2143,7 +2143,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
SimulatorRuntimeDirectGetterCall target =
reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
if (!ABI_PASSES_HANDLES_IN_REGS) {
arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
arg[0] = bit_cast<intptr_t>(arg[0]);
}
target(arg[0], arg[1]);
} else if (redirection->type() ==
@ -2162,7 +2162,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
SimulatorRuntimeProfilingGetterCall target =
reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
if (!ABI_PASSES_HANDLES_IN_REGS) {
arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
arg[0] = bit_cast<intptr_t>(arg[0]);
}
target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
} else {
@ -2270,7 +2270,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) {
// }
// #endif
}
int64_t saved_lr = *reinterpret_cast<intptr_t*>(
int64_t saved_lr = *bit_cast<intptr_t*>(
get_register(sp) + kStackFrameRASlot * kSystemPointerSize);
#if (!V8_TARGET_ARCH_S390X && V8_HOST_ARCH_S390)
// On zLinux-31, the saved_lr might be tagged with a high bit of 1.
@ -2487,7 +2487,7 @@ void Simulator::CallInternal(Address entry, int reg_arg_count) {
// Prepare to execute the code at entry
if (ABI_USES_FUNCTION_DESCRIPTORS) {
// entry is the function descriptor
set_pc(*(reinterpret_cast<intptr_t*>(entry)));
set_pc(*(bit_cast<intptr_t*>(entry)));
} else {
// entry is the instruction address
set_pc(static_cast<intptr_t>(entry));
@ -2609,7 +2609,7 @@ intptr_t Simulator::CallImpl(Address entry, int argument_count,
// Prepare to execute the code at entry
#if ABI_USES_FUNCTION_DESCRIPTORS
// entry is the function descriptor
set_pc(*(reinterpret_cast<intptr_t*>(entry)));
set_pc(*(bit_cast<intptr_t*>(entry)));
#else
// entry is the instruction address
set_pc(static_cast<intptr_t>(entry));
@ -3136,12 +3136,12 @@ EVALUATE(VLREP) {
DCHECK_OPCODE(VLREP);
DECODE_VRX_INSTRUCTION(r1, x2, b2, d2, m3);
intptr_t addr = GET_ADDRESS(x2, b2, d2);
#define CASE(i, type) \
case i: { \
FOR_EACH_LANE(j, type) { \
set_simd_register_by_lane<type>(r1, j, *reinterpret_cast<type*>(addr)); \
} \
break; \
#define CASE(i, type) \
case i: { \
FOR_EACH_LANE(j, type) { \
set_simd_register_by_lane<type>(r1, j, *bit_cast<type*>(addr)); \
} \
break; \
}
switch (m3) {
CASE(0, uint8_t);
@ -3952,8 +3952,7 @@ EVALUATE(VBPERM) {
USE(m5);
USE(m6);
uint16_t result_bits = 0;
unsigned __int128 src_bits =
*(reinterpret_cast<__int128*>(get_simd_register(r2).int8));
unsigned __int128 src_bits = bit_cast<__int128>(get_simd_register(r2).int8);
for (int i = 0; i < kSimd128Size; i++) {
result_bits <<= 1;
uint8_t selected_bit_index = get_simd_register_by_lane<uint8_t>(r3, i);
@ -5494,7 +5493,7 @@ EVALUATE(LD) {
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t addr = b2_val + x2_val + d2_val;
int64_t dbl_val = *reinterpret_cast<int64_t*>(addr);
int64_t dbl_val = *bit_cast<int64_t*>(addr);
set_fpr(r1, dbl_val);
return length;
}
@ -5533,7 +5532,7 @@ EVALUATE(LE) {
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
intptr_t addr = b2_val + x2_val + d2_val;
float float_val = *reinterpret_cast<float*>(addr);
float float_val = *bit_cast<float*>(addr);
set_fpr(r1, float_val);
return length;
}
@ -11208,7 +11207,7 @@ EVALUATE(LEY) {
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
intptr_t addr = x2_val + b2_val + d2;
float float_val = *reinterpret_cast<float*>(addr);
float float_val = *bit_cast<float*>(addr);
set_fpr(r1, float_val);
return length;
}
@ -11220,7 +11219,7 @@ EVALUATE(LDY) {
int64_t x2_val = (x2 == 0) ? 0 : get_register(x2);
int64_t b2_val = (b2 == 0) ? 0 : get_register(b2);
intptr_t addr = x2_val + b2_val + d2;
uint64_t dbl_val = *reinterpret_cast<uint64_t*>(addr);
uint64_t dbl_val = *bit_cast<uint64_t*>(addr);
set_fpr(r1, dbl_val);
return length;
}