llvm-project

Форк
0
674 строки · 27.0 Кб
1
//===-- TargetTest.cpp -----------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8

9
#include "Target.h"
10

11
#include <cassert>
12
#include <memory>
13

14
#include "MCTargetDesc/X86MCTargetDesc.h"
15
#include "MmapUtils.h"
16
#include "SubprocessMemory.h"
17
#include "llvm/MC/TargetRegistry.h"
18
#include "llvm/Support/TargetSelect.h"
19
#include "gmock/gmock.h"
20
#include "gtest/gtest.h"
21

22
#include "llvm/MC/MCInstPrinter.h"
23

24
#ifdef __linux__
25
#include <sys/mman.h>
26
#include <sys/syscall.h>
27
#endif // __linux__
28

29
namespace llvm {
30

31
bool operator==(const MCOperand &a, const MCOperand &b) {
32
  if (a.isImm() && b.isImm())
33
    return a.getImm() == b.getImm();
34
  if (a.isReg() && b.isReg())
35
    return a.getReg() == b.getReg();
36
  return false;
37
}
38

39
bool operator==(const MCInst &a, const MCInst &b) {
40
  if (a.getOpcode() != b.getOpcode())
41
    return false;
42
  if (a.getNumOperands() != b.getNumOperands())
43
    return false;
44
  for (unsigned I = 0; I < a.getNumOperands(); ++I) {
45
    if (!(a.getOperand(I) == b.getOperand(I)))
46
      return false;
47
  }
48
  return true;
49
}
50

51
} // namespace llvm
52

53
namespace llvm {
54
namespace exegesis {
55

56
void InitializeX86ExegesisTarget();
57

58
namespace {
59

60
using testing::AllOf;
61
using testing::ElementsAre;
62
using testing::ElementsAreArray;
63
using testing::Eq;
64
using testing::IsEmpty;
65
using testing::Matcher;
66
using testing::Property;
67

68
Matcher<MCOperand> IsImm(int64_t Value) {
69
  return AllOf(Property(&MCOperand::isImm, Eq(true)),
70
               Property(&MCOperand::getImm, Eq(Value)));
71
}
72

73
Matcher<MCOperand> IsReg(unsigned Reg) {
74
  return AllOf(Property(&MCOperand::isReg, Eq(true)),
75
               Property(&MCOperand::getReg, Eq(Reg)));
76
}
77

78
Matcher<MCInst> OpcodeIs(unsigned Opcode) {
79
  return Property(&MCInst::getOpcode, Eq(Opcode));
80
}
81

82
Matcher<MCInst> IsMovImmediate(unsigned Opcode, int64_t Reg, int64_t Value) {
83
  return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg), IsImm(Value)));
84
}
85

86
#ifdef __linux__
87
Matcher<MCInst> IsMovRegToReg(unsigned Opcode, int64_t Reg1, int64_t Reg2) {
88
  return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg1), IsReg(Reg2)));
89
}
90
#endif
91

92
Matcher<MCInst> IsMovValueToStack(unsigned Opcode, int64_t Value,
93
                                  size_t Offset) {
94
  return AllOf(OpcodeIs(Opcode),
95
               ElementsAre(IsReg(X86::RSP), IsImm(1), IsReg(0), IsImm(Offset),
96
                           IsReg(0), IsImm(Value)));
97
}
98

99
Matcher<MCInst> IsMovValueFromStack(unsigned Opcode, unsigned Reg) {
100
  return AllOf(OpcodeIs(Opcode),
101
               ElementsAre(IsReg(Reg), IsReg(X86::RSP), IsImm(1), IsReg(0),
102
                           IsImm(0), IsReg(0)));
103
}
104

105
Matcher<MCInst> IsStackAllocate(unsigned Size) {
106
  return AllOf(OpcodeIs(X86::SUB64ri8),
107
               ElementsAre(IsReg(X86::RSP), IsReg(X86::RSP), IsImm(Size)));
108
}
109

110
Matcher<MCInst> IsStackDeallocate(unsigned Size) {
111
  return AllOf(OpcodeIs(X86::ADD64ri8),
112
               ElementsAre(IsReg(X86::RSP), IsReg(X86::RSP), IsImm(Size)));
113
}
114

115
constexpr const char kTriple[] = "x86_64-unknown-linux";
116

117
class X86TargetTest : public ::testing::Test {
118
protected:
119
  X86TargetTest(const char *Features)
120
      : State(cantFail(LLVMState::Create(kTriple, "core2", Features))) {}
121

122
  static void SetUpTestCase() {
123
    LLVMInitializeX86TargetInfo();
124
    LLVMInitializeX86Target();
125
    LLVMInitializeX86TargetMC();
126
    InitializeX86ExegesisTarget();
127
  }
128

129
  std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) {
130
    return State.getExegesisTarget().setRegTo(State.getSubtargetInfo(), Reg,
131
                                              Value);
132
  }
133

134
  const Instruction &getInstr(unsigned OpCode) {
135
    return State.getIC().getInstr(OpCode);
136
  }
137

138
  LLVMState State;
139
};
140

141
class X86Core2TargetTest : public X86TargetTest {
142
public:
143
  X86Core2TargetTest() : X86TargetTest("") {}
144
};
145

146
class X86Core2AvxTargetTest : public X86TargetTest {
147
public:
148
  X86Core2AvxTargetTest() : X86TargetTest("+avx") {}
149
};
150

151
class X86Core2Avx512TargetTest : public X86TargetTest {
152
public:
153
  X86Core2Avx512TargetTest() : X86TargetTest("+avx512vl") {}
154
};
155

156
class X86Core2Avx512DQTargetTest : public X86TargetTest {
157
public:
158
  X86Core2Avx512DQTargetTest() : X86TargetTest("+avx512dq") {}
159
};
160

161
class X86Core2Avx512BWTargetTest : public X86TargetTest {
162
public:
163
  X86Core2Avx512BWTargetTest() : X86TargetTest("+avx512bw") {}
164
};
165

166
class X86Core2Avx512DQBWTargetTest : public X86TargetTest {
167
public:
168
  X86Core2Avx512DQBWTargetTest() : X86TargetTest("+avx512dq,+avx512bw") {}
169
};
170

171
TEST_F(X86Core2TargetTest, NoHighByteRegs) {
172
  EXPECT_TRUE(State.getRATC().reservedRegisters().test(X86::AH));
173
}
174

175
TEST_F(X86Core2TargetTest, SetFlags) {
176
  const unsigned Reg = X86::EFLAGS;
177
  EXPECT_THAT(setRegTo(Reg, APInt(64, 0x1111222233334444ULL)),
178
              ElementsAre(IsStackAllocate(8),
179
                          IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),
180
                          IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),
181
                          OpcodeIs(X86::POPF64)));
182
}
183

184
TEST_F(X86Core2TargetTest, SetRegToGR8Value) {
185
  const uint8_t Value = 0xFFU;
186
  const unsigned Reg = X86::AL;
187
  EXPECT_THAT(setRegTo(Reg, APInt(8, Value)),
188
              ElementsAre(IsMovImmediate(X86::MOV8ri, Reg, Value)));
189
}
190

191
TEST_F(X86Core2TargetTest, SetRegToGR16Value) {
192
  const uint16_t Value = 0xFFFFU;
193
  const unsigned Reg = X86::BX;
194
  EXPECT_THAT(setRegTo(Reg, APInt(16, Value)),
195
              ElementsAre(IsMovImmediate(X86::MOV16ri, Reg, Value)));
196
}
197

198
TEST_F(X86Core2TargetTest, SetRegToGR32Value) {
199
  const uint32_t Value = 0x7FFFFU;
200
  const unsigned Reg = X86::ECX;
201
  EXPECT_THAT(setRegTo(Reg, APInt(32, Value)),
202
              ElementsAre(IsMovImmediate(X86::MOV32ri, Reg, Value)));
203
}
204

205
TEST_F(X86Core2TargetTest, SetRegToGR64Value) {
206
  const uint64_t Value = 0x7FFFFFFFFFFFFFFFULL;
207
  const unsigned Reg = X86::RDX;
208
  EXPECT_THAT(setRegTo(Reg, APInt(64, Value)),
209
              ElementsAre(IsMovImmediate(X86::MOV64ri, Reg, Value)));
210
}
211

212
TEST_F(X86Core2TargetTest, SetRegToVR64Value) {
213
  EXPECT_THAT(setRegTo(X86::MM0, APInt(64, 0x1111222233334444ULL)),
214
              ElementsAre(IsStackAllocate(8),
215
                          IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),
216
                          IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),
217
                          IsMovValueFromStack(X86::MMX_MOVQ64rm, X86::MM0),
218
                          IsStackDeallocate(8)));
219
}
220

221
TEST_F(X86Core2TargetTest, SetRegToVR128Value_Use_MOVDQUrm) {
222
  EXPECT_THAT(
223
      setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),
224
      ElementsAre(IsStackAllocate(16),
225
                  IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),
226
                  IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),
227
                  IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),
228
                  IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),
229
                  IsMovValueFromStack(X86::MOVDQUrm, X86::XMM0),
230
                  IsStackDeallocate(16)));
231
}
232

233
TEST_F(X86Core2AvxTargetTest, SetRegToVR128Value_Use_VMOVDQUrm) {
234
  EXPECT_THAT(
235
      setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),
236
      ElementsAre(IsStackAllocate(16),
237
                  IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),
238
                  IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),
239
                  IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),
240
                  IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),
241
                  IsMovValueFromStack(X86::VMOVDQUrm, X86::XMM0),
242
                  IsStackDeallocate(16)));
243
}
244

245
TEST_F(X86Core2Avx512TargetTest, SetRegToVR128Value_Use_VMOVDQU32Z128rm) {
246
  EXPECT_THAT(
247
      setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),
248
      ElementsAre(IsStackAllocate(16),
249
                  IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),
250
                  IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),
251
                  IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),
252
                  IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),
253
                  IsMovValueFromStack(X86::VMOVDQU32Z128rm, X86::XMM0),
254
                  IsStackDeallocate(16)));
255
}
256

257
TEST_F(X86Core2AvxTargetTest, SetRegToVR256Value_Use_VMOVDQUYrm) {
258
  const char ValueStr[] =
259
      "1111111122222222333333334444444455555555666666667777777788888888";
260
  EXPECT_THAT(
261
      setRegTo(X86::YMM0, APInt(256, ValueStr, 16)),
262
      ElementsAreArray({IsStackAllocate(32),
263
                        IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),
264
                        IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),
265
                        IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),
266
                        IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),
267
                        IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),
268
                        IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),
269
                        IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),
270
                        IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),
271
                        IsMovValueFromStack(X86::VMOVDQUYrm, X86::YMM0),
272
                        IsStackDeallocate(32)}));
273
}
274

275
TEST_F(X86Core2Avx512TargetTest, SetRegToVR256Value_Use_VMOVDQU32Z256rm) {
276
  const char ValueStr[] =
277
      "1111111122222222333333334444444455555555666666667777777788888888";
278
  EXPECT_THAT(
279
      setRegTo(X86::YMM0, APInt(256, ValueStr, 16)),
280
      ElementsAreArray({IsStackAllocate(32),
281
                        IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),
282
                        IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),
283
                        IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),
284
                        IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),
285
                        IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),
286
                        IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),
287
                        IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),
288
                        IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),
289
                        IsMovValueFromStack(X86::VMOVDQU32Z256rm, X86::YMM0),
290
                        IsStackDeallocate(32)}));
291
}
292

293
TEST_F(X86Core2Avx512TargetTest, SetRegToVR512Value) {
294
  const char ValueStr[] =
295
      "1111111122222222333333334444444455555555666666667777777788888888"
296
      "99999999AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFF00000000";
297
  EXPECT_THAT(
298
      setRegTo(X86::ZMM0, APInt(512, ValueStr, 16)),
299
      ElementsAreArray({IsStackAllocate(64),
300
                        IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 0),
301
                        IsMovValueToStack(X86::MOV32mi, 0xFFFFFFFFUL, 4),
302
                        IsMovValueToStack(X86::MOV32mi, 0xEEEEEEEEUL, 8),
303
                        IsMovValueToStack(X86::MOV32mi, 0xDDDDDDDDUL, 12),
304
                        IsMovValueToStack(X86::MOV32mi, 0xCCCCCCCCUL, 16),
305
                        IsMovValueToStack(X86::MOV32mi, 0xBBBBBBBBUL, 20),
306
                        IsMovValueToStack(X86::MOV32mi, 0xAAAAAAAAUL, 24),
307
                        IsMovValueToStack(X86::MOV32mi, 0x99999999UL, 28),
308
                        IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 32),
309
                        IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 36),
310
                        IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 40),
311
                        IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 44),
312
                        IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 48),
313
                        IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 52),
314
                        IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 56),
315
                        IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 60),
316
                        IsMovValueFromStack(X86::VMOVDQU32Zrm, X86::ZMM0),
317
                        IsStackDeallocate(64)}));
318
}
319

320
TEST_F(X86Core2Avx512TargetTest, SetRegToK0_16Bits) {
321
  const uint16_t Value = 0xABCDU;
322
  const unsigned Reg = X86::K0;
323
  const unsigned RegBitWidth = 16;
324
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
325
              ElementsAre(IsStackAllocate(2),
326
                          IsMovValueToStack(X86::MOV16mi, Value, 0),
327
                          IsMovValueFromStack(X86::KMOVWkm, Reg),
328
                          IsStackDeallocate(2)));
329
}
330

331
TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_16Bits) {
332
  const uint16_t Value = 0xABCDU;
333
  const unsigned Reg = X86::K0;
334
  const unsigned RegBitWidth = 16;
335
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
336
              ElementsAre(IsStackAllocate(2),
337
                          IsMovValueToStack(X86::MOV16mi, Value, 0),
338
                          IsMovValueFromStack(X86::KMOVWkm, Reg),
339
                          IsStackDeallocate(2)));
340
}
341

342
TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_16Bits) {
343
  const uint16_t Value = 0xABCDU;
344
  const unsigned Reg = X86::K0;
345
  const unsigned RegBitWidth = 16;
346
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
347
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
348
                          IsMovValueToStack(X86::MOV16mi, Value, 0),
349
                          IsMovValueFromStack(X86::KMOVWkm, Reg),
350
                          IsStackDeallocate(RegBitWidth / 8)));
351
}
352

353
TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_16Bits) {
354
  const uint16_t Value = 0xABCDU;
355
  const unsigned Reg = X86::K0;
356
  const unsigned RegBitWidth = 16;
357
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
358
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
359
                          IsMovValueToStack(X86::MOV16mi, Value, 0),
360
                          IsMovValueFromStack(X86::KMOVWkm, Reg),
361
                          IsStackDeallocate(RegBitWidth / 8)));
362
}
363

364
TEST_F(X86Core2Avx512TargetTest, SetRegToK0_8Bits) {
365
  const uint8_t Value = 0xABU;
366
  const unsigned Reg = X86::K0;
367
  const unsigned RegBitWidth = 8;
368
  EXPECT_THAT(
369
      setRegTo(Reg, APInt(RegBitWidth, Value)),
370
      ElementsAre(IsStackAllocate(2),
371
                  IsMovValueToStack(
372
                      X86::MOV16mi,
373
                      APInt(RegBitWidth, Value).zext(16).getZExtValue(), 0),
374
                  IsMovValueFromStack(X86::KMOVWkm, Reg),
375
                  IsStackDeallocate(2)));
376
}
377

378
TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_8Bits) {
379
  const uint8_t Value = 0xABU;
380
  const unsigned Reg = X86::K0;
381
  const unsigned RegBitWidth = 8;
382
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
383
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
384
                          IsMovValueToStack(X86::MOV8mi, Value, 0),
385
                          IsMovValueFromStack(X86::KMOVBkm, Reg),
386
                          IsStackDeallocate(RegBitWidth / 8)));
387
}
388

389
TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_8Bits) {
390
  const uint8_t Value = 0xABU;
391
  const unsigned Reg = X86::K0;
392
  const unsigned RegBitWidth = 8;
393
  EXPECT_THAT(
394
      setRegTo(Reg, APInt(RegBitWidth, Value)),
395
      ElementsAre(IsStackAllocate(2),
396
                  IsMovValueToStack(
397
                      X86::MOV16mi,
398
                      APInt(RegBitWidth, Value).zext(16).getZExtValue(), 0),
399
                  IsMovValueFromStack(X86::KMOVWkm, Reg),
400
                  IsStackDeallocate(2)));
401
}
402

403
TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_8Bits) {
404
  const uint8_t Value = 0xABU;
405
  const unsigned Reg = X86::K0;
406
  const unsigned RegBitWidth = 8;
407
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
408
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
409
                          IsMovValueToStack(X86::MOV8mi, Value, 0),
410
                          IsMovValueFromStack(X86::KMOVBkm, Reg),
411
                          IsStackDeallocate(RegBitWidth / 8)));
412
}
413

414
TEST_F(X86Core2Avx512TargetTest, SetRegToK0_32Bits) {
415
  const uint32_t Value = 0xABCDCABDU;
416
  const unsigned Reg = X86::K0;
417
  const unsigned RegBitWidth = 32;
418
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
419
}
420

421
TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_32Bits) {
422
  const uint32_t Value = 0xABCDCABDU;
423
  const unsigned Reg = X86::K0;
424
  const unsigned RegBitWidth = 32;
425
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
426
}
427

428
TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_32Bits) {
429
  const uint32_t Value = 0xABCDCABDU;
430
  const unsigned Reg = X86::K0;
431
  const unsigned RegBitWidth = 32;
432
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
433
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
434
                          IsMovValueToStack(X86::MOV32mi, Value, 0),
435
                          IsMovValueFromStack(X86::KMOVDkm, Reg),
436
                          IsStackDeallocate(RegBitWidth / 8)));
437
}
438

439
TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_32Bits) {
440
  const uint32_t Value = 0xABCDCABDU;
441
  const unsigned Reg = X86::K0;
442
  const unsigned RegBitWidth = 32;
443
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
444
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
445
                          IsMovValueToStack(X86::MOV32mi, Value, 0),
446
                          IsMovValueFromStack(X86::KMOVDkm, Reg),
447
                          IsStackDeallocate(RegBitWidth / 8)));
448
}
449

450
TEST_F(X86Core2Avx512TargetTest, SetRegToK0_64Bits) {
451
  const uint64_t Value = 0xABCDABCDCABDCABDU;
452
  const unsigned Reg = X86::K0;
453
  const unsigned RegBitWidth = 64;
454
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
455
}
456

457
TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_64Bits) {
458
  const uint64_t Value = 0xABCDABCDCABDCABDU;
459
  const unsigned Reg = X86::K0;
460
  const unsigned RegBitWidth = 64;
461
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
462
}
463

464
TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_64Bits) {
465
  const uint64_t Value = 0xABCDABCDCABDCABDUL;
466
  const unsigned Reg = X86::K0;
467
  const unsigned RegBitWidth = 64;
468
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
469
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
470
                          IsMovValueToStack(X86::MOV32mi, 0XCABDCABDUL, 0),
471
                          IsMovValueToStack(X86::MOV32mi, 0xABCDABCDUL, 4),
472
                          IsMovValueFromStack(X86::KMOVQkm, Reg),
473
                          IsStackDeallocate(RegBitWidth / 8)));
474
}
475

476
TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_64Bits) {
477
  const uint64_t Value = 0xABCDABCDCABDCABDU;
478
  const unsigned Reg = X86::K0;
479
  const unsigned RegBitWidth = 64;
480
  EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
481
              ElementsAre(IsStackAllocate(RegBitWidth / 8),
482
                          IsMovValueToStack(X86::MOV32mi, 0XCABDCABDUL, 0),
483
                          IsMovValueToStack(X86::MOV32mi, 0xABCDABCDUL, 4),
484
                          IsMovValueFromStack(X86::KMOVQkm, Reg),
485
                          IsStackDeallocate(RegBitWidth / 8)));
486
}
487

488
// Note: We always put 80 bits on the stack independently of the size of the
489
// value. This uses a bit more space but makes the code simpler.
490

491
TEST_F(X86Core2TargetTest, SetRegToST0_32Bits) {
492
  EXPECT_THAT(setRegTo(X86::ST0, APInt(32, 0x11112222ULL)),
493
              ElementsAre(IsStackAllocate(10),
494
                          IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),
495
                          IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
496
                          IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
497
                          OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));
498
}
499

500
TEST_F(X86Core2TargetTest, SetRegToST1_32Bits) {
501
  const MCInst CopySt0ToSt1 = MCInstBuilder(X86::ST_Frr).addReg(X86::ST1);
502
  EXPECT_THAT(setRegTo(X86::ST1, APInt(32, 0x11112222ULL)),
503
              ElementsAre(IsStackAllocate(10),
504
                          IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),
505
                          IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
506
                          IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
507
                          OpcodeIs(X86::LD_F80m), CopySt0ToSt1,
508
                          IsStackDeallocate(10)));
509
}
510

511
TEST_F(X86Core2TargetTest, SetRegToST0_64Bits) {
512
  EXPECT_THAT(setRegTo(X86::ST0, APInt(64, 0x1111222233334444ULL)),
513
              ElementsAre(IsStackAllocate(10),
514
                          IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),
515
                          IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),
516
                          IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
517
                          OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));
518
}
519

520
TEST_F(X86Core2TargetTest, SetRegToST0_80Bits) {
521
  EXPECT_THAT(setRegTo(X86::ST0, APInt(80, "11112222333344445555", 16)),
522
              ElementsAre(IsStackAllocate(10),
523
                          IsMovValueToStack(X86::MOV32mi, 0x44445555UL, 0),
524
                          IsMovValueToStack(X86::MOV32mi, 0x22223333UL, 4),
525
                          IsMovValueToStack(X86::MOV16mi, 0x1111UL, 8),
526
                          OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));
527
}
528

529
TEST_F(X86Core2TargetTest, SetRegToFP0_80Bits) {
530
  EXPECT_THAT(setRegTo(X86::FP0, APInt(80, "11112222333344445555", 16)),
531
              ElementsAre(IsStackAllocate(10),
532
                          IsMovValueToStack(X86::MOV32mi, 0x44445555UL, 0),
533
                          IsMovValueToStack(X86::MOV32mi, 0x22223333UL, 4),
534
                          IsMovValueToStack(X86::MOV16mi, 0x1111UL, 8),
535
                          OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));
536
}
537

538
TEST_F(X86Core2TargetTest, SetRegToFP1_32Bits) {
539
  EXPECT_THAT(setRegTo(X86::FP1, APInt(32, 0x11112222ULL)),
540
              ElementsAre(IsStackAllocate(10),
541
                          IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),
542
                          IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
543
                          IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
544
                          OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));
545
}
546

547
TEST_F(X86Core2TargetTest, SetRegToFP1_4Bits) {
548
  EXPECT_THAT(setRegTo(X86::FP1, APInt(4, 0x1ULL)),
549
              ElementsAre(IsStackAllocate(10),
550
                          IsMovValueToStack(X86::MOV32mi, 0x00000001UL, 0),
551
                          IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
552
                          IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
553
                          OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));
554
}
555

556
TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) {
557
  const Instruction &I = getInstr(X86::ADD64rm);
558
  InstructionTemplate IT(&I);
559
  constexpr const int kOffset = 42;
560
  State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);
561
  // Memory is operands 2-6.
562
  EXPECT_THAT(IT.getValueFor(I.Operands[2]), IsReg(X86::RDI));
563
  EXPECT_THAT(IT.getValueFor(I.Operands[3]), IsImm(1));
564
  EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(0));
565
  EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(kOffset));
566
  EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0));
567
}
568

569
TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_VGATHERDPSZ128rm) {
570
  const Instruction &I = getInstr(X86::VGATHERDPSZ128rm);
571
  InstructionTemplate IT(&I);
572
  constexpr const int kOffset = 42;
573
  State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);
574
  // Memory is operands 4-8.
575
  EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(X86::RDI));
576
  EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(1));
577
  EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0));
578
  EXPECT_THAT(IT.getValueFor(I.Operands[7]), IsImm(kOffset));
579
  EXPECT_THAT(IT.getValueFor(I.Operands[8]), IsReg(0));
580
}
581

582
TEST_F(X86Core2TargetTest, AllowAsBackToBack) {
583
  EXPECT_TRUE(
584
      State.getExegesisTarget().allowAsBackToBack(getInstr(X86::ADD64rr)));
585
  EXPECT_FALSE(
586
      State.getExegesisTarget().allowAsBackToBack(getInstr(X86::LEA64r)));
587
}
588

589
#ifdef __linux__
590
TEST_F(X86Core2TargetTest, GenerateLowerMunmapTest) {
591
  std::vector<MCInst> GeneratedCode;
592
  State.getExegesisTarget().generateLowerMunmap(GeneratedCode);
593
  EXPECT_THAT(GeneratedCode,
594
              ElementsAre(IsMovImmediate(X86::MOV64ri, X86::RDI, 0),
595
                          OpcodeIs(X86::LEA64r), OpcodeIs(X86::SHR64ri),
596
                          OpcodeIs(X86::SHL64ri), OpcodeIs(X86::SUB64ri32),
597
                          IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_munmap),
598
                          OpcodeIs(X86::SYSCALL)));
599
}
600

601
#ifdef __arm__
602
static constexpr const intptr_t VAddressSpaceCeiling = 0xC0000000;
603
#else
604
static constexpr const intptr_t VAddressSpaceCeiling = 0x0000800000000000;
605
#endif
606

607
TEST_F(X86Core2TargetTest, GenerateUpperMunmapTest) {
608
  std::vector<MCInst> GeneratedCode;
609
  State.getExegesisTarget().generateUpperMunmap(GeneratedCode);
610
  EXPECT_THAT(
611
      GeneratedCode,
612
      ElementsAreArray({OpcodeIs(X86::LEA64r), OpcodeIs(X86::MOV64rr),
613
                        OpcodeIs(X86::ADD64rr), OpcodeIs(X86::SHR64ri),
614
                        OpcodeIs(X86::SHL64ri), OpcodeIs(X86::ADD64ri32),
615
                        IsMovImmediate(X86::MOV64ri, X86::RSI,
616
                                       VAddressSpaceCeiling - getpagesize()),
617
                        OpcodeIs(X86::SUB64rr),
618
                        IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_munmap),
619
                        OpcodeIs(X86::SYSCALL)}));
620
}
621

622
TEST_F(X86Core2TargetTest, GenerateExitSyscallTest) {
623
  EXPECT_THAT(State.getExegesisTarget().generateExitSyscall(127),
624
              ElementsAre(IsMovImmediate(X86::MOV64ri, X86::RDI, 127),
625
                          IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_exit),
626
                          OpcodeIs(X86::SYSCALL)));
627
}
628

629
TEST_F(X86Core2TargetTest, GenerateMmapTest) {
630
  EXPECT_THAT(State.getExegesisTarget().generateMmap(0x1000, 4096, 0x2000),
631
              ElementsAre(IsMovImmediate(X86::MOV64ri, X86::RDI, 0x1000),
632
                          IsMovImmediate(X86::MOV64ri, X86::RSI, 4096),
633
                          IsMovImmediate(X86::MOV64ri, X86::RDX,
634
                                         PROT_READ | PROT_WRITE),
635
                          IsMovImmediate(X86::MOV64ri, X86::R10,
636
                                         MAP_SHARED | MAP_FIXED_NOREPLACE),
637
                          IsMovImmediate(X86::MOV64ri, X86::R8, 0x2000),
638
                          OpcodeIs(X86::MOV32rm),
639
                          IsMovImmediate(X86::MOV64ri, X86::R9, 0),
640
                          IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_mmap),
641
                          OpcodeIs(X86::SYSCALL)));
642
}
643

644
TEST_F(X86Core2TargetTest, GenerateMmapAuxMemTest) {
645
  std::vector<MCInst> GeneratedCode;
646
  State.getExegesisTarget().generateMmapAuxMem(GeneratedCode);
647
  EXPECT_THAT(
648
      GeneratedCode,
649
      ElementsAre(
650
          IsMovImmediate(
651
              X86::MOV64ri, X86::RDI,
652
              State.getExegesisTarget().getAuxiliaryMemoryStartAddress()),
653
          IsMovImmediate(X86::MOV64ri, X86::RSI,
654
                         SubprocessMemory::AuxiliaryMemorySize),
655
          IsMovImmediate(X86::MOV64ri, X86::RDX, PROT_READ | PROT_WRITE),
656
          IsMovImmediate(X86::MOV64ri, X86::R10,
657
                         MAP_SHARED | MAP_FIXED_NOREPLACE),
658
          OpcodeIs(X86::MOV64rr), IsMovImmediate(X86::MOV64ri, X86::R9, 0),
659
          IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_mmap),
660
          OpcodeIs(X86::SYSCALL)));
661
}
662

663
TEST_F(X86Core2TargetTest, MoveArgumentRegistersTest) {
664
  std::vector<MCInst> GeneratedCode;
665
  State.getExegesisTarget().moveArgumentRegisters(GeneratedCode);
666
  EXPECT_THAT(GeneratedCode,
667
              ElementsAre(IsMovRegToReg(X86::MOV64rr, X86::R12, X86::RDI),
668
                          IsMovRegToReg(X86::MOV64rr, X86::R13, X86::RSI)));
669
}
670
#endif // __linux__
671

672
} // namespace
673
} // namespace exegesis
674
} // namespace llvm
675

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.