Skip to content

Commit 699f483

Browse files
committed
[M68k] Implement TST instruction
TST is identical to CMPI #0, except the immediate operand is not required. The instruction is fully implemented in TableGen, matching the same patterns as CMPI but with a constant instead of variable immediate.
1 parent 2288ba2 commit 699f483

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

llvm/lib/Target/M68k/M68kInstrControl.td

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
/// BRA [x] BSR [~] Bcc [~] DBcc [ ] FBcc [ ]
1616
/// FDBcc [ ] FNOP [ ] FPn [ ] FScc [ ] FTST [ ]
1717
/// JMP [~] JSR [x] NOP [x] RTD [!] RTR [ ]
18-
/// RTS [x] Scc [~] TST [ ]
18+
/// RTS [x] Scc [~] TST [~]
1919
///
2020
/// Pseudo:
2121
///
@@ -435,3 +435,70 @@ def BKPT : MxInst<(outs), (ins MxBkptimm:$vect), "bkpt\t$vect", []> {
435435
def ILLEGAL : MxInst<(outs), (ins), "illegal", []> {
436436
let Inst = (descend 0b0100, 0b1010, 0b1111, 0b1100);
437437
}
438+
439+
//===----------------------------------------------------------------------===//
440+
// TST
441+
//===----------------------------------------------------------------------===//
442+
443+
/// ---------------------------------------------------
444+
/// F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
445+
/// ---------------------------------------------------
446+
/// | | EFFECTIVE ADDRESS
447+
/// 0 1 0 0 1 0 1 0 | SIZE | MODE | REG
448+
/// ---------------------------------------------------
449+
450+
let isCompare = 1, Defs = [CCR] in {
451+
class MxTst_D<MxType TYPE>
452+
: MxInst<(outs), (ins TYPE.ROp:$reg),
453+
"tst."#TYPE.Prefix#"\t$reg",
454+
[(set CCR, (MxCmp TYPE.VT:$reg, (TYPE.VT 0)))]> {
455+
let Inst = (descend 0b01001010,
456+
/*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
457+
//MODE without last bit
458+
0b00,
459+
//REGISTER prefixed by D/A bit
460+
(operand "$reg", 4)
461+
);
462+
}
463+
464+
let mayLoad = 1 in {
465+
class MxTst_M<MxType TYPE, MxOpBundle DST, MxEncMemOp DST_ENC>
466+
: MxInst<(outs), (ins DST.Op:$dst),
467+
"tst."#TYPE.Prefix#"\t$dst",
468+
[(set CCR, (MxCmp (load DST.Pat:$dst), (TYPE.VT 0)))]> {
469+
let Inst = (ascend
470+
(descend 0b01001010,
471+
/*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
472+
DST_ENC.EA), DST_ENC.Supplement
473+
);
474+
}
475+
476+
class MxTst_B<MxType TYPE>
477+
: MxInst<(outs), (ins MxAL32:$abs),
478+
"tst."#TYPE.Prefix#"\t$abs",
479+
[(set CCR, (MxCmp (load (i32 (MxWrapper tglobaladdr:$abs))),
480+
(TYPE.VT 0)))]> {
481+
defvar AbsEncoding = MxEncAddrMode_abs<"abs", true>;
482+
let Inst = (ascend
483+
(descend 0b01001010,
484+
/*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
485+
AbsEncoding.EA), AbsEncoding.Supplement
486+
);
487+
}
488+
} // let mayLoad = 1
489+
} // let Defs = [CCR]
490+
491+
foreach S = [8, 16, 32] in {
492+
defvar DTYPE = !cast<MxType>("MxType"#S#"d");
493+
def TST#S#d : MxTst_D<DTYPE>;
494+
def TST#S#b : MxTst_B<DTYPE>;
495+
496+
defvar MTYPE = !cast<MxType>("MxType"#S);
497+
def TST#S#j : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_j"), MxEncAddrMode_j<"dst">>;
498+
def TST#S#o : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_o"), MxEncAddrMode_o<"dst">>;
499+
def TST#S#e : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_e"), MxEncAddrMode_e<"dst">>;
500+
def TST#S#p : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_p"), MxEncAddrMode_p<"dst">>;
501+
def TST#S#f : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_f"), MxEncAddrMode_f<"dst">>;
502+
def TST#S#q : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_q"), MxEncAddrMode_q<"dst">>;
503+
def TST#S#k : MxTst_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_k"), MxEncAddrMode_k<"dst">>;
504+
}

0 commit comments

Comments
 (0)