Skip to content

Commit 7469aae

Browse files
committed
[M68k] Implement CLR instruction
The CLR instruction is equivalent to moving immediate 0 to an effective address, except it's strictly more efficient due to not requiring the extra bytes and cycles to load the immediate value. Nodes which set or store 0 will prioritize CLR over MOVE in pattern matching. (Note: Usually, when clearing multiple memory addresses, it's faster to clear a register and store that register multiple times, but this would have to be achieved separately in an optimization pass.)
1 parent 1c5e6c4 commit 7469aae

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

llvm/lib/Target/M68k/M68kInstrArithmetic.td

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
/// Machine:
1414
///
1515
/// ADD [~] ADDA [~] ADDI [~] ADDQ [ ] ADDX [~]
16-
/// CLR [ ] CMP [~] CMPA [~] CMPI [~] CMPM [ ]
16+
/// CLR [~] CMP [~] CMPA [~] CMPI [~] CMPM [ ]
1717
/// CMP2 [ ] DIVS/DIVU [~] DIVSL/DIVUL [ ] EXT [~] EXTB [ ]
1818
/// MULS/MULU [~] NEG [~] NEGX [~] NOT [~] SUB [~]
1919
/// SUBA [~] SUBI [~] SUBQ [ ] SUBX [~]
@@ -1106,3 +1106,60 @@ defm FADD : MxFBinaryOp<"add", 0b1100010, 0b1100110, 0b0100010>;
11061106
defm FSUB : MxFBinaryOp<"sub", 0b1101000, 0b1101100, 0b0101000>;
11071107
defm FMUL : MxFBinaryOp<"mul", 0b1100011, 0b1100111, 0b0100011>;
11081108
defm FDIV : MxFBinaryOp<"div", 0b1100000, 0b1100100, 0b0100000>;
1109+
1110+
1111+
//===----------------------------------------------------------------------===//
1112+
// CLR
1113+
//===----------------------------------------------------------------------===//
1114+
1115+
/// ---------------------------------------------------
1116+
/// F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
1117+
/// ---------------------------------------------------
1118+
/// | | EFFECTIVE ADDRESS
1119+
/// 0 1 0 0 0 0 1 0 | SIZE | MODE | REG
1120+
/// ---------------------------------------------------
1121+
1122+
let Defs = [CCR] in {
1123+
1124+
class MxClr_D<MxType TYPE>
1125+
: MxInst<(outs TYPE.ROp:$dst), (ins),
1126+
"clr."#TYPE.Prefix#"\t$dst",
1127+
[(set TYPE.VT:$dst, (TYPE.VT 0))]> {
1128+
let Inst = (descend 0b01000010,
1129+
/*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
1130+
//MODE without last bit
1131+
0b00,
1132+
//REGISTER prefixed by D/A bit
1133+
(operand "$dst", 4)
1134+
);
1135+
}
1136+
1137+
// CLR reads memory before clearing on M68000 and M68008
1138+
// TODO: mayLoad is *only* applicable on M68000 and M68008
1139+
let mayLoad = 1, mayStore = 1 in
1140+
class MxClr_M<MxType TYPE, MxOpBundle DST, MxEncMemOp DST_ENC>
1141+
: MxInst<(outs), (ins DST.Op:$dst),
1142+
"clr."#TYPE.Prefix#"\t$dst",
1143+
[(store (TYPE.VT 0), DST.Pat:$dst)]> {
1144+
let Inst = (ascend
1145+
(descend 0b01000010,
1146+
/*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
1147+
DST_ENC.EA), DST_ENC.Supplement
1148+
);
1149+
}
1150+
} // let Defs = [CCR]
1151+
1152+
foreach S = [8, 16, 32] in {
1153+
defvar DTYPE = !cast<MxType>("MxType"#S#"d");
1154+
def CLR#S#d : MxClr_D<DTYPE>;
1155+
1156+
defvar MTYPE = !cast<MxType>("MxType"#S);
1157+
def CLR#S#j : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_j"), MxEncAddrMode_j<"dst">>;
1158+
def CLR#S#o : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_o"), MxEncAddrMode_o<"dst">>;
1159+
def CLR#S#e : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_e"), MxEncAddrMode_e<"dst">>;
1160+
def CLR#S#p : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_p"), MxEncAddrMode_p<"dst">>;
1161+
def CLR#S#f : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_f"), MxEncAddrMode_f<"dst">>;
1162+
def CLR#S#b : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_b"), MxEncAddrMode_abs<"dst", true>>;
1163+
def CLR#S#q : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_q"), MxEncAddrMode_q<"dst">>;
1164+
def CLR#S#k : MxClr_M<MTYPE, !cast<MxOpBundle>("MxOp"#S#"AddrMode_k"), MxEncAddrMode_k<"dst">>;
1165+
}

0 commit comments

Comments
 (0)