244 lines · plain
1//===-- M68kInstrFormats.td - M68k Instruction Formats -----*- tablegen -*-===//2// The LLVM Compiler Infrastructure3// 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-exception6//===----------------------------------------------------------------------===//7///8/// \file9/// This file contains M68k instruction formats.10///11/// Since M68k has quite a lot memory addressing modes there are more12/// instruction prefixes than just i, r and m:13/// TSF Since Form Letter Description14/// 00 M68000 Dn or An r any register15/// 01 M68000 Dn d data register direct16/// 02 M68000 An a address register direct17/// 03 M68000 (An) j address register indirect18/// 04 M68000 (An)+ o address register indirect with postincrement19/// 05 M68000 -(An) e address register indirect with predecrement20/// 06 M68000 (d16,An) p address register indirect with displacement21/// 10 M68000 (d8,An,Xn.L) f address register indirect with index and scale = 122/// 07 M68000 (d8,An,Xn.W) F address register indirect with index and scale = 123/// 12 M68020 (d8,An,Xn.L,SCALE) g address register indirect with index24/// 11 M68020 (d8,An,Xn.W,SCALE) G address register indirect with index25/// 14 M68020 ([bd,An],Xn.L,SCALE,od) u memory indirect postindexed mode26/// 13 M68020 ([bd,An],Xn.W,SCALE,od) U memory indirect postindexed mode27/// 16 M68020 ([bd,An,Xn.L,SCALE],od) v memory indirect preindexed mode28/// 15 M68020 ([bd,An,Xn.W,SCALE],od) V memory indirect preindexed mode29/// 20 M68000 abs.L b absolute long address30/// 17 M68000 abs.W B absolute short address31/// 21 M68000 (d16,PC) q program counter with displacement32/// 23 M68000 (d8,PC,Xn.L) k program counter with index and scale = 133/// 22 M68000 (d8,PC,Xn.W) K program counter with index and scale = 134/// 25 M68020 (d8,PC,Xn.L,SCALE) l program counter with index35/// 24 M68020 (d8,PC,Xn.W,SCALE) L program counter with index36/// 27 M68020 ([bd,PC],Xn.L,SCALE,od) x program counter memory indirect postindexed mode37/// 26 M68020 ([bd,PC],Xn.W,SCALE,od) X program counter memory indirect postindexed mode38/// 31 M68020 ([bd,PC,Xn.L,SCALE],od) y program counter memory indirect preindexed mode39/// 30 M68020 ([bd,PC,Xn.W,SCALE],od) Y program counter memory indirect preindexed mode40/// 32 M68000 #immediate i immediate data41///42/// NOTE that long form is always lowercase, word variants are capitalized43///44/// Operand can be qualified with size where appropriate to force a particular45/// instruction encoding, e.g.:46/// (i8,An,Xn.W) f8 1 extension word47/// (i16,An,Xn.W) f16 2 extension words48/// (i32,An,Xn.W) f32 3 extension words49///50/// Form without size qualifier will adapt to operand size automatically, e.g.:51/// (i,An,Xn.W) f 1, 2 or 3 extension words52///53/// Some forms already imply a particular size of their operands, e.g.:54/// (i,An) p 1 extension word and i is 16bit55///56/// Operand order follows x86 Intel order(destination before source), e.g.:57/// MOV8df MOVE (4,A0,D0), D158///59/// Number after instruction mnemonics determines the size of the data60///61//===----------------------------------------------------------------------===//62 63/// ??? Is it possible to use this stuff for disassembling?64/// NOTE 1: In case of conditional beads(DA, DAReg), cond part is able to65/// consume any bit, though a more general instructions must be chosen, e.g.66/// d -> r, a -> r67 68//===----------------------------------------------------------------------===//69// Encoding primitives70//===----------------------------------------------------------------------===//71 72class MxEncMemOp {73 dag EA = (ascend);74 dag Supplement = (ascend);75}76 77class MxEncBriefExt<string reg_opnd, string disp_opnd,78 bit size_w_l = false, int scale = 1,79 string disp_encoder = ""> {80 dag Value = (descend81 // D/A + REGISTER82 (operand "$"#reg_opnd, 4),83 // W/L84 size_w_l,85 // SCALE86 !cond(87 !eq(scale, 1) : 0b00,88 !eq(scale, 2) : 0b01,89 !eq(scale, 4) : 0b10,90 !eq(scale, 8) : 0b1191 ),92 0b0,93 // Displacement94 (operand "$"#disp_opnd, 8, (encoder disp_encoder))95 );96}97 98class MxEncAddrMode_d<string reg_opnd> : MxEncMemOp {99 let EA = (descend /*MODE*/0b000,100 /*REGISTER*/(operand "$"#reg_opnd, 3));101}102 103class MxEncAddrMode_a<string reg_opnd> : MxEncMemOp {104 let EA = (descend /*MODE*/0b001,105 /*REGISTER*/(operand "$"#reg_opnd, 3));106}107 108class MxEncAddrMode_r<string reg_opnd> : MxEncMemOp {109 let EA = (descend /*MODE without the last bit*/0b00,110 /*REGISTER with D/A bit*/(operand "$"#reg_opnd, 4));111}112 113class MxEncAddrMode_k<string opnd_name> : MxEncMemOp {114 let EA = (descend /*MODE*/0b111,115 /*REGISTER*/0b011);116 117 let Supplement = MxEncBriefExt<opnd_name#".index", opnd_name#".disp",118 /*W/L*/true, /*SCALE*/1,119 "encodePCRelImm<8>">.Value;120}121 122class MxEncAddrMode_q<string opnd_name> : MxEncMemOp {123 let EA = (descend /*MODE*/0b111,124 /*REGISTER*/0b010);125 126 // 16-bit Displacement127 let Supplement = (operand "$"#opnd_name, 16,128 (encoder "encodePCRelImm<16>"));129}130 131class MxEncAddrMode_p<string opnd_name> : MxEncMemOp {132 let EA = (descend /*MODE*/0b101,133 /*REGISTER*/(operand "$"#opnd_name#".reg", 3));134 135 // 16-bit Displacement136 let Supplement = (operand "$"#opnd_name#".disp", 16,137 (encoder "encodeRelocImm<16>"));138}139 140class MxEncAddrMode_f<string opnd_name> : MxEncMemOp {141 let EA = (descend /*MODE*/0b110,142 /*REGISTER*/(operand "$"#opnd_name#".reg", 3));143 144 let Supplement = MxEncBriefExt<opnd_name#".index", opnd_name#".disp",145 /*W/L*/true, /*SCALE*/1,146 "encodeRelocImm<8>">.Value;147}148 149class MxEncAddrMode_j<string reg_opnd> : MxEncMemOp {150 let EA = (descend /*MODE*/0b010,151 /*REGISTER*/(operand "$"#reg_opnd, 3));152}153 154class MxEncAddrMode_i<string opnd_name, int size> : MxEncMemOp {155 let EA = (descend /*MODE*/0b111,156 /*REGISTER*/0b100);157 158 // Immediate159 let Supplement =160 !cond(161 !eq(size, 8) : (descend 0b00000000, (operand "$"#opnd_name, 8,162 (encoder "encodeRelocImm<8>"))),163 !eq(size, 16) : (operand "$"#opnd_name, 16,164 (encoder "encodeRelocImm<16>")),165 !eq(size, 32) : (operand "$"#opnd_name, 32,166 (encoder "encodeRelocImm<32>"),167 (decoder "DecodeImm32"))168 );169}170 171// abs.W -> size_w_l = false172// abs.L -> size_w_l = true173class MxEncAddrMode_abs<string opnd_name, bit size_w_l = false> : MxEncMemOp {174 let EA = (descend /*MODE*/0b111,175 // Wrap the REGISTER part in another dag to make sure176 // the dag assigned to EA only has two arguments. Such177 // that it's easier for MOV instructions to reverse178 // on its destination part.179 /*REGISTER*/(descend 0b00, size_w_l));180 181 // Absolute address182 let Supplement = !if(size_w_l,183 // abs.L184 (operand "$"#opnd_name, 32, (encoder "encodeRelocImm<32>"),185 (decoder "DecodeImm32")),186 // abs.W187 (operand "$"#opnd_name, 16, (encoder "encodeRelocImm<16>"))188 );189}190 191class MxEncAddrMode_o<string reg_opnd> : MxEncMemOp {192 let EA = (descend /*MODE*/0b011,193 /*REGISTER*/(operand "$"#reg_opnd, 3));194}195 196class MxEncAddrMode_e<string reg_opnd> : MxEncMemOp {197 let EA = (descend /*MODE*/0b100,198 /*REGISTER*/(operand "$"#reg_opnd, 3));199}200 201class MxEncSize<bits<2> value> {202 bits<2> Value = value;203}204def MxEncSize8 : MxEncSize<0b00>;205def MxEncSize16 : MxEncSize<0b01>;206def MxEncSize32 : MxEncSize<0b10>;207def MxEncSize64 : MxEncSize<0b11>;208 209// M68k INSTRUCTION. Most instructions specify the location of an operand by210// using the effective address field in the operation word. The effective address211// is composed of two 3-bit fields: the mode field and the register field. The212// value in the mode field selects the different address modes. The register213// field contains the number of a register. The effective address field may214// require additional information to fully specify the operand. This additional215// information, called the effective address extension, is contained in the216// following word or words and is considered part of the instruction. The217// effective address modes are grouped into three categories: register direct,218// memory addressing, and special.219class MxInst<dag outs, dag ins,220 string asmStr = "",221 list<dag> pattern = [],222 InstrItinClass itin = NoItinerary>223 : Instruction {224 let Namespace = "M68k";225 let OutOperandList = outs;226 let InOperandList = ins;227 let AsmString = asmStr;228 let Pattern = pattern;229 let Itinerary = itin;230 231 dag Inst = (ascend);232 233 // Number of bytes234 let Size = 0;235 236 let UseLogicalOperandMappings = 1;237}238 239// M68k PSEUDO INSTRUCTION240class MxPseudo<dag outs, dag ins, list<dag> pattern = []>241 : MxInst<outs, ins, "; error: this should not be emitted", pattern> {242 let isPseudo = 1;243}244