xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrCompiler.td (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
1*04eeddc0SDimitry Andric//===-- M68kInstrCompiler.td - Pseudos and Patterns --------*- tablegen -*-===//
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 describes the various pseudo instructions used by the compiler,
11fe6060f1SDimitry Andric/// as well as Pat patterns used during instruction selection.
12fe6060f1SDimitry Andric///
13fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
14fe6060f1SDimitry Andric
15fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
16fe6060f1SDimitry Andric// ConstantPool, GlobalAddress, ExternalSymbol, and JumpTable
17fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
18fe6060f1SDimitry Andric
19fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapper tconstpool    :$src)), (MOV32ri tconstpool    :$src)>;
20fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapper tglobaladdr   :$src)), (MOV32ri tglobaladdr   :$src)>;
21fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapper texternalsym  :$src)), (MOV32ri texternalsym  :$src)>;
22fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapper tjumptable    :$src)), (MOV32ri tjumptable    :$src)>;
23fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapper tblockaddress :$src)), (MOV32ri tblockaddress :$src)>;
24fe6060f1SDimitry Andric
25fe6060f1SDimitry Andricdef : Pat<(add MxDRD32:$src, (MxWrapper tconstpool:$opd)),
26349cc55cSDimitry Andric          (ADD32di MxDRD32:$src, tconstpool:$opd)>;
27fe6060f1SDimitry Andricdef : Pat<(add MxARD32:$src, (MxWrapper tjumptable:$opd)),
28349cc55cSDimitry Andric          (ADD32ai MxARD32:$src, tjumptable:$opd)>;
29fe6060f1SDimitry Andricdef : Pat<(add MxARD32:$src, (MxWrapper tglobaladdr :$opd)),
30349cc55cSDimitry Andric          (ADD32ai MxARD32:$src, tglobaladdr:$opd)>;
31fe6060f1SDimitry Andricdef : Pat<(add MxARD32:$src, (MxWrapper texternalsym:$opd)),
32349cc55cSDimitry Andric          (ADD32ai MxARD32:$src, texternalsym:$opd)>;
33fe6060f1SDimitry Andricdef : Pat<(add MxARD32:$src, (MxWrapper tblockaddress:$opd)),
34349cc55cSDimitry Andric          (ADD32ai MxARD32:$src, tblockaddress:$opd)>;
35fe6060f1SDimitry Andric
36fe6060f1SDimitry Andricdef : Pat<(store (i32 (MxWrapper tglobaladdr:$src)), iPTR:$dst),
37fe6060f1SDimitry Andric          (MOV32ji MxARI32:$dst, tglobaladdr:$src)>;
38fe6060f1SDimitry Andricdef : Pat<(store (i32 (MxWrapper texternalsym:$src)), iPTR:$dst),
39fe6060f1SDimitry Andric          (MOV32ji MxARI32:$dst, texternalsym:$src)>;
40fe6060f1SDimitry Andricdef : Pat<(store (i32 (MxWrapper tblockaddress:$src)), iPTR:$dst),
41fe6060f1SDimitry Andric          (MOV32ji MxARI32:$dst, tblockaddress:$src)>;
42fe6060f1SDimitry Andric
43fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapperPC tconstpool    :$src)), (LEA32q tconstpool    :$src)>;
44fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapperPC tglobaladdr   :$src)), (LEA32q tglobaladdr   :$src)>;
45fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapperPC texternalsym  :$src)), (LEA32q texternalsym  :$src)>;
46fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapperPC tjumptable    :$src)), (LEA32q tjumptable    :$src)>;
47fe6060f1SDimitry Andricdef : Pat<(i32 (MxWrapperPC tblockaddress :$src)), (LEA32q tblockaddress :$src)>;
48fe6060f1SDimitry Andric
49fe6060f1SDimitry Andric
50fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
51fe6060f1SDimitry Andric// Conditional Move Pseudo Instructions
52fe6060f1SDimitry Andric//
53fe6060f1SDimitry Andric// CMOV* - Used to implement the SELECT DAG operation. Expanded after
54fe6060f1SDimitry Andric// instruction selection into a branch sequence.
55fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
56fe6060f1SDimitry Andric
57fe6060f1SDimitry Andriclet usesCustomInserter = 1, Uses = [CCR] in
58fe6060f1SDimitry Andricclass MxCMove<MxType TYPE>
59fe6060f1SDimitry Andric    : MxPseudo<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$t, TYPE.ROp:$f, i8imm:$cond),
60fe6060f1SDimitry Andric               [(set TYPE.VT:$dst,
61fe6060f1SDimitry Andric                     (TYPE.VT (MxCmov TYPE.VT:$t, TYPE.VT:$f, imm:$cond, CCR)))]>;
62fe6060f1SDimitry Andric
63fe6060f1SDimitry Andricdef CMOV8d  : MxCMove<MxType8d>;
64fe6060f1SDimitry Andricdef CMOV16d : MxCMove<MxType16d>;
65fe6060f1SDimitry Andricdef CMOV32r : MxCMove<MxType32r>;
66fe6060f1SDimitry Andric
67fe6060f1SDimitry Andric
68fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
69fe6060f1SDimitry Andric// Calls
70fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
71fe6060f1SDimitry Andric
72fe6060f1SDimitry Andric// ADJCALLSTACKDOWN/UP implicitly use/def %SP because they may be expanded into
73fe6060f1SDimitry Andric// a stack adjustment and the codegen must know that they may modify the stack
74fe6060f1SDimitry Andric// pointer before prolog-epilog rewriting occurs.
75fe6060f1SDimitry Andric// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
76fe6060f1SDimitry Andric// sub / add which can clobber CCR.
77fe6060f1SDimitry Andriclet Defs = [SP, CCR], Uses = [SP] in {
78fe6060f1SDimitry Andric
79fe6060f1SDimitry Andric  def ADJCALLSTACKDOWN
80fe6060f1SDimitry Andric    : MxPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
81fe6060f1SDimitry Andric               [(MxCallSeqStart timm:$amt1, timm:$amt2)]>;
82fe6060f1SDimitry Andric
83fe6060f1SDimitry Andric  def ADJCALLSTACKUP
84fe6060f1SDimitry Andric    : MxPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
85fe6060f1SDimitry Andric               [(MxCallSeqEnd timm:$amt1, timm:$amt2)]>;
86fe6060f1SDimitry Andric
87fe6060f1SDimitry Andric} // Defs
88fe6060f1SDimitry Andric
89fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
90fe6060f1SDimitry Andric// Tail Call
91fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
92fe6060f1SDimitry Andric
93fe6060f1SDimitry Andric// Tailcall stuff. The TCRETURN instructions execute after the epilog, so they
94fe6060f1SDimitry Andric// can never use callee-saved registers. That is the purpose of the XR32_TC
95fe6060f1SDimitry Andric// register classes.
96fe6060f1SDimitry Andric
97fe6060f1SDimitry Andric// FIXME TC is disabled for PIC mode because the global base
98fe6060f1SDimitry Andric// register which is part of the address mode may be assigned a
99fe6060f1SDimitry Andric// callee-saved register.
100fe6060f1SDimitry Andricdef : Pat<(MxTCRet (load MxCP_ARII:$dst), imm:$adj),
101fe6060f1SDimitry Andric          (TCRETURNj (MOV32af_TC MxARII32:$dst), imm:$adj)>,
102fe6060f1SDimitry Andric      Requires<[IsNotPIC]>;
103fe6060f1SDimitry Andric
104fe6060f1SDimitry Andricdef : Pat<(MxTCRet AR32_TC:$dst, imm:$adj),
105fe6060f1SDimitry Andric          (TCRETURNj MxARI32_TC:$dst, imm:$adj)>;
106fe6060f1SDimitry Andric
107fe6060f1SDimitry Andricdef : Pat<(MxTCRet (i32 tglobaladdr:$dst), imm:$adj),
108fe6060f1SDimitry Andric          (TCRETURNq MxPCD32:$dst, imm:$adj)>;
109fe6060f1SDimitry Andric
110fe6060f1SDimitry Andricdef : Pat<(MxTCRet (i32 texternalsym:$dst), imm:$adj),
111fe6060f1SDimitry Andric          (TCRETURNq MxPCD32:$dst, imm:$adj)>;
112fe6060f1SDimitry Andric
113fe6060f1SDimitry Andric
114fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
115fe6060f1SDimitry Andric// Segmented Stack
116fe6060f1SDimitry Andric//
117fe6060f1SDimitry Andric// When using segmented stacks these are lowered into instructions which first
118fe6060f1SDimitry Andric// check if the current stacklet has enough free memory. If it does, memory is
119fe6060f1SDimitry Andric// allocated by bumping the stack pointer. Otherwise memory is allocated from
120fe6060f1SDimitry Andric// the heap.
121fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
122fe6060f1SDimitry Andric
123fe6060f1SDimitry Andriclet Defs = [SP, CCR], Uses = [SP] in
124fe6060f1SDimitry Andriclet usesCustomInserter = 1 in
125fe6060f1SDimitry Andricdef SALLOCA : MxPseudo<(outs MxARD32:$dst), (ins MxARD32:$size),
126fe6060f1SDimitry Andric                       [(set iPTR:$dst, (MxSegAlloca iPTR:$size))]>;
127