1*04eeddc0SDimitry Andric //===-- M68kInstrBuilder.h - Functions to build M68k insts ------*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric ///
9fe6060f1SDimitry Andric /// \file
10fe6060f1SDimitry Andric /// This file exposes functions that may be used with BuildMI from the
11fe6060f1SDimitry Andric /// MachineInstrBuilder.h file to handle M68k'isms in a clean way.
12fe6060f1SDimitry Andric ///
13fe6060f1SDimitry Andric /// TODO The BuildMem function may be used with the BuildMI function to add
14fe6060f1SDimitry Andric /// entire memory references in a single, typed, function call. M68k memory
15fe6060f1SDimitry Andric /// references can be very complex expressions (described in the README), so
16fe6060f1SDimitry Andric /// wrapping them up behind an easier to use interface makes sense.
17fe6060f1SDimitry Andric /// Descriptions of the functions are included below.
18fe6060f1SDimitry Andric ///
19fe6060f1SDimitry Andric /// For reference, the order of operands for memory references is:
20fe6060f1SDimitry Andric /// (Operand), Base, Scale, Index, Displacement.
21fe6060f1SDimitry Andric ///
22fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
23fe6060f1SDimitry Andric //
24fe6060f1SDimitry Andric #ifndef LLVM_LIB_TARGET_M68K_M68KINSTRBUILDER_H
25fe6060f1SDimitry Andric #define LLVM_LIB_TARGET_M68K_M68KINSTRBUILDER_H
26fe6060f1SDimitry Andric
27fe6060f1SDimitry Andric #include "llvm/ADT/SmallVector.h"
28fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
29fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
30fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
31fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
32fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
33fe6060f1SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
34fe6060f1SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
35fe6060f1SDimitry Andric
36fe6060f1SDimitry Andric #include <cassert>
37fe6060f1SDimitry Andric
38fe6060f1SDimitry Andric namespace llvm {
39fe6060f1SDimitry Andric namespace M68k {
40fe6060f1SDimitry Andric static inline const MachineInstrBuilder &
addOffset(const MachineInstrBuilder & MIB,int Offset)41fe6060f1SDimitry Andric addOffset(const MachineInstrBuilder &MIB, int Offset) {
42fe6060f1SDimitry Andric return MIB.addImm(Offset);
43fe6060f1SDimitry Andric }
44fe6060f1SDimitry Andric
45fe6060f1SDimitry Andric /// addRegIndirectWithDisp - This function is used to add a memory reference
46fe6060f1SDimitry Andric /// of the form (Offset, Base), i.e., one with no scale or index, but with a
47fe6060f1SDimitry Andric /// displacement. An example is: (4,D0).
48fe6060f1SDimitry Andric static inline const MachineInstrBuilder &
addRegIndirectWithDisp(const MachineInstrBuilder & MIB,Register Reg,bool IsKill,int Offset)49fe6060f1SDimitry Andric addRegIndirectWithDisp(const MachineInstrBuilder &MIB, Register Reg,
50fe6060f1SDimitry Andric bool IsKill, int Offset) {
51fe6060f1SDimitry Andric return MIB.addImm(Offset).addReg(Reg, getKillRegState(IsKill));
52fe6060f1SDimitry Andric }
53fe6060f1SDimitry Andric
54fe6060f1SDimitry Andric /// addFrameReference - This function is used to add a reference to the base of
55fe6060f1SDimitry Andric /// an abstract object on the stack frame of the current function. This
56fe6060f1SDimitry Andric /// reference has base register as the FrameIndex offset until it is resolved.
57fe6060f1SDimitry Andric /// This allows a constant offset to be specified as well...
58fe6060f1SDimitry Andric static inline const MachineInstrBuilder &
59fe6060f1SDimitry Andric addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0) {
60fe6060f1SDimitry Andric MachineInstr *MI = MIB;
61fe6060f1SDimitry Andric MachineFunction &MF = *MI->getParent()->getParent();
62fe6060f1SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
63fe6060f1SDimitry Andric const MCInstrDesc &MCID = MI->getDesc();
64fe6060f1SDimitry Andric auto Flags = MachineMemOperand::MONone;
65fe6060f1SDimitry Andric if (MCID.mayLoad())
66fe6060f1SDimitry Andric Flags |= MachineMemOperand::MOLoad;
67fe6060f1SDimitry Andric if (MCID.mayStore())
68fe6060f1SDimitry Andric Flags |= MachineMemOperand::MOStore;
69fe6060f1SDimitry Andric MachineMemOperand *MMO = MF.getMachineMemOperand(
70fe6060f1SDimitry Andric MachinePointerInfo::getFixedStack(MF, FI, Offset), Flags,
71fe6060f1SDimitry Andric MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
72fe6060f1SDimitry Andric return MIB.addImm(Offset).addFrameIndex(FI).addMemOperand(MMO);
73fe6060f1SDimitry Andric }
74fe6060f1SDimitry Andric
75fe6060f1SDimitry Andric static inline const MachineInstrBuilder &
76fe6060f1SDimitry Andric addMemOperand(const MachineInstrBuilder &MIB, int FI, int Offset = 0) {
77fe6060f1SDimitry Andric MachineInstr *MI = MIB;
78fe6060f1SDimitry Andric MachineFunction &MF = *MI->getParent()->getParent();
79fe6060f1SDimitry Andric MachineFrameInfo &MFI = MF.getFrameInfo();
80fe6060f1SDimitry Andric const MCInstrDesc &MCID = MI->getDesc();
81fe6060f1SDimitry Andric auto Flags = MachineMemOperand::MONone;
82fe6060f1SDimitry Andric if (MCID.mayLoad())
83fe6060f1SDimitry Andric Flags |= MachineMemOperand::MOLoad;
84fe6060f1SDimitry Andric if (MCID.mayStore())
85fe6060f1SDimitry Andric Flags |= MachineMemOperand::MOStore;
86fe6060f1SDimitry Andric MachineMemOperand *MMO = MF.getMachineMemOperand(
87fe6060f1SDimitry Andric MachinePointerInfo::getFixedStack(MF, FI, Offset), Flags,
88fe6060f1SDimitry Andric MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
89fe6060f1SDimitry Andric return MIB.addMemOperand(MMO);
90fe6060f1SDimitry Andric }
91fe6060f1SDimitry Andric } // end namespace M68k
92fe6060f1SDimitry Andric } // end namespace llvm
93fe6060f1SDimitry Andric
94*04eeddc0SDimitry Andric #endif // LLVM_LIB_TARGET_M68K_M68KINSTRBUILDER_H
95