2 * Copyright 2018 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Karol Herbst <kherbst@redhat.com>
25 #include "codegen/nv50_ir_lowering_helper.h"
30 LoweringHelper::visit(Instruction
*insn
)
34 return handleABS(insn
);
36 return handleCVT(insn
);
39 return handleMAXMIN(insn
);
41 return handleMOV(insn
);
43 return handleNEG(insn
);
45 return handleSAT(insn
);
47 return handleSLCT(insn
->asCmp());
52 return handleLogOp(insn
);
59 LoweringHelper::handleABS(Instruction
*insn
)
61 DataType dTy
= insn
->dType
;
62 if (!(dTy
== TYPE_U64
|| dTy
== TYPE_S64
))
65 bld
.setPosition(insn
, false);
67 Value
*neg
= bld
.getSSA(8);
68 Value
*negComp
[2], *srcComp
[2];
69 Value
*lo
= bld
.getSSA(), *hi
= bld
.getSSA();
70 bld
.mkOp2(OP_SUB
, dTy
, neg
, bld
.mkImm((uint64_t)0), insn
->getSrc(0));
71 bld
.mkSplit(negComp
, 4, neg
);
72 bld
.mkSplit(srcComp
, 4, insn
->getSrc(0));
73 bld
.mkCmp(OP_SLCT
, CC_LT
, TYPE_S32
, lo
, TYPE_S32
, negComp
[0], srcComp
[0], srcComp
[1]);
74 bld
.mkCmp(OP_SLCT
, CC_LT
, TYPE_S32
, hi
, TYPE_S32
, negComp
[1], srcComp
[1], srcComp
[1]);
83 LoweringHelper::handleCVT(Instruction
*insn
)
85 DataType dTy
= insn
->dType
;
86 DataType sTy
= insn
->sType
;
88 if (typeSizeof(dTy
) <= 4 && typeSizeof(sTy
) <= 4)
91 bld
.setPosition(insn
, false);
93 if ((dTy
== TYPE_S32
&& sTy
== TYPE_S64
) ||
94 (dTy
== TYPE_U32
&& sTy
== TYPE_U64
)) {
96 bld
.mkSplit(src
, 4, insn
->getSrc(0));
98 insn
->setSrc(0, src
[0]);
99 } else if (dTy
== TYPE_S64
&& sTy
== TYPE_S32
) {
100 Value
*tmp
= bld
.getSSA();
101 bld
.mkOp2(OP_SHR
, TYPE_S32
, tmp
, insn
->getSrc(0), bld
.loadImm(bld
.getSSA(), 31));
103 insn
->setSrc(1, tmp
);
104 } else if (dTy
== TYPE_U64
&& sTy
== TYPE_U32
) {
106 insn
->setSrc(1, bld
.loadImm(bld
.getSSA(), 0));
113 LoweringHelper::handleMAXMIN(Instruction
*insn
)
115 DataType dTy
= insn
->dType
;
116 if (!(dTy
== TYPE_U64
|| dTy
== TYPE_S64
))
119 DataType sTy
= typeOfSize(4, false, isSignedIntType(dTy
));
120 bld
.setPosition(insn
, false);
122 Value
*flag
= bld
.getSSA(1, FILE_FLAGS
);
127 bld
.mkSplit(src0
, 4, insn
->getSrc(0));
128 bld
.mkSplit(src1
, 4, insn
->getSrc(1));
130 def
[0] = bld
.getSSA();
131 def
[1] = bld
.getSSA();
133 Instruction
*hi
= bld
.mkOp2(insn
->op
, sTy
, def
[1], src0
[1], src1
[1]);
134 hi
->subOp
= NV50_IR_SUBOP_MINMAX_HIGH
;
135 hi
->setFlagsDef(1, flag
);
137 Instruction
*lo
= bld
.mkOp2(insn
->op
, sTy
, def
[0], src0
[0], src1
[0]);
138 lo
->subOp
= NV50_IR_SUBOP_MINMAX_LOW
;
139 lo
->setFlagsSrc(2, flag
);
142 insn
->setSrc(0, def
[0]);
143 insn
->setSrc(1, def
[1]);
149 LoweringHelper::handleMOV(Instruction
*insn
)
151 DataType dTy
= insn
->dType
;
153 if (typeSizeof(dTy
) != 8)
156 Storage
®
= insn
->getSrc(0)->reg
;
158 if (reg
.file
!= FILE_IMMEDIATE
)
161 bld
.setPosition(insn
, false);
163 Value
*hi
= bld
.getSSA();
164 Value
*lo
= bld
.getSSA();
166 bld
.loadImm(lo
, (uint32_t)(reg
.data
.u64
& 0xffffffff));
167 bld
.loadImm(hi
, (uint32_t)(reg
.data
.u64
>> 32));
177 LoweringHelper::handleNEG(Instruction
*insn
)
179 if (typeSizeof(insn
->dType
) != 8 || isFloatType(insn
->dType
))
182 bld
.setPosition(insn
, false);
185 insn
->setSrc(1, insn
->getSrc(0));
186 insn
->setSrc(0, bld
.mkImm((uint64_t)0));
191 LoweringHelper::handleSAT(Instruction
*insn
)
193 DataType dTy
= insn
->dType
;
195 if (typeSizeof(dTy
) != 8 || !isFloatType(dTy
))
198 bld
.setPosition(insn
, false);
200 Value
*tmp
= bld
.mkOp2v(OP_MAX
, dTy
, bld
.getSSA(8), insn
->getSrc(0), bld
.loadImm(bld
.getSSA(8), 0.0));
202 insn
->setSrc(0, tmp
);
203 insn
->setSrc(1, bld
.loadImm(bld
.getSSA(8), 1.0));
208 LoweringHelper::handleSLCT(CmpInstruction
*insn
)
210 DataType dTy
= insn
->dType
;
211 DataType sTy
= insn
->sType
;
213 if (typeSizeof(dTy
) != 8 || typeSizeof(sTy
) == 8)
216 CondCode cc
= insn
->getCondition();
217 DataType hdTy
= typeOfSize(4, isFloatType(dTy
), isSignedIntType(dTy
));
218 bld
.setPosition(insn
, false);
224 bld
.mkSplit(src0
, 4, insn
->getSrc(0));
225 bld
.mkSplit(src1
, 4, insn
->getSrc(1));
227 def
[0] = bld
.getSSA();
228 def
[1] = bld
.getSSA();
230 bld
.mkCmp(OP_SLCT
, cc
, hdTy
, def
[0], sTy
, src0
[0], src1
[0], insn
->getSrc(2));
231 bld
.mkCmp(OP_SLCT
, cc
, hdTy
, def
[1], sTy
, src0
[1], src1
[1], insn
->getSrc(2));
234 insn
->setSrc(0, def
[0]);
235 insn
->setSrc(1, def
[1]);
236 insn
->setSrc(2, NULL
);
242 LoweringHelper::handleLogOp(Instruction
*insn
)
244 DataType dTy
= insn
->dType
;
245 DataType sTy
= typeOfSize(4, isFloatType(dTy
), isSignedIntType(dTy
));
247 if (typeSizeof(dTy
) != 8)
250 bld
.setPosition(insn
, false);
254 Value
*def0
= bld
.getSSA();
255 Value
*def1
= bld
.getSSA();
257 bld
.mkSplit(src0
, 4, insn
->getSrc(0));
258 if (insn
->srcExists(1))
259 bld
.mkSplit(src1
, 4, insn
->getSrc(1));
261 Instruction
*lo
= bld
.mkOp1(insn
->op
, sTy
, def0
, src0
[0]);
262 Instruction
*hi
= bld
.mkOp1(insn
->op
, sTy
, def1
, src0
[1]);
263 if (insn
->srcExists(1)) {
264 lo
->setSrc(1, src1
[0]);
265 hi
->setSrc(1, src1
[1]);
269 insn
->setSrc(0, def0
);
270 insn
->setSrc(1, def1
);
275 } // namespace nv50_ir