Skip to content

Commit 451c1a7

Browse files
committed
[x64] Move all sequences in same compilation unit
Currently, sequences are in separate compilation units, but their constructors all share the same unordered_map, which is in one of the compilation unit. Due to that, when compiling using GCC with LTO enabled, the constructor of some units is called before the constructor of the unit with the map, also called 'Static Initialization Order Fiasco' (see: https://en.cppreference.com/w/cpp/language/siof). Thus, the map is not initialized, which causes a division-by-zero error (SIGFPE). Fix this by converting the files that contain specific sequences to be includable in the main file. This way all sequences are in the same compilation unit and guarantees the map is initialized.
1 parent 47271f2 commit 451c1a7

File tree

5 files changed

+29
-92
lines changed

5 files changed

+29
-92
lines changed

src/xenia/cpu/backend/x64/x64_seq_control.cc renamed to src/xenia/cpu/backend/x64/x64_seq_control.inc

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,12 @@
22
******************************************************************************
33
* Xenia : Xbox 360 Emulator Research Project *
44
******************************************************************************
5-
* Copyright 2018 Xenia Developers. All rights reserved. *
5+
* Copyright 2022 Xenia Developers. All rights reserved. *
66
* Released under the BSD license - see LICENSE in the root for more details. *
77
******************************************************************************
88
*/
99

10-
#include "xenia/cpu/backend/x64/x64_sequences.h"
11-
12-
#include <algorithm>
13-
#include <cstring>
14-
15-
#include "xenia/cpu/backend/x64/x64_op.h"
16-
17-
namespace xe {
18-
namespace cpu {
19-
namespace backend {
20-
namespace x64 {
21-
22-
volatile int anchor_control = 0;
10+
// NOTICE: This file is #included in x64_sequences.cc
2311

2412
// ============================================================================
2513
// OPCODE_DEBUG_BREAK
@@ -546,8 +534,3 @@ struct BRANCH_FALSE_F64
546534
EMITTER_OPCODE_TABLE(OPCODE_BRANCH_FALSE, BRANCH_FALSE_I8, BRANCH_FALSE_I16,
547535
BRANCH_FALSE_I32, BRANCH_FALSE_I64, BRANCH_FALSE_F32,
548536
BRANCH_FALSE_F64);
549-
550-
} // namespace x64
551-
} // namespace backend
552-
} // namespace cpu
553-
} // namespace xe

src/xenia/cpu/backend/x64/x64_seq_memory.cc renamed to src/xenia/cpu/backend/x64/x64_seq_memory.inc

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,12 @@
22
******************************************************************************
33
* Xenia : Xbox 360 Emulator Research Project *
44
******************************************************************************
5-
* Copyright 2018 Xenia Developers. All rights reserved. *
5+
* Copyright 2022 Xenia Developers. All rights reserved. *
66
* Released under the BSD license - see LICENSE in the root for more details. *
77
******************************************************************************
88
*/
99

10-
#include "xenia/cpu/backend/x64/x64_sequences.h"
11-
12-
#include <algorithm>
13-
#include <cstring>
14-
15-
#include "xenia/base/memory.h"
16-
#include "xenia/cpu/backend/x64/x64_op.h"
17-
#include "xenia/cpu/backend/x64/x64_tracers.h"
18-
19-
namespace xe {
20-
namespace cpu {
21-
namespace backend {
22-
namespace x64 {
23-
24-
volatile int anchor_memory = 0;
10+
// NOTICE: This file is #included in x64_sequences.cc
2511

2612
// Note: all types are always aligned in the context.
2713
RegExp ComputeContextAddress(X64Emitter& e, const OffsetOp& offset) {
@@ -1169,8 +1155,3 @@ struct MEMSET_I64_I8_I64
11691155
}
11701156
};
11711157
EMITTER_OPCODE_TABLE(OPCODE_MEMSET, MEMSET_I64_I8_I64);
1172-
1173-
} // namespace x64
1174-
} // namespace backend
1175-
} // namespace cpu
1176-
} // namespace xe

src/xenia/cpu/backend/x64/x64_seq_vector.cc renamed to src/xenia/cpu/backend/x64/x64_seq_vector.inc

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,7 @@
77
******************************************************************************
88
*/
99

10-
#include "xenia/cpu/backend/x64/x64_sequences.h"
11-
12-
#include <algorithm>
13-
#include <cstring>
14-
15-
#include "xenia/cpu/backend/x64/x64_op.h"
16-
17-
// For OPCODE_PACK/OPCODE_UNPACK
18-
#include "third_party/half/include/half.hpp"
19-
20-
namespace xe {
21-
namespace cpu {
22-
namespace backend {
23-
namespace x64 {
24-
25-
volatile int anchor_vector = 0;
10+
// NOTICE: This file is #included in x64_sequences.cc
2611

2712
// ============================================================================
2813
// OPCODE_VECTOR_CONVERT_I2F
@@ -2684,8 +2669,3 @@ struct UNPACK : Sequence<UNPACK, I<OPCODE_UNPACK, V128Op, V128Op>> {
26842669
}
26852670
};
26862671
EMITTER_OPCODE_TABLE(OPCODE_UNPACK, UNPACK);
2687-
2688-
} // namespace x64
2689-
} // namespace backend
2690-
} // namespace cpu
2691-
} // namespace xe

src/xenia/cpu/backend/x64/x64_sequences.cc

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "xenia/cpu/hir/hir_builder.h"
3939
#include "xenia/cpu/processor.h"
4040

41+
// For OPCODE_PACK/OPCODE_UNPACK
42+
#include "third_party/half/include/half.hpp"
43+
4144
namespace xe {
4245
namespace cpu {
4346
namespace backend {
@@ -54,6 +57,23 @@ using xe::cpu::hir::Instr;
5457
typedef bool (*SequenceSelectFn)(X64Emitter&, const Instr*);
5558
std::unordered_map<uint32_t, SequenceSelectFn> sequence_table;
5659

60+
template <typename T>
61+
bool Register() {
62+
sequence_table.insert({T::head_key(), T::Select});
63+
return true;
64+
}
65+
66+
template <typename T, typename Tn, typename... Ts>
67+
static bool Register() {
68+
bool b = true;
69+
b = b && Register<T>(); // Call the above function
70+
b = b && Register<Tn, Ts...>(); // Call ourself again (recursively)
71+
return b;
72+
}
73+
74+
#define EMITTER_OPCODE_TABLE(name, ...) \
75+
const auto X64_INSTR_##name = Register<__VA_ARGS__>();
76+
5777
// ============================================================================
5878
// OPCODE_COMMENT
5979
// ============================================================================
@@ -3299,15 +3319,9 @@ struct SET_ROUNDING_MODE_I32
32993319
};
33003320
EMITTER_OPCODE_TABLE(OPCODE_SET_ROUNDING_MODE, SET_ROUNDING_MODE_I32);
33013321

3302-
// Include anchors to other sequence sources so they get included in the build.
3303-
extern volatile int anchor_control;
3304-
static int anchor_control_dest = anchor_control;
3305-
3306-
extern volatile int anchor_memory;
3307-
static int anchor_memory_dest = anchor_memory;
3308-
3309-
extern volatile int anchor_vector;
3310-
static int anchor_vector_dest = anchor_vector;
3322+
#include "x64_seq_control.inc"
3323+
#include "x64_seq_memory.inc"
3324+
#include "x64_seq_vector.inc"
33113325

33123326
bool SelectSequence(X64Emitter* e, const Instr* i, const Instr** new_tail) {
33133327
const InstrKey key(i);

src/xenia/cpu/backend/x64/x64_sequences.h

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
******************************************************************************
33
* Xenia : Xbox 360 Emulator Research Project *
44
******************************************************************************
5-
* Copyright 2014 Ben Vanik. All rights reserved. *
5+
* Copyright 2022 Ben Vanik. All rights reserved. *
66
* Released under the BSD license - see LICENSE in the root for more details. *
77
******************************************************************************
88
*/
@@ -12,34 +12,13 @@
1212

1313
#include "xenia/cpu/hir/instr.h"
1414

15-
#include <unordered_map>
16-
1715
namespace xe {
1816
namespace cpu {
1917
namespace backend {
2018
namespace x64 {
2119

2220
class X64Emitter;
2321

24-
typedef bool (*SequenceSelectFn)(X64Emitter&, const hir::Instr*);
25-
extern std::unordered_map<uint32_t, SequenceSelectFn> sequence_table;
26-
27-
template <typename T>
28-
bool Register() {
29-
sequence_table.insert({T::head_key(), T::Select});
30-
return true;
31-
}
32-
33-
template <typename T, typename Tn, typename... Ts>
34-
static bool Register() {
35-
bool b = true;
36-
b = b && Register<T>(); // Call the above function
37-
b = b && Register<Tn, Ts...>(); // Call ourself again (recursively)
38-
return b;
39-
}
40-
#define EMITTER_OPCODE_TABLE(name, ...) \
41-
const auto X64_INSTR_##name = Register<__VA_ARGS__>();
42-
4322
bool SelectSequence(X64Emitter* e, const hir::Instr* i,
4423
const hir::Instr** new_tail);
4524

0 commit comments

Comments
 (0)