diff options
author | Kai Nacke <kai@redstar.de> | 2022-07-15 22:03:13 -0400 |
---|---|---|
committer | Kai Nacke <kai@redstar.de> | 2022-11-13 11:07:34 -0500 |
commit | b68fc168b5d442707160189596aa6cbfa339ac03 (patch) | |
tree | 052f283a864c82400540236d95c209e74836169f | |
parent | 108379ff20e371e57cbe3f34eff4bfaf6f029569 (diff) | |
download | llvm-b68fc168b5d442707160189596aa6cbfa339ac03.zip llvm-b68fc168b5d442707160189596aa6cbfa339ac03.tar.gz llvm-b68fc168b5d442707160189596aa6cbfa339ac03.tar.bz2 |
[m88k] Better floating point support.
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/M88kInstrInfo.td | 42 | ||||
-rw-r--r-- | llvm/test/CodeGen/M88k/floatarith.ll | 350 |
5 files changed, 426 insertions, 30 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp index f64dc32..710e7f4 100644 --- a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp @@ -94,11 +94,12 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) { getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({P0}); getActionDefinitionsBuilder(G_GLOBAL_VALUE).legalFor({P0}); - getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FNEG}) - .legalFor({S32, S64, S80}); - - getActionDefinitionsBuilder(G_FCONSTANT) - .customFor({S32, S64}); + getActionDefinitionsBuilder(G_FCONSTANT).customFor({S32, S64}); + getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV}) + .legalFor({S32, S64}); + getActionDefinitionsBuilder({G_FNEG, G_FABS}).lower(); + getActionDefinitionsBuilder(G_FPEXT).legalFor({{S64, S32}}); + getActionDefinitionsBuilder(G_FPTRUNC).legalFor({{S32, S64}}); // FP to int conversion instructions getActionDefinitionsBuilder(G_FPTOSI) diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp index 0d47d5c..7de2b3f 100644 --- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp @@ -76,39 +76,47 @@ static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) { return false; } -const RegisterBankInfo::InstructionMapping & -M88kRegisterBankInfo::getSameKindOfOperandsMapping( - const MachineInstr &MI) const { +const RegisterBankInfo::ValueMapping * +M88kRegisterBankInfo::getFPOperandsMapping(const MachineInstr &MI) const { const unsigned Opc = MI.getOpcode(); const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); - unsigned NumOperands = MI.getNumOperands(); + const unsigned NumOperands = MI.getNumOperands(); assert(NumOperands <= 3 && "This code is for instructions with 3 or less operands"); + assert(isPreISelGenericFloatingPointOpcode(Opc) && + "No floating point istruction"); - LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - unsigned Size = Ty.getSizeInBits(); - bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc); + bool RequiresXPR = false; + for (unsigned I = 0; I < NumOperands; ++I) + if (MRI.getType(MI.getOperand(0).getReg()).getScalarSizeInBits() == 80) + RequiresXPR = true; + //const RegisterBankInfo::ValueMapping *ValMap[3]; + SmallVector<const RegisterBankInfo::ValueMapping *, 3> ValMap; + for (unsigned I = 0; I < NumOperands; ++I) { PartialMappingIdx RBIdx = PMI_None; - if (IsFPR && Size == 80) { - RBIdx = PMI_XR80; - } else { - switch (Size) { + LLT Ty = MRI.getType(MI.getOperand(I).getReg()); + switch (Ty.getSizeInBits()) { case 32: - RBIdx = PMI_GR32; + RBIdx = RequiresXPR ? PMI_XR32 : PMI_GR32; break; case 64: - RBIdx = PMI_GR64; + RBIdx = RequiresXPR ? PMI_XR64 : PMI_GR64; + break; + case 80: + RBIdx = PMI_XR80; break; default: llvm_unreachable("Unsupport register size"); } + //ValMap[I] = getValueMapping(RBIdx); + ValMap.push_back(getValueMapping(RBIdx)); } - return getInstructionMapping(DefaultMappingID, 1, getValueMapping(RBIdx), - NumOperands); + //return getOperandsMapping(&ValMap[0], &ValMap[NumOperands-1]); + return getOperandsMapping(ValMap); } const RegisterBankInfo::InstructionMapping & @@ -157,7 +165,8 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case TargetOpcode::G_FSUB: case TargetOpcode::G_FMUL: case TargetOpcode::G_FDIV: - return getSameKindOfOperandsMapping(MI); + OperandsMapping = getFPOperandsMapping(MI); + break; case TargetOpcode::G_FCONSTANT: { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); if (Ty.getSizeInBits() != 64 && Ty.getSizeInBits() != 32) @@ -167,6 +176,14 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { {getValueMapping(RBIdx), nullptr}); break; } + case TargetOpcode::G_FPEXT: + OperandsMapping = getOperandsMapping( + {getValueMapping(PMI_GR64), getValueMapping(PMI_GR32)}); + break; + case TargetOpcode::G_FPTRUNC: + OperandsMapping = getOperandsMapping( + {getValueMapping(PMI_GR32), getValueMapping(PMI_GR64)}); + break; case TargetOpcode::G_FPTOSI: case TargetOpcode::G_FPTOUI: { LLT Ty = MRI.getType(MI.getOperand(1).getReg()); diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h index e379367..ccba9aa 100644 --- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h +++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h @@ -71,8 +71,8 @@ protected: /// This class provides the information for the target register banks. class M88kRegisterBankInfo final : public M88kGenRegisterBankInfo { - const InstructionMapping & - getSameKindOfOperandsMapping(const MachineInstr &MI) const; + const RegisterBankInfo::ValueMapping * + getFPOperandsMapping(const MachineInstr &MI) const; public: M88kRegisterBankInfo(const TargetRegisterInfo &TRI); diff --git a/llvm/lib/Target/M88k/M88kInstrInfo.td b/llvm/lib/Target/M88k/M88kInstrInfo.td index 2ba33fb..27b7654 100644 --- a/llvm/lib/Target/M88k/M88kInstrInfo.td +++ b/llvm/lib/Target/M88k/M88kInstrInfo.td @@ -1096,12 +1096,16 @@ multiclass FCmpX<bits<4> Func, bits<2> td, string OpcStr> { multiclass FCmp<bits<4> Func, bits<2> td, string OpcStr> : FCmpG<Func, td, OpcStr>, FCmpX<Func, td, OpcStr>; -// TODO Why does ftrunc not work? multiclass FloatBinPat<string Inst, SDPatternOperator OpNode> { def : Pat<(OpNode GPR:$rs1, GPR:$rs2), (!cast<InstM88k>(Inst#"gsss") GPR:$rs1, GPR:$rs2)>; -// def : Pat<(ftrunc (OpNode (fpextend GPR:$rs1), GPR64:$rs2)), -// (!cast<InstM88k>(Inst#"ssd") GPR:$rs1, GPR:$rs2)>; + def : Pat<(fpround (OpNode (fpextend GPR:$rs1), GPR64:$rs2)), + (!cast<InstM88k>(Inst#"gssd") GPR:$rs1, GPR64:$rs2)>; + def : Pat<(fpround (OpNode GPR64:$rs1, (fpextend GPR:$rs2))), + (!cast<InstM88k>(Inst#"gsds") GPR64:$rs1, GPR:$rs2)>; + def : Pat<(fpround (OpNode GPR64:$rs1, GPR64:$rs2)), + (!cast<InstM88k>(Inst#"gsdd") GPR64:$rs1, GPR64:$rs2)>; + def : Pat<(fpextend (OpNode GPR:$rs1, GPR:$rs2)), (!cast<InstM88k>(Inst#"gdss") GPR:$rs1, GPR:$rs2)>; def : Pat<(OpNode (fpextend GPR:$rs1), GPR64:$rs2), @@ -1111,10 +1115,11 @@ multiclass FloatBinPat<string Inst, SDPatternOperator OpNode> { def : Pat<(OpNode GPR64:$rs1, GPR64:$rs2), (!cast<InstM88k>(Inst#"gddd") GPR64:$rs1, GPR64:$rs2)>; + // TODO Extends patterns def : Pat<(OpNode (f32 XR:$rs1), (f32 XR:$rs2)), (!cast<InstM88k>(Inst#"xsss") XR:$rs1, XR:$rs2)>; def : Pat<(OpNode (f64 XR:$rs1), (fpextend (f32 XR:$rs2))), - (!cast<InstM88k>(Inst#"gdds") XR:$rs1, XR:$rs2)>; + (!cast<InstM88k>(Inst#"xdds") XR:$rs1, XR:$rs2)>; def : Pat<(OpNode (f64 XR:$rs1), (f64 XR:$rs2)), (!cast<InstM88k>(Inst#"xddd") XR:$rs1, XR:$rs2)>; def : Pat<(OpNode (f80 XR:$rs1), (f80 XR:$rs2)), @@ -1136,9 +1141,32 @@ defm NINT : FArith2<0b1010, "nint">; defm TRNC : FArith2<0b1011, "trnc">; let Predicates = [IsMC881100] in { -defm FCVT : FUnary<0b0001, "fcvt", false>; -defm FSQRT : FUnary<0b1111, "fsqrt", true>; -} + defm FCVT : FUnary<0b0001, "fcvt", false>; + defm FSQRT : FUnary<0b1111, "fsqrt", true>; + + def : Pat<(fpextend (f32 GPR:$rs1)), + (FCVTgds GPR:$rs1)>; + def : Pat<(fpround (f64 GPR64:$rs1)), + (FCVTgsd GPR64:$rs1)>; + + def : Pat<(f64 (fpextend (f32 XR:$rs1))), + (FCVTxds XR:$rs1)>; + def : Pat<(f80 (fpextend (f32 XR:$rs1))), + (FCVTxxs XR:$rs1)>; + def : Pat<(f80 (fpextend (f64 XR:$rs1))), + (FCVTxxd XR:$rs1)>; + def : Pat<(f32 (fpround (f64 XR:$rs1))), + (FCVTxsd XR:$rs1)>; + def : Pat<(f32 (fpround (f80 XR:$rs1))), + (FCVTxsx XR:$rs1)>; + def : Pat<(f64 (fpround (f80 XR:$rs1))), + (FCVTxdx XR:$rs1)>; +} + +def : Pat<(fpextend (f32 GPR:$rs1)), + (FSUBgdss GPR:$rs1, (f32 R0))>; +def : Pat<(fpround (f64 GPR64:$rs1)), + (FSUBgsds GPR64:$rs1, (f32 R0))>; // Missing: fcmp, fcmpu defm FCMP : FCmp<0b0111, 0b00, "fcmp">; diff --git a/llvm/test/CodeGen/M88k/floatarith.ll b/llvm/test/CodeGen/M88k/floatarith.ll new file mode 100644 index 0000000..a61f4fa --- /dev/null +++ b/llvm/test/CodeGen/M88k/floatarith.ll @@ -0,0 +1,350 @@ +; Test floating point arithmetic. +; +; RUN: llc < %s -mtriple=m88k-openbsd -mcpu=mc88100 -O0 | FileCheck --check-prefixes=CHECK,MC88100 %s +; RUN: llc < %s -mtriple=m88k-openbsd -mcpu=mc88110 -O0 | FileCheck --check-prefixes=CHECK,MC88110 %s + +define float @trunc(double %a) { +; CHECK-LABEL: trunc: +; MC88100: fsub.sds %r2, %r2, %r0 +; MC88110: fcvt.sd %r2, %r2 +; CHECK: jmp %r1 + %trnc = fptrunc double %a to float + ret float %trnc +} + +define double @extend(float %a) { +; CHECK-LABEL: extend: +; MC88100: fsub.dss %r4, %r2, %r0 +; MC88110: fcvt.ds %r4, %r2 +; CHECK: jmp %r1 + %ext = fpext float %a to double + ret double %ext +} + +define float @negate(float %a) { +; CHECK-LABEL: negate: +; CHECK: xor.u %r2, %r2, 32768 +; CHECK: jmp %r1 + %neg = fneg float %a + ret float %neg +} + +define i32 @f32tosi32(float %a) { +; CHECK-LABEL: f32tosi32: +; CHECK: trnc.ss %r2, %r2 +; CHECK: jmp %r1 + %trnc = fptosi float %a to i32 + ret i32 %trnc +} + +define i32 @f64tosi32(double %a) { +; CHECK-LABEL: f64tosi32: +; CHECK: trnc.sd %r2, %r2 +; CHECK: jmp %r1 + %trnc = fptosi double %a to i32 + ret i32 %trnc +} + +define i64 @f32tosi64(float %a) { +; CHECK-LABEL: f32tosi64: +; CHECK: bsr __fixsfdi +; CHECK: jmp %r1 + %trnc = fptosi float %a to i64 + ret i64 %trnc +} + +define i64 @f64tosi64(double %a) { +; CHECK-LABEL: f64tosi64: +; CHECK: bsr __fixdfdi +; CHECK: jmp %r1 + %trnc = fptosi double %a to i64 + ret i64 %trnc +} + +define float @fadd1(float %a, float %b) { +; CHECK-LABEL: fadd1: +; CHECK: fadd.sss %r2, %r2, %r3 +; CHECK: jmp %r1 + %sum = fadd float %a, %b + ret float %sum +} + +define float @fadd2(float %a, double %b) { +; CHECK-LABEL: fadd2: +; CHECK: fadd.ssd %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fadd double %ext, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fadd3(double %a, float %b) { +; CHECK-LABEL: fadd3: +; CHECK: fadd.sds %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fadd double %a, %ext + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fadd4(double %a, double %b) { +; CHECK-LABEL: fadd4: +; CHECK: fadd.sdd %r2, %r2, %r4 +; CHECK: jmp %r1 + %sum = fadd double %a, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define double @fadd5(double %a, double %b) { +; CHECK-LABEL: fadd5: +; CHECK: fadd.ddd %r4, %r2, %r4 +; CHECK: jmp %r1 + %sum = fadd double %a, %b + ret double %sum +} + +define double @fadd6(double %a, float %b) { +; CHECK-LABEL: fadd6: +; CHECK: fadd.dds %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fadd double %a, %ext + ret double %sum +} + +define double @fadd7(float %a, double %b) { +; CHECK-LABEL: fadd7: +; CHECK: fadd.dsd %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fadd double %ext, %b + ret double %sum +} + +define double @fadd8(float %a, float %b) { +; CHECK-LABEL: fadd8: +; CHECK: fadd.dss %r4, %r2, %r3 +; CHECK: jmp %r1 + %sum = fadd float %a, %b + %ext = fpext float %sum to double + ret double %ext +} + +define float @fsub1(float %a, float %b) { +; CHECK-LABEL: fsub1: +; CHECK: fsub.sss %r2, %r2, %r3 +; CHECK: jmp %r1 + %sum = fsub float %a, %b + ret float %sum +} + +define float @fsub2(float %a, double %b) { +; CHECK-LABEL: fsub2: +; CHECK: fsub.ssd %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fsub double %ext, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fsub3(double %a, float %b) { +; CHECK-LABEL: fsub3: +; CHECK: fsub.sds %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fsub double %a, %ext + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fsub4(double %a, double %b) { +; CHECK-LABEL: fsub4: +; CHECK: fsub.sdd %r2, %r2, %r4 +; CHECK: jmp %r1 + %sum = fsub double %a, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define double @fsub5(double %a, double %b) { +; CHECK-LABEL: fsub5: +; CHECK: fsub.ddd %r4, %r2, %r4 +; CHECK: jmp %r1 + %sum = fsub double %a, %b + ret double %sum +} + +define double @fsub6(double %a, float %b) { +; CHECK-LABEL: fsub6: +; CHECK: fsub.dds %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fsub double %a, %ext + ret double %sum +} + +define double @fsub7(float %a, double %b) { +; CHECK-LABEL: fsub7: +; CHECK: fsub.dsd %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fsub double %ext, %b + ret double %sum +} + +define double @fsub8(float %a, float %b) { +; CHECK-LABEL: fsub8: +; CHECK: fsub.dss %r4, %r2, %r3 +; CHECK: jmp %r1 + %sum = fsub float %a, %b + %ext = fpext float %sum to double + ret double %ext +} + +define float @fmul1(float %a, float %b) { +; CHECK-LABEL: fmul1: +; CHECK: fmul.sss %r2, %r2, %r3 +; CHECK: jmp %r1 + %sum = fmul float %a, %b + ret float %sum +} + +define float @fmul2(float %a, double %b) { +; CHECK-LABEL: fmul2: +; CHECK: fmul.ssd %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fmul double %ext, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fmul3(double %a, float %b) { +; CHECK-LABEL: fmul3: +; CHECK: fmul.sds %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fmul double %a, %ext + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fmul4(double %a, double %b) { +; CHECK-LABEL: fmul4: +; CHECK: fmul.sdd %r2, %r2, %r4 +; CHECK: jmp %r1 + %sum = fmul double %a, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define double @fmul5(double %a, double %b) { +; CHECK-LABEL: fmul5: +; CHECK: fmul.ddd %r4, %r2, %r4 +; CHECK: jmp %r1 + %sum = fmul double %a, %b + ret double %sum +} + +define double @fmul6(double %a, float %b) { +; CHECK-LABEL: fmul6: +; CHECK: fmul.dds %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fmul double %a, %ext + ret double %sum +} + +define double @fmul7(float %a, double %b) { +; CHECK-LABEL: fmul7: +; CHECK: fmul.dsd %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fmul double %ext, %b + ret double %sum +} + +define double @fmul8(float %a, float %b) { +; CHECK-LABEL: fmul8: +; CHECK: fmul.dss %r4, %r2, %r3 +; CHECK: jmp %r1 + %sum = fmul float %a, %b + %ext = fpext float %sum to double + ret double %ext +} + +define float @fdiv1(float %a, float %b) { +; CHECK-LABEL: fdiv1: +; CHECK: fdiv.sss %r2, %r2, %r3 +; CHECK: jmp %r1 + %sum = fdiv float %a, %b + ret float %sum +} + +define float @fdiv2(float %a, double %b) { +; CHECK-LABEL: fdiv2: +; CHECK: fdiv.ssd %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fdiv double %ext, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fdiv3(double %a, float %b) { +; CHECK-LABEL: fdiv3: +; CHECK: fdiv.sds %r2, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fdiv double %a, %ext + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define float @fdiv4(double %a, double %b) { +; CHECK-LABEL: fdiv4: +; CHECK: fdiv.sdd %r2, %r2, %r4 +; CHECK: jmp %r1 + %sum = fdiv double %a, %b + %trnc = fptrunc double %sum to float + ret float %trnc +} + +define double @fdiv5(double %a, double %b) { +; CHECK-LABEL: fdiv5: +; CHECK: fdiv.ddd %r4, %r2, %r4 +; CHECK: jmp %r1 + %sum = fdiv double %a, %b + ret double %sum +} + +define double @fdiv6(double %a, float %b) { +; CHECK-LABEL: fdiv6: +; CHECK: fdiv.dds %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %b to double + %sum = fdiv double %a, %ext + ret double %sum +} + +define double @fdiv7(float %a, double %b) { +; CHECK-LABEL: fdiv7: +; CHECK: fdiv.dsd %r4, %r2, %r4 +; CHECK: jmp %r1 + %ext = fpext float %a to double + %sum = fdiv double %ext, %b + ret double %sum +} + +define double @fdiv8(float %a, float %b) { +; CHECK-LABEL: fdiv8: +; CHECK: fdiv.dss %r4, %r2, %r3 +; CHECK: jmp %r1 + %sum = fdiv float %a, %b + %ext = fpext float %sum to double + ret double %ext +} |