From 3823bb41764801a8a1c5e04bdc11976c9ff84ff3 Mon Sep 17 00:00:00 2001 From: YazZz1k Date: Wed, 23 Nov 2022 12:45:44 +0300 Subject: [PATCH] [maplecg] asm instruction builders implement builders for following asm inst: adds, subs, adc, sbc, mulh, tst --- .../include/cg/aarch64/aarch64_cgfunc.h | 14 +- .../include/cg/aarch64/aarch64_md.def | 47 +++- .../src/cg/aarch64/aarch64_cgfunc.cpp | 207 +++++++++++++++++- 3 files changed, 255 insertions(+), 13 deletions(-) diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h index e39b201631..6a73804a7a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_cgfunc.h @@ -187,6 +187,11 @@ class AArch64CGFunc : public CGFunc { void SelectAdd(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; Operand *SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; + void SelectAdds(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); + void SelectSubs(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); + void SelectAdc(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); + void SelectSbc(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); + void SelectCarryOperator(bool isAdc, Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); Operand &SelectCGArrayElemAdd(BinaryNode &node, const BaseNode &parent) override; void SelectMadd(Operand &resOpnd, Operand &opndM0, Operand &opndM1, Operand &opnd1, PrimType primType) override; Operand *SelectMadd(BinaryNode &node, Operand &opndM0, Operand &opndM1, Operand &opnd1, @@ -201,8 +206,9 @@ class AArch64CGFunc : public CGFunc { void SelectBior(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; Operand *SelectBxor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; void SelectBxor(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; - - void SelectBxorShift(Operand &resOpnd, Operand *opnd0, Operand *opnd1, Operand &opnd2, PrimType primType); + void SelectBandShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, BitShiftOperand &shiftOp, PrimType primType); + void SelectBiorShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, BitShiftOperand &shiftOp, PrimType primType); + void SelectBxorShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, BitShiftOperand &shiftOp, PrimType primType); Operand *SelectLand(BinaryNode &node, Operand &lhsOpnd, Operand &rhsOpnd, const BaseNode &parent) override; Operand *SelectLor(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent, bool parentIsBr = false) override; @@ -223,6 +229,8 @@ class AArch64CGFunc : public CGFunc { void SelectAArch64CSINV(Operand &res, Operand &o0, Operand &o1, CondOperand &cond, bool is64Bits); void SelectAArch64CSINC(Operand &res, Operand &o0, Operand &o1, CondOperand &cond, bool is64Bits); void SelectShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, ShiftDirection direct, PrimType primType); + void SelectTst(Operand &opnd0, Operand &opnd1, uint32 dsize); + void SelectMulh(bool isSigned, Operand &resOpnd, Operand &opnd0, Operand &opnd1); Operand *SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) override; void SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) override; /* method description contains method information which is metadata for reflection. */ @@ -881,6 +889,8 @@ class AArch64CGFunc : public CGFunc { PrimType primType); MOperator SelectRelationMop(RelationOperator operatorCode, RelationOperatorOpndPattern opndPattern, bool is64Bits, bool isBitmaskImmediate, bool isBitNumLessThan16) const; + void SelectRelationShiftOperator(RelationOperator operatorCode, Operand &resOpnd, Operand &opnd0, Operand &opnd1, + BitShiftOperand &shiftOp, PrimType primType); Operand *SelectMinOrMax(bool isMin, const BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent); void SelectMinOrMax(bool isMin, Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType); Operand *SelectRoundLibCall(RoundType roundType, const TypeCvtNode &node, Operand &opnd0); diff --git a/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def b/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def index 4e84c64354..8ecd1c646a 100644 --- a/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def +++ b/src/mapleall/maple_be/include/cg/aarch64/aarch64_md.def @@ -53,27 +53,46 @@ DEFINE_MOP(MOP_xadri64, {&OpndDesc::Reg64ID,&OpndDesc::Imm64},ISLOADADDR,kLtShif DEFINE_MOP(MOP_xadrpl12, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Literal12Src},ISLOADADDR,kLtAlu,"add","0,1,2",1) -/* AARCH64 Arithmetic: add */ +/* AARCH64 Arithmetic: add/adds */ +/* MOP newly add to the following group should be related pairs with such order :{ add, adds } */ /* MOP_xaddrrr */ DEFINE_MOP(MOP_xaddrrr, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtAlu,"add","0,1,2",1) +/* MOP_xaddsrrr */ +DEFINE_MOP(MOP_xaddsrrr, {&OpndDesc::CCD, &OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtAlu,"adds","1,2,3",1) /* MOP_xaddrrrs */ DEFINE_MOP(MOP_xaddrrrs, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS,&OpndDesc::Bitshift64},0,kLtAluShift,"add","0,1,2,3",1) -/* MOP_xxwaddrrre */ -DEFINE_MOP(MOP_xxwaddrrre, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg32IS,&OpndDesc::Extendshift64},0,kLtAluShift,"add","0,1,2,3",1) +/* MOP_xaddsrrrs */ +DEFINE_MOP(MOP_xaddsrrrs, {&OpndDesc::CCD, &OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS,&OpndDesc::Bitshift64},0,kLtAluShift,"adds","1,2,3,4",1) /* MOP_xaddrri24 */ -DEFINE_MOP(MOP_xaddrri24, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Imm12,&OpndDesc::Lsl12},0,kLtShift,"add","0,1,2,3",1,Imm12BitValid) +DEFINE_MOP(MOP_xaddrri24, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Imm12,&OpndDesc::Lsl12},0,kLtAluShift,"add","0,1,2,3",1,Imm12BitValid) +/* MOP_xaddsrri24 */ +DEFINE_MOP(MOP_xaddsrri24, {&OpndDesc::CCD, &OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Imm12,&OpndDesc::Lsl12},0,kLtAluShift,"adds","1,2,3,4",1,Imm12BitValid) /* MOP_xaddrri12 */ DEFINE_MOP(MOP_xaddrri12, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Imm12},0,kLtAlu,"add","0,1,2",1,Imm12BitValid) +/* MOP_xaddsrri12 */ +DEFINE_MOP(MOP_xaddsrri12, {&OpndDesc::CCD, &OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Imm12},0,kLtAlu,"adds","1,2,3",1,Imm12BitValid) /* MOP_waddrrr */ DEFINE_MOP(MOP_waddrrr, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS},0,kLtAlu,"add","0,1,2",1) +/* MOP_waddsrrr */ +DEFINE_MOP(MOP_waddsrrr, {&OpndDesc::CCD,&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS},0,kLtAlu,"adds","1,2,3",1) /* MOP_waddrrrs */ DEFINE_MOP(MOP_waddrrrs, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS,&OpndDesc::Bitshift32},0,kLtAluShift,"add","0,1,2,3",1) -/* MOP_xxwaddrrre */ -DEFINE_MOP(MOP_wwwaddrrre, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS,&OpndDesc::Extendshift64},0,kLtAluShift,"add","0,1,2,3",1) +/* MOP_waddsrrrs */ +DEFINE_MOP(MOP_waddsrrrs, {&OpndDesc::CCD,&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS,&OpndDesc::Bitshift32},0,kLtAluShift,"adds","1,2,3,4",1) /* MOP_waddrri24 */ DEFINE_MOP(MOP_waddrri24, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Imm12,&OpndDesc::Lsl12},0,kLtAluShift,"add","0,1,2,3",1,Imm12BitValid) +/* MOP_waddsrri24 */ +DEFINE_MOP(MOP_waddsrri24, {&OpndDesc::CCD,&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Imm12,&OpndDesc::Lsl12},0,kLtAluShift,"adds","1,2,3,4",1,Imm12BitValid) /* MOP_waddrri12 */ DEFINE_MOP(MOP_waddrri12, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Imm12},0,kLtAlu,"add","0,1,2",1,Imm12BitValid) +/* MOP_waddsrri12 */ +DEFINE_MOP(MOP_waddsrri12, {&OpndDesc::CCD,&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Imm12},0,kLtAlu,"adds","1,2,3",1,Imm12BitValid) + +/* AARCH64 Arithmetic: add */ +/* MOP_xxwaddrrre */ +DEFINE_MOP(MOP_xxwaddrrre, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg32IS,&OpndDesc::Extendshift64},0,kLtAluShift,"add","0,1,2,3",1) +/* MOP_wwwaddrrre */ +DEFINE_MOP(MOP_wwwaddrrre, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS,&OpndDesc::Extendshift64},0,kLtAluShift,"add","0,1,2,3",1) /* MOP_dadd */ DEFINE_MOP(MOP_dadd, {&OpndDesc::Reg64FD,&OpndDesc::Reg64FS,&OpndDesc::Reg64FS},0,kLtFpalu,"fadd","0,1,2",1) /* MOP_sadd */ @@ -124,6 +143,16 @@ DEFINE_MOP(MOP_dsub, {&OpndDesc::Reg64FD,&OpndDesc::Reg64FS,&OpndDesc::Reg64FS}, /* MOP_ssub */ DEFINE_MOP(MOP_ssub, {&OpndDesc::Reg32FD,&OpndDesc::Reg32FS,&OpndDesc::Reg32FS},0,kLtFpalu,"fsub","0,1,2",1) +/* AARCH64 Arithmetic: adc/sbc */ +/* MOP_xadcrrr */ +DEFINE_MOP(MOP_xadcrrr, {&OpndDesc::CCD, &OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtAlu,"adc","1,2,3",1) +/* MOP_xsbcrrr */ +DEFINE_MOP(MOP_xsbcrrr, {&OpndDesc::CCD, &OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtAlu,"sbc","1,2,3",1) +/* MOP_wadcrrr */ +DEFINE_MOP(MOP_wadcrrr, {&OpndDesc::CCD,&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS},0,kLtAlu,"adc","1,2,3",1) +/* MOP_wsbcrrr */ +DEFINE_MOP(MOP_wsbcrrr, {&OpndDesc::CCD,&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS},0,kLtAlu,"sbc","1,2,3",1) + /* AARCH64 Arithmetic: multiply */ /* MOP_Tbxmulrrr */ DEFINE_MOP(MOP_xmulrrr, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtMul,"mul","0,1,2",1) @@ -142,6 +171,12 @@ DEFINE_MOP(MOP_xmaddrrrr, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg6 /* MOP_wmaddrrrr */ DEFINE_MOP(MOP_wmaddrrrr, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS,&OpndDesc::Reg32IS},0,kLtMul,"madd","0,1,2,3",1) +/* AARCH64 Arithmetic: multiply high */ +/* MOP_smulh */ +DEFINE_MOP(MOP_smulh, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtMul,"smulh","0,1,2",1) +/* MOP_umulh */ +DEFINE_MOP(MOP_umulh, {&OpndDesc::Reg64ID,&OpndDesc::Reg64IS,&OpndDesc::Reg64IS},0,kLtMul,"umulh","0,1,2",1) + /* AARCH64 leading zeros, reverse bits (for trailing zeros) */ /* MOP_wclz */ DEFINE_MOP(MOP_wclz, {&OpndDesc::Reg32ID,&OpndDesc::Reg32IS},0,kLtAlu,"clz","0,1", 1) diff --git a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp index 67fde07e02..a482dc855f 100644 --- a/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp +++ b/src/mapleall/maple_be/src/cg/aarch64/aarch64_cgfunc.cpp @@ -3976,6 +3976,151 @@ void AArch64CGFunc::SelectGoto(GotoNode &stmt) { GetCurBB()->SetKind(BB::kBBGoto); } +void AArch64CGFunc::SelectAdds(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) { + ASSERT((opnd0.IsImmediate() || opnd0.IsRegister()) && (opnd1.IsImmediate() || opnd1.IsRegister()), + "opnd type isn't expected"); + + // adds #imm, reg + if (opnd0.IsImmediate() && opnd1.IsRegister()) { + // swap operands + SelectAdds(resOpnd, opnd1, opnd0, primType); + return; + } + + // adds #imm, #imm + if (opnd0.IsImmediate() && opnd1.IsImmediate()) { + SelectAdds(resOpnd, SelectCopy(opnd0, primType, primType), opnd1, primType); + return; + } + + uint8 dsize = (GetPrimTypeBitSize(primType) == k64BitSize) ? k64BitSize : k32BitSize; + bool is64bits = (dsize == k64BitSize); + + // adds reg, reg + if (opnd0.IsRegister() && opnd1.IsRegister()) { + Operand &rflag = GetOrCreateRflag(); + MOperator mOp = is64bits ? MOP_xaddsrrr : MOP_waddsrrr; + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, opnd0, opnd1); + GetCurBB()->AppendInsn(insn); + return; + } + + // adds reg, #imm + if (opnd0.IsRegister() && opnd1.IsImmediate()) { + ImmOperand &imm = static_cast(opnd1); + + // { adds reg, #-imm } is equal to { subs reg, #imm } + if (imm.IsNegative()) { + imm.Negate(); + SelectSubs(resOpnd, opnd0, opnd1, primType); + return; + } + + // imm : 0 ~ 0xfff + // adds reg, #imm12 + if (imm.IsInBitSize(kMaxImmVal12Bits, 0)) { + Operand &rflag = GetOrCreateRflag(); + MOperator mOp = is64bits ? MOP_xaddsrri12 : MOP_waddsrri12; + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, opnd0, imm); + GetCurBB()->AppendInsn(insn); + return; + } + + // imm : 0x0001 ~ 0x000fff + // adds reg, #imm24 << #12 + if (imm.IsInBitSize(kMaxImmVal24Bits, 0) && imm.IsInBitSizeRot(kMaxImmVal12Bits)) { + MOperator mOp = is64bits ? MOP_xaddsrri24 : MOP_waddsrri24; + BitShiftOperand &shiftOpnd = CreateBitShiftOperand(BitShiftOperand::kLSL, kShiftAmount12, k64BitSize); + imm.DivideByPow2(kMaxImmVal12Bits); + Operand &rflag = GetOrCreateRflag(); + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, opnd0, imm, shiftOpnd); + GetCurBB()->AppendInsn(insn); + return; + } + + RegOperand ®Opnd1 = LoadIntoRegister(opnd1, true, dsize); + SelectAdds(resOpnd, opnd0, regOpnd1, primType); + return; + } +} + +void AArch64CGFunc::SelectSubs(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) { + ASSERT((opnd0.IsImmediate() || opnd0.IsRegister()) && (opnd1.IsImmediate() || opnd1.IsRegister()), + "opnd type isn't expected"); + + uint8 dsize = (GetPrimTypeBitSize(primType) == k64BitSize) ? k64BitSize : k32BitSize; + bool is64bits = (dsize == k64BitSize); + + // first operand must be a register + RegOperand ®Opnd0 = LoadIntoRegister(opnd0, true, dsize); + + // subs reg, reg + if (opnd1.IsRegister()) { + MOperator mOp = is64bits ? MOP_xsubsrrr : MOP_wsubsrrr; + Operand &rflag = GetOrCreateRflag(); + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, opnd0, opnd1); + GetCurBB()->AppendInsn(insn); + return; + } + + // subs reg, #imm + if (opnd1.IsImmediate()) { + ImmOperand &imm = static_cast(opnd1); + + // { subs reg, #-imm } is equal to { adds reg, #imm } + if (imm.IsNegative()) { + imm.Negate(); + SelectAdds(resOpnd, regOpnd0, opnd1, primType); + return; + } + + // imm : 0 ~ 0xfff + // subs reg, #imm12 + if (imm.IsInBitSize(kMaxImmVal12Bits, 0)) { + MOperator mOp = is64bits ? MOP_xsubsrri12 : MOP_wsubsrri12; + Operand &rflag = GetOrCreateRflag(); + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, regOpnd0, imm); + GetCurBB()->AppendInsn(insn); + return; + } + + // imm : 0x0001 ~ 0x000fff + // subs reg, #imm24 << #12 + if (imm.IsInBitSize(kMaxImmVal24Bits, 0) && imm.IsInBitSizeRot(kMaxImmVal12Bits)) { + MOperator mOp = is64bits ? MOP_xsubsrri24 : MOP_wsubsrri24; + BitShiftOperand &shiftOpnd = CreateBitShiftOperand(BitShiftOperand::kLSL, kShiftAmount12, k64BitSize); + imm.DivideByPow2(kMaxImmVal12Bits); + Operand &rflag = GetOrCreateRflag(); + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, regOpnd0, imm, shiftOpnd); + GetCurBB()->AppendInsn(insn); + return; + } + + RegOperand ®Opnd1 = LoadIntoRegister(opnd1, true, dsize); + SelectSubs(resOpnd, regOpnd0, regOpnd1, primType); + return; + } +} + +void AArch64CGFunc::SelectAdc(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) { + SelectCarryOperator(true /* adc */, resOpnd, opnd0, opnd1, primType); +} +void AArch64CGFunc::SelectSbc(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) { + SelectCarryOperator(false /* sbc */, resOpnd, opnd0, opnd1, primType); +} + +void AArch64CGFunc::SelectCarryOperator(bool isAdc, Operand &resOpnd, Operand &opnd0, Operand &opnd1, + PrimType primType) { + uint8 dsize = (GetPrimTypeBitSize(primType) == k64BitSize) ? k64BitSize : k32BitSize; + RegOperand ®Opnd0 = LoadIntoRegister(opnd0, true, dsize); + RegOperand ®Opnd1 = LoadIntoRegister(opnd1, true, dsize); + Operand &rflag = GetOrCreateRflag(); + + MOperator mOp = (dsize == k64BitSize) ? (isAdc ? MOP_xadcrrr : MOP_xsbcrrr) : (isAdc ? MOP_wadcrrr : MOP_wsbcrrr); + auto &insn = GetInsnBuilder()->BuildInsn(mOp, rflag, resOpnd, regOpnd0, regOpnd1); + GetCurBB()->AppendInsn(insn); +} + Operand *AArch64CGFunc::SelectAdd(BinaryNode &node, Operand &opnd0, Operand &opnd1, const BaseNode &parent) { PrimType dtype = node.GetPrimType(); bool isSigned = IsSignedInteger(dtype); @@ -4306,6 +4451,16 @@ Operand *AArch64CGFunc::SelectMpy(BinaryNode &node, Operand &opnd0, Operand &opn return resOpnd; } +void AArch64CGFunc::SelectMulh(bool isSigned, Operand &resOpnd, Operand &opnd0, Operand &opnd1) { + ASSERT(resOpnd.IsRegister(), "res opnd must be a register"); + auto pTy = isSigned ? PTY_i64 : PTY_u64; // MULH supports only 64-bits registers + RegOperand ®Opnd0 = LoadIntoRegister(opnd0, pTy); + RegOperand ®Opnd1 = LoadIntoRegister(opnd1, pTy); + MOperator mOp = isSigned ? MOP_smulh : MOP_umulh; + auto &insn = GetInsnBuilder()->BuildInsn(mOp, resOpnd, regOpnd0, regOpnd1); + GetCurBB()->AppendInsn(insn); +} + void AArch64CGFunc::SelectMpy(Operand &resOpnd, Operand &opnd0, Operand &opnd1, PrimType primType) { Operand::OperandType opnd0Type = opnd0.GetKind(); Operand::OperandType opnd1Type = opnd1.GetKind(); @@ -5137,14 +5292,45 @@ Operand *AArch64CGFunc::SelectRor(BinaryNode &node, Operand &opnd0, Operand &opn return resOpnd; } -void AArch64CGFunc::SelectBxorShift(Operand &resOpnd, Operand *opnd0, Operand *opnd1, Operand &opnd2, +void AArch64CGFunc::SelectBandShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, BitShiftOperand &shiftOp, + PrimType primType) { + SelectRelationShiftOperator(kAND, resOpnd, opnd0, opnd1, shiftOp, primType); +} + +void AArch64CGFunc::SelectBiorShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, BitShiftOperand &shiftOp, + PrimType primType) { + SelectRelationShiftOperator(kIOR, resOpnd, opnd0, opnd1, shiftOp, primType); +} + +void AArch64CGFunc::SelectBxorShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, BitShiftOperand &shiftOp, PrimType primType) { - opnd0 = &LoadIntoRegister(*opnd0, primType); - opnd1 = &LoadIntoRegister(*opnd1, primType); + SelectRelationShiftOperator(kEOR, resOpnd, opnd0, opnd1, shiftOp, primType); +} + +void AArch64CGFunc::SelectRelationShiftOperator(RelationOperator operatorCode, Operand &resOpnd, Operand &opnd0, + Operand &opnd1, BitShiftOperand &shiftOp, PrimType primType) { + RegOperand ®Opnd0 = LoadIntoRegister(opnd0, primType); + RegOperand ®Opnd1 = LoadIntoRegister(opnd1, primType); + uint32 dsize = GetPrimTypeBitSize(primType); bool is64Bits = (dsize == k64BitSize); - MOperator mopBxor = is64Bits ? MOP_xeorrrrs : MOP_weorrrrs; - GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(mopBxor, resOpnd, *opnd0, *opnd1, opnd2)); + + MOperator mOp = MOP_undef; + switch (operatorCode) { + case kAND: + mOp = is64Bits ? MOP_xandrrrs : MOP_wandrrrs; + break; + case kIOR: + mOp = is64Bits ? MOP_xiorrrrs : MOP_wiorrrrs; + break; + case kEOR: + mOp = is64Bits ? MOP_xeorrrrs : MOP_weorrrrs; + break; + default: + break; + } + + GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(mOp, resOpnd, regOpnd0, regOpnd1, shiftOp)); } void AArch64CGFunc::SelectShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1, ShiftDirection direct, @@ -5199,6 +5385,17 @@ void AArch64CGFunc::SelectShift(Operand &resOpnd, Operand &opnd0, Operand &opnd1 GetCurBB()->AppendInsn(GetInsnBuilder()->BuildInsn(mopShift, resOpnd, *firstOpnd, opnd1)); } +void AArch64CGFunc::SelectTst(Operand &opnd0, Operand &opnd1, uint32 size) { + ASSERT(opnd0.IsRegister() && (opnd1.IsRegister() || opnd1.IsImmediate()), "opnd type isn't expected"); + + auto mOpCode = opnd1.IsImmediate() ? (size <= k32BitSize ? MOP_wtstri32 : MOP_xtstri64) + : (size <= k32BitSize ? MOP_wtstrr : MOP_xtstrr); + + Operand &rflag = GetOrCreateRflag(); + Insn &insn = GetInsnBuilder()->BuildInsn(mOpCode, rflag, opnd0, opnd1); + GetCurBB()->AppendInsn(insn); +} + Operand *AArch64CGFunc::SelectAbsSub(Insn &lastInsn, const UnaryNode &node, Operand &newOpnd0) { PrimType dtyp = node.GetPrimType(); bool is64Bits = (GetPrimTypeBitSize(dtyp) == k64BitSize); -- Gitee