Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrInfo.cpp
35266 views
1
//===-- M68kInstrInfo.cpp - M68k Instruction Information --------*- 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
/// \file
10
/// This file contains the M68k declaration of the TargetInstrInfo class.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "M68kInstrInfo.h"
15
16
#include "M68kInstrBuilder.h"
17
#include "M68kMachineFunction.h"
18
#include "M68kTargetMachine.h"
19
#include "MCTargetDesc/M68kMCCodeEmitter.h"
20
21
#include "llvm/ADT/STLExtras.h"
22
#include "llvm/ADT/ScopeExit.h"
23
#include "llvm/CodeGen/LivePhysRegs.h"
24
#include "llvm/CodeGen/LiveVariables.h"
25
#include "llvm/CodeGen/MachineInstrBuilder.h"
26
#include "llvm/CodeGen/MachineRegisterInfo.h"
27
#include "llvm/MC/TargetRegistry.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Support/Regex.h"
30
31
#include <functional>
32
33
using namespace llvm;
34
35
#define DEBUG_TYPE "M68k-instr-info"
36
37
#define GET_INSTRINFO_CTOR_DTOR
38
#include "M68kGenInstrInfo.inc"
39
40
// Pin the vtable to this file.
41
void M68kInstrInfo::anchor() {}
42
43
M68kInstrInfo::M68kInstrInfo(const M68kSubtarget &STI)
44
: M68kGenInstrInfo(M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0,
45
M68k::RET),
46
Subtarget(STI), RI(STI) {}
47
48
static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc) {
49
switch (BrOpc) {
50
default:
51
return M68k::COND_INVALID;
52
case M68k::Beq8:
53
return M68k::COND_EQ;
54
case M68k::Bne8:
55
return M68k::COND_NE;
56
case M68k::Blt8:
57
return M68k::COND_LT;
58
case M68k::Ble8:
59
return M68k::COND_LE;
60
case M68k::Bgt8:
61
return M68k::COND_GT;
62
case M68k::Bge8:
63
return M68k::COND_GE;
64
case M68k::Bcs8:
65
return M68k::COND_CS;
66
case M68k::Bls8:
67
return M68k::COND_LS;
68
case M68k::Bhi8:
69
return M68k::COND_HI;
70
case M68k::Bcc8:
71
return M68k::COND_CC;
72
case M68k::Bmi8:
73
return M68k::COND_MI;
74
case M68k::Bpl8:
75
return M68k::COND_PL;
76
case M68k::Bvs8:
77
return M68k::COND_VS;
78
case M68k::Bvc8:
79
return M68k::COND_VC;
80
}
81
}
82
83
bool M68kInstrInfo::AnalyzeBranchImpl(MachineBasicBlock &MBB,
84
MachineBasicBlock *&TBB,
85
MachineBasicBlock *&FBB,
86
SmallVectorImpl<MachineOperand> &Cond,
87
bool AllowModify) const {
88
89
auto UncondBranch =
90
std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{
91
MBB.rend(), nullptr};
92
93
// Erase any instructions if allowed at the end of the scope.
94
std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList;
95
auto FinalizeOnReturn = llvm::make_scope_exit([&EraseList] {
96
std::for_each(EraseList.begin(), EraseList.end(),
97
[](auto &ref) { ref.get().eraseFromParent(); });
98
});
99
100
// Start from the bottom of the block and work up, examining the
101
// terminator instructions.
102
for (auto iter = MBB.rbegin(); iter != MBB.rend(); iter = std::next(iter)) {
103
104
unsigned Opcode = iter->getOpcode();
105
106
if (iter->isDebugInstr())
107
continue;
108
109
// Working from the bottom, when we see a non-terminator instruction, we're
110
// done.
111
if (!isUnpredicatedTerminator(*iter))
112
break;
113
114
// A terminator that isn't a branch can't easily be handled by this
115
// analysis.
116
if (!iter->isBranch())
117
return true;
118
119
// Handle unconditional branches.
120
if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) {
121
if (!iter->getOperand(0).isMBB())
122
return true;
123
UncondBranch = {iter, iter->getOperand(0).getMBB()};
124
125
// TBB is used to indicate the unconditional destination.
126
TBB = UncondBranch.second;
127
128
if (!AllowModify)
129
continue;
130
131
// If the block has any instructions after a JMP, erase them.
132
EraseList.insert(EraseList.begin(), MBB.rbegin(), iter);
133
134
Cond.clear();
135
FBB = nullptr;
136
137
// Erase the JMP if it's equivalent to a fall-through.
138
if (MBB.isLayoutSuccessor(UncondBranch.second)) {
139
TBB = nullptr;
140
EraseList.push_back(*iter);
141
UncondBranch = {MBB.rend(), nullptr};
142
}
143
144
continue;
145
}
146
147
// Handle conditional branches.
148
auto BranchCode = M68k::GetCondFromBranchOpc(Opcode);
149
150
// Can't handle indirect branch.
151
if (BranchCode == M68k::COND_INVALID)
152
return true;
153
154
// In practice we should never have an undef CCR operand, if we do
155
// abort here as we are not prepared to preserve the flag.
156
// ??? Is this required?
157
// if (iter->getOperand(1).isUndef())
158
// return true;
159
160
// Working from the bottom, handle the first conditional branch.
161
if (Cond.empty()) {
162
if (!iter->getOperand(0).isMBB())
163
return true;
164
MachineBasicBlock *CondBranchTarget = iter->getOperand(0).getMBB();
165
166
// If we see something like this:
167
//
168
// bcc l1
169
// bra l2
170
// ...
171
// l1:
172
// ...
173
// l2:
174
if (UncondBranch.first != MBB.rend()) {
175
176
assert(std::next(UncondBranch.first) == iter && "Wrong block layout.");
177
178
// And we are allowed to modify the block and the target block of the
179
// conditional branch is the direct successor of this block:
180
//
181
// bcc l1
182
// bra l2
183
// l1:
184
// ...
185
// l2:
186
//
187
// we change it to this if allowed:
188
//
189
// bncc l2
190
// l1:
191
// ...
192
// l2:
193
//
194
// Which is a bit more efficient.
195
if (AllowModify && MBB.isLayoutSuccessor(CondBranchTarget)) {
196
197
BranchCode = GetOppositeBranchCondition(BranchCode);
198
unsigned BNCC = GetCondBranchFromCond(BranchCode);
199
200
BuildMI(MBB, *UncondBranch.first, MBB.rfindDebugLoc(iter), get(BNCC))
201
.addMBB(UncondBranch.second);
202
203
EraseList.push_back(*iter);
204
EraseList.push_back(*UncondBranch.first);
205
206
TBB = UncondBranch.second;
207
FBB = nullptr;
208
Cond.push_back(MachineOperand::CreateImm(BranchCode));
209
210
// Otherwise preserve TBB, FBB and Cond as requested
211
} else {
212
TBB = CondBranchTarget;
213
FBB = UncondBranch.second;
214
Cond.push_back(MachineOperand::CreateImm(BranchCode));
215
}
216
217
UncondBranch = {MBB.rend(), nullptr};
218
continue;
219
}
220
221
TBB = CondBranchTarget;
222
FBB = nullptr;
223
Cond.push_back(MachineOperand::CreateImm(BranchCode));
224
225
continue;
226
}
227
228
// Handle subsequent conditional branches. Only handle the case where all
229
// conditional branches branch to the same destination and their condition
230
// opcodes fit one of the special multi-branch idioms.
231
assert(Cond.size() == 1);
232
assert(TBB);
233
234
// If the conditions are the same, we can leave them alone.
235
auto OldBranchCode = static_cast<M68k::CondCode>(Cond[0].getImm());
236
if (!iter->getOperand(0).isMBB())
237
return true;
238
auto NewTBB = iter->getOperand(0).getMBB();
239
if (OldBranchCode == BranchCode && TBB == NewTBB)
240
continue;
241
242
// If they differ we cannot do much here.
243
return true;
244
}
245
246
return false;
247
}
248
249
bool M68kInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
250
MachineBasicBlock *&TBB,
251
MachineBasicBlock *&FBB,
252
SmallVectorImpl<MachineOperand> &Cond,
253
bool AllowModify) const {
254
return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify);
255
}
256
257
unsigned M68kInstrInfo::removeBranch(MachineBasicBlock &MBB,
258
int *BytesRemoved) const {
259
assert(!BytesRemoved && "code size not handled");
260
261
MachineBasicBlock::iterator I = MBB.end();
262
unsigned Count = 0;
263
264
while (I != MBB.begin()) {
265
--I;
266
if (I->isDebugValue())
267
continue;
268
if (I->getOpcode() != M68k::BRA8 &&
269
getCondFromBranchOpc(I->getOpcode()) == M68k::COND_INVALID)
270
break;
271
// Remove the branch.
272
I->eraseFromParent();
273
I = MBB.end();
274
++Count;
275
}
276
277
return Count;
278
}
279
280
unsigned M68kInstrInfo::insertBranch(
281
MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
282
ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
283
// Shouldn't be a fall through.
284
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
285
assert((Cond.size() == 1 || Cond.size() == 0) &&
286
"M68k branch conditions have one component!");
287
assert(!BytesAdded && "code size not handled");
288
289
if (Cond.empty()) {
290
// Unconditional branch?
291
assert(!FBB && "Unconditional branch with multiple successors!");
292
BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(TBB);
293
return 1;
294
}
295
296
// If FBB is null, it is implied to be a fall-through block.
297
bool FallThru = FBB == nullptr;
298
299
// Conditional branch.
300
unsigned Count = 0;
301
M68k::CondCode CC = (M68k::CondCode)Cond[0].getImm();
302
unsigned Opc = GetCondBranchFromCond(CC);
303
BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
304
++Count;
305
if (!FallThru) {
306
// Two-way Conditional branch. Insert the second branch.
307
BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(FBB);
308
++Count;
309
}
310
return Count;
311
}
312
313
void M68kInstrInfo::AddSExt(MachineBasicBlock &MBB,
314
MachineBasicBlock::iterator I, DebugLoc DL,
315
unsigned Reg, MVT From, MVT To) const {
316
if (From == MVT::i8) {
317
unsigned R = Reg;
318
// EXT16 requires i16 register
319
if (To == MVT::i32) {
320
R = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
321
assert(R && "No viable SUB register available");
322
}
323
BuildMI(MBB, I, DL, get(M68k::EXT16), R).addReg(R);
324
}
325
326
if (To == MVT::i32)
327
BuildMI(MBB, I, DL, get(M68k::EXT32), Reg).addReg(Reg);
328
}
329
330
void M68kInstrInfo::AddZExt(MachineBasicBlock &MBB,
331
MachineBasicBlock::iterator I, DebugLoc DL,
332
unsigned Reg, MVT From, MVT To) const {
333
334
unsigned Mask, And;
335
if (From == MVT::i8)
336
Mask = 0xFF;
337
else
338
Mask = 0xFFFF;
339
340
if (To == MVT::i16)
341
And = M68k::AND16di;
342
else // i32
343
And = M68k::AND32di;
344
345
// TODO use xor r,r to decrease size
346
BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask);
347
}
348
349
// Convert MOVI to MOVQ if the target is a data register and the immediate
350
// fits in a sign-extended i8, otherwise emit a plain MOV.
351
bool M68kInstrInfo::ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const {
352
Register Reg = MIB->getOperand(0).getReg();
353
int64_t Imm = MIB->getOperand(1).getImm();
354
bool IsAddressReg = false;
355
356
const auto *DR32 = RI.getRegClass(M68k::DR32RegClassID);
357
const auto *AR32 = RI.getRegClass(M68k::AR32RegClassID);
358
const auto *AR16 = RI.getRegClass(M68k::AR16RegClassID);
359
360
if (AR16->contains(Reg) || AR32->contains(Reg))
361
IsAddressReg = true;
362
363
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
364
365
if (MVTSize == MVT::i8 || (!IsAddressReg && Imm >= -128 && Imm <= 127)) {
366
LLVM_DEBUG(dbgs() << "MOVEQ\n");
367
368
// We need to assign to the full register to make IV happy
369
Register SReg =
370
MVTSize == MVT::i32 ? Reg : Register(RI.getMatchingMegaReg(Reg, DR32));
371
assert(SReg && "No viable MEGA register available");
372
373
MIB->setDesc(get(M68k::MOVQ));
374
MIB->getOperand(0).setReg(SReg);
375
} else {
376
LLVM_DEBUG(dbgs() << "MOVE\n");
377
MIB->setDesc(get(MVTSize == MVT::i16 ? M68k::MOV16ri : M68k::MOV32ri));
378
}
379
380
return true;
381
}
382
383
bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,
384
MVT MVTSrc) const {
385
unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
386
Register Dst = MIB->getOperand(0).getReg();
387
Register Src = MIB->getOperand(1).getReg();
388
389
assert(Dst != Src && "You cannot use the same Regs with MOVX_RR");
390
391
const auto &TRI = getRegisterInfo();
392
393
const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
394
const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
395
396
assert(RCDst && RCSrc && "Wrong use of MOVX_RR");
397
assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");
398
(void)RCSrc;
399
400
// We need to find the super source register that matches the size of Dst
401
unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
402
assert(SSrc && "No viable MEGA register available");
403
404
DebugLoc DL = MIB->getDebugLoc();
405
406
// If it happens to that super source register is the destination register
407
// we do nothing
408
if (Dst == SSrc) {
409
LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');
410
MIB->eraseFromParent();
411
} else { // otherwise we need to MOV
412
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");
413
MIB->setDesc(get(Move));
414
MIB->getOperand(1).setReg(SSrc);
415
}
416
417
return true;
418
}
419
420
/// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two
421
/// different registers or just EXT if it is the same register
422
bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
423
MVT MVTDst, MVT MVTSrc) const {
424
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
425
426
unsigned Move;
427
428
if (MVTDst == MVT::i16)
429
Move = M68k::MOV16rr;
430
else // i32
431
Move = M68k::MOV32rr;
432
433
Register Dst = MIB->getOperand(0).getReg();
434
Register Src = MIB->getOperand(1).getReg();
435
436
assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR");
437
438
const auto &TRI = getRegisterInfo();
439
440
const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
441
const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
442
443
assert(RCDst && RCSrc && "Wrong use of MOVSX_RR");
444
assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");
445
(void)RCSrc;
446
447
// We need to find the super source register that matches the size of Dst
448
unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
449
assert(SSrc && "No viable MEGA register available");
450
451
MachineBasicBlock &MBB = *MIB->getParent();
452
DebugLoc DL = MIB->getDebugLoc();
453
454
if (Dst != SSrc) {
455
LLVM_DEBUG(dbgs() << "Move and " << '\n');
456
BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
457
}
458
459
if (IsSigned) {
460
LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
461
AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
462
} else {
463
LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
464
AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
465
}
466
467
MIB->eraseFromParent();
468
469
return true;
470
}
471
472
bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
473
const MCInstrDesc &Desc, MVT MVTDst,
474
MVT MVTSrc) const {
475
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");
476
477
Register Dst = MIB->getOperand(0).getReg();
478
479
// We need the subreg of Dst to make instruction verifier happy because the
480
// real machine instruction consumes and produces values of the same size and
481
// the registers the will be used here fall into different classes and this
482
// makes IV cry. We could use a bigger operation, but this will put some
483
// pressure on cache and memory, so no.
484
unsigned SubDst =
485
RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
486
: M68k::MxSubRegIndex16Lo);
487
assert(SubDst && "No viable SUB register available");
488
489
// Make this a plain move
490
MIB->setDesc(Desc);
491
MIB->getOperand(0).setReg(SubDst);
492
493
MachineBasicBlock::iterator I = MIB.getInstr();
494
I++;
495
MachineBasicBlock &MBB = *MIB->getParent();
496
DebugLoc DL = MIB->getDebugLoc();
497
498
if (IsSigned) {
499
LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
500
AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
501
} else {
502
LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
503
AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
504
}
505
506
return true;
507
}
508
509
bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,
510
const MCInstrDesc &Desc, bool IsPush) const {
511
MachineBasicBlock::iterator I = MIB.getInstr();
512
I++;
513
MachineBasicBlock &MBB = *MIB->getParent();
514
MachineOperand MO = MIB->getOperand(0);
515
DebugLoc DL = MIB->getDebugLoc();
516
if (IsPush)
517
BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO);
518
else
519
BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister());
520
521
MIB->eraseFromParent();
522
return true;
523
}
524
525
bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
526
527
// Replace the pseudo instruction with the real one
528
if (IsToCCR)
529
MIB->setDesc(get(M68k::MOV16cd));
530
else
531
// FIXME M68010 or later is required
532
MIB->setDesc(get(M68k::MOV16dc));
533
534
// Promote used register to the next class
535
auto &Opd = MIB->getOperand(1);
536
Opd.setReg(getRegisterInfo().getMatchingSuperReg(
537
Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
538
539
return true;
540
}
541
542
bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB,
543
const MCInstrDesc &Desc, bool IsRM) const {
544
int Reg = 0, Offset = 0, Base = 0;
545
auto XR32 = RI.getRegClass(M68k::XR32RegClassID);
546
auto DL = MIB->getDebugLoc();
547
auto MI = MIB.getInstr();
548
auto &MBB = *MIB->getParent();
549
550
if (IsRM) {
551
Reg = MIB->getOperand(0).getReg();
552
Offset = MIB->getOperand(1).getImm();
553
Base = MIB->getOperand(2).getReg();
554
} else {
555
Offset = MIB->getOperand(0).getImm();
556
Base = MIB->getOperand(1).getReg();
557
Reg = MIB->getOperand(2).getReg();
558
}
559
560
// If the register is not in XR32 then it is smaller than 32 bit, we
561
// implicitly promote it to 32
562
if (!XR32->contains(Reg)) {
563
Reg = RI.getMatchingMegaReg(Reg, XR32);
564
assert(Reg && "Has not meaningful MEGA register");
565
}
566
567
unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);
568
if (IsRM) {
569
BuildMI(MBB, MI, DL, Desc)
570
.addImm(Mask)
571
.addImm(Offset)
572
.addReg(Base)
573
.addReg(Reg, RegState::ImplicitDefine)
574
.copyImplicitOps(*MIB);
575
} else {
576
BuildMI(MBB, MI, DL, Desc)
577
.addImm(Offset)
578
.addReg(Base)
579
.addImm(Mask)
580
.addReg(Reg, RegState::Implicit)
581
.copyImplicitOps(*MIB);
582
}
583
584
MIB->eraseFromParent();
585
586
return true;
587
}
588
589
/// Expand a single-def pseudo instruction to a two-addr
590
/// instruction with two undef reads of the register being defined.
591
/// This is used for mapping:
592
/// %d0 = SETCS_C32d
593
/// to:
594
/// %d0 = SUBX32dd %d0<undef>, %d0<undef>
595
///
596
static bool Expand2AddrUndef(MachineInstrBuilder &MIB,
597
const MCInstrDesc &Desc) {
598
assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");
599
Register Reg = MIB->getOperand(0).getReg();
600
MIB->setDesc(Desc);
601
602
// MachineInstr::addOperand() will insert explicit operands before any
603
// implicit operands.
604
MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef);
605
// But we don't trust that.
606
assert(MIB->getOperand(1).getReg() == Reg &&
607
MIB->getOperand(2).getReg() == Reg && "Misplaced operand");
608
return true;
609
}
610
611
bool M68kInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
612
MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
613
switch (MI.getOpcode()) {
614
case M68k::PUSH8d:
615
return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true);
616
case M68k::PUSH16d:
617
return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true);
618
case M68k::PUSH32r:
619
return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true);
620
621
case M68k::POP8d:
622
return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false);
623
case M68k::POP16d:
624
return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false);
625
case M68k::POP32r:
626
return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false);
627
628
case M68k::SETCS_C8d:
629
return Expand2AddrUndef(MIB, get(M68k::SUBX8dd));
630
case M68k::SETCS_C16d:
631
return Expand2AddrUndef(MIB, get(M68k::SUBX16dd));
632
case M68k::SETCS_C32d:
633
return Expand2AddrUndef(MIB, get(M68k::SUBX32dd));
634
}
635
return false;
636
}
637
638
bool M68kInstrInfo::isPCRelRegisterOperandLegal(
639
const MachineOperand &MO) const {
640
assert(MO.isReg());
641
642
// Check whether this MO belongs to an instruction with addressing mode 'k',
643
// Refer to TargetInstrInfo.h for more information about this function.
644
645
const MachineInstr *MI = MO.getParent();
646
const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()];
647
StringRef InstrName(&M68kInstrNameData[NameIndices]);
648
const unsigned OperandNo = MO.getOperandNo();
649
650
// If this machine operand is the 2nd operand, then check
651
// whether the instruction has destination addressing mode 'k'.
652
if (OperandNo == 1)
653
return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName);
654
655
// If this machine operand is the last one, then check
656
// whether the instruction has source addressing mode 'k'.
657
if (OperandNo == MI->getNumExplicitOperands() - 1)
658
return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName);
659
660
return false;
661
}
662
663
void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
664
MachineBasicBlock::iterator MI,
665
const DebugLoc &DL, MCRegister DstReg,
666
MCRegister SrcReg, bool KillSrc) const {
667
unsigned Opc = 0;
668
669
// First deal with the normal symmetric copies.
670
if (M68k::XR32RegClass.contains(DstReg, SrcReg))
671
Opc = M68k::MOV32rr;
672
else if (M68k::XR16RegClass.contains(DstReg, SrcReg))
673
Opc = M68k::MOV16rr;
674
else if (M68k::DR8RegClass.contains(DstReg, SrcReg))
675
Opc = M68k::MOV8dd;
676
677
if (Opc) {
678
BuildMI(MBB, MI, DL, get(Opc), DstReg)
679
.addReg(SrcReg, getKillRegState(KillSrc));
680
return;
681
}
682
683
// Now deal with asymmetrically sized copies. The cases that follow are upcast
684
// moves.
685
//
686
// NOTE
687
// These moves are not aware of type nature of these values and thus
688
// won't do any SExt or ZExt and upper bits will basically contain garbage.
689
MachineInstrBuilder MIB(*MBB.getParent(), MI);
690
if (M68k::DR8RegClass.contains(SrcReg)) {
691
if (M68k::XR16RegClass.contains(DstReg))
692
Opc = M68k::MOVXd16d8;
693
else if (M68k::XR32RegClass.contains(DstReg))
694
Opc = M68k::MOVXd32d8;
695
} else if (M68k::XR16RegClass.contains(SrcReg) &&
696
M68k::XR32RegClass.contains(DstReg))
697
Opc = M68k::MOVXd32d16;
698
699
if (Opc) {
700
BuildMI(MBB, MI, DL, get(Opc), DstReg)
701
.addReg(SrcReg, getKillRegState(KillSrc));
702
return;
703
}
704
705
bool FromCCR = SrcReg == M68k::CCR;
706
bool FromSR = SrcReg == M68k::SR;
707
bool ToCCR = DstReg == M68k::CCR;
708
bool ToSR = DstReg == M68k::SR;
709
710
if (FromCCR) {
711
assert(M68k::DR8RegClass.contains(DstReg) &&
712
"Need DR8 register to copy CCR");
713
Opc = M68k::MOV8dc;
714
} else if (ToCCR) {
715
assert(M68k::DR8RegClass.contains(SrcReg) &&
716
"Need DR8 register to copy CCR");
717
Opc = M68k::MOV8cd;
718
} else if (FromSR || ToSR)
719
llvm_unreachable("Cannot emit SR copy instruction");
720
721
if (Opc) {
722
BuildMI(MBB, MI, DL, get(Opc), DstReg)
723
.addReg(SrcReg, getKillRegState(KillSrc));
724
return;
725
}
726
727
LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to "
728
<< RI.getName(DstReg) << '\n');
729
llvm_unreachable("Cannot emit physreg copy instruction");
730
}
731
732
namespace {
733
unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,
734
const TargetRegisterInfo *TRI,
735
const M68kSubtarget &STI, bool load) {
736
switch (TRI->getRegSizeInBits(*RC)) {
737
default:
738
llvm_unreachable("Unknown spill size");
739
case 8:
740
if (M68k::DR8RegClass.hasSubClassEq(RC))
741
return load ? M68k::MOV8dp : M68k::MOV8pd;
742
if (M68k::CCRCRegClass.hasSubClassEq(RC))
743
return load ? M68k::MOV16cp : M68k::MOV16pc;
744
745
llvm_unreachable("Unknown 1-byte regclass");
746
case 16:
747
assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass");
748
return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
749
case 32:
750
assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass");
751
return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
752
}
753
}
754
755
unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,
756
const TargetRegisterInfo *TRI,
757
const M68kSubtarget &STI) {
758
return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);
759
}
760
761
unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC,
762
const TargetRegisterInfo *TRI,
763
const M68kSubtarget &STI) {
764
return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true);
765
}
766
} // end anonymous namespace
767
768
bool M68kInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
769
unsigned SubIdx, unsigned &Size,
770
unsigned &Offset,
771
const MachineFunction &MF) const {
772
// The slot size must be the maximum size so we can easily use MOVEM.L
773
Size = 4;
774
Offset = 0;
775
return true;
776
}
777
778
void M68kInstrInfo::storeRegToStackSlot(
779
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
780
bool IsKill, int FrameIndex, const TargetRegisterClass *RC,
781
const TargetRegisterInfo *TRI, Register VReg) const {
782
const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
783
assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
784
"Stack slot is too small to store");
785
(void)MFI;
786
787
unsigned Opc = getStoreRegOpcode(SrcReg, RC, TRI, Subtarget);
788
DebugLoc DL = MBB.findDebugLoc(MI);
789
// (0,FrameIndex) <- $reg
790
M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)
791
.addReg(SrcReg, getKillRegState(IsKill));
792
}
793
794
void M68kInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
795
MachineBasicBlock::iterator MI,
796
Register DstReg, int FrameIndex,
797
const TargetRegisterClass *RC,
798
const TargetRegisterInfo *TRI,
799
Register VReg) const {
800
const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
801
assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
802
"Stack slot is too small to load");
803
(void)MFI;
804
805
unsigned Opc = getLoadRegOpcode(DstReg, RC, TRI, Subtarget);
806
DebugLoc DL = MBB.findDebugLoc(MI);
807
M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex);
808
}
809
810
/// Return a virtual register initialized with the global base register
811
/// value. Output instructions required to initialize the register in the
812
/// function entry block, if necessary.
813
///
814
/// TODO Move this function to M68kMachineFunctionInfo.
815
unsigned M68kInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
816
M68kMachineFunctionInfo *MxFI = MF->getInfo<M68kMachineFunctionInfo>();
817
unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
818
if (GlobalBaseReg != 0)
819
return GlobalBaseReg;
820
821
// Create the register. The code to initialize it is inserted later,
822
// by the M68kGlobalBaseReg pass (below).
823
//
824
// NOTE
825
// Normally M68k uses A5 register as global base pointer but this will
826
// create unnecessary spill if we use less then 4 registers in code; since A5
827
// is callee-save anyway we could try to allocate caller-save first and if
828
// lucky get one, otherwise it does not really matter which callee-save to
829
// use.
830
MachineRegisterInfo &RegInfo = MF->getRegInfo();
831
GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
832
MxFI->setGlobalBaseReg(GlobalBaseReg);
833
return GlobalBaseReg;
834
}
835
836
std::pair<unsigned, unsigned>
837
M68kInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
838
return std::make_pair(TF, 0u);
839
}
840
841
ArrayRef<std::pair<unsigned, const char *>>
842
M68kInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
843
using namespace M68kII;
844
static const std::pair<unsigned, const char *> TargetFlags[] = {
845
{MO_ABSOLUTE_ADDRESS, "m68k-absolute"},
846
{MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"},
847
{MO_GOT, "m68k-got"},
848
{MO_GOTOFF, "m68k-gotoff"},
849
{MO_GOTPCREL, "m68k-gotpcrel"},
850
{MO_PLT, "m68k-plt"},
851
{MO_TLSGD, "m68k-tlsgd"},
852
{MO_TLSLD, "m68k-tlsld"},
853
{MO_TLSLDM, "m68k-tlsldm"},
854
{MO_TLSIE, "m68k-tlsie"},
855
{MO_TLSLE, "m68k-tlsle"}};
856
return ArrayRef(TargetFlags);
857
}
858
859
#undef DEBUG_TYPE
860
#define DEBUG_TYPE "m68k-create-global-base-reg"
861
862
#define PASS_NAME "M68k PIC Global Base Reg Initialization"
863
864
namespace {
865
/// This initializes the PIC global base register
866
struct M68kGlobalBaseReg : public MachineFunctionPass {
867
static char ID;
868
M68kGlobalBaseReg() : MachineFunctionPass(ID) {}
869
870
bool runOnMachineFunction(MachineFunction &MF) override {
871
const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
872
M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>();
873
874
unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
875
876
// If we didn't need a GlobalBaseReg, don't insert code.
877
if (GlobalBaseReg == 0)
878
return false;
879
880
// Insert the set of GlobalBaseReg into the first MBB of the function
881
MachineBasicBlock &FirstMBB = MF.front();
882
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
883
DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
884
const M68kInstrInfo *TII = STI.getInstrInfo();
885
886
// Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
887
BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
888
.addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
889
890
return true;
891
}
892
893
void getAnalysisUsage(AnalysisUsage &AU) const override {
894
AU.setPreservesCFG();
895
MachineFunctionPass::getAnalysisUsage(AU);
896
}
897
};
898
char M68kGlobalBaseReg::ID = 0;
899
} // namespace
900
901
INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false)
902
903
FunctionPass *llvm::createM68kGlobalBaseRegPass() {
904
return new M68kGlobalBaseReg();
905
}
906
907