aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-04 19:20:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:02:26 +0000
commit81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch)
tree311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td
parent5fff09660e06a66bed6482da9c70df328e16bbb6 (diff)
parent145449b1e420787bb99721a429341fa6be3adfb6 (diff)
downloadsrc-81ad626541db97eb356e2c1d4a20eb2a26a766ab.tar.gz
src-81ad626541db97eb356e2c1d4a20eb2a26a766ab.zip
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td717
1 files changed, 387 insertions, 330 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td
index ef50de576641..2339e3caa517 100644
--- a/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td
+++ b/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrArithmetic.td
@@ -28,9 +28,34 @@
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
+// OPMODE Encoding
+//===----------------------------------------------------------------------===//
+class MxOpModeEncoding<bits<3> encoding> {
+ bits<3> Value = encoding;
+}
+
+// op EA, Dn
+def MxOpMode8_d_EA : MxOpModeEncoding<0b000>;
+def MxOpMode16_d_EA : MxOpModeEncoding<0b001>;
+def MxOpMode32_d_EA : MxOpModeEncoding<0b010>;
+
+// op Dn, EA
+def MxOpMode8_EA_d : MxOpModeEncoding<0b100>;
+def MxOpMode16_EA_d : MxOpModeEncoding<0b101>;
+def MxOpMode32_EA_d : MxOpModeEncoding<0b110>;
+
+// op EA, An
+def MxOpMode16_a_EA : MxOpModeEncoding<0b011>;
+def MxOpMode32_a_EA : MxOpModeEncoding<0b111>;
+
+
+//===----------------------------------------------------------------------===//
// Encoding
//===----------------------------------------------------------------------===//
+let Defs = [CCR] in {
+let Constraints = "$src = $dst" in {
+
/// Encoding for Normal forms
/// ----------------------------------------------------
/// F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
@@ -38,23 +63,54 @@
/// | | | EFFECTIVE ADDRESS
/// x x x x | REG | OP MODE | MODE | REG
/// ----------------------------------------------------
-class MxArithEncoding<MxBead4Bits CMD, MxEncOpMode OPMODE, MxBead REG,
- MxEncEA EA, MxEncExt EXT>
- : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE.B0, OPMODE.B1, OPMODE.B2, REG,
- CMD,EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
-/// Encoding for Extended forms
-/// ------------------------------------------------------
-/// F E D C | B A 9 | 8 | 7 6 | 5 4 | 3 | 2 1 0
-/// ------------------------------------------------------
-/// x x x x | REG Rx | 1 | SIZE | 0 0 | M | REG Ry
-/// ------------------------------------------------------
-/// Rx - destination
-/// Ry - source
-/// M - address mode switch
-class MxArithXEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxBead1Bit MODE,
- MxBeadDReg SRC, MxBeadDReg DST>
- : MxEncoding<SRC, MODE, MxBead2Bits<0b00>, SIZE, MxBead1Bit<0b1>, DST, CMD>;
+// $reg, $ccr <- $reg op $reg
+class MxBiArOp_R_RR_xEA<string MN, SDNode NODE, MxType DST_TYPE, MxType SRC_TYPE,
+ bits<4> CMD>
+ : MxInst<(outs DST_TYPE.ROp:$dst), (ins DST_TYPE.ROp:$src, SRC_TYPE.ROp:$opd),
+ MN#"."#DST_TYPE.Prefix#"\t$opd, $dst",
+ [(set DST_TYPE.VT:$dst, CCR, (NODE DST_TYPE.VT:$src, SRC_TYPE.VT:$opd))]> {
+ let Inst = (descend
+ CMD, (operand "$dst", 3),
+ !cast<MxOpModeEncoding>("MxOpMode"#DST_TYPE.Size#"_"#DST_TYPE.RLet#"_EA").Value,
+ !cond(
+ !eq(SRC_TYPE.RLet, "r") : (descend 0b00, (operand "$opd", 4)),
+ !eq(SRC_TYPE.RLet, "d") : (descend 0b000, (operand "$opd", 3))
+ )
+ );
+}
+
+/// This Op is similar to the one above except it uses reversed opmode, some
+/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for
+/// register only operations.
+/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems)
+/// but some opcodes support address register and some do not which creates this
+/// mess.
+class MxBiArOp_R_RR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+ : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
+ MN#"."#TYPE.Prefix#"\t$opd, $dst",
+ [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))]> {
+ let Inst = (descend
+ CMD, (operand "$opd", 3),
+ !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_EA_"#TYPE.RLet).Value,
+ /*Destination can only be a data register*/
+ /*MODE*/0b000,
+ /*REGISTER*/(operand "$dst", 3));
+}
+
+let mayLoad = 1 in
+class MxBiArOp_R_RM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT,
+ bits<4> CMD, MxEncMemOp SRC_ENC>
+ : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd),
+ MN#"."#TYPE.Prefix#"\t$opd, $dst",
+ [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))]> {
+ let Inst = (ascend
+ (descend CMD, (operand "$dst", 3),
+ !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_"#TYPE.RLet#"_EA").Value,
+ SRC_ENC.EA),
+ SRC_ENC.Supplement
+ );
+}
/// Encoding for Immediate forms
/// ---------------------------------------------------
@@ -69,211 +125,154 @@ class MxArithXEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxBead1Bit MODE,
/// ---------------------------------------------------
/// NOTE It is used to store an immediate to memory, imm-to-reg are handled with
/// normal version
-class MxArithImmEncoding<MxBead4Bits CMD, MxEncSize SIZE,
- MxEncEA DST_EA, MxEncExt DST_EXT, MxEncExt SRC_EXT>
- : MxEncoding<DST_EA.Reg, DST_EA.DA, DST_EA.Mode, SIZE, CMD, MxBead4Bits<0>,
- // Source
- SRC_EXT.Imm, SRC_EXT.B8, SRC_EXT.Scale,
- SRC_EXT.WL, SRC_EXT.DAReg,
- // Destination
- DST_EXT.Imm, DST_EXT.B8, DST_EXT.Scale,
- DST_EXT.WL, DST_EXT.DAReg>;
-
-
-//===----------------------------------------------------------------------===//
-// Add/Sub
-//===----------------------------------------------------------------------===//
-
-let Defs = [CCR] in {
-let Constraints = "$src = $dst" in {
-
-// $reg, $ccr <- $reg op $reg
-class MxBiArOp_RFRR_xEA<string MN, SDNode NODE, MxType DST_TYPE, MxType SRC_TYPE,
- bits<4> CMD, MxBead REG>
- : MxInst<(outs DST_TYPE.ROp:$dst), (ins DST_TYPE.ROp:$src, SRC_TYPE.ROp:$opd),
- MN#"."#DST_TYPE.Prefix#"\t$opd, $dst",
- [(set DST_TYPE.VT:$dst, CCR, (NODE DST_TYPE.VT:$src, SRC_TYPE.VT:$opd))],
- MxArithEncoding<MxBead4Bits<CMD>,
- !cast<MxEncOpMode>("MxOpMode"#DST_TYPE.Size#DST_TYPE.RLet#"EA"),
- REG,
- !cast<MxEncEA>("MxEncEA"#SRC_TYPE.RLet#"_2"),
- MxExtEmpty>>;
-
-/// This Op is similar to the one above except it uses reversed opmode, some
-/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for
-/// register only operations.
-/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems)
-/// but some opcodes support address register and some do not which creates this
-/// mess.
-class MxBiArOp_RFRR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
- : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
- MN#"."#TYPE.Prefix#"\t$opd, $dst",
- [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))],
- MxArithEncoding<MxBead4Bits<CMD>,
- !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EAd"),
- MxBeadDReg<2>, MxEncEAd_0, MxExtEmpty>>;
// $reg <- $reg op $imm
-class MxBiArOp_RFRI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+class MxBiArOp_R_RI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
: MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
MN#"."#TYPE.Prefix#"\t$opd, $dst",
- [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))],
- MxArithEncoding<MxBead4Bits<CMD>,
- !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
- MxBeadDReg<0>, MxEncEAi,
- !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>;
+ [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))]> {
+ let Inst = (ascend
+ (descend CMD, (operand "$dst", 3),
+ !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_"#TYPE.RLet#"_EA").Value,
+ MxEncAddrMode_i<"opd", TYPE.Size>.EA),
+ MxEncAddrMode_i<"opd", TYPE.Size>.Supplement
+ );
+}
// Again, there are two ways to write an immediate to Dn register either dEA
-// opmode or using *I encoding, and again some instrucitons also support address
+// opmode or using *I encoding, and again some instructions also support address
// registers some do not.
-class MxBiArOp_RFRI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+class MxBiArOp_R_RI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
: MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
MN#"i."#TYPE.Prefix#"\t$opd, $dst",
- [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))],
- MxArithImmEncoding<MxBead4Bits<CMD>, !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- !cast<MxEncEA>("MxEncEA"#TYPE.RLet#"_0"), MxExtEmpty,
- !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>;
-
-let mayLoad = 1 in
-class MxBiArOp_RFRM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT,
- bits<4> CMD, MxEncEA EA, MxEncExt EXT>
- : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd),
- MN#"."#TYPE.Prefix#"\t$opd, $dst",
- [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))],
- MxArithEncoding<MxBead4Bits<CMD>,
- !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
- MxBeadDReg<0>, EA, EXT>>;
-
+ [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))]> {
+ let Inst = (ascend
+ (descend 0b0000, CMD,
+ !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ // The destination cannot be address register, so it's always
+ // the MODE for data register direct mode.
+ /*MODE*/0b000,
+ /*REGISTER*/(operand "$dst", 3)),
+ // Source (i.e. immediate value) encoding
+ MxEncAddrMode_i<"opd", TYPE.Size>.Supplement
+ );
+}
} // Constraints
let mayLoad = 1, mayStore = 1 in {
// FIXME MxBiArOp_FMR/FMI cannot consume CCR from MxAdd/MxSub which leads for
// MxAdd to survive the match and subsequent mismatch.
-class MxBiArOp_FMR<string MN, MxType TYPE, MxOperand MEMOpd,
- bits<4> CMD, MxEncEA EA, MxEncExt EXT>
+class MxBiArOp_MR<string MN, MxType TYPE,
+ MxOperand MEMOpd, bits<4> CMD, MxEncMemOp DST_ENC>
: MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$opd),
- MN#"."#TYPE.Prefix#"\t$opd, $dst",
- [],
- MxArithEncoding<MxBead4Bits<CMD>,
- !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EA"#TYPE.RLet),
- MxBeadDReg<1>, EA, EXT>>;
+ MN#"."#TYPE.Prefix#"\t$opd, $dst", []> {
+ let Inst = (ascend
+ (descend CMD, (operand "$opd", 3),
+ !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_EA_"#TYPE.RLet).Value,
+ DST_ENC.EA),
+ DST_ENC.Supplement
+ );
+}
-class MxBiArOp_FMI<string MN, MxType TYPE, MxOperand MEMOpd,
- bits<4> CMD, MxEncEA MEMEA, MxEncExt MEMExt>
+class MxBiArOp_MI<string MN, MxType TYPE,
+ MxOperand MEMOpd, bits<4> CMD, MxEncMemOp DST_ENC>
: MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$opd),
- MN#"."#TYPE.Prefix#"\t$opd, $dst",
- [],
- MxArithImmEncoding<MxBead4Bits<CMD>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- MEMEA, MEMExt,
- !cast<MxEncExt>("MxExtI"#TYPE.Size#"_1")>>;
+ MN#"."#TYPE.Prefix#"\t$opd, $dst", []> {
+ let Inst = (ascend
+ (descend 0b0000, CMD,
+ !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ DST_ENC.EA),
+ // Source (i.e. immediate value) encoding
+ MxEncAddrMode_i<"opd", TYPE.Size>.Supplement,
+ // Destination encoding
+ DST_ENC.Supplement
+ );
+}
} // mayLoad, mayStore
} // Defs = [CCR]
multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,
bits<4> CMD, bits<4> CMDI> {
- // op $mem, $reg
- def NAME#"8dk" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.KOp, MxType8.KPat,
- CMD, MxEncEAk, MxExtBrief_2>;
- def NAME#"16dk" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.KOp, MxType16.KPat,
- CMD, MxEncEAk, MxExtBrief_2>;
- def NAME#"32dk" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.KOp, MxType32.KPat,
- CMD, MxEncEAk, MxExtBrief_2>;
-
- def NAME#"8dq" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.QOp, MxType8.QPat,
- CMD, MxEncEAq, MxExtI16_2>;
- def NAME#"16dq" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.QOp, MxType16.QPat,
- CMD, MxEncEAq, MxExtI16_2>;
- def NAME#"32dq" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.QOp, MxType32.QPat,
- CMD, MxEncEAq, MxExtI16_2>;
-
- def NAME#"8dp" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.POp, MxType8.PPat,
- CMD, MxEncEAp_2, MxExtI16_2>;
- def NAME#"16dp" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.POp, MxType16.PPat,
- CMD, MxEncEAp_2, MxExtI16_2>;
- def NAME#"32dp" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.POp, MxType32.PPat,
- CMD, MxEncEAp_2, MxExtI16_2>;
-
- def NAME#"8df" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.FOp, MxType8.FPat,
- CMD, MxEncEAf_2, MxExtBrief_2>;
- def NAME#"16df" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.FOp, MxType16.FPat,
- CMD, MxEncEAf_2, MxExtBrief_2>;
- def NAME#"32df" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.FOp, MxType32.FPat,
- CMD, MxEncEAf_2, MxExtBrief_2>;
-
- def NAME#"8dj" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.JOp, MxType8.JPat,
- CMD, MxEncEAj_2, MxExtEmpty>;
- def NAME#"16dj" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.JOp, MxType16.JPat,
- CMD, MxEncEAj_2, MxExtEmpty>;
- def NAME#"32dj" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.JOp, MxType32.JPat,
- CMD, MxEncEAj_2, MxExtEmpty>;
-
- // op $imm, $reg
- def NAME#"8di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType8d, CMD>;
- def NAME#"16di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType16d, CMD>;
- def NAME#"32di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32d, CMD>;
-
- // op $reg, $mem
- def NAME#"8pd" : MxBiArOp_FMR<MN, MxType8d, MxType8.POp,
- CMD, MxEncEAp_0, MxExtI16_0>;
- def NAME#"16pd" : MxBiArOp_FMR<MN, MxType16d, MxType16.POp,
- CMD, MxEncEAp_0, MxExtI16_0>;
- def NAME#"32pd" : MxBiArOp_FMR<MN, MxType32d, MxType32.POp,
- CMD, MxEncEAp_0, MxExtI16_0>;
-
- def NAME#"8fd" : MxBiArOp_FMR<MN, MxType8d, MxType8.FOp,
- CMD, MxEncEAf_0, MxExtBrief_0>;
- def NAME#"16fd" : MxBiArOp_FMR<MN, MxType16d, MxType16.FOp,
- CMD, MxEncEAf_0, MxExtBrief_0>;
- def NAME#"32fd" : MxBiArOp_FMR<MN, MxType32d, MxType32.FOp,
- CMD, MxEncEAf_0, MxExtBrief_0>;
-
- def NAME#"8jd" : MxBiArOp_FMR<MN, MxType8d, MxType8.JOp,
- CMD, MxEncEAj_0, MxExtEmpty>;
- def NAME#"16jd" : MxBiArOp_FMR<MN, MxType16d, MxType16.JOp,
- CMD, MxEncEAj_0, MxExtEmpty>;
- def NAME#"32jd" : MxBiArOp_FMR<MN, MxType32d, MxType32.JOp,
- CMD, MxEncEAj_0, MxExtEmpty>;
-
- // op $imm, $mem
- def NAME#"8pi" : MxBiArOp_FMI<MN, MxType8, MxType8.POp,
- CMDI, MxEncEAp_0, MxExtI16_0>;
- def NAME#"16pi" : MxBiArOp_FMI<MN, MxType16, MxType16.POp,
- CMDI, MxEncEAp_0, MxExtI16_0>;
- def NAME#"32pi" : MxBiArOp_FMI<MN, MxType32, MxType32.POp,
- CMDI, MxEncEAp_0, MxExtI16_0>;
-
- def NAME#"8fi" : MxBiArOp_FMI<MN, MxType8, MxType8.FOp,
- CMDI, MxEncEAf_0, MxExtBrief_0>;
- def NAME#"16fi" : MxBiArOp_FMI<MN, MxType16, MxType16.FOp,
- CMDI, MxEncEAf_0, MxExtBrief_0>;
- def NAME#"32fi" : MxBiArOp_FMI<MN, MxType32, MxType32.FOp,
- CMDI, MxEncEAf_0, MxExtBrief_0>;
-
- def NAME#"8ji" : MxBiArOp_FMI<MN, MxType8, MxType8.JOp,
- CMDI, MxEncEAj_0, MxExtEmpty>;
- def NAME#"16ji" : MxBiArOp_FMI<MN, MxType16, MxType16.JOp,
- CMDI, MxEncEAj_0, MxExtEmpty>;
- def NAME#"32ji" : MxBiArOp_FMI<MN, MxType32, MxType32.JOp,
- CMDI, MxEncEAj_0, MxExtEmpty>;
-
- def NAME#"16dr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, MxType16r,
- CMD, MxBeadDReg<0>>;
- def NAME#"32dr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, MxType32r,
- CMD, MxBeadDReg<0>>;
-
- let isCommutable = isComm in {
-
- def NAME#"8dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType8d, MxType8d,
- CMD, MxBeadDReg<0>>;
- def NAME#"16dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, MxType16d,
- CMD, MxBeadDReg<0>>;
- def NAME#"32dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, MxType32d,
- CMD, MxBeadDReg<0>>;
-
- } // isComm
+ foreach SZ = [8, 16, 32] in {
+ // op $mem, $reg
+ def NAME#SZ#"dk" : MxBiArOp_R_RM<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).KOp,
+ !cast<MxType>("MxType"#SZ).KPat,
+ CMD, MxEncAddrMode_k<"opd">>;
+
+ def NAME#SZ#"dq" : MxBiArOp_R_RM<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).QOp,
+ !cast<MxType>("MxType"#SZ).QPat,
+ CMD, MxEncAddrMode_q<"opd">>;
+
+ def NAME#SZ#"dp" : MxBiArOp_R_RM<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).POp,
+ !cast<MxType>("MxType"#SZ).PPat,
+ CMD, MxEncAddrMode_p<"opd">>;
+
+ def NAME#SZ#"df" : MxBiArOp_R_RM<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).FOp,
+ !cast<MxType>("MxType"#SZ).FPat,
+ CMD, MxEncAddrMode_f<"opd">>;
+
+ def NAME#SZ#"dj" : MxBiArOp_R_RM<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).JOp,
+ !cast<MxType>("MxType"#SZ).JPat,
+ CMD, MxEncAddrMode_j<"opd">>;
+ // op $imm, $reg
+ def NAME#SZ#"di" : MxBiArOp_R_RI_xEA<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ CMD>;
+ // op $reg, $mem
+ def NAME#SZ#"pd" : MxBiArOp_MR<MN,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).POp,
+ CMD, MxEncAddrMode_p<"dst">>;
+
+ def NAME#SZ#"fd" : MxBiArOp_MR<MN,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).FOp,
+ CMD, MxEncAddrMode_f<"dst">>;
+
+ def NAME#SZ#"jd" : MxBiArOp_MR<MN,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ).JOp,
+ CMD, MxEncAddrMode_j<"dst">>;
+ // op $imm, $mem
+ def NAME#SZ#"pi" : MxBiArOp_MI<MN,
+ !cast<MxType>("MxType"#SZ),
+ !cast<MxType>("MxType"#SZ).POp,
+ CMDI, MxEncAddrMode_p<"dst">>;
+
+ def NAME#SZ#"fi" : MxBiArOp_MI<MN,
+ !cast<MxType>("MxType"#SZ),
+ !cast<MxType>("MxType"#SZ).FOp,
+ CMDI, MxEncAddrMode_f<"dst">>;
+
+ def NAME#SZ#"ji" : MxBiArOp_MI<MN,
+ !cast<MxType>("MxType"#SZ),
+ !cast<MxType>("MxType"#SZ).JOp,
+ CMDI, MxEncAddrMode_j<"dst">>;
+ // op $reg, $reg
+ let isCommutable = isComm in
+ def NAME#SZ#"dd" : MxBiArOp_R_RR_xEA<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ#"d"),
+ CMD>;
+ } // foreach SZ
+
+ foreach SZ = [16, 32] in
+ def NAME#SZ#"dr" : MxBiArOp_R_RR_xEA<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ !cast<MxType>("MxType"#SZ#"r"),
+ CMD>;
} // MxBiArOp_DF
@@ -284,25 +283,28 @@ multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,
let Pattern = [(null_frag)] in
multiclass MxBiArOp_AF<string MN, SDNode NODE, bits<4> CMD> {
- def NAME#"32ak" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.KOp, MxType32.KPat,
- CMD, MxEncEAk, MxExtBrief_2>;
- def NAME#"32aq" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.QOp, MxType32.QPat,
- CMD, MxEncEAq, MxExtI16_2>;
- def NAME#"32af" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.FOp, MxType32.FPat,
- CMD, MxEncEAf_2, MxExtBrief_2>;
- def NAME#"32ap" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.POp, MxType32.PPat,
- CMD, MxEncEAp_2, MxExtI16_2>;
- def NAME#"32aj" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.JOp, MxType32.JPat,
- CMD, MxEncEAj_2, MxExtEmpty>;
- def NAME#"32ai" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32a, CMD>;
-
- def NAME#"32ar" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32a, MxType32r,
- CMD, MxBeadReg<0>>;
+ def NAME#"32ak" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.KOp, MxType32.KPat,
+ CMD, MxEncAddrMode_k<"opd">>;
+ def NAME#"32aq" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.QOp, MxType32.QPat,
+ CMD, MxEncAddrMode_q<"opd">>;
+ def NAME#"32af" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.FOp, MxType32.FPat,
+ CMD, MxEncAddrMode_f<"opd">>;
+ def NAME#"32ap" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.POp, MxType32.PPat,
+ CMD, MxEncAddrMode_p<"opd">>;
+ def NAME#"32aj" : MxBiArOp_R_RM<MN, NODE, MxType32a, MxType32.JOp, MxType32.JPat,
+ CMD, MxEncAddrMode_j<"opd">>;
+ def NAME#"32ai" : MxBiArOp_R_RI_xEA<MN, NODE, MxType32a, CMD>;
+
+ def NAME#"32ar" : MxBiArOp_R_RR_xEA<MN, NODE, MxType32a, MxType32r, CMD>;
} // MxBiArOp_AF
// NOTE These naturally produce CCR
+//===----------------------------------------------------------------------===//
+// Add/Sub
+//===----------------------------------------------------------------------===//
+
defm ADD : MxBiArOp_DF<"add", MxAdd, 1, 0xD, 0x6>;
defm ADD : MxBiArOp_AF<"adda", MxAdd, 0xD>;
defm SUB : MxBiArOp_DF<"sub", MxSub, 0, 0x9, 0x4>;
@@ -312,26 +314,42 @@ defm SUB : MxBiArOp_AF<"suba", MxSub, 0x9>;
let Uses = [CCR], Defs = [CCR] in {
let Constraints = "$src = $dst" in {
+/// Encoding for Extended forms
+/// ------------------------------------------------------
+/// F E D C | B A 9 | 8 | 7 6 | 5 4 | 3 | 2 1 0
+/// ------------------------------------------------------
+/// x x x x | REG Rx | 1 | SIZE | 0 0 | M | REG Ry
+/// ------------------------------------------------------
+/// Rx - destination
+/// Ry - source
+/// M - address mode switch
+
// $reg, ccr <- $reg op $reg op ccr
-class MxBiArOp_RFRRF<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+class MxBiArOp_R_RRX<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
: MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
MN#"."#TYPE.Prefix#"\t$opd, $dst",
- [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))],
- MxArithXEncoding<MxBead4Bits<CMD>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- MxBead1Bit<0>, MxBeadDReg<2>, MxBeadDReg<0>>>;
-
+ [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))]> {
+ let Inst = (descend CMD,
+ // Destination register
+ (operand "$dst", 3),
+ 0b1,
+ // SIZE
+ !cond(!eq(TYPE.Size, 8): 0b00,
+ !eq(TYPE.Size, 16): 0b01,
+ !eq(TYPE.Size, 32): 0b10),
+ 0b00, /*R/M*/0b0,
+ // Source register
+ (operand "$opd", 3)
+ );
+}
} // Constraints
} // Uses, Defs
multiclass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> {
let isCommutable = isComm in {
-
- def NAME#"8dd" : MxBiArOp_RFRRF<MN, NODE, MxType8d, CMD>;
- def NAME#"16dd" : MxBiArOp_RFRRF<MN, NODE, MxType16d, CMD>;
- def NAME#"32dd" : MxBiArOp_RFRRF<MN, NODE, MxType32d, CMD>;
-
+ foreach SZ = [8, 16, 32] in
+ def NAME#SZ#"dd" : MxBiArOp_R_RRX<MN, NODE, !cast<MxType>("MxType"#SZ#"d"), CMD>;
} // isComm
} // MxBiArOp_RFF
@@ -349,19 +367,16 @@ defm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>;
defm OR : MxBiArOp_DF<"or", MxOr, 1, 0x8, 0x0>;
multiclass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> {
-
- let isCommutable = 1 in {
-
- def NAME#"8dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType8d, CMD>;
- def NAME#"16dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType16d, CMD>;
- def NAME#"32dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType32d, CMD>;
-
- } // isCommutable = 1
-
- def NAME#"8di" : MxBiArOp_RFRI<MN, NODE, MxType8d, CMDI>;
- def NAME#"16di" : MxBiArOp_RFRI<MN, NODE, MxType16d, CMDI>;
- def NAME#"32di" : MxBiArOp_RFRI<MN, NODE, MxType32d, CMDI>;
-
+ foreach SZ = [8, 16, 32] in {
+ let isCommutable = 1 in
+ def NAME#SZ#"dd" : MxBiArOp_R_RR_EAd<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ CMD>;
+
+ def NAME#SZ#"di" : MxBiArOp_R_RI<MN, NODE,
+ !cast<MxType>("MxType"#SZ#"d"),
+ CMDI>;
+ } // foreach SZ
} // MxBiArOp_DF_EAd
defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;
@@ -372,84 +387,112 @@ defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;
//===----------------------------------------------------------------------===//
let Defs = [CCR] in {
-class MxCmp_RR<MxType LHS_TYPE, MxType RHS_TYPE = LHS_TYPE,
- MxBead REG = MxBeadDReg<1>>
+class MxCmp_RR<MxType LHS_TYPE, MxType RHS_TYPE = LHS_TYPE>
: MxInst<(outs), (ins LHS_TYPE.ROp:$lhs, RHS_TYPE.ROp:$rhs),
"cmp."#RHS_TYPE.Prefix#"\t$lhs, $rhs",
- [(set CCR, (MxCmp LHS_TYPE.VT:$lhs, RHS_TYPE.VT:$rhs))],
- MxArithEncoding<MxBead4Bits<0xB>,
- !cast<MxEncOpMode>("MxOpMode"#RHS_TYPE.Size#RHS_TYPE.RLet#"EA"),
- REG,
- !cast<MxEncEA>("MxEncEA"#LHS_TYPE.RLet#"_0"),
- MxExtEmpty>>;
+ [(set CCR, (MxCmp LHS_TYPE.VT:$lhs, RHS_TYPE.VT:$rhs))]> {
+ let Inst = (descend 0b1011,
+ // REGISTER
+ (operand "$rhs", 3),
+ // OPMODE
+ !cast<MxOpModeEncoding>("MxOpMode"#RHS_TYPE.Size#"_"#RHS_TYPE.RLet#"_EA").Value,
+ // MODE without last bit
+ 0b00,
+ // REGISTER prefixed by D/A bit
+ (operand "$lhs", 4)
+ );
+}
class MxCmp_RI<MxType TYPE>
: MxInst<(outs), (ins TYPE.IOp:$imm, TYPE.ROp:$reg),
"cmpi."#TYPE.Prefix#"\t$imm, $reg",
- [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))],
- MxArithImmEncoding<MxBead4Bits<0xC>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- MxEncEAd_1, MxExtEmpty,
- !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
+ [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))]> {
+ let Inst = (ascend
+ (descend 0b00001100,
+ !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ // The destination cannot be address register, so it's always
+ // the MODE for data register direct mode.
+ /*MODE*/0b000,
+ /*REGISTER*/(operand "$reg", 3)),
+ // Source (i.e. immediate value) encoding
+ MxEncAddrMode_i<"imm", TYPE.Size>.Supplement
+ );
+}
let mayLoad = 1 in {
class MxCmp_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
- MxEncEA EA, MxEncExt EXT>
+ MxEncMemOp MEM_ENC>
: MxInst<(outs), (ins TYPE.IOp:$imm, MEMOpd:$mem),
"cmpi."#TYPE.Prefix#"\t$imm, $mem",
- [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))],
- MxArithImmEncoding<MxBead4Bits<0xC>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- EA, EXT,
- !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
+ [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))]> {
+ let Inst = (ascend
+ (descend 0b00001100,
+ !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ MEM_ENC.EA),
+ // Source (i.e. immediate value) encoding
+ MxEncAddrMode_i<"imm", TYPE.Size>.Supplement,
+ // Destination (i.e. memory operand) encoding
+ MEM_ENC.Supplement
+ );
+}
+// FIXME: What about abs.W?
class MxCmp_BI<MxType TYPE>
: MxInst<(outs), (ins TYPE.IOp:$imm, MxAL32:$abs),
"cmpi."#TYPE.Prefix#"\t$imm, $abs",
[(set CCR, (MxCmp TYPE.IPat:$imm,
- (load (i32 (MxWrapper tglobaladdr:$abs)))))],
- MxArithImmEncoding<MxBead4Bits<0xC>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- MxEncEAb, MxExtI32_1,
- !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
+ (load (i32 (MxWrapper tglobaladdr:$abs)))))]> {
+ defvar AbsEncoding = MxEncAddrMode_abs<"abs", true>;
+ let Inst = (ascend
+ (descend 0b00001100,
+ !cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ AbsEncoding.EA),
+ // Source (i.e. immediate value) encoding
+ MxEncAddrMode_i<"imm", TYPE.Size>.Supplement,
+ // Destination (i.e. memory operand) encoding
+ AbsEncoding.Supplement
+ );
+}
class MxCmp_RM<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
- MxEncEA EA, MxEncExt EXT>
+ MxEncMemOp MEM_ENC>
: MxInst<(outs), (ins TYPE.ROp:$reg, MEMOpd:$mem),
"cmp."#TYPE.Prefix#"\t$mem, $reg",
- [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))],
- MxArithEncoding<MxBead4Bits<0xB>,
- !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"dEA"),
- MxBeadDReg<0>, EA, EXT>>;
+ [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))]> {
+ let Inst = (ascend
+ (descend 0b1011,
+ // REGISTER
+ (operand "$reg", 3),
+ // OPMODE
+ !cast<MxOpModeEncoding>("MxOpMode"#TYPE.Size#"_d_EA").Value,
+ MEM_ENC.EA),
+ MEM_ENC.Supplement
+ );
+}
} // let mayLoad = 1
} // let Defs = [CCR]
multiclass MMxCmp_RM<MxType TYPE> {
- def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
- MxExtBrief_1>;
- def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
- MxExtI16_1>;
- def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
- MxExtI16_1>;
- def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
- MxExtBrief_1>;
- def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
- MxExtEmpty>;
+ def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncAddrMode_k<"mem">>;
+ def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncAddrMode_q<"mem">>;
+ def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncAddrMode_p<"mem">>;
+ def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncAddrMode_f<"mem">>;
+ def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncAddrMode_j<"mem">>;
}
multiclass MMxCmp_MI<MxType TYPE> {
- def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
- MxExtBrief_1>;
- def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
- MxExtI16_1>;
- def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
- MxExtI16_1>;
- def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
- MxExtBrief_1>;
- def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
- MxExtEmpty>;
+ def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat,
+ MxEncAddrMode_k<"mem">>;
+ def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat,
+ MxEncAddrMode_q<"mem">>;
+ def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat,
+ MxEncAddrMode_p<"mem">>;
+ def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat,
+ MxEncAddrMode_f<"mem">>;
+ def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat,
+ MxEncAddrMode_j<"mem">>;
}
foreach S = [8, 16, 32] in {
@@ -478,25 +521,31 @@ defm CMP32 : MMxCmp_MI<MxType32d>;
// EXT
//===----------------------------------------------------------------------===//
-def MxExtOpmode_wb : MxBead3Bits<0b010>;
-def MxExtOpmode_lw : MxBead3Bits<0b011>;
-def MxExtOpmode_lb : MxBead3Bits<0b111>;
-
/// ---------------------------------------------------
/// F E D C B A 9 | 8 7 6 | 5 4 3 | 2 1 0
/// ---------------------------------------------------
/// 0 1 0 0 1 0 0 | OPMODE | 0 0 0 | REG
/// ---------------------------------------------------
-class MxExtEncoding<MxBead3Bits OPMODE>
- : MxEncoding<MxBeadDReg<0>, MxBead3Bits<0b000>, OPMODE,
- MxBead3Bits<0b100>, MxBead4Bits<0b0100>>;
-
let Defs = [CCR] in
let Constraints = "$src = $dst" in
class MxExt<MxType TO, MxType FROM>
: MxInst<(outs TO.ROp:$dst), (ins TO.ROp:$src),
- "ext."#TO.Prefix#"\t$src", [],
- MxExtEncoding<!cast<MxBead3Bits>("MxExtOpmode_"#TO.Prefix#FROM.Prefix)>>;
+ "ext."#TO.Prefix#"\t$src", []> {
+ let Inst = (descend 0b0100100,
+ // OPMODE
+ !cond(
+ // byte -> word
+ !and(!eq(FROM.Size, 8), !eq(TO.Size, 16)): 0b010,
+ // word -> long
+ !and(!eq(FROM.Size, 16), !eq(TO.Size, 32)): 0b011,
+ // byte -> long
+ !and(!eq(FROM.Size, 8), !eq(TO.Size, 32)): 0b111
+ ),
+ 0b000,
+ // REGISTER
+ (operand "$src", 3)
+ );
+}
def EXT16 : MxExt<MxType16d, MxType8d>;
def EXT32 : MxExt<MxType32d, MxType16d>;
@@ -511,9 +560,6 @@ def : Pat<(sext_inreg i32:$src, i8),
// DIV/MUL
//===----------------------------------------------------------------------===//
-def MxSDiMuOpmode : MxBead3Bits<0b111>;
-def MxUDiMuOpmode : MxBead3Bits<0b011>;
-
/// Word operation:
/// ----------------------------------------------------
/// F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
@@ -521,40 +567,45 @@ def MxUDiMuOpmode : MxBead3Bits<0b011>;
/// | | | EFFECTIVE ADDRESS
/// x x x x | REG | OP MODE | MODE | REG
/// ----------------------------------------------------
-class MxDiMuEncoding<MxBead4Bits CMD, MxBead3Bits OPMODE, MxEncEA EA, MxEncExt EXT>
- : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE, MxBeadDReg<0>, CMD,
- EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
-
let Defs = [CCR] in {
let Constraints = "$src = $dst" in {
-// $reg <- $reg op $reg
-class MxDiMuOp_DD<string MN, bits<4> CMD, MxBead3Bits OPMODE,
+// $dreg <- $dreg op $dreg
+class MxDiMuOp_DD<string MN, bits<4> CMD, bit SIGNED = false,
MxOperand DST, MxOperand OPD>
- : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [],
- MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAd_2, MxExtEmpty>>;
+ : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", []> {
+ let Inst = (descend CMD,
+ // REGISTER
+ (operand "$dst", 3),
+ !if(SIGNED, 0b111, 0b011),
+ /*MODE*/0b000, /*REGISTER*/(operand "$opd", 3)
+ );
+}
// $reg <- $reg op $imm
-class MxDiMuOp_DI<string MN, bits<4> CMD, MxBead3Bits OPMODE,
+class MxDiMuOp_DI<string MN, bits<4> CMD, bit SIGNED = false,
MxOperand DST, MxOperand OPD>
- : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [],
- MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAi, MxExtI16_2>>;
+ : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", []> {
+ // FIXME: Support immediates with different widths.
+ defvar ImmEnc = MxEncAddrMode_i<"opd", 16>;
+ let Inst = (ascend
+ (descend CMD,
+ // REGISTER
+ (operand "$dst", 3),
+ !if(SIGNED, 0b111, 0b011), ImmEnc.EA),
+ ImmEnc.Supplement
+ );
+}
} // let Constraints
} // Defs = [CCR]
multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> {
-
let isCommutable = isComm in {
- def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
- MxDRD16>;
- def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
- MxDRD16>;
+ def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, /*SIGNED*/true, MxDRD32, MxDRD16>;
+ def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, /*SIGNED*/false, MxDRD32, MxDRD16>;
}
- def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
- Mxi16imm>;
- def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
- Mxi16imm>;
-
+ def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, /*SIGNED*/true, MxDRD32, Mxi16imm>;
+ def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, /*SIGNED*/false, MxDRD32, Mxi16imm>;
}
defm DIV : MxDiMuOp<"div", 0x8>;
@@ -697,29 +748,35 @@ def : Pat<(mulhu i16:$dst, MximmSExt16:$opd),
/// | | | EFFECTIVE ADDRESS
/// 0 1 0 0 | x x x x | SIZE | MODE | REG
/// ------------+------------+------+---------+---------
-class MxNEGEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxEncEA EA, MxEncExt EXT>
- : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, CMD, MxBead4Bits<0b0100>,
- EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
-
let Defs = [CCR] in {
let Constraints = "$src = $dst" in {
class MxNeg_D<MxType TYPE>
: MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
"neg."#TYPE.Prefix#"\t$dst",
- [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))],
- MxNEGEncoding<MxBead4Bits<0x4>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- MxEncEAd_0, MxExtEmpty>>;
+ [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))]> {
+ let Inst = (descend 0b01000100,
+ /*SIZE*/!cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ //MODE without last bit
+ 0b00,
+ //REGISTER prefixed by D/A bit
+ (operand "$dst", 4)
+ );
+}
let Uses = [CCR] in {
class MxNegX_D<MxType TYPE>
: MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
"negx."#TYPE.Prefix#"\t$dst",
- [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))],
- MxNEGEncoding<MxBead4Bits<0x0>,
- !cast<MxEncSize>("MxEncSize"#TYPE.Size),
- MxEncEAd_0, MxExtEmpty>>;
+ [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))]> {
+ let Inst = (descend 0b01000000,
+ /*SIZE*/!cast<MxNewEncSize>("MxNewEncSize"#TYPE.Size).Value,
+ //MODE without last bit
+ 0b00,
+ //REGISTER prefixed by D/A bit
+ (operand "$dst", 4)
+ );
+}
}
} // let Constraints