xref: /freebsd/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrShiftRotate.td (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1//===-- M68kInstrShiftRotate.td - Logical Instrs -----------*- tablegen -*-===//
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 describes the logical instructions in the M68k architecture.
11/// Here is the current status of the file:
12///
13///  Machine:
14///
15///    SHL     [~]   ASR     [~]   LSR      [~]   SWAP     [ ]
16///    ROL     [~]   ROR     [~]   ROXL     [ ]   ROXR     [ ]
17///
18///  Map:
19///
20///   [ ] - was not touched at all
21///   [!] - requires extarnal stuff implemented
22///   [~] - in progress but usable
23///   [x] - done
24///
25//===----------------------------------------------------------------------===//
26
27defvar MxROKind_R = true;
28defvar MxROKind_I = false;
29
30defvar MxRODI_R = false;
31defvar MxRODI_L = true;
32
33defvar MxROOP_AS  = 0b00;
34defvar MxROOP_LS  = 0b01;
35defvar MxROOP_ROX = 0b10;
36defvar MxROOP_RO  = 0b11;
37
38/// ------------+---------+---+------+---+------+---------
39///  F  E  D  C | B  A  9 | 8 | 7  6 | 5 | 4  3 | 2  1  0
40/// ------------+---------+---+------+---+------+---------
41///  1  1  1  0 | REG/IMM | D | SIZE |R/I|  OP  |   REG
42/// ------------+---------+---+------+---+------+---------
43class MxSREncoding<bit kind, string src_opnd, string dst_opnd,
44                   bit direction, bits<2> ro_op, MxEncSize size> {
45  dag Value = (descend 0b1110,
46    // REG/IMM
47    (operand "$"#src_opnd, 3),
48    direction, size.Value, kind, ro_op,
49    // REG
50    (operand "$"#dst_opnd, 3)
51  );
52}
53
54// $reg <- $reg op $reg
55class MxSR_DD<string MN, MxType TYPE, SDNode NODE, bit RODI, bits<2> ROOP>
56    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
57             MN#"."#TYPE.Prefix#"\t$opd, $dst",
58             [(set TYPE.VT:$dst, (NODE TYPE.VT:$src, TYPE.VT:$opd))]> {
59  let Inst = MxSREncoding<MxROKind_R, "opd", "dst", RODI, ROOP,
60                          !cast<MxEncSize>("MxEncSize"#TYPE.Size)>.Value;
61}
62
63// $reg <- $reg op $imm
64class MxSR_DI<string MN, MxType TYPE, SDNode NODE, bit RODI, bits<2> ROOP>
65    : MxInst<(outs TYPE.ROp:$dst),
66             (ins TYPE.ROp:$src, !cast<Operand>("Mxi"#TYPE.Size#"imm"):$opd),
67             MN#"."#TYPE.Prefix#"\t$opd, $dst",
68             [(set TYPE.VT:$dst,
69                   (NODE TYPE.VT:$src,
70                         !cast<ImmLeaf>("Mximm"#TYPE.Size#"_1to8"):$opd))]> {
71  let Inst = MxSREncoding<MxROKind_I, "opd", "dst", RODI, ROOP,
72                          !cast<MxEncSize>("MxEncSize"#TYPE.Size)>.Value;
73}
74
75multiclass MxSROp<string MN, SDNode NODE, bit RODI, bits<2> ROOP> {
76
77  let Defs = [CCR] in {
78  let Constraints = "$src = $dst" in {
79
80  def NAME#"8dd"  : MxSR_DD<MN, MxType8d,  NODE, RODI, ROOP>;
81  def NAME#"16dd" : MxSR_DD<MN, MxType16d, NODE, RODI, ROOP>;
82  def NAME#"32dd" : MxSR_DD<MN, MxType32d, NODE, RODI, ROOP>;
83
84  def NAME#"8di"  : MxSR_DI<MN, MxType8d,  NODE, RODI, ROOP>;
85  def NAME#"16di" : MxSR_DI<MN, MxType16d, NODE, RODI, ROOP>;
86  def NAME#"32di" : MxSR_DI<MN, MxType32d, NODE, RODI, ROOP>;
87
88  } // $src = $dst
89  } // Defs = [CCR]
90
91} // MxBiArOp_RF
92
93defm SHL : MxSROp<"lsl", shl, MxRODI_L, MxROOP_LS>;
94defm LSR : MxSROp<"lsr", srl, MxRODI_R, MxROOP_LS>;
95defm ASR : MxSROp<"asr", sra, MxRODI_R, MxROOP_AS>;
96
97defm ROL : MxSROp<"rol", rotl, MxRODI_L, MxROOP_RO>;
98defm ROR : MxSROp<"ror", rotr, MxRODI_R, MxROOP_RO>;
99