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