@@ -63,6 +63,8 @@ def SBFRevSub : Predicate<"Subtarget->getReverseSubImm()">;
6363def SBFNoRevSub : Predicate<"!Subtarget->getReverseSubImm()">;
6464def SBFCallxSrc : Predicate<"Subtarget->getCallXRegSrc()">, AssemblerPredicate<(all_of FeatureCallxRegSrc)>;
6565def NoSBFCallxSrc : Predicate<"!Subtarget->getCallXRegSrc()">;
66+ def SBFPqrInstr : Predicate<"Subtarget->getHasPqrClass()">;
67+ def SBFNoPqrInstr : Predicate<"!Subtarget->getHasPqrClass()">;
6668
6769def brtarget : Operand<OtherVT> {
6870 let PrintMethod = "printBrTargetOperand";
@@ -136,10 +138,13 @@ def SBF_CC_LEU : PatLeaf<(i64 imm),
136138// +----------------+--------+--------------------+
137139// (MSB) (LSB)
138140class TYPE_ALU_JMP<bits<4> op, bits<1> srctype,
139- dag outs, dag ins, string asmstr, list<dag> pattern>
141+ dag outs, dag ins, string asmstr, list<dag> pattern,
142+ bit IsPqr64 = 0>
140143 : InstSBF<outs, ins, asmstr, pattern> {
141144
142- let Inst{63-60} = op;
145+ // In the PQR class, instructions that deal with 64-bit registers have a different OpCode.
146+ // To obtain it, we add one to its base value.
147+ let Inst{63-60} = !if(IsPqr64, !add(op, 1), op);
143148 let Inst{59} = srctype;
144149}
145150
@@ -211,9 +216,11 @@ defm JSLE : J<SBF_JSLE, "jsle", SBF_CC_LE>;
211216}
212217
213218// ALU instructions
214- class ALU_RI<SBFOpClass Class, SBFArithOp Opc,
215- dag outs, dag ins, string asmstr, list<dag> pattern>
216- : TYPE_ALU_JMP<Opc.Value, SBF_K.Value, outs, ins, asmstr, pattern> {
219+ class MATH_RI<SBFOpClass Class, SBFArithOp Opc,
220+ dag outs, dag ins, string asmstr,
221+ list<dag> pattern, bit isPqr64 = 0>
222+ : TYPE_ALU_JMP<Opc.Value, SBF_K.Value, outs, ins,
223+ asmstr, pattern, isPqr64> {
217224 bits<4> dst;
218225 bits<32> imm;
219226
@@ -222,9 +229,11 @@ class ALU_RI<SBFOpClass Class, SBFArithOp Opc,
222229 let SBFClass = Class;
223230}
224231
225- class ALU_RR<SBFOpClass Class, SBFArithOp Opc,
226- dag outs, dag ins, string asmstr, list<dag> pattern>
227- : TYPE_ALU_JMP<Opc.Value, SBF_X.Value, outs, ins, asmstr, pattern> {
232+ class MATH_RR<SBFOpClass Class, SBFArithOp Opc,
233+ dag outs, dag ins, string asmstr,
234+ list<dag> pattern, bit isPqr64 = 0>
235+ : TYPE_ALU_JMP<Opc.Value, SBF_X.Value, outs, ins,
236+ asmstr, pattern, isPqr64> {
228237 bits<4> dst;
229238 bits<4> src;
230239
@@ -233,25 +242,14 @@ class ALU_RR<SBFOpClass Class, SBFArithOp Opc,
233242 let SBFClass = Class;
234243}
235244
236- multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode, bit UseImmPat = 1> {
237- def _rr : ALU_RR<SBF_ALU64, Opc,
238- (outs GPR:$dst),
239- (ins GPR:$src2, GPR:$src),
240- Mnemonic # "64 $dst, $src",
241- [(set GPR:$dst, (OpNode i64:$src2, i64:$src))]>;
242- def _ri : ALU_RI<SBF_ALU64, Opc,
243- (outs GPR:$dst),
244- (ins GPR:$src2, i64imm:$imm),
245- Mnemonic # "64 $dst, $imm",
246- !if(UseImmPat,
247- [(set GPR:$dst,
248- (OpNode GPR:$src2, i64immSExt32:$imm))], [])>;
249- def _rr_32 : ALU_RR<SBF_ALU, Opc,
245+ multiclass MATH_32<SBFArithOp Opc, string Mnemonic,
246+ SBFOpClass Class, SDNode OpNode, bit UseImmPat = 1> {
247+ def _rr_32 : MATH_RR<Class, Opc,
250248 (outs GPR32:$dst),
251249 (ins GPR32:$src2, GPR32:$src),
252250 Mnemonic # "32 $dst, $src",
253251 [(set GPR32:$dst, (OpNode i32:$src2, i32:$src))]>;
254- def _ri_32 : ALU_RI<SBF_ALU , Opc,
252+ def _ri_32 : MATH_RI<Class , Opc,
255253 (outs GPR32:$dst),
256254 (ins GPR32:$src2, i32imm:$imm),
257255 Mnemonic # "32 $dst, $imm",
@@ -260,6 +258,40 @@ multiclass ALU<SBFArithOp Opc, string Mnemonic, SDNode OpNode, bit UseImmPat = 1
260258 (OpNode GPR32:$src2, i32immSExt32:$imm))], [])>;
261259}
262260
261+ multiclass MATH_64<SBFArithOp Opc, string Mnemonic,
262+ SBFOpClass Class, SDNode OpNode, bit UseImmPat = 1> {
263+
264+ defvar isPqr64 = !if(!eq(Class, SBF_PQR), 1, 0);
265+
266+ def _rr : MATH_RR<Class, Opc,
267+ (outs GPR:$dst),
268+ (ins GPR:$src2, GPR:$src),
269+ Mnemonic # "64 $dst, $src",
270+ [(set GPR:$dst, (OpNode i64:$src2, i64:$src))],
271+ isPqr64>;
272+
273+ def _ri : MATH_RI<Class, Opc,
274+ (outs GPR:$dst),
275+ (ins GPR:$src2, i64imm:$imm),
276+ Mnemonic # "64 $dst, $imm",
277+ !if(UseImmPat,
278+ [(set GPR:$dst,
279+ (OpNode GPR:$src2, i64immSExt32:$imm))], []),
280+ isPqr64>;
281+ }
282+
283+ multiclass ALU<SBFArithOp Opc, string Mnemonic,
284+ SDNode OpNode, bit UseImmPat = 1> {
285+ defm "" : MATH_64<Opc, Mnemonic, SBF_ALU64, OpNode, UseImmPat>;
286+
287+ defm "" : MATH_32<Opc, Mnemonic, SBF_ALU, OpNode, UseImmPat>;
288+ }
289+
290+ multiclass PQR<SBFArithOp Opc, string Mnemonic, SDNode OpNode> {
291+ defm "" : MATH_64<Opc, Mnemonic, SBF_PQR, OpNode>;
292+ defm "" : MATH_32<Opc, Mnemonic, SBF_PQR, OpNode>;
293+ }
294+
263295let Constraints = "$dst = $src2" in {
264296 let isAsCheapAsAMove = 1 in {
265297 defm ADD : ALU<SBF_ADD, "add", add>;
@@ -272,13 +304,13 @@ let Constraints = "$dst = $src2" in {
272304 defm SRA : ALU<SBF_ARSH, "arsh", sra>;
273305
274306 let Predicates = [SBFNoLddw] in {
275- def HOR : ALU_RI <SBF_ALU64, SBF_HOR,
307+ def HOR : MATH_RI <SBF_ALU64, SBF_HOR,
276308 (outs GPR:$dst),
277309 (ins GPR:$src2, i32imm:$imm),
278310 "hor64 $dst, $imm",
279311 []>;
280312 let DecoderNamespace = "SBFv2" in {
281- def HOR_addr : ALU_RI <SBF_ALU64, SBF_HOR,
313+ def HOR_addr : MATH_RI <SBF_ALU64, SBF_HOR,
282314 (outs GPR:$dst),
283315 (ins GPR:$src2, u64imm:$imm),
284316 "hor64 $dst, $imm",
@@ -288,11 +320,20 @@ let Constraints = "$dst = $src2" in {
288320 }
289321 }
290322
291- defm MUL : ALU<SBF_MUL, "mul", mul>;
292- defm DIV : ALU<SBF_DIV, "div", udiv>;
293323
294- let Predicates = [SBFSubtargetSolana] in {
295- defm SDIV : ALU<SBF_SDIV, "sdiv", sdiv>;
324+ let Predicates = [SBFNoPqrInstr] in {
325+ defm MUL : ALU<SBF_MUL, "mul", mul>;
326+ defm DIV : ALU<SBF_DIV, "div", udiv>;
327+ }
328+
329+ let Predicates = [SBFPqrInstr] in {
330+ defm UHMUL : MATH_64<PQR_UHMUL, "uhmul", SBF_PQR, mulhu>;
331+ defm UDIV : PQR<PQR_UDIV, "udiv", udiv>;
332+ defm UREM : PQR<PQR_UREM, "urem", urem>;
333+ defm LMUL : PQR<PQR_LMUL, "lmul", mul>;
334+ defm SHMUL : MATH_64<PQR_SHMUL, "shmul", SBF_PQR, mulhs>;
335+ defm SDIV_pqr : PQR<PQR_SDIV, "sdiv", sdiv>;
336+ defm SREM : PQR<PQR_SREM, "srem", srem>;
296337 }
297338}
298339
@@ -355,22 +396,22 @@ class LD_IMM64<bits<4> Pseudo, string Mnemonic>
355396
356397let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
357398def LD_imm64 : LD_IMM64<0, "lddw">, Requires<[SBFHasLddw]>;
358- def MOV_rr : ALU_RR <SBF_ALU64, SBF_MOV,
399+ def MOV_rr : MATH_RR <SBF_ALU64, SBF_MOV,
359400 (outs GPR:$dst),
360401 (ins GPR:$src),
361402 "mov64 $dst, $src",
362403 []>;
363- def MOV_ri : ALU_RI <SBF_ALU64, SBF_MOV,
404+ def MOV_ri : MATH_RI <SBF_ALU64, SBF_MOV,
364405 (outs GPR:$dst),
365406 (ins i64imm:$imm),
366407 "mov64 $dst, $imm",
367408 [(set GPR:$dst, (i64 i64immSExt32:$imm))]>;
368- def MOV_rr_32 : ALU_RR <SBF_ALU, SBF_MOV,
409+ def MOV_rr_32 : MATH_RR <SBF_ALU, SBF_MOV,
369410 (outs GPR32:$dst),
370411 (ins GPR32:$src),
371412 "mov32 $dst, $src",
372413 []>;
373- def MOV_ri_32 : ALU_RI <SBF_ALU, SBF_MOV,
414+ def MOV_ri_32 : MATH_RI <SBF_ALU, SBF_MOV,
374415 (outs GPR32:$dst),
375416 (ins i32imm:$imm),
376417 "mov32 $dst, $imm",
@@ -468,7 +509,7 @@ let isCodeGenOnly = 1 in {
468509 "$dst = core_alu32_mem($opcode, $src, $offset)",
469510 []>;
470511 let Constraints = "$dst = $src" in {
471- def CORE_SHIFT : ALU_RR <SBF_ALU64, SBF_LSH,
512+ def CORE_SHIFT : MATH_RR <SBF_ALU64, SBF_LSH,
472513 (outs GPR:$dst),
473514 (ins u64imm:$opcode, GPR:$src, u64imm:$offset),
474515 "$dst = core_shift($opcode, $src, $offset)",
@@ -896,16 +937,16 @@ let Constraints = "$dst = $src" in {
896937}
897938
898939let isCodeGenOnly = 1 in {
899- def MOV_32_64 : ALU_RR <SBF_ALU, SBF_MOV,
940+ def MOV_32_64 : MATH_RR <SBF_ALU, SBF_MOV,
900941 (outs GPR:$dst), (ins GPR32:$src),
901942 "mov32 $dst, $src", []>;
902- def MOV_32_64_addr : ALU_RI <SBF_ALU, SBF_MOV,
943+ def MOV_32_64_addr : MATH_RI <SBF_ALU, SBF_MOV,
903944 (outs GPR:$dst), (ins u64imm:$imm),
904945 "mov32 $dst, $imm", []>, Requires<[SBFNoLddw]>;
905946}
906947
907948let DecoderNamespace = "SBFv2", Predicates = [SBFNoLddw] in {
908- def MOV_32_64_imm : ALU_RI <SBF_ALU, SBF_MOV,
949+ def MOV_32_64_imm : MATH_RI <SBF_ALU, SBF_MOV,
909950 (outs GPR:$dst), (ins i32imm:$imm),
910951 "mov32 $dst, $imm", []>;
911952}
0 commit comments