| //===-- M68kInstrShiftRotate.td - Logical Instrs -----------*- tablegen -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /// | |
| /// \file | |
| /// This file describes the logical instructions in the M68k architecture. | |
| /// Here is the current status of the file: | |
| /// | |
| /// Machine: | |
| /// | |
| /// SHL [~] ASR [~] LSR [~] SWAP [ ] | |
| /// ROL [~] ROR [~] ROXL [ ] ROXR [ ] | |
| /// | |
| /// Map: | |
| /// | |
| /// [ ] - was not touched at all | |
| /// [!] - requires extarnal stuff implemented | |
| /// [~] - in progress but usable | |
| /// [x] - done | |
| /// | |
| //===----------------------------------------------------------------------===// | |
| defvar MxROKind_R = true; | |
| defvar MxROKind_I = false; | |
| defvar MxRODI_R = false; | |
| defvar MxRODI_L = true; | |
| defvar MxROOP_AS = 0b00; | |
| defvar MxROOP_LS = 0b01; | |
| defvar MxROOP_ROX = 0b10; | |
| defvar MxROOP_RO = 0b11; | |
| /// ------------+---------+---+------+---+------+--------- | |
| /// F E D C | B A 9 | 8 | 7 6 | 5 | 4 3 | 2 1 0 | |
| /// ------------+---------+---+------+---+------+--------- | |
| /// 1 1 1 0 | REG/IMM | D | SIZE |R/I| OP | REG | |
| /// ------------+---------+---+------+---+------+--------- | |
| class MxSREncoding<bit kind, string src_opnd, string dst_opnd, | |
| bit direction, bits<2> ro_op, MxNewEncSize size> { | |
| dag Value = (descend 0b1110, | |
| // REG/IMM | |
| (operand "$"#src_opnd, 3), | |
| direction, size.Value, kind, ro_op, | |
| // REG | |
| (operand "$"#dst_opnd, 3) | |
| ); | |
| } | |
| // $reg <- $reg op $reg | |
| class MxSR_DD<string MN, MxType TYPE, SDNode NODE, bit RODI, bits<2> ROOP> | |
| : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd), | |
| MN#"."#TYPE.Prefix#"\t$opd, $dst", | |
| [(set TYPE.VT:$dst, (NODE TYPE.VT:$src, TYPE.VT:$opd))]> { | |
| let Inst = MxSREncoding<MxROKind_R, "opd", "dst", RODI, ROOP, | |
| !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size)>.Value; | |
| } | |
| // $reg <- $reg op $imm | |
| class MxSR_DI<string MN, MxType TYPE, SDNode NODE, bit RODI, bits<2> ROOP> | |
| : MxInst<(outs TYPE.ROp:$dst), | |
| (ins TYPE.ROp:$src, !cast<Operand>("Mxi"#TYPE.Size#"imm"):$opd), | |
| MN#"."#TYPE.Prefix#"\t$opd, $dst", | |
| [(set TYPE.VT:$dst, | |
| (NODE TYPE.VT:$src, | |
| !cast<ImmLeaf>("Mximm"#TYPE.Size#"_1to8"):$opd))]> { | |
| let Inst = MxSREncoding<MxROKind_I, "opd", "dst", RODI, ROOP, | |
| !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size)>.Value; | |
| } | |
| multiclass MxSROp<string MN, SDNode NODE, bit RODI, bits<2> ROOP> { | |
| let Defs = [CCR] in { | |
| let Constraints = "$src = $dst" in { | |
| def NAME#"8dd" : MxSR_DD<MN, MxType8d, NODE, RODI, ROOP>; | |
| def NAME#"16dd" : MxSR_DD<MN, MxType16d, NODE, RODI, ROOP>; | |
| def NAME#"32dd" : MxSR_DD<MN, MxType32d, NODE, RODI, ROOP>; | |
| def NAME#"8di" : MxSR_DI<MN, MxType8d, NODE, RODI, ROOP>; | |
| def NAME#"16di" : MxSR_DI<MN, MxType16d, NODE, RODI, ROOP>; | |
| def NAME#"32di" : MxSR_DI<MN, MxType32d, NODE, RODI, ROOP>; | |
| } // $src = $dst | |
| } // Defs = [CCR] | |
| } // MxBiArOp_RF | |
| defm SHL : MxSROp<"lsl", shl, MxRODI_L, MxROOP_LS>; | |
| defm LSR : MxSROp<"lsr", srl, MxRODI_R, MxROOP_LS>; | |
| defm ASR : MxSROp<"asr", sra, MxRODI_R, MxROOP_AS>; | |
| defm ROL : MxSROp<"rol", rotl, MxRODI_L, MxROOP_RO>; | |
| defm ROR : MxSROp<"ror", rotr, MxRODI_R, MxROOP_RO>; |