Skip to content

Commit a556ec8

Browse files
committed
[CSKY] Complete codegen of basic arithmetic and load/store operations
Complete basic arithmetic operations such as add/sub/mul/div, and it also includes converions and some specific operations such as bswap.Add load/store patterns to generate different addressing mode instructions. Also enable some infra such as copy physical register and eliminate frame index.
1 parent ec63930 commit a556ec8

File tree

12 files changed

+2514
-2
lines changed

12 files changed

+2514
-2
lines changed

llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class CSKYDAGToDAGISel : public SelectionDAGISel {
4040
}
4141

4242
void Select(SDNode *N) override;
43+
bool selectAddCarry(SDNode *N);
44+
bool selectSubCarry(SDNode *N);
4345

4446
#include "CSKYGenDAGISel.inc"
4547
};
@@ -60,7 +62,12 @@ void CSKYDAGToDAGISel::Select(SDNode *N) {
6062
switch (Opcode) {
6163
default:
6264
break;
63-
// FIXME: Add selection nodes needed later.
65+
case ISD::ADDCARRY:
66+
IsSelected = selectAddCarry(N);
67+
break;
68+
case ISD::SUBCARRY:
69+
IsSelected = selectSubCarry(N);
70+
break;
6471
}
6572

6673
if (IsSelected)
@@ -70,6 +77,86 @@ void CSKYDAGToDAGISel::Select(SDNode *N) {
7077
SelectCode(N);
7178
}
7279

80+
bool CSKYDAGToDAGISel::selectAddCarry(SDNode *N) {
81+
MachineSDNode *NewNode = nullptr;
82+
auto Type0 = N->getValueType(0);
83+
auto Type1 = N->getValueType(1);
84+
auto Op0 = N->getOperand(0);
85+
auto Op1 = N->getOperand(1);
86+
auto Op2 = N->getOperand(2);
87+
88+
SDLoc Dl(N);
89+
90+
if (isNullConstant(Op2)) {
91+
auto *CA = CurDAG->getMachineNode(
92+
Subtarget->has2E3() ? CSKY::CLRC32 : CSKY::CLRC16, Dl, Type1);
93+
NewNode = CurDAG->getMachineNode(
94+
Subtarget->has2E3() ? CSKY::ADDC32 : CSKY::ADDC16, Dl, {Type0, Type1},
95+
{Op0, Op1, SDValue(CA, 0)});
96+
} else if (isOneConstant(Op2)) {
97+
auto *CA = CurDAG->getMachineNode(
98+
Subtarget->has2E3() ? CSKY::SETC32 : CSKY::SETC16, Dl, Type1);
99+
NewNode = CurDAG->getMachineNode(
100+
Subtarget->has2E3() ? CSKY::ADDC32 : CSKY::ADDC16, Dl, {Type0, Type1},
101+
{Op0, Op1, SDValue(CA, 0)});
102+
} else {
103+
NewNode = CurDAG->getMachineNode(Subtarget->has2E3() ? CSKY::ADDC32
104+
: CSKY::ADDC16,
105+
Dl, {Type0, Type1}, {Op0, Op1, Op2});
106+
}
107+
ReplaceNode(N, NewNode);
108+
return true;
109+
}
110+
111+
static SDValue InvertCarryFlag(const CSKYSubtarget *Subtarget,
112+
SelectionDAG *DAG, SDLoc Dl, SDValue OldCarry) {
113+
auto NewCarryReg =
114+
DAG->getMachineNode(Subtarget->has2E3() ? CSKY::MVCV32 : CSKY::MVCV16, Dl,
115+
MVT::i32, OldCarry);
116+
auto NewCarry =
117+
DAG->getMachineNode(Subtarget->hasE2() ? CSKY::BTSTI32 : CSKY::BTSTI16,
118+
Dl, OldCarry.getValueType(), SDValue(NewCarryReg, 0),
119+
DAG->getTargetConstant(0, Dl, MVT::i32));
120+
return SDValue(NewCarry, 0);
121+
}
122+
123+
bool CSKYDAGToDAGISel::selectSubCarry(SDNode *N) {
124+
MachineSDNode *NewNode = nullptr;
125+
auto Type0 = N->getValueType(0);
126+
auto Type1 = N->getValueType(1);
127+
auto Op0 = N->getOperand(0);
128+
auto Op1 = N->getOperand(1);
129+
auto Op2 = N->getOperand(2);
130+
131+
SDLoc Dl(N);
132+
133+
if (isNullConstant(Op2)) {
134+
auto *CA = CurDAG->getMachineNode(
135+
Subtarget->has2E3() ? CSKY::SETC32 : CSKY::SETC16, Dl, Type1);
136+
NewNode = CurDAG->getMachineNode(
137+
Subtarget->has2E3() ? CSKY::SUBC32 : CSKY::SUBC16, Dl, {Type0, Type1},
138+
{Op0, Op1, SDValue(CA, 0)});
139+
} else if (isOneConstant(Op2)) {
140+
auto *CA = CurDAG->getMachineNode(
141+
Subtarget->has2E3() ? CSKY::CLRC32 : CSKY::CLRC16, Dl, Type1);
142+
NewNode = CurDAG->getMachineNode(
143+
Subtarget->has2E3() ? CSKY::SUBC32 : CSKY::SUBC16, Dl, {Type0, Type1},
144+
{Op0, Op1, SDValue(CA, 0)});
145+
} else {
146+
auto CarryIn = InvertCarryFlag(Subtarget, CurDAG, Dl, Op2);
147+
NewNode = CurDAG->getMachineNode(Subtarget->has2E3() ? CSKY::SUBC32
148+
: CSKY::SUBC16,
149+
Dl, {Type0, Type1}, {Op0, Op1, CarryIn});
150+
}
151+
auto CarryOut = InvertCarryFlag(Subtarget, CurDAG, Dl, SDValue(NewNode, 1));
152+
153+
ReplaceUses(SDValue(N, 0), SDValue(NewNode, 0));
154+
ReplaceUses(SDValue(N, 1), CarryOut);
155+
CurDAG->RemoveDeadNode(N);
156+
157+
return true;
158+
}
159+
73160
FunctionPass *llvm::createCSKYISelDag(CSKYTargetMachine &TM) {
74161
return new CSKYDAGToDAGISel(TM);
75162
}

llvm/lib/Target/CSKY/CSKYISelLowering.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,46 @@ CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM,
3737
// Register Class
3838
addRegisterClass(MVT::i32, &CSKY::GPRRegClass);
3939

40+
setOperationAction(ISD::ADDCARRY, MVT::i32, Legal);
41+
setOperationAction(ISD::SUBCARRY, MVT::i32, Legal);
42+
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
43+
44+
setOperationAction(ISD::SREM, MVT::i32, Expand);
45+
setOperationAction(ISD::UREM, MVT::i32, Expand);
46+
setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
47+
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
48+
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
49+
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
50+
setOperationAction(ISD::ROTR, MVT::i32, Expand);
51+
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
52+
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
53+
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
54+
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
55+
setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
56+
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
57+
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
58+
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
59+
setOperationAction(ISD::MULHS, MVT::i32, Expand);
60+
setOperationAction(ISD::MULHU, MVT::i32, Expand);
61+
62+
setLoadExtAction(ISD::EXTLOAD, MVT::i32, MVT::i1, Promote);
63+
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i1, Promote);
64+
setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, MVT::i1, Promote);
65+
66+
if (!Subtarget.hasE2()) {
67+
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i8, Expand);
68+
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i16, Expand);
69+
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
70+
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
71+
}
72+
73+
if (!Subtarget.has2E3()) {
74+
setOperationAction(ISD::ABS, MVT::i32, Expand);
75+
setOperationAction(ISD::BITREVERSE, MVT::i32, Expand);
76+
setOperationAction(ISD::SDIV, MVT::i32, Expand);
77+
setOperationAction(ISD::UDIV, MVT::i32, Expand);
78+
}
79+
4080
// Compute derived properties from the register classes.
4181
computeRegisterProperties(STI.getRegisterInfo());
4282

0 commit comments

Comments
 (0)