Index: llvm/CODE_OWNERS.TXT =================================================================== --- llvm/CODE_OWNERS.TXT +++ llvm/CODE_OWNERS.TXT @@ -228,3 +228,7 @@ N: Martin Storsjö E: martin@martin.st D: MinGW + +N: Zi Xuan Wu (Zeson) +E: zixuan.wu@linux.alibaba.com +D: CSKY backend (lib/Target/CSKY/*) Index: llvm/include/llvm/IR/CMakeLists.txt =================================================================== --- llvm/include/llvm/IR/CMakeLists.txt +++ llvm/include/llvm/IR/CMakeLists.txt @@ -8,6 +8,7 @@ tablegen(LLVM IntrinsicsAMDGPU.h -gen-intrinsic-enums -intrinsic-prefix=amdgcn) tablegen(LLVM IntrinsicsARM.h -gen-intrinsic-enums -intrinsic-prefix=arm) tablegen(LLVM IntrinsicsBPF.h -gen-intrinsic-enums -intrinsic-prefix=bpf) +tablegen(LLVM IntrinsicsCSKY.h -gen-intrinsic-enums -intrinsic-prefix=csky) tablegen(LLVM IntrinsicsHexagon.h -gen-intrinsic-enums -intrinsic-prefix=hexagon) tablegen(LLVM IntrinsicsMips.h -gen-intrinsic-enums -intrinsic-prefix=mips) tablegen(LLVM IntrinsicsNVPTX.h -gen-intrinsic-enums -intrinsic-prefix=nvvm) Index: llvm/include/llvm/IR/Intrinsics.td =================================================================== --- llvm/include/llvm/IR/Intrinsics.td +++ llvm/include/llvm/IR/Intrinsics.td @@ -1588,3 +1588,4 @@ include "llvm/IR/IntrinsicsSystemZ.td" include "llvm/IR/IntrinsicsWebAssembly.td" include "llvm/IR/IntrinsicsRISCV.td" +include "llvm/IR/IntrinsicsCSKY.td" Index: llvm/include/llvm/IR/IntrinsicsCSKY.td =================================================================== --- /dev/null +++ llvm/include/llvm/IR/IntrinsicsCSKY.td @@ -0,0 +1,38 @@ +//===- IntrinsicsCSKY.td - Defines CSKY intrinsics ---------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines all of the CSKY-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "csky" in { // All intrinsics start with "llvm.csky.". + + /// CSKY_Intrinsic - Base class for the majority of CSKY intrinsics. + class CSKY_Intrinsic ret_types, + list param_types, + list properties> + : GCCBuiltin, + Intrinsic; + + /// CSKY_NonGCC_Intrinsic - Base class for bitcode convertible CSKY + /// intrinsics. + class CSKY_NonGCC_Intrinsic ret_types, + list param_types, + list properties> + : Intrinsic; + + // Mark locked loads as read/write to prevent any accidental reordering. + def int_csky_ldex_w : + CSKY_NonGCC_Intrinsic<[llvm_i32_ty], [llvm_ptr32_ty], + [IntrArgMemOnly, NoCapture>]>; + + def int_csky_stex_w : + CSKY_NonGCC_Intrinsic<[llvm_i32_ty], + [llvm_ptr32_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture>]>; + +} // end TargetPrefix Index: llvm/lib/Target/CSKY/AsmParser/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/AsmParser/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMCSKYAsmParser + CSKYAsmParser.cpp + ) Index: llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp @@ -0,0 +1,7 @@ +//===-- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// Index: llvm/lib/Target/CSKY/AsmParser/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/AsmParser/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./lib/Target/CSKY/AsmParser/LLVMBuild.txt ----------------*- Conf -*--===; +; +; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = CSKYAsmParser +parent = CSKY +required_libraries = MC MCParser Support +add_to_library_groups = CSKY Index: llvm/lib/Target/CSKY/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CMakeLists.txt @@ -0,0 +1,32 @@ +set(LLVM_TARGET_DEFINITIONS CSKY.td) + +tablegen(LLVM CSKYGenAsmWriter.inc -gen-asm-writer) +tablegen(LLVM CSKYGenDAGISel.inc -gen-dag-isel) +tablegen(LLVM CSKYGenRegisterInfo.inc -gen-register-info) +tablegen(LLVM CSKYGenInstrInfo.inc -gen-instr-info) +tablegen(LLVM CSKYGenSubtargetInfo.inc -gen-subtarget) +tablegen(LLVM CSKYGenMCCodeEmitter.inc -gen-emitter) +tablegen(LLVM CSKYGenCallingConv.inc -gen-callingconv) +tablegen(LLVM CSKYGenMCPseudoLowering.inc -gen-pseudo-lowering) + +add_public_tablegen_target(CSKYCommonTableGen) + +add_llvm_target(CSKYCodeGen + CSKYAsmPrinter.cpp + CSKYISelDAGToDAG.cpp + CSKYInstrInfo.cpp + CSKYRegisterInfo.cpp + CSKYSubtarget.cpp + CSKYTargetMachine.cpp + CSKYTargetObjectFile.cpp + CSKYFrameLowering.cpp + CSKYISelLowering.cpp + CSKYMCInstLower.cpp + CSKYMachineFunctionInfo.cpp + CSKYConstantPoolValue.cpp + CSKYConstantIslandPass.cpp + ) + +add_subdirectory(TargetInfo) +add_subdirectory(MCTargetDesc) +add_subdirectory(Utils) Index: llvm/lib/Target/CSKY/CSKY.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKY.h @@ -0,0 +1,32 @@ +//===-- CSKY.h - Top-level interface for CSKY--------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in the LLVM +// CSKY back-end. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKY_H +#define LLVM_LIB_TARGET_CSKY_CSKY_H + +#include "llvm/Target/TargetMachine.h" + +namespace llvm { +class CSKYTargetMachine; +class FunctionPass; + +FunctionPass *createCSKYISelDag(CSKYTargetMachine &TM); +FunctionPass *createCSKYConstantIslandPass(); +FunctionPass *createCSKYShrinkInstPass(); +FunctionPass *createCSKYConstantIslandPass(); + +void initializeCSKYConstantIslandsPass(PassRegistry &); + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKY_H Index: llvm/lib/Target/CSKY/CSKY.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKY.td @@ -0,0 +1,101 @@ +//===-- CSKY.td - Describe the CSKY Target Machine ---------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +include "llvm/Target/Target.td" + +//===----------------------------------------------------------------------===// +// CSKY subtarget features and instruction predicates. +//===----------------------------------------------------------------------===// + +def FeatureFPUV2_SF + : SubtargetFeature<"fpuv2_sf", "HasFPUv2SingleFloat", "true", + "Enable FPUv2 single float instructions">; +def HasFPUv2_SF : Predicate<"Subtarget->hasFPUv2SingleFloat()">, + AssemblerPredicate<(all_of FeatureFPUV2_SF)>; + +def FeatureFPUV2_DF + : SubtargetFeature<"fpuv2_df", "HasFPUv2DoubleFloat", "true", + "Enable FPUv2 double float instructions">; +def HasFPUv2_DF : Predicate<"Subtarget->hasFPUv2DoubleFloat()">, + AssemblerPredicate<(all_of FeatureFPUV2_DF)>; + +def FeatureFdivdu : SubtargetFeature<"fdivdu", "HasFdivdu", "true", + "Enable float divide instructions">; +def HasFdivdu : Predicate<"Subtarget->hasFdivdu()">, + AssemblerPredicate<(all_of FeatureFdivdu)>; + +def FeatureFPUV2 + : SubtargetFeature<"fpuv2", "HasFPUv2", "true", "Enable FPUv2 instructions", + [FeatureFPUV2_SF, FeatureFPUV2_DF, FeatureFdivdu]>; +def HasFPUv2 : Predicate<"Subtarget->hasFPUv2()">, + AssemblerPredicate<(all_of FeatureFPUV2)>; + +def FeatureFPUV3_HI + : SubtargetFeature<"fpuv3_hi", "HasFPUv3HalfWord", "true", + "Enable FPUv3 harf word converting instructions">; +def HasFPUv3_HI : Predicate<"Subtarget->hasFPUv3HalfWord()">, + AssemblerPredicate<(all_of FeatureFPUV3_HI)>; + +def FeatureFPUV3_HF + : SubtargetFeature<"fpuv3_hf", "HasFPUv3HalfFloat", "true", + "Enable FPUv3 harf precision operate instructions">; +def HasFPUv3_HF : Predicate<"Subtarget->hasFPUv3HalfFloat()">, + AssemblerPredicate<(all_of FeatureFPUV3_HF)>; + +def FeatureFPUV3_SF + : SubtargetFeature<"fpuv3_sf", "HasFPUv3SingleFloat", "true", + "Enable FPUv3 single float instructions">; +def HasFPUv3_SF : Predicate<"Subtarget->hasFPUv3SingleFloat()">, + AssemblerPredicate<(all_of FeatureFPUV3_SF)>; + +def FeatureFPUV3_DF + : SubtargetFeature<"fpuv3_df", "HasFPUv3DoubleFloat", "true", + "Enable FPUv3 double float instructions">; +def HasFPUv3_DF : Predicate<"Subtarget->hasFPUv3DoubleFloat()">, + AssemblerPredicate<(all_of FeatureFPUV3_DF)>; + +def FeatureFPUV3 + : SubtargetFeature<"fpuv3", "HasFPUv3", "true", "Enable FPUv3 instructions", + [FeatureFPUV3_HI, FeatureFPUV3_SF, FeatureFPUV3_DF]>; +def HasFPUv3 : Predicate<"Subtarget->hasFPUv3()">, + AssemblerPredicate<(all_of FeatureFPUV3)>; + +def ModeSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", + "Use software floating " + "point features">; + +def Has3E3r1 : SubtargetFeature<"3e3r1", "Has3E3r1", "true", + "Support CSKY 3e3r1 instructions">; +def iHas3E3r1 : Predicate<"Subtarget->has3E3r1()">, + AssemblerPredicate<(all_of Has3E3r1)>; + +//===----------------------------------------------------------------------===// +// Registers, calling conventions, instruction descriptions. +//===----------------------------------------------------------------------===// + +include "CSKYRegisterInfo.td" +include "CSKYCallingConv.td" +include "CSKYInstrInfo.td" + +//===----------------------------------------------------------------------===// +// CSKY processors supported. +//===----------------------------------------------------------------------===// + +def : ProcessorModel<"generic-csky", NoSchedModel, []>; +def : ProcessorModel<"ck810", NoSchedModel, []>; + +//===----------------------------------------------------------------------===// +// Define the CSKY target. +//===----------------------------------------------------------------------===// + +def CSKYInstrInfo : InstrInfo; + +def CSKY : Target { + let InstructionSet = CSKYInstrInfo; + let AllowRegisterRenaming = 1; +} \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYAsmPrinter.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYAsmPrinter.h @@ -0,0 +1,58 @@ +//===-- CSKYAsmPrinter.h - CSKY implementation of AsmPrinter ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYASMPRINTER_H +#define LLVM_LIB_TARGET_CSKY_CSKYASMPRINTER_H + +#include "CSKYMCInstLower.h" +#include "CSKYMachineFunctionInfo.h" +#include "CSKYSubtarget.h" +#include "llvm/CodeGen/AsmPrinter.h" + +namespace llvm { +class LLVM_LIBRARY_VISIBILITY CSKYAsmPrinter : public AsmPrinter { + CSKYMCInstLower MCInstLowering; + + /// Subtarget - Keep a pointer to the CSKYSubtarget around so that we can + /// make the right decision when printing asm code for different targets. + const CSKYSubtarget *Subtarget; + + /// CFI - Keep a pointer to CSKYTargetMachine for the current + /// MachineFunction. + CSKYMachineFunctionInfo *CFI; + + /// MCP - Keep a pointer to constantpool entries of the current + /// MachineFunction. + const MachineConstantPool *MCP; + + /// InConstantPool - Maintain state when emitting a sequence of constant + /// pool entries so we can properly mark them as data regions. + bool InConstantPool; + +public: + explicit CSKYAsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer); + + /// tblgen'erated driver function for lowering simple MI->MC + /// pseudo instructions. + bool emitPseudoExpansionLowering(MCStreamer &OutStreamer, + const MachineInstr *MI); + void emitInstruction(const MachineInstr *MI) override; + void emitFunctionBodyEnd() override; + void emitFunctionEntryLabel() override; + void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; + + void emitConstantPool() override { + // we emit constant pools customly! + } + + bool runOnMachineFunction(MachineFunction &MF) override; +}; +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYASMPRINTER_H Index: llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYAsmPrinter.cpp @@ -0,0 +1,202 @@ +//===-- CSKYAsmPrinter.cpp - CSKY LLVM assembly writer --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the CSKY assembly language. +// +//===----------------------------------------------------------------------===// +#include "CSKYAsmPrinter.h" +#include "CSKY.h" +#include "CSKYConstantPoolValue.h" +#include "MCTargetDesc/CSKYInstPrinter.h" +#include "MCTargetDesc/CSKYMCExpr.h" +#include "TargetInfo/CSKYTargetInfo.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +CSKYAsmPrinter::CSKYAsmPrinter(llvm::TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this), + InConstantPool(false) {} + +bool CSKYAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + CFI = MF.getInfo(); + MCP = MF.getConstantPool(); + Subtarget = &MF.getSubtarget(); + + return AsmPrinter::runOnMachineFunction(MF); +} + +// Simple pseudo-instructions have their lowering (with expansion to real +// instructions) auto-generated. +#include "CSKYGenMCPseudoLowering.inc" + +void CSKYAsmPrinter::emitInstruction(const MachineInstr *MI) { + // Do any auto-generated pseudo lowerings. + if (emitPseudoExpansionLowering(*OutStreamer, MI)) + return; + + // Check for manual lowerings. + unsigned Opc = MI->getOpcode(); + // If we just ended a constant pool, mark it as such. + if (InConstantPool && Opc != CSKY::CONSTPOOL_ENTRY) { + OutStreamer->emitDataRegion(MCDR_DataRegionEnd); + InConstantPool = false; + } + if (Opc == CSKY::CONSTPOOL_ENTRY) { + // CONSTPOOL_ENTRY - This instruction represents a floating + // constant pool in the function. The first operand is the ID# + // for this instruction, the second is the index into the + // MachineConstantPool that this is, the third is the size in + // bytes of this constant pool entry. + // The required alignment is specified on the basic block holding this MI. + // + unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); + unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); + + // If this is the first entry of the pool, mark it. + if (!InConstantPool) { + OutStreamer->emitDataRegion(MCDR_DataRegion); + InConstantPool = true; + } + + OutStreamer->emitLabel(GetCPISymbol(LabelId)); + + const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; + if (MCPE.isMachineConstantPoolEntry()) + emitMachineConstantPoolValue(MCPE.Val.MachineCPVal); + else + emitGlobalConstant(MF->getDataLayout(), MCPE.Val.ConstVal); + return; + } + + switch (Opc) { + case CSKY::LRWJT32: { + MCInst TmpInst; + TmpInst.setOpcode(CSKY::LRW32); + + const MCSymbol *Label = GetCPISymbol(MI->getOperand(2).getIndex()); + const MCExpr *SymbolExpr = MCSymbolRefExpr::create(Label, OutContext); + + Register Dest = MI->getOperand(0).getReg(); + TmpInst.addOperand(MCOperand::createReg(Dest)); + TmpInst.addOperand(MCOperand::createExpr(SymbolExpr)); + EmitToStreamer(*OutStreamer, TmpInst); + return; + } + } + + MCInst TmpInst; + MCInstLowering.Lower(MI, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); +} + +static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber, + unsigned LabelId, MCContext &Ctx) { + MCSymbol *Label = Ctx.getOrCreateSymbol( + Twine(Prefix) + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); + return Label; +} + +// Convert a CSKY-specific constant pool modifier into the associated +// MCSymbolRefExpr variant kind. +static CSKYMCExpr::VariantKind +getModifierVariantKind(CSKYCP::CSKYCPModifier Modifier) { + switch (Modifier) { + case CSKYCP::no_modifier: + return CSKYMCExpr::VK_CSKY_None; + case CSKYCP::TLSGD: + return CSKYMCExpr::VK_CSKY_TLSGD; + case CSKYCP::TPOFF: + return CSKYMCExpr::VK_CSKY_TPOFF; + case CSKYCP::GOTTPOFF: + return CSKYMCExpr::VK_CSKY_GOTTPOFF; + case CSKYCP::GOT: + return CSKYMCExpr::VK_CSKY_GOT; + case CSKYCP::GOTOFF: + return CSKYMCExpr::VK_CSKY_GOTOFF; + } + llvm_unreachable("Invalid CSKYCPModifier!"); +} + +void CSKYAsmPrinter::emitFunctionBodyEnd() { + // Make sure to terminate any constant pools that were at the end + // of the function. + if (!InConstantPool) + return; + InConstantPool = false; + OutStreamer->emitDataRegion(MCDR_DataRegionEnd); +} + +void CSKYAsmPrinter::emitFunctionEntryLabel() { + OutStreamer->emitLabel(CurrentFnSym); +} + +void CSKYAsmPrinter::emitMachineConstantPoolValue( + MachineConstantPoolValue *MCPV) { + int Size = getDataLayout().getTypeAllocSize(MCPV->getType()); + CSKYConstantPoolValue *CCPV = static_cast(MCPV); + MCSymbol *MCSym; + + if (CCPV->isLSDA()) { + SmallString<128> Str; + raw_svector_ostream OS(Str); + OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); + MCSym = OutContext.getOrCreateSymbol(OS.str()); + } else if (CCPV->isBlockAddress()) { + const BlockAddress *BA = + cast(CCPV)->getBlockAddress(); + MCSym = GetBlockAddressSymbol(BA); + } else if (CCPV->isGlobalValue()) { + const GlobalValue *GV = cast(CCPV)->getGV(); + MCSym = getSymbol(GV); + } else if (CCPV->isMachineBasicBlock()) { + const MachineBasicBlock *MBB = cast(CCPV)->getMBB(); + MCSym = MBB->getSymbol(); + } else if (CCPV->isJT()) { + signed JTI = cast(CCPV)->getJTI(); + MCSym = GetJTISymbol(JTI); + } else { + assert(CCPV->isExtSymbol() && "unrecognized constant pool value"); + const char *Sym = cast(CCPV)->getSymbol(); + MCSym = GetExternalSymbolSymbol(Sym); + } + // Create an MCSymbol for the reference. + const MCExpr *Expr = + MCSymbolRefExpr::create(MCSym, MCSymbolRefExpr::VK_None, OutContext); + Expr = CSKYMCExpr::create(Expr, getModifierVariantKind(CCPV->getModifier()), + OutContext); + + if (CCPV->getPCAdjustment()) { + MCSymbol *PCLabel = + getPICLabel(MAI->getPrivateGlobalPrefix(), getFunctionNumber(), + CCPV->getLabelId(), OutContext); + const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext); + if (CCPV->mustAddCurrentAddress()) { + // We want "( - .)", but MC doesn't have a concept of the '.' + // label, so just emit a local label end reference that instead. + MCSymbol *DotSym = OutContext.createTempSymbol(); + OutStreamer->emitLabel(DotSym); + const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext); + PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext); + } + Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext); + } + OutStreamer->emitValue(Expr, Size); +} + +extern "C" void LLVMInitializeCSKYAsmPrinter() { + RegisterAsmPrinter X(getTheCSKYTarget()); +} Index: llvm/lib/Target/CSKY/CSKYBasicBlockInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYBasicBlockInfo.h @@ -0,0 +1,69 @@ +//===-- CSKYBasicBlockInfo.h - Basic Block Information --------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Utility functions and data structure for computing block size. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYBASICBLOCKINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYBASICBLOCKINFO_H + +namespace llvm { +// Return the worst case padding that could result from unknown offset bits. +inline unsigned UnknownPadding(unsigned LogAlign, unsigned KnownBits) { + if (KnownBits < LogAlign) + return (1u << LogAlign) - (1u << KnownBits); + return 0; +} + +struct BasicBlockInfo { + unsigned Offset = 0; + unsigned Size = 0; + + // The number of low bits in Offset that are known to be exact. + uint8_t KnownBits = 0; + // When non-zero, this field indicates that the block contains instructions + // (inline-asm) of unknown size, which is multiple of (1 << Unalign). + uint8_t Unalign = 0; + // When non-zero, the block terminator contains a .align directive, so the end + // of the block is aligned to 1 << PostAlign bytes. + uint8_t PostAlign = 0; + + BasicBlockInfo() = default; + + // Compute the number of known offset bits internally to this block. + unsigned internalKnownBits() const { + unsigned Bits = Unalign ? Unalign : KnownBits; + // If the block size isn't a multiple of the known bits, + // assume the worst case padding. + if (Size & ((1u << Bits) - 1)) + Bits = countTrailingZeros(Size); + return Bits; + } + + // Compute the offset immediately following this block. If LogAlign is + // specified, return the offset the successor block will get if it has + // this alignment. + unsigned postOffset(unsigned LogAlign = 0) const { + unsigned PO = Offset + Size; + unsigned LA = std::max(unsigned(PostAlign), LogAlign); + if (!LA) + return PO; + // Add alignment padding from the terminator. + return PO + UnknownPadding(LA, internalKnownBits()); + } + + // Compute the number of known low bits of postOffset. + unsigned postKnownBits(unsigned LogAlign = 0) { + return std::max(std::max(unsigned(PostAlign), LogAlign), + internalKnownBits()); + } +}; +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_BASICBLOCKINFO_H Index: llvm/lib/Target/CSKY/CSKYCallingConv.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYCallingConv.h @@ -0,0 +1,25 @@ +//=== CSKYCallingConv.h - CSKY Custom Calling Convention Routines -*-C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the custom routines for the CSKY Calling Convention that +// aren't done by tablegen. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYCALLINGCONV_H +#define LLVM_LIB_TARGET_CSKY_CSKYCALLINGCONV_H + +#include "CSKY.h" +#include "CSKYSubtarget.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/IR/CallingConv.h" + +namespace llvm {} // namespace llvm + +#endif Index: llvm/lib/Target/CSKY/CSKYCallingConv.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYCallingConv.td @@ -0,0 +1,88 @@ +//===-- CSKYCallingConv.td - Calling Conventions CSKY ----*- tablegen -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This describes the calling conventions for the CSKY architecture. +// +//===----------------------------------------------------------------------===// + +def CSR_I32 : CalleeSavedRegs<(add LR, GP, (sequence "R%u", 4, 11), + (sequence "R%u", 16, 17))>; +def CSR_GPR_FPR32 : CalleeSavedRegs<(add CSR_I32, (sequence "F%u_32", 8, 15))>; +def CSR_GPR_FPR64 : CalleeSavedRegs<(add CSR_I32, + (sequence "F%u_64", 8, 15))>; +def CSR_GPR_FPR128: CalleeSavedRegs<(add CSR_I32, + (sequence "F%u_128",8, 15))>; + +def CC_CSKY_ABIV2_SOFT : CallingConv<[ + CCIfByVal>, + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[v2i16, v4i8], CCAssignToStack<4, 4>>, + CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[i32], CCAssignToStack<4, 4>>, + CCIfType<[v2i64, v4i32, v8i16, v16i8], + CCAssignToReg<[F0_128, F1_128, F2_128, F3_128]>> +]>; +def RetCC_CSKY_ABIV2_SOFT : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1]>>, + CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToReg<[R0, R1]>>, + CCIfType<[v2i64, v4i32, v8i16, v16i8], + CCAssignToReg<[F0_128]>> +]>; + +def CC_CSKY_ABIV2_SF : CallingConv<[ + CCIfByVal>, + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[v2i16, v4i8], CCAssignToStack<4, 4>>, + CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[i32], CCAssignToStack<4, 4>>, + CCIfType<[f32], CCAssignToReg<[F0_32, F1_32, F2_32, F3_32]>>, + CCIfType<[f32], CCAssignToStack<4, 4>>, + CCIfType<[v2i64, v4i32, v8i16, v16i8, v8f16, v4f32], + CCAssignToReg<[F0_128, F1_128, F2_128, F3_128]>> +]>; +def RetCC_CSKY_ABIV2_SF : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1]>>, + CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToReg<[R0, R1]>>, + CCIfType<[f32], CCAssignToReg<[F0_32]>>, + CCIfType<[v2i64, v4i32, v8i16, v16i8, v8f16, v4f32], + CCAssignToReg<[F0_128]>> +]>; + +def CC_CSKY_ABIV2_DF : CallingConv<[ + CCIfByVal>, + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[v2i16, v4i8], CCAssignToStack<4, 4>>, + CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, + CCIfType<[i32], CCAssignToStack<4, 4>>, + CCIfType<[f32], CCAssignToReg<[F0_32, F1_32, F2_32, F3_32]>>, + CCIfType<[f32], CCAssignToStack<4, 4>>, + CCIfType<[f64], CCAssignToReg<[F0_64, F1_64, F2_64, F3_64]>>, + CCIfType<[f64], CCAssignToStack<8, 8>>, + CCIfType<[v2i64, v4i32, v8i16, v16i8, v8f16, v4f32, v2f64], + CCAssignToReg<[F0_128, F1_128, F2_128, F3_128]>> +]>; +def RetCC_CSKY_ABIV2_DF : CallingConv<[ + // DSP types + CCIfType<[v2i16, v4i8], CCAssignToReg<[R0, R1]>>, + CCIfType<[i8, i16], CCPromoteToType>, + CCIfType<[i32], CCAssignToReg<[R0, R1]>>, + CCIfType<[f32], CCAssignToReg<[F0_32]>>, + CCIfType<[f64], CCAssignToReg<[F0_64]>>, + CCIfType<[v2i64, v4i32, v8i16, v16i8, v8f16, v4f32, v2f64], + CCAssignToReg<[F0_128]>> +]>; Index: llvm/lib/Target/CSKY/CSKYConstantIslandPass.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYConstantIslandPass.cpp @@ -0,0 +1,1504 @@ +//===- CSKYConstantIslandPass.cpp - Emit PC Relative loads ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// +// Loading constants inline is expensive on CSKY and it's in general better +// to place the constant nearby in code space and then it can be loaded with a +// simple 16/32 bit load instruction like lrw. +// +// The constants can be not just numbers but addresses of functions and labels. +// This can be particularly helpful in static relocation mode for embedded +// non-linux targets. +// +//===----------------------------------------------------------------------===// + +#include "CSKY.h" +#include "CSKYMachineFunctionInfo.h" +#include "CSKYSubtarget.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include +#include + +using namespace llvm; + +#define DEBUG_TYPE "CSKY-constant-islands" + +STATISTIC(NumCPEs, "Number of constpool entries"); +STATISTIC(NumSplit, "Number of uncond branches inserted"); +STATISTIC(NumCBrFixed, "Number of cond branches fixed"); +STATISTIC(NumUBrFixed, "Number of uncond branches fixed"); + +// FIXME: This option should be removed once it has received sufficient testing. +static cl::opt + AlignConstantIslands("CSKY-align-constant-islands", cl::Hidden, + cl::init(true), + cl::desc("Align constant islands in code")); + +// Rather than do make check tests with huge amounts of code, we force +// the test to use this amount. +static cl::opt ConstantIslandsSmallOffset( + "CSKY-constant-islands-small-offset", cl::init(0), + cl::desc("Make small offsets be this amount for testing purposes"), + cl::Hidden); + +// For testing purposes we tell it to not use relaxed load forms so that it +// will split blocks. +static cl::opt NoLoadRelaxation( + "CSKY-constant-islands-no-load-relaxation", cl::init(false), + cl::desc("Don't relax loads to long loads - for testing purposes"), + cl::Hidden); + +static unsigned int longformBranchOpcode(unsigned int Opcode) { + // TODO: Add support for 16bit instr. + return Opcode; +} + +// FIXME: need to go through this whole constant islands port and check +// the math for branch ranges and clean this up and make some functions +// to calculate things that are done many times identically. +// Need to refactor some of the code to call this routine. +static unsigned int branchMaxOffsets(unsigned int Opcode) { + unsigned Bits, Scale; + // TODO: Add support for 16bit instr. + Bits = 16; + Scale = 2; + + unsigned MaxOffs = ((1 << (Bits - 1)) - 1) * Scale; + return MaxOffs; +} + +namespace { + +using Iter = MachineBasicBlock::iterator; +using ReverseIter = MachineBasicBlock::reverse_iterator; + +/// CSKYConstantIslands - Due to limited PC-relative displacements, CSKY +/// requires constant pool entries to be scattered among the instructions +/// inside a function. To do this, it completely ignores the normal LLVM +/// constant pool; instead, it places constants wherever it feels like with +/// special instructions. +/// +/// The terminology used in this pass includes: +/// Islands - Clumps of constants placed in the function. +/// Water - Potential places where an island could be formed. +/// CPE - A constant pool entry that has been placed somewhere, which +/// tracks a list of users. + +class CSKYConstantIslands : public MachineFunctionPass { + /// BasicBlockInfo - Information about the offset and size of a single + /// basic block. + struct BasicBlockInfo { + /// Offset - Distance from the beginning of the function to the beginning + /// of this basic block. + /// + /// Offsets are computed assuming worst case padding before an aligned + /// block. This means that subtracting basic block offsets always gives a + /// conservative estimate of the real distance which may be smaller. + /// + /// Because worst case padding is used, the computed offset of an aligned + /// block may not actually be aligned. + unsigned Offset = 0; + + /// Size - Size of the basic block in bytes. If the block contains + /// inline assembly, this is a worst case estimate. + /// + /// The size does not include any alignment padding whether from the + /// beginning of the block, or from an aligned jump table at the end. + unsigned Size = 0; + + BasicBlockInfo() = default; + + unsigned postOffset() const { return Offset + Size; } + }; + + std::vector BBInfo; + + /// WaterList - A sorted list of basic blocks where islands could be placed + /// (i.e. blocks that don't fall through to the following block, due + /// to a return, unreachable, or unconditional branch). + std::vector WaterList; + + /// NewWaterList - The subset of WaterList that was created since the + /// previous iteration by inserting unconditional branches. + SmallSet NewWaterList; + + using water_iterator = std::vector::iterator; + + /// CPUser - One user of a constant pool, keeping the machine instruction + /// pointer, the constant pool being referenced, and the max displacement + /// allowed from the instruction to the CP. The HighWaterMark records the + /// highest basic block where a new CPEntry can be placed. To ensure this + /// pass terminates, the CP entries are initially placed at the end of the + /// function and then move monotonically to lower addresses. The + /// exception to this rule is when the current CP entry for a particular + /// CPUser is out of range, but there is another CP entry for the same + /// constant value in range. We want to use the existing in-range CP + /// entry, but if it later moves out of range, the search for new water + /// should resume where it left off. The HighWaterMark is used to record + /// that point. + struct CPUser { + MachineInstr *MI; + MachineInstr *CPEMI; + MachineBasicBlock *HighWaterMark; + + private: + unsigned MaxDisp; + unsigned LongFormMaxDisp; // CSKY16 has 16/32 bit instructions + // with different displacements + unsigned LongFormOpcode; + + public: + bool NegOk; + + CPUser(MachineInstr *Mi, MachineInstr *Cpemi, unsigned Maxdisp, bool Neg, + unsigned Longformmaxdisp, unsigned Longformopcode) + : MI(Mi), CPEMI(Cpemi), MaxDisp(Maxdisp), + LongFormMaxDisp(Longformmaxdisp), LongFormOpcode(Longformopcode), + NegOk(Neg) { + HighWaterMark = CPEMI->getParent(); + } + + /// getMaxDisp - Returns the maximum displacement supported by MI. + unsigned getMaxDisp() const { + unsigned XMaxDisp = + ConstantIslandsSmallOffset ? ConstantIslandsSmallOffset : MaxDisp; + return XMaxDisp; + } + + void setMaxDisp(unsigned Val) { MaxDisp = Val; } + + unsigned getLongFormMaxDisp() const { return LongFormMaxDisp; } + + unsigned getLongFormOpcode() const { return LongFormOpcode; } + }; + + /// CPUsers - Keep track of all of the machine instructions that use various + /// constant pools and their max displacement. + std::vector CPUsers; + + /// CPEntry - One per constant pool entry, keeping the machine instruction + /// pointer, the constpool index, and the number of CPUser's which + /// reference this entry. + struct CPEntry { + MachineInstr *CPEMI; + unsigned CPI; + unsigned RefCount; + + CPEntry(MachineInstr *Cpemi, unsigned Cpi, unsigned Rc = 0) + : CPEMI(Cpemi), CPI(Cpi), RefCount(Rc) {} + }; + + /// CPEntries - Keep track of all of the constant pool entry machine + /// instructions. For each original constpool index (i.e. those that + /// existed upon entry to this pass), it keeps a vector of entries. + /// Original elements are cloned as we go along; the clones are + /// put in the vector of the original element, but have distinct CPIs. + std::vector> CPEntries; + + /// ImmBranch - One per immediate branch, keeping the machine instruction + /// pointer, conditional or unconditional, the max displacement, + /// and (if isCond is true) the corresponding unconditional branch + /// opcode. + struct ImmBranch { + MachineInstr *MI; + unsigned MaxDisp : 31; + bool IsCond : 1; + int UncondBr; + + ImmBranch(MachineInstr *Mi, unsigned Maxdisp, bool Cond, int Ubr) + : MI(Mi), MaxDisp(Maxdisp), IsCond(Cond), UncondBr(Ubr) {} + }; + + /// ImmBranches - Keep track of all the immediate branch instructions. + /// + std::vector ImmBranches; + + /// HasFarJump - True if any far jump instruction has been emitted during + /// the branch fix up pass. + bool HasFarJump; + + const CSKYSubtarget *STI = nullptr; + const CSKYInstrInfo *TII; + CSKYMachineFunctionInfo *MFI; + MachineFunction *MF = nullptr; + MachineConstantPool *MCP = nullptr; + +public: + static char ID; + + CSKYConstantIslands() : MachineFunctionPass(ID) {} + + StringRef getPassName() const override { return "CSKY Constant Islands"; } + + bool runOnMachineFunction(MachineFunction &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + MachineFunctionProperties getRequiredProperties() const override { + return MachineFunctionProperties().set( + MachineFunctionProperties::Property::NoVRegs); + } + + void doInitialPlacement(std::vector &CPEMIs); + CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI); + Align getCPEAlign(const MachineInstr &CPEMI); + void initializeFunctionInfo(const std::vector &CPEMIs); + unsigned getOffsetOf(MachineInstr *MI) const; + unsigned getUserOffset(CPUser &) const; + void dumpBBs(); + + bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset, unsigned Disp, + bool NegativeOK); + bool isOffsetInRange(unsigned UserOffset, unsigned TrialOffset, + const CPUser &U); + + void computeBlockSize(MachineBasicBlock *MBB); + MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI); + void updateForInsertedWaterBlock(MachineBasicBlock *NewBB); + void adjustBBOffsetsAfter(MachineBasicBlock *BB); + bool decrementCPEReferenceCount(unsigned CPI, MachineInstr *CPEMI); + int findInRangeCPEntry(CPUser &U, unsigned UserOffset); + int findLongFormInRangeCPEntry(CPUser &U, unsigned UserOffset); + bool findAvailableWater(CPUser &U, unsigned UserOffset, + water_iterator &WaterIter); + void createNewWater(unsigned CPUserIndex, unsigned UserOffset, + MachineBasicBlock *&NewMBB); + bool handleConstantPoolUser(unsigned CPUserIndex); + void removeDeadCPEMI(MachineInstr *CPEMI); + bool removeUnusedCPEntries(); + bool isCPEntryInRange(MachineInstr *MI, unsigned UserOffset, + MachineInstr *CPEMI, unsigned Disp, bool NegOk, + bool DoDump = false); + bool isWaterInRange(unsigned UserOffset, MachineBasicBlock *Water, CPUser &U, + unsigned &Growth); + bool isBBInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp); + bool fixupImmediateBr(ImmBranch &Br); + bool fixupConditionalBr(ImmBranch &Br); + bool fixupUnconditionalBr(ImmBranch &Br); +}; +} // end anonymous namespace + +char CSKYConstantIslands::ID = 0; + +bool CSKYConstantIslands::isOffsetInRange(unsigned UserOffset, + unsigned TrialOffset, + const CPUser &U) { + return isOffsetInRange(UserOffset, TrialOffset, U.getMaxDisp(), U.NegOk); +} + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +/// print block size and offset information - debugging +LLVM_DUMP_METHOD void CSKYConstantIslands::dumpBBs() { + for (unsigned J = 0, E = BBInfo.size(); J != E; ++J) { + const BasicBlockInfo &BBI = BBInfo[J]; + dbgs() << format("%08x %bb.%u\t", BBI.Offset, J) + << format(" size=%#x\n", BBInfo[J].Size); + } +} +#endif + +bool CSKYConstantIslands::runOnMachineFunction(MachineFunction &Mf) { + MF = &Mf; + MCP = Mf.getConstantPool(); + STI = &static_cast(Mf.getSubtarget()); + + LLVM_DEBUG(dbgs() << "***** CSKYConstantIslands: " + << MCP->getConstants().size() << " CP entries, aligned to " + << MCP->getConstantPoolAlign().value() << " bytes *****\n"); + + if (!STI->useConstantIslands()) + return false; + + TII = STI->getInstrInfo(); + MFI = MF->getInfo(); + + HasFarJump = false; + // This pass invalidates liveness information when it splits basic blocks. + MF->getRegInfo().invalidateLiveness(); + + // Renumber all of the machine basic blocks in the function, guaranteeing that + // the numbers agree with the position of the block in the function. + MF->RenumberBlocks(); + + bool MadeChange = false; + + // Perform the initial placement of the constant pool entries. To start with, + // we put them all at the end of the function. + std::vector CPEMIs; + if (!MCP->isEmpty()) + doInitialPlacement(CPEMIs); + + /// The next UID to take is the first unused one. + MFI->initPICLabelUId(CPEMIs.size()); + + // Do the initial scan of the function, building up information about the + // sizes of each block, the location of all the water, and finding all of the + // constant pool users. + initializeFunctionInfo(CPEMIs); + CPEMIs.clear(); + LLVM_DEBUG(dumpBBs()); + + /// Remove dead constant pool entries. + MadeChange |= removeUnusedCPEntries(); + + // Iteratively place constant pool entries and fix up branches until there + // is no change. + unsigned NoCPIters = 0, NoBRIters = 0; + (void)NoBRIters; + while (true) { + LLVM_DEBUG(dbgs() << "Beginning CP iteration #" << NoCPIters << '\n'); + bool CPChange = false; + for (unsigned I = 0, E = CPUsers.size(); I != E; ++I) + CPChange |= handleConstantPoolUser(I); + if (CPChange && ++NoCPIters > 30) + report_fatal_error("Constant Island pass failed to converge!"); + LLVM_DEBUG(dumpBBs()); + + // Clear NewWaterList now. If we split a block for branches, it should + // appear as "new water" for the next iteration of constant pool placement. + NewWaterList.clear(); + + LLVM_DEBUG(dbgs() << "Beginning BR iteration #" << NoBRIters << '\n'); + bool BRChange = false; + for (unsigned I = 0, E = ImmBranches.size(); I != E; ++I) + BRChange |= fixupImmediateBr(ImmBranches[I]); + if (BRChange && ++NoBRIters > 30) + report_fatal_error("Branch Fix Up pass failed to converge!"); + LLVM_DEBUG(dumpBBs()); + if (!CPChange && !BRChange) + break; + MadeChange = true; + } + + LLVM_DEBUG(dbgs() << '\n'; dumpBBs()); + + BBInfo.clear(); + WaterList.clear(); + CPUsers.clear(); + CPEntries.clear(); + ImmBranches.clear(); + return MadeChange; +} + +/// doInitialPlacement - Perform the initial placement of the constant pool +/// entries. To start with, we put them all at the end of the function. +void CSKYConstantIslands::doInitialPlacement( + std::vector &CPEMIs) { + // Create the basic block to hold the CPE's. + MachineBasicBlock *BB = MF->CreateMachineBasicBlock(); + MF->push_back(BB); + + // MachineConstantPool measures alignment in bytes. We measure in log2(bytes). + const Align MaxAlign = MCP->getConstantPoolAlign(); + + // Mark the basic block as required by the const-pool. + // If AlignConstantIslands isn't set, use 4-byte alignment for everything. + BB->setAlignment(AlignConstantIslands ? MaxAlign : Align(4)); + + // The function needs to be as aligned as the basic blocks. The linker may + // move functions around based on their alignment. + MF->ensureAlignment(BB->getAlignment()); + + // Order the entries in BB by descending alignment. That ensures correct + // alignment of all entries as long as BB is sufficiently aligned. Keep + // track of the insertion point for each alignment. We are going to bucket + // sort the entries as they are created. + SmallVector InsPoint(Log2(MaxAlign) + 1, + BB->end()); + + // Add all of the constants from the constant pool to the end block, use an + // identity mapping of CPI's to CPE's. + const std::vector &CPs = MCP->getConstants(); + + const DataLayout &TD = MF->getDataLayout(); + for (unsigned I = 0, E = CPs.size(); I != E; ++I) { + unsigned Size = TD.getTypeAllocSize(CPs[I].getType()); + assert(Size >= 4 && "Too small constant pool entry"); + Align Alignment = CPs[I].getAlign(); + // Verify that all constant pool entries are a multiple of their alignment. + // If not, we would have to pad them out so that instructions stay aligned. + assert(isAligned(Alignment, Size) && "CP Entry not multiple of 4 bytes!"); + + // Insert CONSTPOOL_ENTRY before entries with a smaller alignment. + unsigned LogAlign = Log2(Alignment); + MachineBasicBlock::iterator InsAt = InsPoint[LogAlign]; + + MachineInstr *CPEMI = + BuildMI(*BB, InsAt, DebugLoc(), TII->get(CSKY::CONSTPOOL_ENTRY)) + .addImm(I) + .addConstantPoolIndex(I) + .addImm(Size); + + CPEMIs.push_back(CPEMI); + + // Ensure that future entries with higher alignment get inserted before + // CPEMI. This is bucket sort with iterators. + for (unsigned A = LogAlign + 1; A <= Log2(MaxAlign); ++A) + if (InsPoint[A] == InsAt) + InsPoint[A] = CPEMI; + // Add a new CPEntry, but no corresponding CPUser yet. + CPEntries.emplace_back(1, CPEntry(CPEMI, I)); + ++NumCPEs; + LLVM_DEBUG(dbgs() << "Moved CPI#" << I << " to end of function, size = " + << Size << ", align = " << Alignment.value() << '\n'); + } + LLVM_DEBUG(BB->dump()); +} + +/// BBHasFallthrough - Return true if the specified basic block can fallthrough +/// into the block immediately after it. +static bool bbHasFallthrough(MachineBasicBlock *MBB) { + // Get the next machine basic block in the function. + MachineFunction::iterator MBBI = MBB->getIterator(); + // Can't fall off end of function. + if (std::next(MBBI) == MBB->getParent()->end()) + return false; + + MachineBasicBlock *NextBB = &*std::next(MBBI); + for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(), + E = MBB->succ_end(); + I != E; ++I) + if (*I == NextBB) + return true; + + return false; +} + +/// findConstPoolEntry - Given the constpool index and CONSTPOOL_ENTRY MI, +/// look up the corresponding CPEntry. +CSKYConstantIslands::CPEntry * +CSKYConstantIslands::findConstPoolEntry(unsigned CPI, + const MachineInstr *CPEMI) { + std::vector &CPEs = CPEntries[CPI]; + // Number of entries per constpool index should be small, just do a + // linear search. + for (unsigned I = 0, E = CPEs.size(); I != E; ++I) { + if (CPEs[I].CPEMI == CPEMI) + return &CPEs[I]; + } + return nullptr; +} + +/// getCPEAlign - Returns the required alignment of the constant pool entry +/// represented by CPEMI. Alignment is measured in log2(bytes) units. +Align CSKYConstantIslands::getCPEAlign(const MachineInstr &CPEMI) { + assert(CPEMI.getOpcode() == CSKY::CONSTPOOL_ENTRY); + + // Everything is 4-byte aligned unless AlignConstantIslands is set. + if (!AlignConstantIslands) + return Align(4); + + unsigned CPI = CPEMI.getOperand(1).getIndex(); + assert(CPI < MCP->getConstants().size() && "Invalid constant pool index."); + return MCP->getConstants()[CPI].getAlign(); +} + +/// initializeFunctionInfo - Do the initial scan of the function, building up +/// information about the sizes of each block, the location of all the water, +/// and finding all of the constant pool users. +void CSKYConstantIslands::initializeFunctionInfo( + const std::vector &CPEMIs) { + BBInfo.clear(); + BBInfo.resize(MF->getNumBlockIDs()); + + // First thing, compute the size of all basic blocks, and see if the function + // has any inline assembly in it. If so, we have to be conservative about + // alignment assumptions, as we don't know for sure the size of any + // instructions in the inline assembly. + for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) + computeBlockSize(&*I); + + // Compute block offsets. + adjustBBOffsetsAfter(&MF->front()); + + // Now go back through the instructions and build up our data structures. + for (MachineBasicBlock &MBB : *MF) { + // If this block doesn't fall through into the next MBB, then this is + // 'water' that a constant pool island could be placed. + if (!bbHasFallthrough(&MBB)) + WaterList.push_back(&MBB); + for (MachineInstr &MI : MBB) { + if (MI.isDebugInstr()) + continue; + + int Opc = MI.getOpcode(); + if (MI.isBranch() && !MI.isIndirectBranch()) { + bool IsCond = MI.isConditionalBranch(); + unsigned Bits = 0; + unsigned Scale = 1; + int UOpc = Opc; + + // TODO: Add support for 16bit instr. + Bits = 16; + Scale = 2; + + if (IsCond) { + LLVM_DEBUG(MI.dump()); + SmallVector Cond; + Cond.push_back(MachineOperand::CreateImm(MI.getOpcode())); + Cond.push_back(MI.getOperand(0)); + TII->reverseBranchCondition(Cond); + UOpc = Cond[0].getImm(); + } + + // Record this immediate branch. + unsigned MaxOffs = ((1 << (Bits - 1)) - 1) * Scale; + ImmBranches.push_back(ImmBranch(&MI, MaxOffs, IsCond, UOpc)); + } + + if (Opc == CSKY::CONSTPOOL_ENTRY) + continue; + + // Scan the instructions for constant pool operands. + for (unsigned Op = 0, E = MI.getNumOperands(); Op != E; ++Op) + if (MI.getOperand(Op).isCPI()) { + // We found one. The addressing mode tells us the max displacement + // from the PC that this instruction permits. + + // Basic size info comes from the TSFlags field. + unsigned Bits = 0; + unsigned Scale = 1; + bool NegOk = false; + unsigned LongFormBits = 0; + unsigned LongFormScale = 0; + unsigned LongFormOpcode = 0; + switch (Opc) { + default: + llvm_unreachable("Unknown addressing mode for CP reference!"); + case CSKY::LRWJT32: + case CSKY::JSRI32: + case CSKY::LRW32: + Bits = 16; + Scale = 4; + LongFormOpcode = Opc; + LongFormBits = 16; + LongFormScale = 4; + break; + } + // Remember that this is a user of a CP entry. + unsigned CPI = MI.getOperand(Op).getIndex(); + MachineInstr *CPEMI = CPEMIs[CPI]; + unsigned MaxOffs = ((1 << Bits) - 1) * Scale; + unsigned LongFormMaxOffs = ((1 << LongFormBits) - 1) * LongFormScale; + CPUsers.push_back(CPUser(&MI, CPEMI, MaxOffs, NegOk, LongFormMaxOffs, + LongFormOpcode)); + + // Increment corresponding CPEntry reference count. + CPEntry *CPE = findConstPoolEntry(CPI, CPEMI); + assert(CPE && "Cannot find a corresponding CPEntry!"); + CPE->RefCount++; + + // Instructions can only use one CP entry, don't bother scanning the + // rest of the operands. + break; + } + } + } +} + +/// computeBlockSize - Compute the size and some alignment information for MBB. +/// This function updates BBInfo directly. +void CSKYConstantIslands::computeBlockSize(MachineBasicBlock *MBB) { + BasicBlockInfo &BBI = BBInfo[MBB->getNumber()]; + BBI.Size = 0; + + for (const MachineInstr &MI : *MBB) + BBI.Size += TII->getInstSizeInBytes(MI); +} + +/// getOffsetOf - Return the current offset of the specified machine instruction +/// from the start of the function. This offset changes as stuff is moved +/// around inside the function. +unsigned CSKYConstantIslands::getOffsetOf(MachineInstr *MI) const { + MachineBasicBlock *MBB = MI->getParent(); + + // The offset is composed of two things: the sum of the sizes of all MBB's + // before this instruction's block, and the offset from the start of the block + // it is in. + unsigned Offset = BBInfo[MBB->getNumber()].Offset; + + // Sum instructions before MI in MBB. + for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) { + assert(I != MBB->end() && "Didn't find MI in its own basic block?"); + Offset += TII->getInstSizeInBytes(*I); + } + return Offset; +} + +/// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB +/// ID. +static bool compareMbbNumbers(const MachineBasicBlock *LHS, + const MachineBasicBlock *RHS) { + return LHS->getNumber() < RHS->getNumber(); +} + +/// updateForInsertedWaterBlock - When a block is newly inserted into the +/// machine function, it upsets all of the block numbers. Renumber the blocks +/// and update the arrays that parallel this numbering. +void CSKYConstantIslands::updateForInsertedWaterBlock( + MachineBasicBlock *NewBB) { + // Renumber the MBB's to keep them consecutive. + NewBB->getParent()->RenumberBlocks(NewBB); + + // Insert an entry into BBInfo to align it properly with the (newly + // renumbered) block numbers. + BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo()); + + // Next, update WaterList. Specifically, we need to add NewMBB as having + // available water after it. + water_iterator IP = llvm::lower_bound(WaterList, NewBB, compareMbbNumbers); + WaterList.insert(IP, NewBB); +} + +unsigned CSKYConstantIslands::getUserOffset(CPUser &U) const { + return getOffsetOf(U.MI); +} + +/// Split the basic block containing MI into two blocks, which are joined by +/// an unconditional branch. Update data structures and renumber blocks to +/// account for this change and returns the newly created block. +MachineBasicBlock * +CSKYConstantIslands::splitBlockBeforeInstr(MachineInstr &MI) { + MachineBasicBlock *OrigBB = MI.getParent(); + + // Create a new MBB for the code after the OrigBB. + MachineBasicBlock *NewBB = + MF->CreateMachineBasicBlock(OrigBB->getBasicBlock()); + MachineFunction::iterator MBBI = ++OrigBB->getIterator(); + MF->insert(MBBI, NewBB); + + // Splice the instructions starting with MI over to NewBB. + NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end()); + + // Add an unconditional branch from OrigBB to NewBB. + // Note the new unconditional branch is not being recorded. + // There doesn't seem to be meaningful DebugInfo available; this doesn't + // correspond to anything in the source. + + // TODO: Add support for 16bit instr. + BuildMI(OrigBB, DebugLoc(), TII->get(CSKY::BR32)).addMBB(NewBB); + ++NumSplit; + + // Update the CFG. All succs of OrigBB are now succs of NewBB. + NewBB->transferSuccessors(OrigBB); + + // OrigBB branches to NewBB. + OrigBB->addSuccessor(NewBB); + + // Update internal data structures to account for the newly inserted MBB. + // This is almost the same as updateForInsertedWaterBlock, except that + // the Water goes after OrigBB, not NewBB. + MF->RenumberBlocks(NewBB); + + // Insert an entry into BBInfo to align it properly with the (newly + // renumbered) block numbers. + BBInfo.insert(BBInfo.begin() + NewBB->getNumber(), BasicBlockInfo()); + + // Next, update WaterList. Specifically, we need to add OrigMBB as having + // available water after it (but not if it's already there, which happens + // when splitting before a conditional branch that is followed by an + // unconditional branch - in that case we want to insert NewBB). + water_iterator IP = llvm::lower_bound(WaterList, OrigBB, compareMbbNumbers); + MachineBasicBlock *WaterBB = *IP; + if (WaterBB == OrigBB) + WaterList.insert(std::next(IP), NewBB); + else + WaterList.insert(IP, OrigBB); + NewWaterList.insert(OrigBB); + + // Figure out how large the OrigBB is. As the first half of the original + // block, it cannot contain a tablejump. The size includes + // the new jump we added. (It should be possible to do this without + // recounting everything, but it's very confusing, and this is rarely + // executed.) + computeBlockSize(OrigBB); + + // Figure out how large the NewMBB is. As the second half of the original + // block, it may contain a tablejump. + computeBlockSize(NewBB); + + // All BBOffsets following these blocks must be modified. + adjustBBOffsetsAfter(OrigBB); + + return NewBB; +} + +/// isOffsetInRange - Checks whether UserOffset (the location of a constant pool +/// reference) is within MaxDisp of TrialOffset (a proposed location of a +/// constant pool entry). +bool CSKYConstantIslands::isOffsetInRange(unsigned UserOffset, + unsigned TrialOffset, + unsigned MaxDisp, bool NegativeOK) { + if (UserOffset <= TrialOffset) { + // User before the Trial. + if (TrialOffset - UserOffset <= MaxDisp) + return true; + } else if (NegativeOK) { + if (UserOffset - TrialOffset <= MaxDisp) + return true; + } + return false; +} + +/// isWaterInRange - Returns true if a CPE placed after the specified +/// Water (a basic block) will be in range for the specific MI. +/// +/// Compute how much the function will grow by inserting a CPE after Water. +bool CSKYConstantIslands::isWaterInRange(unsigned UserOffset, + MachineBasicBlock *Water, CPUser &U, + unsigned &Growth) { + unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(); + unsigned NextBlockOffset; + Align NextBlockAlignment; + MachineFunction::const_iterator NextBlock = ++Water->getIterator(); + if (NextBlock == MF->end()) { + NextBlockOffset = BBInfo[Water->getNumber()].postOffset(); + NextBlockAlignment = Align(1); + } else { + NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset; + NextBlockAlignment = NextBlock->getAlignment(); + } + unsigned Size = U.CPEMI->getOperand(2).getImm(); + unsigned CPEEnd = CPEOffset + Size; + + // The CPE may be able to hide in the alignment padding before the next + // block. It may also cause more padding to be required if it is more aligned + // that the next block. + if (CPEEnd > NextBlockOffset) { + Growth = CPEEnd - NextBlockOffset; + // Compute the padding that would go at the end of the CPE to align the next + // block. + Growth += offsetToAlignment(CPEEnd, NextBlockAlignment); + + // If the CPE is to be inserted before the instruction, that will raise + // the offset of the instruction. Also account for unknown alignment padding + // in blocks between CPE and the user. + if (CPEOffset < UserOffset) + UserOffset += Growth; + } else + // CPE fits in existing padding. + Growth = 0; + + return isOffsetInRange(UserOffset, CPEOffset, U); +} + +/// isCPEntryInRange - Returns true if the distance between specific MI and +/// specific ConstPool entry instruction can fit in MI's displacement field. +bool CSKYConstantIslands::isCPEntryInRange(MachineInstr *MI, + unsigned UserOffset, + MachineInstr *CPEMI, + unsigned MaxDisp, bool NegOk, + bool DoDump) { + unsigned CPEOffset = getOffsetOf(CPEMI); + + if (DoDump) { + LLVM_DEBUG({ + unsigned Block = MI->getParent()->getNumber(); + const BasicBlockInfo &BBI = BBInfo[Block]; + dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm() + << " max delta=" << MaxDisp + << format(" insn address=%#x", UserOffset) << " in " + << printMBBReference(*MI->getParent()) << ": " + << format("%#x-%x\t", BBI.Offset, BBI.postOffset()) << *MI + << format("CPE address=%#x offset=%+d: ", CPEOffset, + int(CPEOffset - UserOffset)); + }); + } + + return isOffsetInRange(UserOffset, CPEOffset, MaxDisp, NegOk); +} + +#ifndef NDEBUG +/// BBIsJumpedOver - Return true of the specified basic block's only predecessor +/// unconditionally branches to its only successor. +static bool bbIsJumpedOver(MachineBasicBlock *MBB) { + if (MBB->pred_size() != 1 || MBB->succ_size() != 1) + return false; + MachineBasicBlock *Succ = *MBB->succ_begin(); + MachineBasicBlock *Pred = *MBB->pred_begin(); + MachineInstr *PredMI = &Pred->back(); + if (PredMI->getOpcode() == CSKY::BR32 /*TODO: change to 16bit instr. */) + return PredMI->getOperand(0).getMBB() == Succ; + return false; +} +#endif + +void CSKYConstantIslands::adjustBBOffsetsAfter(MachineBasicBlock *BB) { + unsigned BBNum = BB->getNumber(); + for (unsigned I = BBNum + 1, E = MF->getNumBlockIDs(); I < E; ++I) { + // Get the offset and known bits at the end of the layout predecessor. + // Include the alignment of the current block. + unsigned Offset = BBInfo[I - 1].Offset + BBInfo[I - 1].Size; + BBInfo[I].Offset = Offset; + } +} + +/// decrementCPEReferenceCount - find the constant pool entry with index CPI +/// and instruction CPEMI, and decrement its refcount. If the refcount +/// becomes 0 remove the entry and instruction. Returns true if we removed +/// the entry, false if we didn't. +bool CSKYConstantIslands::decrementCPEReferenceCount(unsigned CPI, + MachineInstr *CPEMI) { + // Find the old entry. Eliminate it if it is no longer used. + CPEntry *CPE = findConstPoolEntry(CPI, CPEMI); + assert(CPE && "Unexpected!"); + if (--CPE->RefCount == 0) { + removeDeadCPEMI(CPEMI); + CPE->CPEMI = nullptr; + --NumCPEs; + return true; + } + return false; +} + +/// LookForCPEntryInRange - see if the currently referenced CPE is in range; +/// if not, see if an in-range clone of the CPE is in range, and if so, +/// change the data structures so the user references the clone. Returns: +/// 0 = no existing entry found +/// 1 = entry found, and there were no code insertions or deletions +/// 2 = entry found, and there were code insertions or deletions +int CSKYConstantIslands::findInRangeCPEntry(CPUser &U, unsigned UserOffset) { + MachineInstr *UserMI = U.MI; + MachineInstr *CPEMI = U.CPEMI; + + // Check to see if the CPE is already in-range. + if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getMaxDisp(), U.NegOk, + true)) { + LLVM_DEBUG(dbgs() << "In range\n"); + return 1; + } + + // No. Look for previously created clones of the CPE that are in range. + unsigned CPI = CPEMI->getOperand(1).getIndex(); + std::vector &CPEs = CPEntries[CPI]; + for (unsigned I = 0, E = CPEs.size(); I != E; ++I) { + // We already tried this one + if (CPEs[I].CPEMI == CPEMI) + continue; + // Removing CPEs can leave empty entries, skip + if (CPEs[I].CPEMI == nullptr) + continue; + if (isCPEntryInRange(UserMI, UserOffset, CPEs[I].CPEMI, U.getMaxDisp(), + U.NegOk)) { + LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" + << CPEs[I].CPI << "\n"); + // Point the CPUser node to the replacement + U.CPEMI = CPEs[I].CPEMI; + // Change the CPI in the instruction operand to refer to the clone. + for (unsigned J = 0, E = UserMI->getNumOperands(); J != E; ++J) + if (UserMI->getOperand(J).isCPI()) { + UserMI->getOperand(J).setIndex(CPEs[I].CPI); + break; + } + // Adjust the refcount of the clone... + CPEs[I].RefCount++; + // ...and the original. If we didn't remove the old entry, none of the + // addresses changed, so we don't need another pass. + return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1; + } + } + return 0; +} + +/// LookForCPEntryInRange - see if the currently referenced CPE is in range; +/// This version checks if the longer form of the instruction can be used to +/// to satisfy things. +/// if not, see if an in-range clone of the CPE is in range, and if so, +/// change the data structures so the user references the clone. Returns: +/// 0 = no existing entry found +/// 1 = entry found, and there were no code insertions or deletions +/// 2 = entry found, and there were code insertions or deletions +int CSKYConstantIslands::findLongFormInRangeCPEntry(CPUser &U, + unsigned UserOffset) { + MachineInstr *UserMI = U.MI; + MachineInstr *CPEMI = U.CPEMI; + + // Check to see if the CPE is already in-range. + if (isCPEntryInRange(UserMI, UserOffset, CPEMI, U.getLongFormMaxDisp(), + U.NegOk, true)) { + LLVM_DEBUG(dbgs() << "In range\n"); + UserMI->setDesc(TII->get(U.getLongFormOpcode())); + U.setMaxDisp(U.getLongFormMaxDisp()); + return 2; // instruction is longer length now + } + + // No. Look for previously created clones of the CPE that are in range. + unsigned CPI = CPEMI->getOperand(1).getIndex(); + std::vector &CPEs = CPEntries[CPI]; + for (unsigned I = 0, E = CPEs.size(); I != E; ++I) { + // We already tried this one + if (CPEs[I].CPEMI == CPEMI) + continue; + // Removing CPEs can leave empty entries, skip + if (CPEs[I].CPEMI == nullptr) + continue; + if (isCPEntryInRange(UserMI, UserOffset, CPEs[I].CPEMI, + U.getLongFormMaxDisp(), U.NegOk)) { + LLVM_DEBUG(dbgs() << "Replacing CPE#" << CPI << " with CPE#" + << CPEs[I].CPI << "\n"); + // Point the CPUser node to the replacement + U.CPEMI = CPEs[I].CPEMI; + // Change the CPI in the instruction operand to refer to the clone. + for (unsigned J = 0, E = UserMI->getNumOperands(); J != E; ++J) + if (UserMI->getOperand(J).isCPI()) { + UserMI->getOperand(J).setIndex(CPEs[I].CPI); + break; + } + // Adjust the refcount of the clone... + CPEs[I].RefCount++; + // ...and the original. If we didn't remove the old entry, none of the + // addresses changed, so we don't need another pass. + return decrementCPEReferenceCount(CPI, CPEMI) ? 2 : 1; + } + } + return 0; +} + +/// getUnconditionalBrDisp - Returns the maximum displacement that can fit in +/// the specific unconditional branch instruction. +static inline unsigned getUnconditionalBrDisp(int Opc) { + switch (Opc) { + ; + // TODO: Add support for 16bit instr. + case CSKY::BR32: + return ((1 << 16) - 1) * 2; + default: + break; + } + return ((1 << 16) - 1) * 2; +} + +/// findAvailableWater - Look for an existing entry in the WaterList in which +/// we can place the CPE referenced from U so it's within range of U's MI. +/// Returns true if found, false if not. If it returns true, WaterIter +/// is set to the WaterList entry. +/// To ensure that this pass +/// terminates, the CPE location for a particular CPUser is only allowed to +/// move to a lower address, so search backward from the end of the list and +/// prefer the first water that is in range. +bool CSKYConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset, + water_iterator &WaterIter) { + if (WaterList.empty()) + return false; + + unsigned BestGrowth = ~0u; + for (water_iterator IP = std::prev(WaterList.end()), B = WaterList.begin();; + --IP) { + MachineBasicBlock *WaterBB = *IP; + // Check if water is in range and is either at a lower address than the + // current "high water mark" or a new water block that was created since + // the previous iteration by inserting an unconditional branch. In the + // latter case, we want to allow resetting the high water mark back to + // this new water since we haven't seen it before. Inserting branches + // should be relatively uncommon and when it does happen, we want to be + // sure to take advantage of it for all the CPEs near that block, so that + // we don't insert more branches than necessary. + unsigned Growth; + if (isWaterInRange(UserOffset, WaterBB, U, Growth) && + (WaterBB->getNumber() < U.HighWaterMark->getNumber() || + NewWaterList.count(WaterBB)) && + Growth < BestGrowth) { + // This is the least amount of required padding seen so far. + BestGrowth = Growth; + WaterIter = IP; + LLVM_DEBUG(dbgs() << "Found water after " << printMBBReference(*WaterBB) + << " Growth=" << Growth << '\n'); + + // Keep looking unless it is perfect. + if (BestGrowth == 0) + return true; + } + if (IP == B) + break; + } + return BestGrowth != ~0u; +} + +/// createNewWater - No existing WaterList entry will work for +/// CPUsers[CPUserIndex], so create a place to put the CPE. The end of the +/// block is used if in range, and the conditional branch munged so control +/// flow is correct. Otherwise the block is split to create a hole with an +/// unconditional branch around it. In either case NewMBB is set to a +/// block following which the new island can be inserted (the WaterList +/// is not adjusted). +void CSKYConstantIslands::createNewWater(unsigned CPUserIndex, + unsigned UserOffset, + MachineBasicBlock *&NewMBB) { + CPUser &U = CPUsers[CPUserIndex]; + MachineInstr *UserMI = U.MI; + MachineInstr *CPEMI = U.CPEMI; + MachineBasicBlock *UserMBB = UserMI->getParent(); + const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()]; + + // If the block does not end in an unconditional branch already, and if the + // end of the block is within range, make new water there. + if (bbHasFallthrough(UserMBB)) { + // Size of branch to insert. + unsigned Delta = 2; + // Compute the offset where the CPE will begin. + unsigned CPEOffset = UserBBI.postOffset() + Delta; + + if (isOffsetInRange(UserOffset, CPEOffset, U)) { + LLVM_DEBUG(dbgs() << "Split at end of " << printMBBReference(*UserMBB) + << format(", expected CPE offset %#x\n", CPEOffset)); + NewMBB = &*++UserMBB->getIterator(); + // Add an unconditional branch from UserMBB to fallthrough block. Record + // it for branch lengthening; this new branch will not get out of range, + // but if the preceding conditional branch is out of range, the targets + // will be exchanged, and the altered branch may be out of range, so the + // machinery has to know about it. + + // TODO: Add support for 16bit instr. + int UncondBr = CSKY::BR32; + auto *NewMI = BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)) + .addMBB(NewMBB) + .getInstr(); + unsigned MaxDisp = getUnconditionalBrDisp(UncondBr); + ImmBranches.push_back( + ImmBranch(&UserMBB->back(), MaxDisp, false, UncondBr)); + BBInfo[UserMBB->getNumber()].Size += TII->getInstSizeInBytes(*NewMI); + adjustBBOffsetsAfter(UserMBB); + return; + } + } + + // What a big block. Find a place within the block to split it. + + // Try to split the block so it's fully aligned. Compute the latest split + // point where we can add a 4-byte branch instruction, and then align to + // Align which is the largest possible alignment in the function. + const Align Align = MF->getAlignment(); + unsigned BaseInsertOffset = UserOffset + U.getMaxDisp(); + LLVM_DEBUG(dbgs() << format("Split in middle of big block before %#x", + BaseInsertOffset)); + + // The 4 in the following is for the unconditional branch we'll be inserting + // Alignment of the island is handled + // inside isOffsetInRange. + BaseInsertOffset -= 4; + + LLVM_DEBUG(dbgs() << format(", adjusted to %#x", BaseInsertOffset) + << " la=" << Log2(Align) << '\n'); + + // This could point off the end of the block if we've already got constant + // pool entries following this block; only the last one is in the water list. + // Back past any possible branches (allow for a conditional and a maximally + // long unconditional). + if (BaseInsertOffset + 8 >= UserBBI.postOffset()) { + BaseInsertOffset = UserBBI.postOffset() - 8; + LLVM_DEBUG(dbgs() << format("Move inside block: %#x\n", BaseInsertOffset)); + } + unsigned EndInsertOffset = + BaseInsertOffset + 4 + CPEMI->getOperand(2).getImm(); + MachineBasicBlock::iterator MI = UserMI; + ++MI; + unsigned CPUIndex = CPUserIndex + 1; + unsigned NumCPUsers = CPUsers.size(); + // MachineInstr *LastIT = 0; + for (unsigned Offset = UserOffset + TII->getInstSizeInBytes(*UserMI); + Offset < BaseInsertOffset; + Offset += TII->getInstSizeInBytes(*MI), MI = std::next(MI)) { + assert(MI != UserMBB->end() && "Fell off end of block"); + if (CPUIndex < NumCPUsers && CPUsers[CPUIndex].MI == MI) { + CPUser &U = CPUsers[CPUIndex]; + if (!isOffsetInRange(Offset, EndInsertOffset, U)) { + // Shift intertion point by one unit of alignment so it is within reach. + BaseInsertOffset -= Align.value(); + EndInsertOffset -= Align.value(); + } + // This is overly conservative, as we don't account for CPEMIs being + // reused within the block, but it doesn't matter much. Also assume CPEs + // are added in order with alignment padding. We may eventually be able + // to pack the aligned CPEs better. + EndInsertOffset += U.CPEMI->getOperand(2).getImm(); + CPUIndex++; + } + } + + NewMBB = splitBlockBeforeInstr(*--MI); +} + +/// handleConstantPoolUser - Analyze the specified user, checking to see if it +/// is out-of-range. If so, pick up the constant pool value and move it some +/// place in-range. Return true if we changed any addresses (thus must run +/// another pass of branch lengthening), false otherwise. +bool CSKYConstantIslands::handleConstantPoolUser(unsigned CPUserIndex) { + CPUser &U = CPUsers[CPUserIndex]; + MachineInstr *UserMI = U.MI; + MachineInstr *CPEMI = U.CPEMI; + unsigned CPI = CPEMI->getOperand(1).getIndex(); + unsigned Size = CPEMI->getOperand(2).getImm(); + // Compute this only once, it's expensive. + unsigned UserOffset = getUserOffset(U); + + // See if the current entry is within range, or there is a clone of it + // in range. + int result = findInRangeCPEntry(U, UserOffset); + if (result == 1) + return false; + if (result == 2) + return true; + + // Look for water where we can place this CPE. + MachineBasicBlock *NewIsland = MF->CreateMachineBasicBlock(); + MachineBasicBlock *NewMBB; + water_iterator IP; + if (findAvailableWater(U, UserOffset, IP)) { + LLVM_DEBUG(dbgs() << "Found water in range\n"); + MachineBasicBlock *WaterBB = *IP; + + // If the original WaterList entry was "new water" on this iteration, + // propagate that to the new island. This is just keeping NewWaterList + // updated to match the WaterList, which will be updated below. + if (NewWaterList.erase(WaterBB)) + NewWaterList.insert(NewIsland); + + // The new CPE goes before the following block (NewMBB). + NewMBB = &*++WaterBB->getIterator(); + } else { + // No water found. + // we first see if a longer form of the instrucion could have reached + // the constant. in that case we won't bother to split + if (!NoLoadRelaxation) { + result = findLongFormInRangeCPEntry(U, UserOffset); + if (result != 0) + return true; + } + LLVM_DEBUG(dbgs() << "No water found\n"); + createNewWater(CPUserIndex, UserOffset, NewMBB); + + // splitBlockBeforeInstr adds to WaterList, which is important when it is + // called while handling branches so that the water will be seen on the + // next iteration for constant pools, but in this context, we don't want + // it. Check for this so it will be removed from the WaterList. + // Also remove any entry from NewWaterList. + MachineBasicBlock *WaterBB = &*--NewMBB->getIterator(); + IP = llvm::find(WaterList, WaterBB); + if (IP != WaterList.end()) + NewWaterList.erase(WaterBB); + + // We are adding new water. Update NewWaterList. + NewWaterList.insert(NewIsland); + } + + // Remove the original WaterList entry; we want subsequent insertions in + // this vicinity to go after the one we're about to insert. This + // considerably reduces the number of times we have to move the same CPE + // more than once and is also important to ensure the algorithm terminates. + if (IP != WaterList.end()) + WaterList.erase(IP); + + // Okay, we know we can put an island before NewMBB now, do it! + MF->insert(NewMBB->getIterator(), NewIsland); + + // Update internal data structures to account for the newly inserted MBB. + updateForInsertedWaterBlock(NewIsland); + + // Decrement the old entry, and remove it if refcount becomes 0. + decrementCPEReferenceCount(CPI, CPEMI); + + // No existing clone of this CPE is within range. + // We will be generating a new clone. Get a UID for it. + unsigned ID = MFI->createPICLabelUId(); + + // Now that we have an island to add the CPE to, clone the original CPE and + // add it to the island. + U.HighWaterMark = NewIsland; + U.CPEMI = BuildMI(NewIsland, DebugLoc(), TII->get(CSKY::CONSTPOOL_ENTRY)) + .addImm(ID) + .addConstantPoolIndex(CPI) + .addImm(Size); + CPEntries[CPI].push_back(CPEntry(U.CPEMI, ID, 1)); + ++NumCPEs; + + // Mark the basic block as aligned as required by the const-pool entry. + NewIsland->setAlignment(getCPEAlign(*U.CPEMI)); + + // Increase the size of the island block to account for the new entry. + BBInfo[NewIsland->getNumber()].Size += Size; + adjustBBOffsetsAfter(&*--NewIsland->getIterator()); + + // Finally, change the CPI in the instruction operand to be ID. + for (unsigned I = 0, E = UserMI->getNumOperands(); I != E; ++I) + if (UserMI->getOperand(I).isCPI()) { + UserMI->getOperand(I).setIndex(ID); + break; + } + + LLVM_DEBUG( + dbgs() << " Moved CPE to #" << ID << " CPI=" << CPI + << format(" offset=%#x\n", BBInfo[NewIsland->getNumber()].Offset)); + + return true; +} + +/// removeDeadCPEMI - Remove a dead constant pool entry instruction. Update +/// sizes and offsets of impacted basic blocks. +void CSKYConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) { + MachineBasicBlock *CPEBB = CPEMI->getParent(); + unsigned Size = CPEMI->getOperand(2).getImm(); + CPEMI->eraseFromParent(); + BBInfo[CPEBB->getNumber()].Size -= Size; + // All succeeding offsets have the current size value added in, fix this. + if (CPEBB->empty()) { + BBInfo[CPEBB->getNumber()].Size = 0; + + // This block no longer needs to be aligned. + CPEBB->setAlignment(Align(1)); + } else { + // Entries are sorted by descending alignment, so realign from the front. + CPEBB->setAlignment(getCPEAlign(*CPEBB->begin())); + } + + adjustBBOffsetsAfter(CPEBB); + // An island has only one predecessor BB and one successor BB. Check if + // this BB's predecessor jumps directly to this BB's successor. This + // shouldn't happen currently. + assert(!bbIsJumpedOver(CPEBB) && "How did this happen?"); + // FIXME: remove the empty blocks after all the work is done? +} + +/// removeUnusedCPEntries - Remove constant pool entries whose refcounts +/// are zero. +bool CSKYConstantIslands::removeUnusedCPEntries() { + unsigned MadeChange = false; + for (unsigned I = 0, E = CPEntries.size(); I != E; ++I) { + std::vector &CPEs = CPEntries[I]; + for (unsigned J = 0, Ee = CPEs.size(); J != Ee; ++J) { + if (CPEs[J].RefCount == 0 && CPEs[J].CPEMI) { + removeDeadCPEMI(CPEs[J].CPEMI); + CPEs[J].CPEMI = nullptr; + MadeChange = true; + } + } + } + return MadeChange; +} + +/// isBBInRange - Returns true if the distance between specific MI and +/// specific BB can fit in MI's displacement field. +bool CSKYConstantIslands::isBBInRange(MachineInstr *MI, + MachineBasicBlock *DestBB, + unsigned MaxDisp) { + unsigned PCAdj = 4; + unsigned BrOffset = getOffsetOf(MI) + PCAdj; + unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset; + + LLVM_DEBUG(dbgs() << "Branch of destination " << printMBBReference(*DestBB) + << " from " << printMBBReference(*MI->getParent()) + << " max delta=" << MaxDisp << " from " << getOffsetOf(MI) + << " to " << DestOffset << " offset " + << int(DestOffset - BrOffset) << "\t" << *MI); + + if (BrOffset <= DestOffset) { + // Branch before the Dest. + if (DestOffset - BrOffset <= MaxDisp) + return true; + } else { + if (BrOffset - DestOffset <= MaxDisp) + return true; + } + return false; +} + +/// fixupImmediateBr - Fix up an immediate branch whose destination is too far +/// away to fit in its displacement field. +bool CSKYConstantIslands::fixupImmediateBr(ImmBranch &Br) { + MachineInstr *MI = Br.MI; + MachineBasicBlock *DestBB = TII->getBranchDestBlock(*MI); + + // Check to see if the DestBB is already in-range. + if (isBBInRange(MI, DestBB, Br.MaxDisp)) + return false; + + if (!Br.IsCond) + return fixupUnconditionalBr(Br); + return fixupConditionalBr(Br); +} + +/// fixupUnconditionalBr - Fix up an unconditional branch whose destination is +/// too far away to fit in its displacement field. If the LR register has been +/// spilled in the epilogue, then we can use BSR to implement a far jump. +/// Otherwise, add an intermediate branch instruction to a branch. +bool CSKYConstantIslands::fixupUnconditionalBr(ImmBranch &Br) { + MachineInstr *MI = Br.MI; + MachineBasicBlock *MBB = MI->getParent(); + MachineBasicBlock *DestBB = MI->getOperand(0).getMBB(); + // Use BSR to implement far jump. + unsigned BR32MaxDisp = ((1 << 16) - 1) * 2; + if (isBBInRange(MI, DestBB, BR32MaxDisp)) { + Br.MaxDisp = BR32MaxDisp; + MI->setDesc(TII->get(CSKY::BR32)); + } else { + // need to give the math a more careful look here + // this is really a segment address and not + // a PC relative address. FIXME. But I think that + // just reducing the bits by 1 as I've done is correct. + // The basic block we are branching too much be longword aligned. + // we know that RA is saved because we always save it right now. + // this requirement will be relaxed later but we also have an alternate + // way to implement this that I will implement that does not need jal. + // We should have a way to back out this alignment restriction + // if we "can" later. but it is not harmful. + // + DestBB->setAlignment(Align(4)); + Br.MaxDisp = ((1 << 26) - 1) * 2; + MI->setDesc(TII->get(CSKY::BSR32)); + } + BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(*MI); + adjustBBOffsetsAfter(MBB); + HasFarJump = true; + ++NumUBrFixed; + + LLVM_DEBUG(dbgs() << " Changed B to long jump " << *MI); + + return true; +} + +/// fixupConditionalBr - Fix up a conditional branch whose destination is too +/// far away to fit in its displacement field. It is converted to an inverse +/// conditional branch + an unconditional branch to the destination. +bool CSKYConstantIslands::fixupConditionalBr(ImmBranch &Br) { + MachineInstr *MI = Br.MI; + MachineBasicBlock *DestBB = TII->getBranchDestBlock(*MI); + unsigned Opcode = MI->getOpcode(); + unsigned LongFormOpcode = longformBranchOpcode(Opcode); + unsigned LongFormMaxOff = branchMaxOffsets(LongFormOpcode); + + // Check to see if the DestBB is already in-range. + if (isBBInRange(MI, DestBB, LongFormMaxOff)) { + Br.MaxDisp = LongFormMaxOff; + MI->setDesc(TII->get(LongFormOpcode)); + return true; + } + + // Add an unconditional branch to the destination and invert the branch + // condition to jump over it: + // bteqz L1 + // => + // bnez L2 + // b L1 + // L2: + + // If the branch is at the end of its MBB and that has a fall-through block, + // direct the updated conditional branch to the fall-through block. Otherwise, + // split the MBB before the next instruction. + MachineBasicBlock *MBB = MI->getParent(); + MachineInstr *BMI = &MBB->back(); + bool NeedSplit = (BMI != MI) || !bbHasFallthrough(MBB); + + ++NumCBrFixed; + if (BMI != MI) { + if (std::next(MachineBasicBlock::iterator(MI)) == std::prev(MBB->end()) && + BMI->isUnconditionalBranch()) { + // Last MI in the BB is an unconditional branch. Can we simply invert the + // condition and swap destinations: + // beqz L1 + // b L2 + // => + // bnez L2 + // b L1 + MachineBasicBlock *NewDest = TII->getBranchDestBlock(*BMI); + if (isBBInRange(MI, NewDest, Br.MaxDisp)) { + LLVM_DEBUG( + dbgs() << " Invert Bcc condition and swap its destination with " + << *BMI); + BMI->getOperand(BMI->getNumExplicitOperands() - 1).setMBB(DestBB); + MI->getOperand(MI->getNumExplicitOperands() - 1).setMBB(NewDest); + + SmallVector Cond; + Cond.push_back(MachineOperand::CreateImm(MI->getOpcode())); + Cond.push_back(MI->getOperand(0)); + TII->reverseBranchCondition(Cond); + return true; + } + } + } + + if (NeedSplit) { + splitBlockBeforeInstr(*MI); + // No need for the branch to the next block. We're adding an unconditional + // branch to the destination. + int Delta = TII->getInstSizeInBytes(MBB->back()); + BBInfo[MBB->getNumber()].Size -= Delta; + MBB->back().eraseFromParent(); + // BBInfo[SplitBB].Offset is wrong temporarily, fixed below + } + MachineBasicBlock *NextBB = &*++MBB->getIterator(); + + LLVM_DEBUG(dbgs() << " Insert B to " << printMBBReference(*DestBB) + << " also invert condition and change dest. to " + << printMBBReference(*NextBB) << "\n"); + + // Insert a new conditional branch and a new unconditional branch. + // Also update the ImmBranch as well as adding a new entry for the new branch. + + auto *NewMI = BuildMI(MBB, DebugLoc(), TII->get(MI->getOpcode())) + .addReg(MI->getOperand(0).getReg()) + .addMBB(NextBB) + .getInstr(); + + SmallVector Cond; + Cond.push_back(MachineOperand::CreateImm(NewMI->getOpcode())); + Cond.push_back(NewMI->getOperand(0)); + TII->reverseBranchCondition(Cond); + + Br.MI = &MBB->back(); + BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back()); + BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB); + BBInfo[MBB->getNumber()].Size += TII->getInstSizeInBytes(MBB->back()); + unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr); + ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr)); + + // Remove the old conditional branch. It may or may not still be in MBB. + BBInfo[MI->getParent()->getNumber()].Size -= TII->getInstSizeInBytes(*MI); + MI->eraseFromParent(); + adjustBBOffsetsAfter(MBB); + return true; +} + +/// Returns a pass that converts branches to long branches. +FunctionPass *llvm::createCSKYConstantIslandPass() { + return new CSKYConstantIslands(); +} + +INITIALIZE_PASS(CSKYConstantIslands, DEBUG_TYPE, + "CSKY constant island placement and branch shortening pass", + false, false) \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYConstantPoolValue.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYConstantPoolValue.h @@ -0,0 +1,244 @@ +//===-- CSKYConstantPoolValue.h - CSKY constantpool value -----*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the CSKY specific constantpool value class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H +#define LLVM_TARGET_CSKY_CONSTANTPOOLVALUE_H + +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/Support/ErrorHandling.h" +#include + +namespace llvm { + +class BlockAddress; +class Constant; +class GlobalValue; +class LLVMContext; +class MachineBasicBlock; + +namespace CSKYCP { +enum CSKYCPKind { + CPValue, + CPExtSymbol, + CPBlockAddress, + CPLSDA, + CPMachineBasicBlock, + CPJT +}; + +enum CSKYCPModifier { no_modifier, TLSGD, GOT, GOTOFF, GOTTPOFF, TPOFF }; +} // namespace CSKYCP + +/// CSKYConstantPoolValue - CSKY specific constantpool value. This is used to +/// represent PC-relative displacement between the address of the load +/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). +class CSKYConstantPoolValue : public MachineConstantPoolValue { + unsigned LabelId; // Label id of the load. + CSKYCP::CSKYCPKind Kind; // Kind of constant. + unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. + // 8 for CSKY, 4 for Thumb. + CSKYCP::CSKYCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) + bool AddCurrentAddress; + +protected: + CSKYConstantPoolValue(Type *Ty, unsigned id, CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + + CSKYConstantPoolValue(LLVMContext &C, unsigned id, CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + +public: + virtual ~CSKYConstantPoolValue(); + + CSKYCP::CSKYCPModifier getModifier() const { return Modifier; } + const char *getModifierText() const; + bool hasModifier() const { return Modifier != CSKYCP::no_modifier; } + + bool mustAddCurrentAddress() const { return AddCurrentAddress; } + + unsigned getLabelId() const { return LabelId; } + unsigned char getPCAdjustment() const { return PCAdjust; } + + bool isGlobalValue() const { return Kind == CSKYCP::CPValue; } + bool isExtSymbol() const { return Kind == CSKYCP::CPExtSymbol; } + bool isBlockAddress() const { return Kind == CSKYCP::CPBlockAddress; } + bool isLSDA() const { return Kind == CSKYCP::CPLSDA; } + bool isMachineBasicBlock() const { + return Kind == CSKYCP::CPMachineBasicBlock; + } + bool isJT() const { return Kind == CSKYCP::CPJT; } + + bool equals(const CSKYConstantPoolValue *A) const { + return this->LabelId == A->LabelId && this->PCAdjust == A->PCAdjust && + this->Modifier == A->Modifier; + } + + void dump() const; + + virtual unsigned getRelocationInfo() const { return 2; } + + /// hasSameValue - Return true if this CSKY constpool value can share the same + /// constantpool entry as another CSKY constpool value. + virtual bool hasSameValue(CSKYConstantPoolValue *ACPV); + + int getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) override; + + void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; + + void print(raw_ostream &O) const override; +}; + +inline raw_ostream &operator<<(raw_ostream &O, const CSKYConstantPoolValue &V) { + V.print(O); + return O; +} + +/// CSKYConstantPoolConstant - CSKY-specific constant pool values for Constants, +/// Functions, and BlockAddresses. +class CSKYConstantPoolConstant : public CSKYConstantPoolValue { + const Constant *CVal; // Constant being loaded. + + CSKYConstantPoolConstant(const Constant *C, unsigned ID, + CSKYCP::CSKYCPKind Kind, unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + CSKYConstantPoolConstant(Type *Ty, const Constant *C, unsigned ID, + CSKYCP::CSKYCPKind Kind, unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + +public: + static CSKYConstantPoolConstant *Create(const Constant *C, unsigned ID); + static CSKYConstantPoolConstant *Create(const GlobalValue *GV, + CSKYCP::CSKYCPModifier Modifier); + static CSKYConstantPoolConstant *Create(const Constant *C, unsigned ID, + CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj); + static CSKYConstantPoolConstant *Create(const Constant *C, unsigned ID, + CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + + const GlobalValue *getGV() const; + const BlockAddress *getBlockAddress() const; + + int getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) override; + void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; + void print(raw_ostream &O) const override; + + /// hasSameValue - Return true if this CSKY constpool value can share the same + /// constantpool entry as another CSKY constpool value. + virtual bool hasSameValue(CSKYConstantPoolValue *ACPV); + + static bool classof(const CSKYConstantPoolValue *APV) { + return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA(); + } +}; + +/// CSKYConstantPoolSymbol - CSKY-specific constantpool values for external +/// symbols. +class CSKYConstantPoolSymbol : public CSKYConstantPoolValue { + const char *S; // ExtSymbol being loaded. + + CSKYConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + +public: + ~CSKYConstantPoolSymbol(); + + static CSKYConstantPoolSymbol *Create(LLVMContext &C, const char *s, + unsigned ID, unsigned char PCAdj); + + const char *getSymbol() const { return S; } + + int getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) override; + void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; + void print(raw_ostream &O) const override; + + /// hasSameValue - Return true if this CSKY constpool value can share the same + /// constantpool entry as another CSKY constpool value. + virtual bool hasSameValue(CSKYConstantPoolValue *ACPV); + + static bool classof(const CSKYConstantPoolValue *ACPV) { + return ACPV->isExtSymbol(); + } +}; + +/// CSKYConstantPoolMBB - CSKY-specific constantpool value of a machine basic +/// block. +class CSKYConstantPoolMBB : public CSKYConstantPoolValue { + const MachineBasicBlock *MBB; // Machine basic block. + + CSKYConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + +public: + static CSKYConstantPoolMBB *Create(LLVMContext &C, + const MachineBasicBlock *mbb, unsigned ID, + unsigned char PCAdj); + + const MachineBasicBlock *getMBB() const { return MBB; } + + int getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) override; + void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; + void print(raw_ostream &O) const override; + + /// hasSameValue - Return true if this CSKY constpool value can share the same + /// constantpool entry as another CSKY constpool value. + virtual bool hasSameValue(CSKYConstantPoolValue *ACPV); + + static bool classof(const CSKYConstantPoolValue *ACPV) { + return ACPV->isMachineBasicBlock(); + } +}; + +/// CSKYConstantPoolJT - CSKY-specific constantpool value of a jump table. +class CSKYConstantPoolJT : public CSKYConstantPoolValue { + signed JTI; // Machine basic block. + + CSKYConstantPoolJT(LLVMContext &C, int JTIndex, unsigned id, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress); + +public: + static CSKYConstantPoolJT *Create(LLVMContext &C, int JTI, unsigned id, + unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier); + + signed getJTI() { return JTI; } + + int getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) override; + void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; + void print(raw_ostream &O) const override; + + /// hasSameValue - Return true if this CSKY constpool value can share the same + /// constantpool entry as another CSKY constpool value. + virtual bool hasSameValue(CSKYConstantPoolValue *ACPV); + + static bool classof(const CSKYConstantPoolValue *ACPV) { + return ACPV->isJT(); + } +}; + +} // namespace llvm + +#endif Index: llvm/lib/Target/CSKY/CSKYConstantPoolValue.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYConstantPoolValue.cpp @@ -0,0 +1,376 @@ +//===-- CSKYConstantPoolValue.cpp - CSKY constantpool value ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the CSKY specific constantpool value class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYConstantPoolValue.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// CSKYConstantPoolValue +//===----------------------------------------------------------------------===// + +CSKYConstantPoolValue::CSKYConstantPoolValue(Type *Ty, unsigned Id, + CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : MachineConstantPoolValue(Ty), LabelId(Id), Kind(Kind), PCAdjust(PCAdj), + Modifier(Modifier), AddCurrentAddress(AddCurrentAddress) {} + +CSKYConstantPoolValue::CSKYConstantPoolValue(LLVMContext &C, unsigned Id, + CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : MachineConstantPoolValue((Type *)Type::getInt32Ty(C)), LabelId(Id), + Kind(Kind), PCAdjust(PCAdj), Modifier(Modifier), + AddCurrentAddress(AddCurrentAddress) {} + +CSKYConstantPoolValue::~CSKYConstantPoolValue() {} + +const char *CSKYConstantPoolValue::getModifierText() const { + switch (Modifier) { + // FIXME: Are these case sensitive? It'd be nice to lower-case all the + // strings if that's legal. + case CSKYCP::no_modifier: + return "none"; + case CSKYCP::TLSGD: + return "tlsgd"; + case CSKYCP::GOT: + return "GOT"; + case CSKYCP::GOTOFF: + return "GOTOFF"; + case CSKYCP::GOTTPOFF: + return "gottpoff"; + case CSKYCP::TPOFF: + return "tpoff"; + } + llvm_unreachable("Unknown modifier!"); +} + +int CSKYConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) { + llvm_unreachable("Shouldn't be calling this directly!"); +} + +void CSKYConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddInteger(LabelId); + ID.AddInteger(PCAdjust); +} + +bool CSKYConstantPoolValue::hasSameValue(CSKYConstantPoolValue *CCPV) { + if (CCPV->Kind == Kind && CCPV->PCAdjust == PCAdjust && + CCPV->Modifier == Modifier) { + if (CCPV->LabelId == LabelId) + return true; + // Two PC relative constpool entries containing the same GV address or + // external symbols. FIXME: What about blockaddress? + if (Kind == CSKYCP::CPValue || Kind == CSKYCP::CPExtSymbol) + return true; + } + return false; +} + +void CSKYConstantPoolValue::dump() const { errs() << " " << *this; } + +void CSKYConstantPoolValue::print(raw_ostream &O) const { + if (Modifier) + O << "(" << getModifierText() << ")"; + if (PCAdjust != 0) { + O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; + if (AddCurrentAddress) + O << "-."; + O << ")"; + } +} + +//===----------------------------------------------------------------------===// +// CSKYConstantPoolConstant +//===----------------------------------------------------------------------===// + +CSKYConstantPoolConstant::CSKYConstantPoolConstant( + Type *Ty, const Constant *C, unsigned ID, CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : CSKYConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), + CVal(C) {} + +CSKYConstantPoolConstant::CSKYConstantPoolConstant( + const Constant *C, unsigned ID, CSKYCP::CSKYCPKind Kind, + unsigned char PCAdj, CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : CSKYConstantPoolValue((Type *)C->getType(), ID, Kind, PCAdj, Modifier, + AddCurrentAddress), + CVal(C) {} + +CSKYConstantPoolConstant *CSKYConstantPoolConstant::Create(const Constant *C, + unsigned ID) { + return new CSKYConstantPoolConstant(C, ID, CSKYCP::CPValue, 0, + CSKYCP::no_modifier, false); +} + +CSKYConstantPoolConstant * +CSKYConstantPoolConstant::Create(const GlobalValue *GV, + CSKYCP::CSKYCPModifier Modifier) { + return new CSKYConstantPoolConstant( + (Type *)Type::getInt32Ty(GV->getContext()), GV, 0, CSKYCP::CPValue, 0, + Modifier, false); +} + +CSKYConstantPoolConstant * +CSKYConstantPoolConstant::Create(const Constant *C, unsigned ID, + CSKYCP::CSKYCPKind Kind, unsigned char PCAdj) { + return new CSKYConstantPoolConstant(C, ID, Kind, PCAdj, CSKYCP::no_modifier, + false); +} + +CSKYConstantPoolConstant * +CSKYConstantPoolConstant::Create(const Constant *C, unsigned ID, + CSKYCP::CSKYCPKind Kind, unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) { + return new CSKYConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, + AddCurrentAddress); +} + +const GlobalValue *CSKYConstantPoolConstant::getGV() const { + assert(isa(CVal) && "CVal should be GlobalValue"); + return cast(CVal); +} + +const BlockAddress *CSKYConstantPoolConstant::getBlockAddress() const { + assert(isa(CVal) && "CVal should be BlockAddress"); + return cast(CVal); +} + +int CSKYConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) { + unsigned AlignMask = Alignment.value() - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned I = 0, E = Constants.size(); I != E; ++I) { + if (Constants[I].isMachineConstantPoolEntry() && + (Constants[I].getAlign().value() & AlignMask) == 0) { + CSKYConstantPoolValue *CPV = + (CSKYConstantPoolValue *)Constants[I].Val.MachineCPVal; + CSKYConstantPoolConstant *APC = dyn_cast(CPV); + if (!APC) + continue; + if (APC->CVal == CVal && equals(APC)) + return I; + } + } + + return -1; +} + +bool CSKYConstantPoolConstant::hasSameValue(CSKYConstantPoolValue *CCPV) { + const CSKYConstantPoolConstant *ACPC = + dyn_cast(CCPV); + return ACPC && ACPC->CVal == CVal && + CSKYConstantPoolValue::hasSameValue(CCPV); +} + +void CSKYConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddPointer(CVal); + CSKYConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void CSKYConstantPoolConstant::print(raw_ostream &O) const { + O << CVal->getName(); + CSKYConstantPoolValue::print(O); +} + +//===----------------------------------------------------------------------===// +// CSKYConstantPoolSymbol +//===----------------------------------------------------------------------===// + +CSKYConstantPoolSymbol::CSKYConstantPoolSymbol(LLVMContext &C, const char *S, + unsigned Id, unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : CSKYConstantPoolValue(C, Id, CSKYCP::CPExtSymbol, PCAdj, Modifier, + AddCurrentAddress), + S(strdup(S)) {} + +CSKYConstantPoolSymbol::~CSKYConstantPoolSymbol() = default; + +CSKYConstantPoolSymbol *CSKYConstantPoolSymbol::Create(LLVMContext &C, + const char *S, + unsigned ID, + unsigned char PCAdj) { + return new CSKYConstantPoolSymbol(C, S, ID, PCAdj, CSKYCP::no_modifier, + false); +} + +static bool cpvStreq(const char *S1, const char *S2) { + if (S1 == S2) + return true; + if (S1 && S2 && strcmp(S1, S2) == 0) + return true; + return false; +} + +int CSKYConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) { + unsigned AlignMask = Alignment.value() - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned I = 0, E = Constants.size(); I != E; ++I) { + if (Constants[I].isMachineConstantPoolEntry() && + (Constants[I].getAlign().value() & AlignMask) == 0) { + CSKYConstantPoolValue *CPV = + (CSKYConstantPoolValue *)Constants[I].Val.MachineCPVal; + CSKYConstantPoolSymbol *APS = dyn_cast(CPV); + if (!APS) + continue; + + if (cpvStreq(APS->S, S) && equals(APS)) + return I; + } + } + + return -1; +} + +bool CSKYConstantPoolSymbol::hasSameValue(CSKYConstantPoolValue *CCPV) { + const CSKYConstantPoolSymbol *ACPS = dyn_cast(CCPV); + return ACPS && cpvStreq(ACPS->S, S) && + CSKYConstantPoolValue::hasSameValue(CCPV); +} + +void CSKYConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddPointer(S); + CSKYConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void CSKYConstantPoolSymbol::print(raw_ostream &O) const { + O << S; + CSKYConstantPoolValue::print(O); +} + +//===----------------------------------------------------------------------===// +// CSKYConstantPoolMBB +//===----------------------------------------------------------------------===// + +CSKYConstantPoolMBB::CSKYConstantPoolMBB(LLVMContext &C, + const MachineBasicBlock *Mbb, + unsigned Id, unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : CSKYConstantPoolValue(C, Id, CSKYCP::CPMachineBasicBlock, PCAdj, Modifier, + AddCurrentAddress), + MBB(Mbb) {} + +CSKYConstantPoolMBB *CSKYConstantPoolMBB::Create(LLVMContext &C, + const MachineBasicBlock *Mbb, + unsigned ID, + unsigned char PCAdj) { + return new CSKYConstantPoolMBB(C, Mbb, ID, PCAdj, CSKYCP::no_modifier, false); +} + +int CSKYConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) { + unsigned AlignMask = Alignment.value() - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned I = 0, E = Constants.size(); I != E; ++I) { + if (Constants[I].isMachineConstantPoolEntry() && + (Constants[I].getAlign().value() & AlignMask) == 0) { + CSKYConstantPoolValue *CPV = + (CSKYConstantPoolValue *)Constants[I].Val.MachineCPVal; + CSKYConstantPoolMBB *APMBB = dyn_cast(CPV); + if (!APMBB) + continue; + + if (APMBB->MBB == MBB && equals(APMBB)) + return I; + } + } + + return -1; +} + +bool CSKYConstantPoolMBB::hasSameValue(CSKYConstantPoolValue *CCPV) { + const CSKYConstantPoolMBB *ACPMBB = dyn_cast(CCPV); + return ACPMBB && ACPMBB->MBB == MBB && + CSKYConstantPoolValue::hasSameValue(CCPV); +} + +void CSKYConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddPointer(MBB); + CSKYConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void CSKYConstantPoolMBB::print(raw_ostream &O) const { + O << "BB#" << MBB->getNumber(); + CSKYConstantPoolValue::print(O); +} + +//===----------------------------------------------------------------------===// +// CSKYConstantPoolJT +//===----------------------------------------------------------------------===// + +CSKYConstantPoolJT::CSKYConstantPoolJT(LLVMContext &C, int JTIndex, unsigned Id, + unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier, + bool AddCurrentAddress) + : CSKYConstantPoolValue(C, Id, CSKYCP::CPJT, PCAdj, Modifier, + AddCurrentAddress), + JTI(JTIndex) {} + +CSKYConstantPoolJT * +CSKYConstantPoolJT::Create(LLVMContext &C, int JTI, unsigned Id, + unsigned char PCAdj, + CSKYCP::CSKYCPModifier Modifier) { + return new CSKYConstantPoolJT(C, JTI, Id, PCAdj, Modifier, false); +} + +int CSKYConstantPoolJT::getExistingMachineCPValue(MachineConstantPool *CP, + Align Alignment) { + unsigned AlignMask = Alignment.value() - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned I = 0, E = Constants.size(); I != E; ++I) { + if (Constants[I].isMachineConstantPoolEntry() && + (Constants[I].getAlign().value() & AlignMask) == 0) { + CSKYConstantPoolValue *CPV = + (CSKYConstantPoolValue *)Constants[I].Val.MachineCPVal; + CSKYConstantPoolJT *APJT = dyn_cast(CPV); + if (!APJT) + continue; + + if (APJT->JTI == JTI && equals(APJT)) + return I; + } + } + + return -1; +} + +bool CSKYConstantPoolJT::hasSameValue(CSKYConstantPoolValue *CCPV) { + const CSKYConstantPoolJT *ACPJT = dyn_cast(CCPV); + return ACPJT && ACPJT->JTI == JTI && + CSKYConstantPoolValue::hasSameValue(CCPV); +} + +void CSKYConstantPoolJT::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddInteger(JTI); + CSKYConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void CSKYConstantPoolJT::print(raw_ostream &O) const { + O << "JTI#" << JTI; + CSKYConstantPoolValue::print(O); +} Index: llvm/lib/Target/CSKY/CSKYFrameLowering.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYFrameLowering.h @@ -0,0 +1,58 @@ +//===-- CSKYFrameLowering.h - Define frame lowering for CSKY -*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class implements CSKY-specific bits of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYFRAMELOWERING_H +#define LLVM_LIB_TARGET_CSKY_CSKYFRAMELOWERING_H + +#include "llvm/CodeGen/TargetFrameLowering.h" + +namespace llvm { +class CSKYSubtarget; + +class CSKYFrameLowering : public TargetFrameLowering { +protected: + const CSKYSubtarget &STI; + + bool v2sf; + bool v2df; + bool v3sf; + bool v3df; + +public: + explicit CSKYFrameLowering(const CSKYSubtarget &STI); + + void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; + bool hasFP(const MachineFunction &MF) const override; + bool hasBP(const MachineFunction &MF) const; + bool hasReservedCallFrame(const MachineFunction &MF) const override; + int resolveFrameIndexReference(const MachineFunction &MF, int FI, + Register &FrameReg, int SPAdj) const; + bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + ArrayRef CSI, + const TargetRegisterInfo *TRI) const override; + bool + restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + MutableArrayRef CSI, + const TargetRegisterInfo *TRI) const override; + void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, + RegScavenger *RS) const override; + MachineBasicBlock::iterator + eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const override; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYFRAMELOWERING_H Index: llvm/lib/Target/CSKY/CSKYFrameLowering.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYFrameLowering.cpp @@ -0,0 +1,268 @@ +//===-- CSKYFrameLowering.h - Define frame lowering for CSKY -*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class implements CSKY-specific bits of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYFrameLowering.h" +#include "CSKYMachineFunctionInfo.h" +#include "CSKYSubtarget.h" +#include "Utils/CSKYBaseInfo.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/RegisterScavenging.h" + +using namespace llvm; + +CSKYFrameLowering::CSKYFrameLowering(const CSKYSubtarget &STI) + : TargetFrameLowering(StackGrowsDown, /*StackAlignment*/ Align(4), + /*LocalAreaOffset*/ 0), + STI(STI) { + v2sf = STI.hasFPUv2SingleFloat(); + v2df = STI.hasFPUv2DoubleFloat(); + v3sf = STI.hasFPUv3SingleFloat(); + v3df = STI.hasFPUv3DoubleFloat(); +} + +// TODO: mov this function to instr info +static void emitSPAdj(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, + const DebugLoc &DL, const CSKYInstrInfo *TII, + int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) { + bool IsSub = NumBytes < 0; + unsigned Opc = IsSub ? CSKY::SUBI32 : CSKY::ADDI32; + if (IsSub) + NumBytes = -NumBytes; + + unsigned Value; + while (NumBytes) { + if (NumBytes > 0x1000) { + NumBytes -= 0x1000; + Value = 0x1000; + } else { + Value = NumBytes; + NumBytes = 0; + } + BuildMI(MBB, MBBI, DL, TII->get(Opc), CSKY::SP) + .addReg(CSKY::SP) + .addImm(Value) + .setMIFlags(MIFlags); + } +} + +void CSKYFrameLowering::emitPrologue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + MachineBasicBlock::iterator MBBI = MBB.begin(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + unsigned StackSize = MFI.getStackSize(); + const CSKYInstrInfo *TII = STI.getInstrInfo(); + CSKYMachineFunctionInfo *FuncInfo = MF.getInfo(); + unsigned CSRSize = FuncInfo->getCSRSize(); + DebugLoc DL; + + // Callee saved registers already spilled. + // TODO: Allocate vararg register save area. + + // arg regs save size + + // Skip FrameSetup instructions + while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) + ++MBBI; + + // Insert CFI + + // Allocas + unsigned NumBytes = StackSize - CSRSize; + emitSPAdj(MBB, MBBI, DL, TII, -NumBytes, MachineInstr::FrameSetup); +} + +void CSKYFrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + + CSKYMachineFunctionInfo *FuncInfo = MF.getInfo(); + MachineBasicBlock::iterator MBBI = MBB.end(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const CSKYInstrInfo *TII = STI.getInstrInfo(); + unsigned StackSize = MFI.getStackSize(); + unsigned CSRSize = FuncInfo->getCSRSize(); + DebugLoc DL; + + if (!MBB.empty()) { + MBBI = MBB.getFirstTerminator(); + if (MBBI == MBB.end()) + MBBI = MBB.getLastNonDebugInstr(); + DL = MBBI->getDebugLoc(); + + if (!MBBI->isTerminator()) + MBBI = std::next(MBBI); + + while (MBBI != MBB.begin() && + std::prev(MBBI)->getFlag(MachineInstr::FrameDestroy)) + --MBBI; + } + + unsigned NumBytes = StackSize - CSRSize; + emitSPAdj(MBB, MBBI, DL, TII, NumBytes, MachineInstr::FrameDestroy); +} + +bool CSKYFrameLowering::hasFP(const MachineFunction &MF) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); + + return MF.getTarget().Options.DisableFramePointerElim(MF) || + RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() || + MFI.isFrameAddressTaken(); +} + +bool CSKYFrameLowering::hasBP(const MachineFunction &MF) const { return false; } + +bool CSKYFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { + return !MF.getFrameInfo().hasVarSizedObjects(); +} + +int CSKYFrameLowering::resolveFrameIndexReference(const MachineFunction &MF, + int FI, Register &FrameReg, + int SPAdj) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + int Offset = MFI.getObjectOffset(FI) + MFI.getStackSize(); + // int Spilled = FuncInfo->getFrameSpillOffset(); + // TODO: Use fp + // int FPOffset = Offset - CFI->getFrameSpillOffset(); + // Negative FI denotes this is an incoming parameter. + // bool isFixed = MFI.isFixedObjectIndex(FI); + FrameReg = CSKY::SP; + Offset += SPAdj; + return Offset; +} + +bool CSKYFrameLowering::spillCalleeSavedRegisters( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + ArrayRef CSI, const TargetRegisterInfo *TRI) const { + MachineFunction &MF = *MBB.getParent(); + const CSKYInstrInfo *TII = STI.getInstrInfo(); + CSKYMachineFunctionInfo *FuncInfo = MF.getInfo(); + unsigned CSRSize = FuncInfo->getCSRSize(); + DebugLoc DL; + + if (MI != MBB.end() && !MI->isDebugInstr()) + DL = MI->getDebugLoc(); + + emitSPAdj(MBB, MI, DL, TII, -CSRSize, MachineInstr::FrameSetup); + for (const auto &Info : CSI) { + Register Reg = Info.getReg(); + int FI = Info.getFrameIdx(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + + TII->storeRegToStackSlot(MBB, MI, Reg, getKillRegState(true), FI, RC, + STI.getRegisterInfo()); + MachineInstrBuilder(MF, std::prev(MI)).setMIFlag(MachineInstr::FrameSetup); + } + + return true; +} + +bool CSKYFrameLowering::restoreCalleeSavedRegisters( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + MutableArrayRef CSI, const TargetRegisterInfo *TRI) const { + MachineFunction &MF = *MBB.getParent(); + const CSKYInstrInfo *TII = STI.getInstrInfo(); + CSKYMachineFunctionInfo *FuncInfo = MF.getInfo(); + unsigned CSRSize = FuncInfo->getCSRSize(); + DebugLoc DL; + + if (MI != MBB.end() && !MI->isDebugInstr()) + DL = MI->getDebugLoc(); + + for (const auto &Info : CSI) { + Register Reg = Info.getReg(); + int FI = Info.getFrameIdx(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + + TII->loadRegFromStackSlot(MBB, MI, Reg, FI, RC, STI.getRegisterInfo()); + MachineInstrBuilder(MF, std::prev(MI)) + .setMIFlag(MachineInstr::FrameDestroy); + } + + emitSPAdj(MBB, MI, DL, TII, CSRSize, MachineInstr::FrameDestroy); + return true; +} + +void CSKYFrameLowering::determineCalleeSaves(MachineFunction &MF, + BitVector &SavedRegs, + RegScavenger *RS) const { + TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); + CSKYMachineFunctionInfo *FuncInfo = MF.getInfo(); + const CSKYRegisterInfo *RegInfo = static_cast( + MF.getSubtarget().getRegisterInfo()); + MachineFrameInfo &MFI = MF.getFrameInfo(); + + bool HasFP = hasFP(MF); + bool HasBP = hasBP(MF); + Register FrameReg = RegInfo->getFrameRegister(MF); + Register BaseReg = RegInfo->getBaseRegister(); + bool CanEliminateFrame = true; + unsigned GPRSpilledCnt = 0; + unsigned FPR32SpilledCnt = 0; + unsigned FPR64SpilledCnt = 0; + + if (HasFP) + SavedRegs.set(FrameReg); + + if (HasBP) + SavedRegs.set(BaseReg); + + if (FuncInfo->getGlobalBaseReg() != 0) + SavedRegs.set(FuncInfo->getGlobalBaseReg()); + + const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF); + for (unsigned I = 0; CSRegs[I]; ++I) { + unsigned Reg = CSRegs[I]; + if (SavedRegs.test(Reg)) { + // record spilled CSRSize + CanEliminateFrame = false; + if (CSKY::GPRRegClass.contains(Reg)) + ++GPRSpilledCnt; + else if (CSKY::FPR32RegClass.contains(Reg) || + CSKY::sFPR32RegClass.contains(Reg)) + ++FPR32SpilledCnt; + else if (CSKY::FPR64RegClass.contains(Reg) || + CSKY::sFPR64RegClass.contains(Reg)) + ++FPR64SpilledCnt; + else + assert(0 && "unknown reg class"); + } else { + // TODO: record unspilled GPR + } + } + + if (!CanEliminateFrame) + FuncInfo->setHasStackFrame(true); + + FuncInfo->setCSRSize(GPRSpilledCnt * 4 + FPR32SpilledCnt * 4 + + FPR64SpilledCnt * 8); + + if (FuncInfo->isCRSpilled()) + RS->addScavengingFrameIndex(MFI.CreateFixedObject(4, 4, false)); +} + +MachineBasicBlock::iterator CSKYFrameLowering::eliminateCallFramePseudoInstr( + MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const { + const CSKYInstrInfo *TII = STI.getInstrInfo(); + DebugLoc DL = MI->getDebugLoc(); + + if (!hasReservedCallFrame(MF)) { + int64_t Amount = MI->getOperand(0).getImm(); + if (MI->getOpcode() == CSKY::ADJCALLSTACKDOWN) + Amount = -Amount; + + // Adjust sp register + emitSPAdj(MBB, MI, DL, TII, Amount); + } + return MBB.erase(MI); +} Index: llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYISelDAGToDAG.cpp @@ -0,0 +1,194 @@ +//===-- CSKYISelDAGToDAG.cpp - A dag to dag inst selector for CSKY---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the CSKY target. +// +//===----------------------------------------------------------------------===// + +#include "CSKY.h" +#include "CSKYConstantPoolValue.h" +#include "CSKYTargetMachine.h" +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-isel" + +namespace { +class CSKYDAGToDAGISel : public SelectionDAGISel { + const CSKYSubtarget *Subtarget; + +public: + explicit CSKYDAGToDAGISel(CSKYTargetMachine &TM) : SelectionDAGISel(TM) {} + + StringRef getPassName() const override { + return "CSKY DAG->DAG Pattern Instruction Selection"; + } + + bool runOnMachineFunction(MachineFunction &MF) override { + // Reset the subtarget each time through. + Subtarget = &MF.getSubtarget(); + SelectionDAGISel::runOnMachineFunction(MF); + return true; + } + + void Select(SDNode *N) override; + + bool selectAddrFi(SDValue Addr, SDValue &Base); + bool selectAddCarry(SDNode *N); + bool selectSubCarry(SDNode *N); + bool selectMulLohi(SDNode *N); + bool selectSdivrem(SDNode *N); + +#include "CSKYGenDAGISel.inc" +}; +} // namespace + +void CSKYDAGToDAGISel::Select(SDNode *N) { + if (N->isMachineOpcode()) { + LLVM_DEBUG(dbgs() << "== "; N->dump(CurDAG); dbgs() << "\n"); + N->setNodeId(-1); + return; + } + + SDLoc Dl(N); + unsigned Opcode = N->getOpcode(); + bool IsSelected = false; + + switch (Opcode) { + default: + break; + case ISD::ADDCARRY: + IsSelected = selectAddCarry(N); + break; + case ISD::SUBCARRY: + IsSelected = selectSubCarry(N); + break; + case ISD::UMUL_LOHI: + case ISD::SMUL_LOHI: + IsSelected = selectMulLohi(N); + break; + case ISD::SDIVREM: + IsSelected = selectSdivrem(N); + break; + case ISD::GLOBAL_OFFSET_TABLE: + Register GP = Subtarget->getInstrInfo()->getGlobalBaseReg(MF); + ReplaceNode(N, CurDAG->getRegister(GP, N->getValueType(0)).getNode()); + + IsSelected = true; + break; + } + + if (IsSelected) + return; + + SelectCode(N); +} + +bool CSKYDAGToDAGISel::selectSdivrem(SDNode *N) { + auto VT = N->getValueType(0); + + auto *SDIVREM = CurDAG->getMachineNode(CSKY::DIVF, SDLoc(N), MVT::Untyped, + {N->getOperand(0), N->getOperand(1)}); + + SDValue SDIV = CurDAG->getTargetExtractSubreg(CSKY::GPRSubReg0, SDLoc(N), VT, + SDValue(SDIVREM, 0)); + SDValue SRem = CurDAG->getTargetExtractSubreg(CSKY::GPRSubReg1, SDLoc(N), VT, + SDValue(SDIVREM, 0)); + + ReplaceUses(SDValue(N, 0), SDIV); + ReplaceUses(SDValue(N, 1), SRem); + CurDAG->RemoveDeadNode(N); + + return true; +} + +bool CSKYDAGToDAGISel::selectMulLohi(SDNode *N) { + auto VT = N->getValueType(0); + + auto *MULOHI = CurDAG->getMachineNode( + N->getOpcode() == ISD::UMUL_LOHI ? CSKY::MULU32 : CSKY::MULS32, SDLoc(N), + MVT::Untyped, {N->getOperand(0), N->getOperand(1)}); + + SDValue Lo = CurDAG->getTargetExtractSubreg(CSKY::GPRSubReg0, SDLoc(N), VT, + SDValue(MULOHI, 0)); + SDValue Hi = CurDAG->getTargetExtractSubreg(CSKY::GPRSubReg1, SDLoc(N), VT, + SDValue(MULOHI, 0)); + + ReplaceUses(SDValue(N, 0), Lo); + ReplaceUses(SDValue(N, 1), Hi); + CurDAG->RemoveDeadNode(N); + + return true; +} + +bool CSKYDAGToDAGISel::selectAddCarry(SDNode *N) { + MachineSDNode *NewNode = nullptr; + auto Type0 = N->getValueType(0); + auto Type1 = N->getValueType(1); + auto Op0 = N->getOperand(0); + auto Op1 = N->getOperand(1); + auto Op2 = N->getOperand(2); + + SDLoc Dl(N); + + if (isNullConstant(Op2)) { + auto *CA = CurDAG->getMachineNode(CSKY::CLRC32, Dl, Type1); + NewNode = CurDAG->getMachineNode(CSKY::ADDC32, Dl, {Type0, Type1}, + {Op0, Op1, SDValue(CA, 0)}); + } else if (isOneConstant(Op2)) { + auto *CA = CurDAG->getMachineNode(CSKY::SETC32, Dl, Type1); + NewNode = CurDAG->getMachineNode(CSKY::ADDC32, Dl, {Type0, Type1}, + {Op0, Op1, SDValue(CA, 0)}); + } else { + NewNode = CurDAG->getMachineNode(CSKY::ADDC32, Dl, {Type0, Type1}, + {Op0, Op1, Op2}); + } + ReplaceNode(N, NewNode); + return true; +} + +bool CSKYDAGToDAGISel::selectSubCarry(SDNode *N) { + MachineSDNode *NewNode = nullptr; + auto Type0 = N->getValueType(0); + auto Type1 = N->getValueType(1); + auto Op0 = N->getOperand(0); + auto Op1 = N->getOperand(1); + auto Op2 = N->getOperand(2); + + SDLoc Dl(N); + + if (isNullConstant(Op2)) { + auto *CA = CurDAG->getMachineNode(CSKY::SETC32, Dl, Type1); + NewNode = CurDAG->getMachineNode(CSKY::SUBC32, Dl, {Type0, Type1}, + {Op0, Op1, SDValue(CA, 0)}); + } else if (isOneConstant(Op2)) { + auto *CA = CurDAG->getMachineNode(CSKY::CLRC32, Dl, Type1); + NewNode = CurDAG->getMachineNode(CSKY::SUBC32, Dl, {Type0, Type1}, + {Op0, Op1, SDValue(CA, 0)}); + } else { + NewNode = CurDAG->getMachineNode(CSKY::SUBC32, Dl, {Type0, Type1}, + {Op0, Op1, Op2}); + } + ReplaceNode(N, NewNode); + return true; +} + +bool CSKYDAGToDAGISel::selectAddrFi(SDValue Addr, SDValue &Base) { + if (auto *FIN = dyn_cast(Addr)) { + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); + return true; + } + return false; +} + +FunctionPass *llvm::createCSKYISelDag(CSKYTargetMachine &TM) { + return new CSKYDAGToDAGISel(TM); +} \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYISelLowering.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYISelLowering.h @@ -0,0 +1,130 @@ +//===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that CSKY uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H +#define LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H + +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/TargetLowering.h" + +namespace llvm { +class CSKYSubtarget; + +namespace CSKYISD { +enum NodeType : unsigned { + FIRST_NUMBER = ISD::BUILTIN_OP_END, + RET, + JMP, + CALL, + + // CSKY Bitcast to avoid constant folding + BITCAST, + // f64 <-- i32, i32 + BITCAST_FROM_LOHI, + // i32, i32 <-- f64 + BITCAST_TO_LOHI, + JT_CP_WRAP +}; +} + +class CSKYTargetLowering : public TargetLowering { + const CSKYSubtarget &Subtarget; + +public: + explicit CSKYTargetLowering(const TargetMachine &TM, + const CSKYSubtarget &STI); + + SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; + + EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, + EVT VT) const override; + + Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, + AtomicOrdering Ord) const override; + Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val, Value *Addr, + AtomicOrdering Ord) const override; + + bool useSoftFloat() const override; + + SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; + void HandleByVal(CCState *state, unsigned &Size, Align Align) const override; + int StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, const SDLoc &DL, + SDValue &Chain, const Value *OrigArg, + unsigned InRegsParamRecordIdx, int ArgOffset, + unsigned ArgSize) const; + +private: + SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl &Ins, + const SDLoc &DL, SelectionDAG &DAG, + SmallVectorImpl &InVals) const override; + + bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, + bool IsVarArg, + const SmallVectorImpl &Outs, + LLVMContext &Context) const override; + + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, const SDLoc &DL, + SelectionDAG &DAG) const override; + + SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const override; + + SDValue LowerCallResult(SDValue Chain, SDValue Glue, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl &Ins, + const SDLoc &DL, SelectionDAG &DAG, + SmallVectorImpl &InVals) const; + + const char *getTargetNodeName(unsigned Opcode) const override; + + template + SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const; + + SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; + + CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; + CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC) const; + + TargetLowering::AtomicExpansionKind + shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override { + return AtomicExpansionKind::LLSC; + } + + TargetLowering::AtomicExpansionKind + shouldExpandAtomicLoadInIR(LoadInst *LI) const override { + return AtomicExpansionKind::LLSC; + } + + AtomicExpansionKind + shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override { + return AtomicExpansionKind::LLSC; + } + + bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override { + return true; + } +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H Index: llvm/lib/Target/CSKY/CSKYISelLowering.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYISelLowering.cpp @@ -0,0 +1,885 @@ +//===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that CSKY uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#include "CSKYISelLowering.h" +#include "CSKYCallingConv.h" +#include "CSKYConstantPoolValue.h" +#include "CSKYMachineFunctionInfo.h" +#include "CSKYRegisterInfo.h" +#include "CSKYSubtarget.h" +#include "Utils/CSKYBaseInfo.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/IR/IntrinsicsCSKY.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +#include "CSKYGenCallingConv.inc" +#include "CSKYMachineFunctionInfo.h" + +static const MCPhysReg GPRArgRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3}; + +CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM, + const CSKYSubtarget &STI) + : TargetLowering(TM), Subtarget(STI) { + // Register Class + + addRegisterClass(MVT::i32, &CSKY::GPRRegClass); + + if (!STI.useSoftFloat()) { + if (STI.hasFPUv2SingleFloat()) + addRegisterClass(MVT::f32, &CSKY::sFPR32RegClass); + else if (STI.hasFPUv3SingleFloat()) + addRegisterClass(MVT::f32, &CSKY::FPR32RegClass); + if (STI.hasFPUv2DoubleFloat()) + addRegisterClass(MVT::f64, &CSKY::sFPR64RegClass); + else if (STI.hasFPUv3DoubleFloat()) + addRegisterClass(MVT::f64, &CSKY::FPR64RegClass); + } + + // Compute derived properties from the register classes. + computeRegisterProperties(STI.getRegisterInfo()); + + // Integer + + setOperationAction(ISD::ADDCARRY, MVT::i32, Legal); + setOperationAction(ISD::SUBCARRY, MVT::i32, Legal); + setOperationAction(ISD::SREM, MVT::i32, Expand); + setOperationAction(ISD::UREM, MVT::i32, Expand); + setOperationAction(ISD::UDIVREM, MVT::i32, Expand); + setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); + setOperationAction(ISD::SELECT_CC, MVT::i32, Expand); + setOperationAction(ISD::BR_CC, MVT::i32, Expand); + setOperationAction(ISD::BR_JT, MVT::Other, Expand); + + // IF NODSPV1 + setOperationAction(ISD::MULHS, MVT::i32, Expand); + setOperationAction(ISD::MULHU, MVT::i32, Expand); + + setLoadExtAction(ISD::EXTLOAD, MVT::i32, MVT::i1, Promote); + setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i1, Promote); + setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, MVT::i1, Promote); + + setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + setOperationAction(ISD::BlockAddress, MVT::i32, Custom); + setOperationAction(ISD::JumpTable, MVT::i32, Custom); + setOperationAction(ISD::ExternalSymbol, MVT::i32, Custom); + + // Float + + ISD::CondCode FPCCToExtend[] = { + ISD::SETONE, ISD::SETUEQ, ISD::SETUGT, + ISD::SETUGE, ISD::SETULT, ISD::SETULE, + }; + + if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) { + setOperationAction(ISD::ConstantFP, MVT::f32, Legal); + setOperationAction(ISD::FREM, MVT::f32, Expand); + setOperationAction(ISD::SELECT_CC, MVT::f32, Expand); + setOperationAction(ISD::BR_CC, MVT::f32, Expand); + if (STI.hasFPUv2SingleFloat()) + setOperationAction(ISD::SELECT, MVT::f32, Expand); + for (auto CC : FPCCToExtend) + setCondCodeAction(CC, MVT::f32, Expand); + } + if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat()) { + setOperationAction(ISD::ConstantFP, MVT::f64, Custom); + setOperationAction(ISD::FREM, MVT::f64, Expand); + setOperationAction(ISD::SELECT_CC, MVT::f64, Expand); + setOperationAction(ISD::BR_CC, MVT::f64, Expand); + if (STI.hasFPUv2DoubleFloat()) + setOperationAction(ISD::SELECT, MVT::f64, Expand); + for (auto CC : FPCCToExtend) + setCondCodeAction(CC, MVT::f64, Expand); + } + + // DAG combine + + // Attributes + + setBooleanContents(ZeroOrOneBooleanContent); + setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); + setMaxAtomicSizeInBitsSupported(32); + setMinCmpXchgSizeInBits(32); + setStackPointerRegisterToSaveRestore(CSKY::SP); + const Align FunctionAlignment(2); + setMinFunctionAlignment(FunctionAlignment); + setSchedulingPreference(Sched::Source); +} + +Value *CSKYTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr, + AtomicOrdering Ord) const { + BasicBlock *BB = Builder.GetInsertBlock(); + Module *M = BB->getParent()->getParent(); + auto *PT = cast(Addr->getType()); + Type *Ty = PT->getElementType(); + unsigned SZ = Ty->getPrimitiveSizeInBits(); + assert((SZ == 32) && "Only 32-bit atomic loads supported"); + + Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::csky_ldex_w); + + PointerType *NewPtrTy = + Builder.getIntNTy(SZ)->getPointerTo(PT->getAddressSpace()); + Addr = Builder.CreateBitCast(Addr, NewPtrTy); + + Value *Call = Builder.CreateCall(Fn, Addr, "ldex"); + + return Builder.CreateBitCast(Call, Ty); +} + +/// Perform a store-conditional operation to Addr. Return the status of the +/// store. This should be 0 if the store succeeded, non-zero otherwise. +Value *CSKYTargetLowering::emitStoreConditional(IRBuilder<> &Builder, + Value *Val, Value *Addr, + AtomicOrdering Ord) const { + BasicBlock *BB = Builder.GetInsertBlock(); + Module *M = BB->getParent()->getParent(); + Type *Ty = Val->getType(); + unsigned SZ = Ty->getPrimitiveSizeInBits(); + + Type *CastTy = Builder.getIntNTy(SZ); + assert((SZ == 32) && "Only 32-bit atomic stores supported"); + Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::csky_stex_w); + + unsigned AS = Addr->getType()->getPointerAddressSpace(); + Addr = Builder.CreateBitCast(Addr, CastTy->getPointerTo(AS)); + Val = Builder.CreateBitCast(Val, CastTy); + + Value *Call = Builder.CreateCall(Fn, {Addr, Val}, "stex"); + + return Builder.CreateSub(Builder.getIntN(SZ, 1), Call); +} + +SDValue CSKYTargetLowering::LowerOperation(SDValue Op, + SelectionDAG &DAG) const { + switch (Op.getOpcode()) { + default: + llvm_unreachable("unimplemented op"); + case ISD::GlobalAddress: + return LowerGlobalAddress(Op, DAG); + case ISD::ExternalSymbol: + return LowerExternalSymbol(Op, DAG); + case ISD::ConstantPool: + return LowerConstantPool(Op, DAG); + case ISD::JumpTable: + return LowerJumpTable(Op, DAG); + case ISD::BlockAddress: + return LowerBlockAddress(Op, DAG); + case ISD::ConstantFP: + return LowerConstantFP(Op, DAG); + case ISD::BUILD_VECTOR: + return LowerBUILD_VECTOR(Op, DAG); + } +} + +SDValue CSKYTargetLowering::PerformDAGCombine( + SDNode *N, TargetLowering::DAGCombinerInfo &DCI) const { + return SDValue(); +} + +SDValue CSKYTargetLowering::LowerFormalArguments( + SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Ins, const SDLoc &DL, + SelectionDAG &DAG, SmallVectorImpl &InVals) const { + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + CSKYMachineFunctionInfo *FuncInfo = MF.getInfo(); + SmallVector ArgLocs; + EVT PtrVT = getPointerTy(DAG.getDataLayout()); + CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, + *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg)); + + // Calculate the amount of stack space that we need to allocate to store + // byval and varargs. + unsigned ArgRegBegin = CSKY::R4; + for (auto &VA : ArgLocs) { + // Process byVal args. + if (CCInfo.getInRegsParamsProcessed() >= CCInfo.getInRegsParamsCount()) + break; + + ISD::ArgFlagsTy Flags = Ins[VA.getValNo()].Flags; + if (!Flags.isByVal()) + continue; + + assert(VA.isMemLoc() && "Unexpected byval arg in reg."); + unsigned BeginReg, EndReg; + CCInfo.getInRegsParamInfo(CCInfo.getInRegsParamsProcessed(), BeginReg, + EndReg); + // Get first byVal reg. + ArgRegBegin = std::min(ArgRegBegin, BeginReg); + CCInfo.nextInRegsParam(); + } + CCInfo.rewindByValRegsInfo(); + + if (IsVarArg && MFI.hasVAStart()) { + unsigned RegIdx = CCInfo.getFirstUnallocated(GPRArgRegs); + if (RegIdx != array_lengthof(GPRArgRegs)) { + ArgRegBegin = std::min(ArgRegBegin, (unsigned)GPRArgRegs[RegIdx]); + } + } + unsigned TotalArgRegsSaveSize = (CSKY::R4 - ArgRegBegin) * 4; + FuncInfo->setArgRegsSaveSize(TotalArgRegsSaveSize); + + Function::const_arg_iterator CurOrigArg = MF.getFunction().arg_begin(); + unsigned CurArgIdx = 0; + int LastInsIndex = -1; + for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { + CCValAssign &VA = ArgLocs[I]; + EVT ValVT = VA.getValVT(); + unsigned ValNo = VA.getValNo(); + if (Ins[ValNo].isOrigArg()) { + std::advance(CurOrigArg, Ins[ValNo].getOrigArgIndex() - CurArgIdx); + CurArgIdx = Ins[ValNo].getOrigArgIndex(); + } + + SDValue ArgValue; + if (VA.isRegLoc()) { + const TargetRegisterClass *RC = nullptr; + EVT RegVT = VA.getLocVT(); + + switch (RegVT.getSimpleVT().SimpleTy) { + default: + llvm_unreachable("RegVT not supported by FormalArguments Lowering"); + break; + case MVT::i32: + RC = &CSKY::GPRRegClass; + break; + case MVT::f32: + RC = Subtarget.hasFPUv2SingleFloat() ? &CSKY::sFPR32RegClass + : &CSKY::FPR32RegClass; + break; + case MVT::f64: + RC = Subtarget.hasFPUv2DoubleFloat() ? &CSKY::sFPR64RegClass + : &CSKY::FPR64RegClass; + break; + case MVT::v2i64: + case MVT::v4i32: + case MVT::v8i16: + case MVT::v16i8: + case MVT::v8f16: + case MVT::v4f32: + case MVT::v2f64: + RC = &CSKY::sFPR128RegClass; + break; + case MVT::v2i16: + case MVT::v4i8: + RC = &CSKY::GPR_DSPRegClass; + break; + } + + Register Reg = MF.addLiveIn(VA.getLocReg(), RC); + ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT); + + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unhandled loc info!"); + case CCValAssign::Full: + case CCValAssign::AExt: + case CCValAssign::SExt: + case CCValAssign::ZExt: + break; + case CCValAssign::BCvt: + ArgValue = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), ArgValue); + break; + } + } else { + assert(VA.isMemLoc() && "CCValAssign is neither reg nor mem"); + int Index = VA.getValNo(); + // Some Ins[] entries become multiple ArgLoc[] entries. + // Process them only once. + if (Index != LastInsIndex) { + ISD::ArgFlagsTy Flags = Ins[Index].Flags; + if (Flags.isByVal()) { + // Iterate by val args. + unsigned CurByValIndex = CCInfo.getInRegsParamsProcessed(); + // Store byval regs to stack. + int FI = StoreByValRegs(CCInfo, DAG, DL, Chain, &*CurOrigArg, + CurByValIndex, VA.getLocMemOffset(), + Flags.getByValSize()); + ArgValue = DAG.getFrameIndex(FI, PtrVT); + CCInfo.nextInRegsParam(); + } else { + unsigned ArgOffset = VA.getLocMemOffset(); + unsigned ArgSize = ValVT.getSizeInBits() / 8; + int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, true); + SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); + ArgValue = DAG.getLoad(ValVT, DL, Chain, FIN, + MachinePointerInfo::getFixedStack(MF, FI)); + } + LastInsIndex = Index; + } + } + + // Store VarArgs to stack. + if (IsVarArg && MFI.hasVAStart()) { + int FI = StoreByValRegs( + CCInfo, DAG, DL, Chain, nullptr, CCInfo.getInRegsParamsCount(), + CCInfo.getNextStackOffset(), std::max(4U, TotalArgRegsSaveSize)); + FuncInfo->setVarArgsFrameIndex(FI); + } + + assert(ArgValue); + InVals.push_back(ArgValue); + } + + return Chain; +} + +bool CSKYTargetLowering::CanLowerReturn( + CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, + const SmallVectorImpl &Outs, LLVMContext &Context) const { + SmallVector RVLocs; + CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); + return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv)); +} + +SDValue +CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, + bool IsVarArg, + const SmallVectorImpl &Outs, + const SmallVectorImpl &OutVals, + const SDLoc &DL, SelectionDAG &DAG) const { + SmallVector RVLocs; + CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, + *DAG.getContext()); + CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv)); + + SDValue Glue; + SDValue Flag; + SmallVector RetOps(1, Chain); + + for (unsigned I = 0; I < RVLocs.size(); ++I) { + CCValAssign &VA = RVLocs[I]; + assert(VA.isRegLoc() && "Can only return in registers!"); + + SDValue Arg = OutVals[I]; + + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unknown loc info!"); + case CCValAssign::Full: + break; + case CCValAssign::AExt: + Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg); + break; + case CCValAssign::ZExt: + Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg); + break; + case CCValAssign::SExt: + Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg); + break; + case CCValAssign::BCvt: + Arg = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Arg); + } + + Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Arg, Glue); + // Guarantee that all emitted copies are stuck together. + Glue = Chain.getValue(1); + RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); + } + + RetOps[0] = Chain; // Update chain. + + if (Glue.getNode()) + RetOps.push_back(Glue); + + return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps); +} + +SDValue CSKYTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, + SmallVectorImpl &InVals) const { + SelectionDAG &DAG = CLI.DAG; + SDLoc &DL = CLI.DL; + SmallVectorImpl &Outs = CLI.Outs; + SmallVectorImpl &OutVals = CLI.OutVals; + SmallVectorImpl &Ins = CLI.Ins; + SDValue Chain = CLI.Chain; + SDValue Callee = CLI.Callee; + bool &IsTailCall = CLI.IsTailCall; + CallingConv::ID CallConv = CLI.CallConv; + bool IsVarArg = CLI.IsVarArg; + EVT PtrVT = getPointerTy(DAG.getDataLayout()); + MachineFunction &MF = DAG.getMachineFunction(); + + SmallVector ArgLocs; + CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg)); + unsigned NumBytes = CCInfo.getNextStackOffset(); + SDValue StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::SP, PtrVT); + + if (!IsTailCall) + Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL); + // TODO: handle byval args + + // Copy argument values to their designated locations. + SmallVector, 8> RegsToPass; + SmallVector MemOpChains; + + for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { + CCValAssign &VA = ArgLocs[I]; + SDValue Arg = OutVals[I]; + + if (VA.isRegLoc()) { + RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); + } else { + assert(VA.isMemLoc()); + // Create store + SDValue Address = + DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, + DAG.getIntPtrConstant(VA.getLocMemOffset(), DL)); + MemOpChains.push_back( + DAG.getStore(Chain, DL, Arg, Address, MachinePointerInfo())); + } + } + + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains); + + // Build a sequence of copy-to-reg nodes chained together with token chain + // and flag operands which copy the outgoing args into the appropriate regs. + SDValue Glue; + for (auto &Reg : RegsToPass) { + Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue); + Glue = Chain.getValue(1); + } + + unsigned Opcode = 0; + if (!IsTailCall) + Opcode = CSKYISD::CALL; + else + Opcode = CSKYISD::JMP; + + // The first call operand is the chain and the second is the target address. + SmallVector Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + + // Add argument registers to the end of the list so that they are known live + // into the call. + for (auto &Reg : RegsToPass) + Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType())); + + if (!IsTailCall) { + const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); + const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv); + Ops.push_back(DAG.getRegisterMask(Mask)); + } + + // Glue the call to the argument copies, if any. + if (Glue.getNode()) + Ops.push_back(Glue); + + // Emit the call. + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); + Chain = DAG.getNode(Opcode, DL, NodeTys, Ops); + Glue = Chain.getValue(1); + if (!IsTailCall) + Chain = + DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true), + DAG.getConstant(0, DL, PtrVT, true), Glue, DL); + if (!Ins.empty()) + Glue = Chain.getValue(1); + + // Handle result values, copying them out of physical + // registers into vregs that we return. + return LowerCallResult(Chain, Glue, CallConv, IsVarArg, Ins, DL, DAG, InVals); +} + +// Lower the result values of call into the appropriate copies out of +// appropriate physical registers. +SDValue CSKYTargetLowering::LowerCallResult( + SDValue Chain, SDValue Glue, CallingConv::ID CallConv, bool IsVarArg, + const SmallVectorImpl &Ins, const SDLoc &DL, + SelectionDAG &DAG, SmallVectorImpl &InVals) const { + SmallVector RVLocs; + MachineFunction &MF = DAG.getMachineFunction(); + CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); + CCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv)); + + for (auto &VA : RVLocs) { + // Copy the value out + SDValue RetValue = + DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue); + // Glue the RetValue to the end of the call sequence + Chain = RetValue.getValue(1); + Glue = RetValue.getValue(2); + switch (VA.getLocInfo()) { + default: + llvm_unreachable("Unknown loc info!"); + case CCValAssign::Full: + break; + case CCValAssign::BCvt: + RetValue = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), RetValue); + } + InVals.push_back(RetValue); + } + + return Chain; +} + +static SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty, + SelectionDAG &DAG, unsigned Flags, bool UseLrw) { + SDValue Addr = DAG.getTargetJumpTable(N->getIndex(), Ty, Flags); + if (!UseLrw) + return Addr; + + return DAG.getLoad( + Ty, DL, DAG.getEntryNode(), Addr, + MachinePointerInfo::getJumpTable(DAG.getMachineFunction())); +} + +static SDValue getTargetNode(ExternalSymbolSDNode *N, SDLoc DL, EVT Ty, + SelectionDAG &DAG, unsigned Flags, bool UseLrw) { + SDValue Addr = DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flags); + if (!UseLrw) + return Addr; + + return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Addr, MachinePointerInfo()); +} + +static SDValue getTargetNode(GlobalAddressSDNode *N, SDLoc DL, EVT Ty, + SelectionDAG &DAG, unsigned Flags, bool UseLrw) { + SDValue Addr = + DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, N->getOffset(), Flags); + if (!UseLrw) + return Addr; + + return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Addr, + MachinePointerInfo(N->getGlobal(), N->getOffset())); +} + +static SDValue getTargetNode(BlockAddressSDNode *N, SDLoc DL, EVT Ty, + SelectionDAG &DAG, unsigned Flags, bool UseLrw) { + SDValue Addr = DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, + N->getOffset(), Flags); + if (!UseLrw) + return Addr; + + return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Addr, + MachinePointerInfo(N->getBlockAddress(), N->getOffset())); +} + +static SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty, + SelectionDAG &DAG, unsigned Flags, bool UseLrw) { + SDValue Addr; + + if (N->isMachineConstantPoolEntry()) + Addr = DAG.getTargetConstantPool(N->getMachineCPVal(), Ty, N->getAlign(), + N->getOffset(), Flags); + else + Addr = DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(), + N->getOffset(), Flags); + + if (!UseLrw) + return Addr; + + return DAG.getLoad( + Ty, DL, DAG.getEntryNode(), Addr, + MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); +} + +template +SDValue CSKYTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, + bool IsLocal) const { + SDLoc DL(N); + EVT Ty = getPointerTy(DAG.getDataLayout()); + SDValue Addr; + + bool IsPIC = isPositionIndependent(); + + if (Subtarget.useConstantIslands()) { + Addr = getTargetNode(N, DL, Ty, DAG, 0, true); + } else { + if (IsPIC && getTargetMachine().getCodeModel() == CodeModel::Small) { + Addr = getTargetNode(N, DL, Ty, DAG, CSKYII::MO_GOT12, false); + } else { + unsigned HiFlag = + !IsPIC ? CSKYII::MO_ADDR_HI16 + : (IsLocal ? CSKYII::MO_GOTOFF_HI16 : CSKYII::MO_GOT_HI16); + unsigned LoFlag = + !IsPIC ? CSKYII::MO_ADDR_LO16 + : (IsLocal ? CSKYII::MO_GOTOFF_LO16 : CSKYII::MO_GOT_LO16); + + SDValue AddrHi = getTargetNode(N, DL, Ty, DAG, HiFlag, false); + SDValue AddrLo = getTargetNode(N, DL, Ty, DAG, LoFlag, false); + + SDValue MNHi = + SDValue(DAG.getMachineNode(CSKY::MOVIH32, DL, Ty, AddrHi), 0); + Addr = SDValue(DAG.getMachineNode(CSKY::ORI32, DL, Ty, MNHi, AddrLo), 0); + } + } + + if (!IsPIC) + return Addr; + + SDValue Result = + DAG.getNode(ISD::ADD, DL, Ty, {DAG.getGLOBAL_OFFSET_TABLE(Ty), Addr}); + if (IsLocal) + return Result; + + bool UseConst = Subtarget.useConstantIslands(); + + return DAG.getLoad( + Ty, DL, UseConst ? SDValue(Addr.getNode(), 1) : DAG.getEntryNode(), + Result, MachinePointerInfo::getGOT(DAG.getMachineFunction())); +} + +SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op, + SelectionDAG &DAG) const { + EVT Ty = Op.getValueType(); + GlobalAddressSDNode *N = cast(Op); + const GlobalValue *GV = N->getGlobal(); + bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV); + + if (Subtarget.useConstantIslands()) { + bool IsPIC = isPositionIndependent(); + CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create( + GV, !IsPIC ? CSKYCP::no_modifier + : (IsLocal ? CSKYCP::GOTOFF : CSKYCP::GOT)); + + return getAddr(cast(DAG.getConstantPool(CPV, Ty)), DAG, + IsLocal); + } + + return getAddr(N, DAG, IsLocal); +} + +SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op, + SelectionDAG &DAG) const { + EVT Ty = getPointerTy(DAG.getDataLayout()); + ExternalSymbolSDNode *N = cast(Op); + + if (Subtarget.useConstantIslands()) { + MachineFunction &MF = DAG.getMachineFunction(); + CSKYMachineFunctionInfo *CFI = MF.getInfo(); + unsigned CSKYPCLabelIndex = CFI->createPICLabelUId(); + CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create( + *DAG.getContext(), N->getSymbol(), CSKYPCLabelIndex, 0); + return getAddr(cast(DAG.getConstantPool(CPV, Ty)), DAG); + } + + return getAddr(N, DAG); +} + +SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op, + SelectionDAG &DAG) const { + EVT Ty = Op.getValueType(); + BlockAddressSDNode *N = cast(Op); + const BlockAddress *BA = N->getBlockAddress(); + + if (Subtarget.useConstantIslands()) { + bool IsPIC = isPositionIndependent(); + CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create( + BA, !IsPIC ? CSKYCP::no_modifier : CSKYCP::GOTOFF); + return getAddr(cast(DAG.getConstantPool(CPV, Ty)), DAG); + } + + return getAddr(N, DAG); +} + +SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op, + SelectionDAG &DAG) const { + EVT Ty = getPointerTy(DAG.getDataLayout()); + JumpTableSDNode *N = cast(Op); + + if (Subtarget.useConstantIslands()) { + MachineFunction &MF = DAG.getMachineFunction(); + CSKYMachineFunctionInfo *CFI = MF.getInfo(); + unsigned CSKYPCLabelIndex = CFI->createPICLabelUId(); + CSKYConstantPoolValue *CPV = + CSKYConstantPoolJT::Create(*DAG.getContext(), N->getIndex(), + CSKYPCLabelIndex, 0, CSKYCP::no_modifier); + + auto TCP = DAG.getTargetConstantPool(CPV, Ty); + auto JT = DAG.getTargetJumpTable(N->getIndex(), Ty); + + return DAG.getNode(CSKYISD::JT_CP_WRAP, SDLoc(N), TCP.getValueType(), + {JT, TCP}); + } + + return getAddr(N, DAG); +} + +SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op, + SelectionDAG &DAG) const { + ConstantPoolSDNode *N = cast(Op); + return getAddr(N, DAG); +} + +SDValue CSKYTargetLowering::LowerBUILD_VECTOR(SDValue Op, + SelectionDAG &DAG) const { + auto VT = Op.getValueType(); + assert(VT == MVT::v4i8 || VT == MVT::v2i16); + + SDLoc Dl(Op); + SDValue Result = DAG.getConstant(0, Dl, MVT::i32); + SDValue Shift = DAG.getConstant(VT.getScalarSizeInBits(), Dl, MVT::i32); + SDValue Mask = DAG.getConstant( + APInt::getMaxValue(VT.getScalarSizeInBits()).zext(32), Dl, MVT::i32); + + for (size_t I = 0; I < Op.getNumOperands(); I++) { + auto V = Op.getOperand(Op.getNumOperands() - 1 - I); + if (V.isUndef()) { + ; + } else { + auto C = DAG.getNode(ISD::AND, Dl, MVT::i32, {V, Mask}); + Result = DAG.getNode(ISD::OR, Dl, MVT::i32, {Result, C}); + } + + if (I != Op.getNumOperands() - 1) + Result = DAG.getNode(ISD::SHL, Dl, MVT::i32, {Result, Shift}); + } + + return DAG.getBitcast(VT, Result); +} + +SDValue CSKYTargetLowering::LowerConstantFP(SDValue Op, + SelectionDAG &DAG) const { + assert(Op.getValueType() == MVT::f32 || Op.getValueType() == MVT::f64); + EVT VT = Op.getValueType(); + SDLoc Dl(Op); + SDValue Tmp = DAG.getConstant( + dyn_cast(Op.getNode())->getValueAPF().bitcastToAPInt(), + Dl, VT == MVT::f32 ? MVT::i32 : MVT::i64); + if (VT == MVT::f32) + return DAG.getNode(CSKYISD::BITCAST, Dl, VT, Tmp); + + SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32, Tmp, + DAG.getConstant(0, Dl, MVT::i32)); + SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::i32, Tmp, + DAG.getConstant(1, Dl, MVT::i32)); + + return DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, Dl, MVT::f64, {Lo, Hi}); +} + +CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC, + bool IsVarArg) const { + if (Subtarget.useSoftFloat()) + return CC_CSKY_ABIV2_SOFT; + + if (Subtarget.hasFPUv2DoubleFloat() || Subtarget.hasFPUv3DoubleFloat()) + return CC_CSKY_ABIV2_DF; + if (Subtarget.hasFPUv2SingleFloat() || Subtarget.hasFPUv3SingleFloat()) + return CC_CSKY_ABIV2_SF; + + return CC_CSKY_ABIV2_SOFT; +} + +CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC) const { + if (Subtarget.useSoftFloat()) + return RetCC_CSKY_ABIV2_SOFT; + + if (Subtarget.hasFPUv2DoubleFloat() || Subtarget.hasFPUv3DoubleFloat()) + return RetCC_CSKY_ABIV2_DF; + if (Subtarget.hasFPUv2SingleFloat() || Subtarget.hasFPUv3SingleFloat()) + return RetCC_CSKY_ABIV2_SF; + + return RetCC_CSKY_ABIV2_SOFT; +} + +const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const { + switch (Opcode) { + default: + llvm_unreachable("unknown CSKYISD node"); + case CSKYISD::RET: + return "CSKYISD::RET"; + case CSKYISD::JMP: + return "CSKYISD::JMP"; + case CSKYISD::CALL: + return "CSKYISD::CALL"; + case CSKYISD::BITCAST: + return "CSKYISD::BITCAST"; + case CSKYISD::BITCAST_FROM_LOHI: + return "CSKYISD::BITCAST_FROM_LOHI"; + case CSKYISD::BITCAST_TO_LOHI: + return "CSKYISD::BITCAST_TO_LOHI"; + case CSKYISD::JT_CP_WRAP: + return "CSKYISD::JT_CP_WRAP"; + } +} + +EVT CSKYTargetLowering::getSetCCResultType(const DataLayout &DL, + LLVMContext &Context, EVT VT) const { + if (!VT.isVector()) + return MVT::i32; + + return VT.changeVectorElementTypeToInteger(); +} + +bool CSKYTargetLowering::useSoftFloat() const { + return Subtarget.useSoftFloat(); +} + +void CSKYTargetLowering::HandleByVal(CCState *State, unsigned &ByValSize, + Align Align) const { + unsigned Reg = State->AllocateReg(GPRArgRegs); + if (!Reg) + return; + + // Maximum available in reg size for byVal args. + unsigned Available = (CSKY::R4 - Reg) * 4; + unsigned ByValRegBegin = Reg; + unsigned ByValRegEnd = std::min(Reg + ByValSize / 4, CSKY::R4); + State->addInRegsParamInfo(ByValRegBegin, ByValRegEnd); + for (unsigned I = Reg + 1; I != ByValRegEnd; ++I) + State->AllocateReg(GPRArgRegs); + + ByValSize = Available >= ByValSize ? 0 : ByValSize - Available; +} + +// Allocate stack slots adjacent to arguments passing by caller +// and store unallocated registers there, which reassembles byval +// args and variadic args that were split between registers and memory. +int CSKYTargetLowering::StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, + const SDLoc &DL, SDValue &Chain, + const Value *OrigArg, + unsigned InRegsParamRecordIdx, + int ArgOffset, unsigned ArgSize) const { + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo &MFI = MF.getFrameInfo(); + + unsigned BeginReg, EndReg; + if (InRegsParamRecordIdx < CCInfo.getInRegsParamsCount()) { + CCInfo.getInRegsParamInfo(InRegsParamRecordIdx, BeginReg, EndReg); + } else { + unsigned BeginIdx = CCInfo.getFirstUnallocated(GPRArgRegs); + BeginReg = BeginIdx == 4 ? (unsigned)CSKY::R4 : GPRArgRegs[BeginIdx]; + EndReg = CSKY::R4; + } + + if (BeginReg != EndReg) + ArgOffset = -4 * (CSKY::R4 - BeginReg); + + EVT PtrVT = getPointerTy(DAG.getDataLayout()); + int FI = MFI.CreateFixedObject(ArgSize, ArgOffset, false); + SDValue FIN = DAG.getFrameIndex(FI, PtrVT); + + SmallVector MemOps; + for (unsigned Reg = BeginReg, I = 0; Reg < EndReg; ++Reg, ++I) { + Register VReg = MF.addLiveIn(Reg, &CSKY::GPRRegClass); + SDValue Val = DAG.getCopyFromReg(Chain, DL, VReg, MVT::i32); + SDValue Store = DAG.getStore(Val.getValue(1), DL, Val, FIN, + MachinePointerInfo(OrigArg, 4 * I)); + MemOps.push_back(Store); + FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN, DAG.getConstant(4, DL, PtrVT)); + } + + if (!MemOps.empty()) + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps); + return FI; +} Index: llvm/lib/Target/CSKY/CSKYInstrFormats.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrFormats.td @@ -0,0 +1,507 @@ +//===-- CSKYInstrFormats.td - CSKY Instruction Formats -----*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class AddrMode val> { + bits<5> Value = val; +} + +def AddrModeNone : AddrMode<0>; +def AddrMode32B : AddrMode<1>; +def AddrMode32H : AddrMode<2>; +def AddrMode32WD : AddrMode<3>; +def AddrMode16B : AddrMode<4>; +def AddrMode16H : AddrMode<5>; +def AddrMode16W : AddrMode<6>; +def AddrMode32SDF : AddrMode<7>; + +class CSKYInst pattern> + : Instruction { + let Namespace = "CSKY"; + int Size = sz; + AddrMode AM = am; + + let OutOperandList = outs; + let InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; + let Itinerary = NoItinerary; + let TSFlags{4-0} = AM.Value; +} + +class CSKYPseudo pattern> + : CSKYInst { + let isCodeGenOnly = 1; + let isPseudo = 1; +} + +class CSKY32Inst opcode, dag outs, dag ins, + string asmstr, list pattern> + : CSKYInst { + field bits<32> Inst; + let Inst{31-26} = opcode; +} + +// CSKY 32-bit instruction +// Format< OP[6] | Offset[26] > +// Instruction(1): bsr32 +class J opcode, dag outs, dag ins, string op, list pattern> + : CSKY32Inst { + bits<26> offset; + let Inst{25 - 0} = offset; +} + +// Format< OP[6] | RZ[5] | SOP[3] | OFFSET[18] > +// Instructions(7): grs, lrs32.b, lrs32.h, lrs32.w, srs32.b, srs32.h, srs32.w +class I_18_Z_L sop, string op, Operand operand, list pattern> + : CSKY32Inst { + bits<5> rz; + bits<18> offset; + let Inst{25 - 21} = rz; + let Inst{20 - 18} = sop; + let Inst{17 - 0} = offset; +} + +// Format< OP[6] | RZ[5] | RX[5] | IMM[16] > +// Instructions(1): ori32 +class I_16_ZX pattern> + : CSKY32Inst { + bits<5> rz; + bits<5> rx; + bits<16> imm16; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 0} = imm16; +} + +// Format< OP[6] | SOP[5] | RZ[5] | IMM[16] > +// Instructions(3): movi32, movih32, (bgeni32) +class I_16_MOV sop, string op, ImmLeaf ImmType> + : CSKY32Inst { + bits<5> rz; + bits<16> imm16; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = rz; + let Inst{15 - 0} = imm16; + let isReMaterializable = 1; + let isAsCheapAsAMove = 1; + let isMoveImm = 1; +} + +// Format< OP[6] | SOP[5] | RZ[5] | OFFSET[16] > +// Instructions(1): lrw32 +class I_16_Z_L sop, string op, Operand operand, list pattern> + : CSKY32Inst { + bits<5> rz; + bits<16> imm16; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = rz; + let Inst{15 - 0} = imm16; +} + +// Format< OP[6] | SOP[5] | 00000[5] | OFFSET[16] > +// Instructions(5): bt32, bf32, br32, jmpi32, jsri32 +class I_16_L sop, dag outs, dag ins, string op, list pattern> + : CSKY32Inst { + bits<16> imm16; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = 0; + let Inst{15 - 0} = imm16; +} + +// bt32, bf32, br32, jmpi32 +class I_16_L_B sop, string op, Operand operand, list pattern> + : I_16_L { + let isBranch = 1; + let isTerminator = 1; +} + +// Format< OP[6] | SOP[5] | RX[5] | 0000000000000000[16] > +// Instructions(2): jmp32, jsr32 +class I_16_JX sop, string op, list pattern> + : CSKY32Inst { + bits<5> rx; + bits<16> imm16; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = rx; + let Inst{15 - 0} = 0; +} + +// Format< OP[6] | SOP[5] | RX[5] | 00000000000000[14] | IMM[2] > +// Instructions(1): jmpix32 +class I_16_J_XI sop, string op, Operand operand, list pattern> + : CSKY32Inst { + bits<5> rx; + bits<2> imm2; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = rx; + let Inst{15 - 2} = 0; + let Inst{1 - 0} = imm2; +} + +// Format< OP[6] | SOP[5] | PCODE[5] | 0000000000000000[16] > +// Instructions(1): rts32 +class I_16_RET sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + let Inst{25 - 21} = sop; + let Inst{20 - 16} = pcode; + let Inst{15 - 0} = 0; + let isTerminator = 1; + let isReturn = 1; + let isBarrier = 1; +} + +// Format< OP[6] | SOP[5] | RX[5] | IMM16[16] > +// Instructions(3): cmpnei32, cmphsi32, cmplti32 +class I_16_X sop, string op> + : CSKY32Inst { + bits<16> imm16; + bits<5> rx; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = rx; + let Inst{15 - 0} = imm16; + let isCompare = 1; +} + +// Format< OP[6] | SOP[5] | RX[5] | OFFSET[16] > +// Instructions(7): bez32, bnez32, bnezad32, bhz32, blsz32, blz32, bhsz32 +class I_16_X_L sop, string op, Operand operand> + : CSKY32Inst { + bits<5> rx; + bits<16> imm16; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = rx; + let Inst{15 - 0} = imm16; + let isBranch = 1; + let isTerminator = 1; +} + +// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | IMM[12] > +// Instructions(5): addi32, subi32, andi32, andni32, xori32 +class I_12 sop, string op, SDNode node, ImmLeaf ImmType> + : CSKY32Inst { + bits<5> rz; + bits<5> rx; + bits<12> imm12; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 12} = sop; + let Inst{11 - 0} = imm12; +} + +class I_LDST opcode, bits<4> sop, dag outs, dag ins, + string op, list pattern> + : CSKY32Inst { + bits<5> rx; + bits<5> rz; + bits<12> imm12; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 12} = sop; + let Inst{11 - 0} = imm12; +} + +// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] > +// Instructions(6): ld32.b, ld32.bs, ld32.h, ld32.hs, ld32.w, ld32.d +class I_LD sop, string op, Operand operand> + : I_LDST; + +// Format< OP[6] | RZ[5] | RX[5] | SOP[4] | OFFSET[12] > +// Instructions(4): st32.b, st32.h, st32.w, st32.d +class I_ST sop, string op, Operand operand> + : I_LDST; + +// Format< OP[6] | SOP[5] | PCODE[5] | 0000[4] | 000 | R28 | LIST2[3] | R15 | LIST1[4] > +// Instructions(2): push32, pop32 +class I_12_PP sop, bits<5> pcode, dag outs, dag ins, string op> + : CSKY32Inst { + bits<12> regs; + let Inst{25 - 21} = sop; + let Inst{20 - 16} = pcode; + let Inst{15 - 12} = 0; + let Inst{11 - 0} = regs; +} + +// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | PCODE[5] | IMM[5]> +// Instructions(4): incf32, inct32, decf32, dect32 +class I_5_ZX sop, bits<5> pcode, string op, ImmLeaf ImmType, list pattern> + : CSKY32Inst { + bits<5> rz; + bits<5> rx; + bits<5> imm5; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = imm5; + let Constraints = "$rz = $false"; +} + +// Format< OP[6] | IMM[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5]> +// Instructions(13): decgt32, declt32, decne32, lsli32, lslc32, lsri32 +// lsrc32, asri32, asrc32, rotli32, xsr32, bclri32, bseti32 +class I_5_XZ sop, bits<5> pcode, string op, dag ins, dag outs, list pattern> + : CSKY32Inst { + bits<5> imm5; + bits<5> rx; + bits<5> rz; + let Inst{25 - 21} = imm5; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = rz; +} + +// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | IMM[5]> +// Instructions(2): ldm32, (ldq32), stm32, (stq32) +class I_5_YX opcode, dag outs, dag ins, string op, list pattern, bits<5> imm5> + : CSKY32Inst(imm5), pattern> { + bits<5> rx; + bits<5> ry; + let Inst{25 - 21} = ry; // ry + let Inst{20 - 16} = rx; + let Inst{15 - 10} = 0b000111; + let Inst{9 - 5} = 0b00001; + let Inst{4 - 0} = imm5{4 - 0}; // imm5 +} + +// Format< OP[6] | LSB[5] | RX[5] | SOP[6] | MSB[5] | RZ[5]> +// Instructions(6): zext32, zextb32, zexth32, sext32, sextb32, sexth32 +class I_5_XZ_U sop, bits<5> lsb, bits<5> msb, dag outs, dag ins, + string op, list pattern> + : CSKY32Inst(msb)#", "#!cast(lsb), pattern> { + bits<5> rx; + bits<5> rz; + let Inst{25 - 21} = lsb; // lsb + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = msb; // msb + let Inst{4 - 0} = rz; +} + +// sextb, sexth +class I_5_XZ_US sop, bits<5> lsb, bits<5> msb, string op, + SDNode opnode, ValueType type> + : I_5_XZ_U; + +class I_5_XZ_UZ sop, bits<5> lsb, bits<5> msb, string op, int v> + : I_5_XZ_U; + +// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | SIZE[5] | LSB[5]> +// Instructions(1): ins32 +class I_5_ZX_U sop, string op, Operand operand, list pattern> + : CSKY32Inst { + bits<10> size_lsb; + bits<5> rz; + bits<5> rx; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = size_lsb{9 - 5}; // size + let Inst{4 - 0} = size_lsb{4 - 0}; // lsb +} + +// Format< OP[6] | IMM[5] | RX[5] | SOP[6] | PCODE[5] | 00000 > +// Instructions(1): btsti32 +class I_5_X sop, bits<5> pcode, string op, ImmLeaf ImmType, list pattern> + : CSKY32Inst { + bits<5> imm5; + bits<5> rx; + let Inst{25 - 21} = imm5; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; + let isCompare = 1; +} + +// Format< OP[6] | IMM[5] | 00000[5] | SOP[6] | PCODE[5] | RZ[5]> +// Instructions(1): bmaski32 +class I_5_Z sop, bits<5> pcode, string op, ImmLeaf ImmType, + list pattern> + : CSKY32Inst { + bits<5> imm5; + bits<5> rz; + let Inst{25 - 21} = imm5; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = rz; +} + +// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] > +// Instructions(24): addu32, addc32, subu32, subc32, (rsub32), ixh32, ixw32, ixd32 +// and32, andn32, or32, xor32, nor32, lsl32, lsr32, asr32, rotl32 +// mult32, divu32, divs32, mul.(u/s)32, mula.32.l, mula.u32, mulall.s16.s +class R_YXZ opcode, bits<6> sop, bits<5> pcode, dag outs, dag ins, string op, + list pattern> + : CSKY32Inst { + bits<5> ry; + bits<5> rx; + bits<5> rz; + let Inst{25 - 21} = ry; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = rz; +} + +// R_YXZ instructions with simple pattern +// Output: GPR:rz +// Input: GPR:rx, GPR:ry +// Asm string: op rz, rx, ry +// Instructions: addu32, subu32, ixh32, ixw32, ixd32, and32, andn32, or32, xor32, +// nor32, lsl32, lsr32, asr32, mult32, divu32, divs32 +class R_YXZ_SP_F1 sop, bits<5> pcode, PatFrag opnode, string op, + bit Commutable = 0> + : R_YXZ<0x31, sop, pcode, (outs GPR:$rz), (ins GPR:$rx, GPR:$ry), op, + [(set GPR:$rz, (opnode GPR:$rx, GPR:$ry))]> { + let isCommutable = Commutable; +} + +// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] > +// Instructions:(8) ldr32.b, ldr32.h, ldr32.bs, ldr32.hs, ldr32.w, +// str32.b, str32.h, str32.w +class R_YXZ_LDST opcode, bits<6> sop, bits<5> pcode, int no, dag outs, dag ins, string op, + list pattern> + : CSKY32Inst { + bits<5> rx; + bits<5> ry; + bits<5> rz; + let Inst{25 - 21} = ry; // ry; + let Inst{20 - 16} = rx; // rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; // pcode; + let Inst{4 - 0} = rz; +} + +class I_LDR sop, bits<5> pcode, string op, int no> + : R_YXZ_LDST<0x34, sop, pcode, no, (outs GPR:$rz), (ins GPR:$rx, GPR:$ry), op, []>; + +class I_STR sop, bits<5> pcode, string op, int no> + : R_YXZ_LDST<0x35, sop, pcode, no, (outs), (ins GPR:$rz, GPR:$rx, GPR:$ry), op, []>; + +// Format< OP[6] | RX[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] > +// Instructions:(1) not32 +class R_XXZ sop, bits<5> pcode, dag outs, dag ins, string op, + list pattern> + : CSKY32Inst { + bits<5> rx; + bits<5> rz; + let Inst{25 - 21} = rx; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = rz; +} + +// Format< OP[6] | RY[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] > +// Instructions:(4) cmpne32, cmphs32, cmplt32, tst32 +class R_YX sop, bits<5> pcode, string op> + : CSKY32Inst { + bits<5> ry; + bits<5> rx; + let Inst{25 - 21} = ry; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; + let isCompare = 1; +} + +// Format< OP[6] | 00000[5] | RX[5] | SOP[6] | PCODE[5] | RZ[5] > +// Instructions:(12) mov32, xtrb0.32, xtrb1.32, xtrb2.32, xtrb3.32, brev32, revb32 +// revh32, abs32, ff0.32, ff1.32, bgenr32 +class R_XZ sop, bits<5> pcode, string op> + : CSKY32Inst { + bits<5> rx; + bits<5> rz; + let Inst{25 - 21} = 0; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = rz; +} + +// Format< OP[6] | RZ[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] > +// Instructions:(2) movf32, movt32 +class R_ZX sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + bits<5> rz; + bits<5> rx; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; + let Constraints = "$rz = $false"; + let isSelect = 1; +} + +// Format< OP[6] | 00000[5] | RX[5] | SOP[6] | PCODE[5] | 00000[5] > +// Instructions:(1) tstnbz32 +class R_X sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + bits<5> rx; + let Inst{25 - 21} = 0; + let Inst{20 - 16} = rx; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; +} + +// Format< OP[6] | 00000[5] | 00000[5] | SOP[6] | PCODE[5] | RZ[5] > +// Instructions:(2) mvc32, mvcv32 +class R_Z_1 sop, bits<5> pcode, string op> + : CSKY32Inst { + bits<5> rz; + let Inst{25 - 21} = 0; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = rz; +} + +// Format< OP[6] | RZ[5] | 00000[5] | SOP[6] | PCODE[5] | 00000[5] > +// Instructions:(2) clrf32, clrt32 +class R_Z_2 sop, bits<5> pcode, string op, list pattern> + : CSKY32Inst { + bits<5> rz; + let Inst{25 - 21} = rz; + let Inst{20 - 16} = 0; + let Inst{15 - 10} = sop; + let Inst{9 - 5} = pcode; + let Inst{4 - 0} = 0; + let Constraints = "$rz = $false"; +} Index: llvm/lib/Target/CSKY/CSKYInstrFormatsF1.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrFormatsF1.td @@ -0,0 +1,226 @@ +//===- CSKYInstrFormatsF1.td - CSKY Float1.0 Instr Format --*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// CSKY Instruction Format Float1.0 Definitions. +// +//===----------------------------------------------------------------------===// + +class CSKYFP1Inst pattern> + : CSKY32Inst, Requires<[HasFPUv2_SF]> { +} + +class F_XYZ_BASE datatype, bits<6> sop, dag outs, dag ins, string opcodestr, list pattern> + : CSKYFP1Inst { + bits<4> vrx; + bits<4> vry; + bits<4> vrz; + let Inst{25 - 21} = {0, vry}; + let Inst{20 - 16} = {0, vrx}; + let Inst{15 - 11} = datatype; + let Inst{10 - 5} = sop; + let Inst{4 - 0} = {0, vrz}; +} + +class F_XZ_GF datatype, bits<6> sop, dag outs, dag ins, string opcodestr, list pattern> + : CSKYFP1Inst { + bits<4> vrx; + bits<5> rz; + let Inst{25 - 21} = 0; + let Inst{20 - 16} = {0, vrx}; + let Inst{15 - 11} = datatype; + let Inst{10 - 5} = sop; + let Inst{4 - 0} = {rz}; +} + +class F_XZ_FG datatype, bits<6> sop, dag outs, dag ins, string opcodestr, list pattern> + : CSKYFP1Inst { + bits<5> rx; + bits<4> vrz; + let Inst{25 - 21} = 0; + let Inst{20 - 16} = {rx}; + let Inst{15 - 11} = datatype; + let Inst{10 - 5} = sop; + let Inst{4 - 0} = {0, vrz}; +} + +class F_XZ_TRANS_FROM sop, string op, RegisterClass regtype1, RegisterClass regtype2> + : F_XZ_GF<3, sop, (outs regtype1:$rz), (ins regtype2:$vrx), !strconcat(op, "\t$rz, $vrx"), + []>; + +class F_XZ_TRANS_TO sop, string op, RegisterClass regtype1, RegisterClass regtype2> + : F_XZ_FG<3, sop, (outs regtype1:$vrz), (ins regtype2:$rx), !strconcat(op, "\t$vrz, $rx"), + []>; + +let vry = 0 in { +class F_XZ datatype, bits<6> sop, string op, string op_su, PatFrag opnode, RegisterClass regtype> + : F_XYZ_BASE; + +class F_MOV datatype, bits<6> sop, string op, string op_su, RegisterClass regtype> + : F_XYZ_BASE; + +class F_XZ_TRANS sop, string op, RegisterClass regtype1, RegisterClass regtype2> + : F_XYZ_BASE<3, sop, (outs regtype1:$vrz), (ins regtype2:$vrx), !strconcat(op, "\t$vrz, $vrx"), + []>; + +class F_XZ_TRANS_DS sop, string op, PatFrag opnode> + : F_XYZ_BASE<3, sop, (outs sFPR32:$vrz), (ins sFPR64:$vrx), !strconcat(op, "\t$vrz, $vrx"), + [(set sFPR32:$vrz, (opnode sFPR64:$vrx))]>; + +class F_XZ_TRANS_SD sop, string op, PatFrag opnode> + : F_XYZ_BASE<3, sop, (outs sFPR64:$vrz), (ins sFPR32:$vrx), !strconcat(op, "\t$vrz, $vrx"), + [(set sFPR64:$vrz, (opnode sFPR32:$vrx))]>; +} + +multiclass FT_MOV sop, string op> { + def _S : F_MOV<0, sop, op, "s", sFPR32>; + let Predicates = [HasFPUv2_DF] in + def _D : F_MOV<1, sop, op, "d", sFPR64>; +} + +multiclass FT_XZ sop, string op, PatFrag opnode> { + def _S : F_XZ<0, sop, op, "s", opnode, sFPR32>; + let Predicates = [HasFPUv2_DF] in + def _D : F_XZ<1, sop, op, "d", opnode, sFPR64>; +} + +let vrz = 0, isCompare = 1 in { +class F_CMPXY datatype, bits<6> sop, string op, string op_su, RegisterClass regtype> + : F_XYZ_BASE; + +let vry = 0 in{ +class F_CMPZX datatype, bits<6> sop, string op, string op_su, RegisterClass regtype> + : F_XYZ_BASE; +} +} + +class F_XYZ datatype, bits<6> sop, string op, string op_su, PatFrag opnode, RegisterClass regtype> + : F_XYZ_BASE; + +multiclass FT_XYZ sop, string op, PatFrag opnode> { + def _S : F_XYZ<0, sop, op, "s", opnode, sFPR32>; + let Predicates = [HasFPUv2_DF] in + def _D : F_XYZ<1, sop, op, "d", opnode, sFPR64>; +} + +let Constraints = "$vrt = $vrz" in { +class F_ACCUM_XYZ datatype, bits<6> sop, string op, string op_su, PatFrag opnode, RegisterClass regtype> + : F_XYZ_BASE; +} + +multiclass FT_ACCUM_XYZ sop, string op, PatFrag opnode> { + def _S : F_ACCUM_XYZ<0, sop, op, "s", opnode, sFPR32>; + let Predicates = [HasFPUv2_DF] in + def _D : F_ACCUM_XYZ<1, sop, op, "d", opnode, sFPR64>; +} + +multiclass FT_CMPXY sop, string op> { + def _S : F_CMPXY<0, sop, op, "s", sFPR32>; + let Predicates = [HasFPUv2_DF] in + def _D : F_CMPXY<1, sop, op, "d", sFPR64>; +} + + +multiclass FT_CMPZX sop, string op> { + def _S : F_CMPZX<0, sop, op, "s", sFPR32>; + let Predicates = [HasFPUv2_DF] in + def _D : F_CMPZX<1, sop, op, "d", sFPR64>; +} + +class F_I8_XY_MEM sop, bits<1> sop_su, dag outs, dag ins, string opcodestr, list pattern> + : CSKY32Inst { + bits<5> rx; + bits<4> vrz; + bits<8> imm8; + let Inst{25} = 0; + let Inst{24 - 21} = imm8{7 - 4}; //imm4h + let Inst{20 - 16} = rx; //rx + let Inst{15 - 9} = sop; + let Inst{8} = sop_su; + let Inst{7 - 4} = imm8{3 - 0}; // imm4l + let Inst{3 - 0} = vrz; +} + +class F_XYZ_MEM sop, bits<1> sop_su, dag outs, dag ins, string opcodestr, bits<2> shift, list pattern> + : CSKY32Inst { + bits<2> shift; + bits<5> rx; + bits<5> ry; + bits<4> vrz; + let Inst{25 - 21} = ry; // ry; + let Inst{20 - 16} = rx; // rx; + let Inst{15 - 9} = sop; + let Inst{8} = sop_su; + let Inst{7} = 0; + let Inst{6,5} = shift; // shift; + let Inst{4} = 0; + let Inst{3 - 0} = vrz; +} + +class F_XYAI_LD sop, bits<1> sop_su, string op, string op_su, + RegisterClass regtype, Operand operand> + : F_I8_XY_MEM; + +class F_XYAR_LD sop, bits<1> sop_su, string op, string op_su, + RegisterClass regtype, bits<2> shift> + : F_XYZ_MEM(shift)#")", shift, []>; + +class F_XYAI_ST sop, bits<1> sop_su, string op, string op_su, + RegisterClass regtype, Operand operand> + : F_I8_XY_MEM; + +class F_XYAR_ST sop, bits<1> sop_su, string op, string op_su, + RegisterClass regtype, bits<2> shift> + : F_XYZ_MEM(shift)#")", shift, []>; + +def Mem8SL2 : Operand, ComplexPattern { + let MIOperandInfo = (ops GPR, i32imm); + let PrintMethod = "printAddrModeRegImmOperand"; + let EncoderMethod = "getAddrModeFloatImm8_sl2OpValue"; +} + +def FRRS : Operand, ComplexPattern { + let MIOperandInfo = (ops GPR, GPR, i32imm); + let PrintMethod = "printAddrModeRegRegSLOperand"; + let EncoderMethod = "getAddrModeFloatRegRegSLOpValue"; +} + +multiclass FT_XYAI_LD sop, string op> { + def _S : F_XYAI_LD; + let Predicates = [HasFPUv2_DF] in + def _D : F_XYAI_LD; +} + +multiclass FT_XYAR_LD sop, string op, bits<2> shift> { + def _S#!cast(shift) : F_XYAR_LD; + let Predicates = [HasFPUv2_DF] in + def _D#!cast(shift) : F_XYAR_LD; +} + +multiclass FT_XYAI_ST sop, string op> { + def _S : F_XYAI_ST; + let Predicates = [HasFPUv2_DF] in + def _D : F_XYAI_ST; +} + +multiclass FT_XYAR_ST sop, string op, bits<2> shift> { + def _S#!cast(shift) : F_XYAR_ST; + let Predicates = [HasFPUv2_DF] in + def _D#!cast(shift) : F_XYAR_ST; +} Index: llvm/lib/Target/CSKY/CSKYInstrFormatsF2.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrFormatsF2.td @@ -0,0 +1,169 @@ +//===- CSKYInstrFormatsF2.td - CSKY Float2.0 Instr Format --*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// CSKY Instruction Format Float2.0 Definitions. +// +//===----------------------------------------------------------------------===// + +class CSKYInstF2 pattern> + : CSKY32Inst { + let Predicates = [HasFPUv3_SF]; +} + +class F2_XYZ datatype, bits<6> sop, string opcodestr, dag outs, dag ins, + list pattern> + : CSKYInstF2 { + bits<5> vry; + bits<5> vrx; + bits<5> vrz; + + let Inst{25-21} = vry; + let Inst{20-16} = vrx; + let Inst{15-11} = datatype; + let Inst{10-5} = sop; + let Inst{4-0} = vrz; +} + +multiclass F2_XYZ_T sop, string op, PatFrag opnode> { + def _S : F2_XYZ<0b00000, sop, op#".32"#"\t$vrz, $vrx, $vry", + (outs FPR32:$vrz), (ins FPR32:$vrx, FPR32:$vry), + [(set FPR32:$vrz, (opnode FPR32:$vrx, FPR32:$vry))]>; + let Predicates = [HasFPUv3_DF] in + def _D : F2_XYZ<0b00001, sop, op#".64"#"\t$vrz, $vrx, $vry", + (outs FPR64:$vrz), (ins FPR64:$vrx, FPR64:$vry), + [(set FPR64:$vrz, (opnode FPR64:$vrx, FPR64:$vry))]>; +} + +let Constraints = "$vrZ = $vrz" in +multiclass F2_XYZZ_T sop, string op, PatFrag opnode> { + def _S : F2_XYZ<0b00000, sop, op#".32"#"\t$vrz, $vrx, $vry", + (outs FPR32:$vrz), (ins FPR32:$vrZ, FPR32:$vrx, FPR32:$vry), + [(set FPR32:$vrz, (opnode FPR32:$vrx, FPR32:$vry, FPR32:$vrZ))]>; + let Predicates = [HasFPUv3_DF] in + def _D : F2_XYZ<0b00001, sop, op#".64"#"\t$vrz, $vrx, $vry", + (outs FPR64:$vrz), (ins FPR64:$vrZ, FPR64:$vrx, FPR64:$vry), + [(set FPR64:$vrz, (opnode FPR64:$vrx, FPR64:$vry, FPR64:$vrZ))]>; +} + +let vry = 0 in { +class F2_XZ datatype, RegisterClass regtype, bits<6> sop, string op, SDNode opnode> + : F2_XYZ; + +class F2_XZ_SET datatype, RegisterClass regtype, bits<6> sop, string op> + : F2_XYZ; + +class F2_XZ_P datatype, bits<6> sop, string op, list pattern = [], + dag outs, dag ins> + : F2_XYZ; +} + +multiclass F2_XZ_RM sop, string op, dag outs, dag ins> { + def _RN : F2_XZ_P<0b00011, {sop, 0b00}, op#".rn", [], outs, ins>; + def _RZ : F2_XZ_P<0b00011, {sop, 0b01}, op#".rz", [], outs, ins>; + def _RPI : F2_XZ_P<0b00011, {sop, 0b10}, op#".rpi", [], outs, ins>; + def _RNI : F2_XZ_P<0b00011, {sop, 0b11}, op#".rni", [], outs, ins>; +} + +multiclass F2_XZ_T sop, string op, SDNode opnode> { + def _S : F2_XZ<0b00000, FPR32, sop, op#".32", opnode>; + let Predicates = [HasFPUv3_DF] in + def _D : F2_XZ<0b00001, FPR64, sop, op#".64", opnode>; +} + +multiclass F2_XZ_SET_T sop, string op, string suffix = ""> { + def _S : F2_XZ_SET<0b00000, FPR32, sop, op#".32"#suffix>; + let Predicates = [HasFPUv3_DF] in + def _D : F2_XZ_SET<0b00001, FPR64, sop, op#".64"#suffix>; +} + + +let vrz = 0, isCompare = 1 in +class F2_CXY datatype, RegisterClass regtype, bits<6> sop, string op> + : F2_XYZ; + +multiclass F2_CXY_T sop, string op> { + def _S : F2_CXY<0b00000, FPR32, sop, op#".32">; + let Predicates = [HasFPUv3_DF] in + def _D : F2_CXY<0b00001, FPR64, sop, op#".64">; +} + + +let vrz = 0, vry = 0, isCompare = 1 in +class F2_CX datatype, RegisterClass regtype, bits<6> sop, string op> + : F2_XYZ; + +multiclass F2_CX_T sop, string op> { + def _S : F2_CX<0b00000, FPR32, sop, op#".32">; + let Predicates = [HasFPUv3_DF] in + def _D : F2_CX<0b00001, FPR64, sop, op#".64">; +} + + +class F2_LDST datatype, bits<1> sop, string op, dag outs, dag ins> + : CSKYInstF2 { + bits<10> imm8; + bits<5> rx; + bits<5> vrz; + + let Inst{25} = vrz{4}; + let Inst{24-21} = imm8{7-4}; + let Inst{20-16} = rx; + let Inst{15-11} = 0b00100; + let Inst{10} = sop; + let Inst{9-8} = datatype; + let Inst{7-4} = imm8{3-0}; + let Inst{3-0} = vrz{3-0}; +} + +class F2_LDST_S sop, string op, dag outs, dag ins> + : F2_LDST<0b00, sop, op#".32", outs, ins>; +class F2_LDST_D sop, string op, dag outs, dag ins> + : F2_LDST<0b01, sop, op#".64", outs, ins>; + + +class F2_LDSTR datatype, bits<1> sop, string op, dag outs, dag ins, bits<2> shift> + : CSKYInstF2(shift)#")", []> { + bits<5> rx; + bits<5> ry; + bits<5> rz; + + let Inst{25-21} = ry; + let Inst{20-16} = rx; + let Inst{15-11} = 0b00101; + let Inst{10} = sop; + let Inst{9-8} = datatype; + let Inst{7} = 0; + let Inst{6-5} = shift; + let Inst{4-0} = rz; +} + +class F2_LDSTR_S sop, string op, dag outs, dag ins, bits<2> shift> + : F2_LDSTR<0b00, sop, op#".32", outs, ins, shift>; +class F2_LDSTR_D sop, string op, dag outs, dag ins, bits<2> shift> + : F2_LDSTR<0b01, sop, op#".64", outs, ins, shift>; + +class F2_CXYZ datatype, RegisterClass regtype, bits<6> sop, string op> + : F2_XYZ; +multiclass F2_CXYZ_T sop, string op> { + def _S : F2_CXYZ<0b00000, FPR32, sop, op#".32">; + let Predicates = [HasFPUv3_DF] in + def _D : F2_CXYZ<0b00001, FPR64, sop, op#".64">; +} Index: llvm/lib/Target/CSKY/CSKYInstrInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrInfo.h @@ -0,0 +1,92 @@ +//===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYINSTRINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYINSTRINFO_H + +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/CodeGen/TargetInstrInfo.h" + +#define GET_INSTRINFO_HEADER +#include "CSKYGenInstrInfo.inc" + +namespace llvm { + +class CSKYSubtarget; + +class CSKYInstrInfo : public CSKYGenInstrInfo { +protected: + CSKYSubtarget &STI; + + bool v2sf; + bool v2df; + bool v3sf; + bool v3df; + + void insertCondBranch(MachineBasicBlock &MBB, const DebugLoc &DL, + MachineBasicBlock *TBB, + ArrayRef Cond) const; + +public: + explicit CSKYInstrInfo(CSKYSubtarget &STI); + + void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, Register SrcReg, + bool IsKill, int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const override; + + void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, Register DestReg, + int FrameIndex, const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const override; + + void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, + const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, + bool KillSrc) const override; + + MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; + + bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify = false) const override; + + unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, ArrayRef Cond, + const DebugLoc &DL, + int *BytesAdded = nullptr) const override; + + unsigned insertIndirectBranch(MachineBasicBlock &MBB, + MachineBasicBlock &NewDestBB, + const DebugLoc &DL, int64_t BrOffset = 0, + RegScavenger *RS = nullptr) const override; + + unsigned removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved = nullptr) const override; + + bool + reverseBranchCondition(SmallVectorImpl &Cond) const override; + + bool isBranchOffsetInRange(unsigned BranchOpc, + int64_t BrOffset) const override; + + unsigned getInstSizeInBytes(const MachineInstr &MI) const override; + + bool expandPostRAPseudo(MachineInstr &MI) const override; + + Register getGlobalBaseReg(MachineFunction *MF) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYINSTRINFO_H Index: llvm/lib/Target/CSKY/CSKYInstrInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrInfo.cpp @@ -0,0 +1,495 @@ +//===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYInstrInfo.h" +#include "CSKYConstantPoolValue.h" +#include "CSKYMachineFunctionInfo.h" +#include "CSKYTargetMachine.h" + +using namespace llvm; + +#define GET_INSTRINFO_CTOR_DTOR +#include "CSKYGenInstrInfo.inc" + +CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI) + : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) { + v2sf = STI.hasFPUv2SingleFloat(); + v2df = STI.hasFPUv2DoubleFloat(); + v3sf = STI.hasFPUv3SingleFloat(); + v3df = STI.hasFPUv3DoubleFloat(); +} + +void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + Register SrcReg, bool IsKill, int FI, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { + DebugLoc DL; + if (I != MBB.end()) + DL = I->getDebugLoc(); + + MachineFunction &MF = *MBB.getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + CSKYMachineFunctionInfo *MFI = MF.getInfo(); + + if (CSKY::GPRRegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::ST32W)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::FST_S)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::FST_D)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::f2FST_S)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::f2FST_D)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::SPILL_CARRY)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addFrameIndex(FI) + .addImm(0); + MFI->setSpillsCR(); + return; + } else if (CSKY::GPRPairRegClass.hasSubClassEq(RC)) { + auto NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); + BuildMI(MBB, I, DL, get(CSKY::ADDI32), NewReg).addFrameIndex(FI).addImm(0); + BuildMI(MBB, I, DL, get(CSKY::STM32_2)) + .addReg(SrcReg, getKillRegState(IsKill)) + .addReg(NewReg, getKillRegState(true)); + return; + } + + llvm_unreachable("Unknown RegisterClass"); +} + +void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + Register DestReg, int FI, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { + DebugLoc DL; + if (I != MBB.end()) + DL = I->getDebugLoc(); + + MachineFunction &MF = *MBB.getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + CSKYMachineFunctionInfo *MFI = MF.getInfo(); + + if (CSKY::GPRRegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::LD32W), DestReg).addFrameIndex(FI).addImm(0); + return; + } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::FLD_S), DestReg).addFrameIndex(FI).addImm(0); + return; + } else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::FLD_D), DestReg).addFrameIndex(FI).addImm(0); + return; + } else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::f2FLD_S), DestReg) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::f2FLD_D), DestReg) + .addFrameIndex(FI) + .addImm(0); + return; + } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) { + BuildMI(MBB, I, DL, get(CSKY::RESTORE_CARRY), DestReg) + .addFrameIndex(FI) + .addImm(0); + MFI->setSpillsCR(); + return; + } else if (CSKY::GPRPairRegClass.hasSubClassEq(RC)) { + auto NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); + BuildMI(MBB, I, DL, get(CSKY::ADDI32), NewReg).addFrameIndex(FI).addImm(0); + BuildMI(MBB, I, DL, get(CSKY::LDM32_2), DestReg) + .addReg(NewReg, getKillRegState(true)); + return; + } + + llvm_unreachable("Unknown RegisterClass"); +} + +void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + const DebugLoc &DL, MCRegister DestReg, + MCRegister SrcReg, bool KillSrc) const { + unsigned Opcode = 0; + + if (CSKY::GPRRegClass.contains(DestReg, SrcReg)) { + Opcode = CSKY::MOV32; + } else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg)) { + Opcode = CSKY::FMOV_S; + } else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg)) { + Opcode = CSKY::f2FMOV_S; + } else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg)) { + Opcode = CSKY::FMOV_D; + } else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg)) { + Opcode = CSKY::f2FMOV_D; + } else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) && + CSKY::GPRRegClass.contains(DestReg)) { + Opcode = CSKY::FMFVRL; + } else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) && + CSKY::GPRRegClass.contains(DestReg)) { + Opcode = CSKY::f2FMFVRL; + } else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) && + CSKY::GPRRegClass.contains(DestReg)) { + Opcode = CSKY::FMFVRL_D; + } else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) && + CSKY::GPRRegClass.contains(DestReg)) { + Opcode = CSKY::f2FMFVRL_D; + } else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) && + CSKY::sFPR32RegClass.contains(DestReg)) { + Opcode = CSKY::FMTVRL; + } else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) && + CSKY::FPR32RegClass.contains(DestReg)) { + Opcode = CSKY::f2FMTVRL; + } else if (v2df && CSKY::GPRRegClass.contains(SrcReg) && + CSKY::sFPR64RegClass.contains(DestReg)) { + Opcode = CSKY::FMTVRL_D; + } else if (v3df && CSKY::GPRRegClass.contains(SrcReg) && + CSKY::FPR64RegClass.contains(DestReg)) { + Opcode = CSKY::f2FMTVRL_D; + } else if (CSKY::GPRRegClass.contains(SrcReg) && + CSKY::CARRYRegClass.contains(DestReg)) { + Opcode = CSKY::BTSTI32; + } else if (CSKY::CARRYRegClass.contains(SrcReg) && + CSKY::GPRRegClass.contains(DestReg)) { + Opcode = CSKY::MVC32; + } else { + llvm_unreachable("Unknown RegisterClass"); + } + + if (Opcode == CSKY::BTSTI32) { + BuildMI(MBB, I, DL, get(Opcode)) + .addReg(DestReg, RegState::Define) + .addReg(SrcReg, getKillRegState(KillSrc)) + .addImm(0); + } else { + BuildMI(MBB, I, DL, get(Opcode)) + .addReg(DestReg, RegState::Define) + .addReg(SrcReg, getKillRegState(KillSrc)); + } +} + +static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target, + SmallVectorImpl &Cond) { + // Block ends with fall-through condbranch. + assert(LastInst.getDesc().isConditionalBranch() && + "Unknown conditional branch"); + Target = LastInst.getOperand(1).getMBB(); + Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode())); + Cond.push_back(LastInst.getOperand(0)); +} + +bool CSKYInstrInfo::analyzeBranch(MachineBasicBlock &MBB, + MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond, + bool AllowModify) const { + TBB = FBB = nullptr; + Cond.clear(); + + // If the block has no terminators, it just falls into the block after it. + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); + if (I == MBB.end() || !isUnpredicatedTerminator(*I)) + return false; + + // Count the number of terminators and find the first unconditional or + // indirect branch. + MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end(); + int NumTerminators = 0; + for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J); + J++) { + NumTerminators++; + if (J->getDesc().isUnconditionalBranch() || + J->getDesc().isIndirectBranch()) { + FirstUncondOrIndirectBr = J.getReverse(); + } + } + + // If AllowModify is true, we can erase any terminators after + // FirstUncondOrIndirectBR. + if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) { + while (std::next(FirstUncondOrIndirectBr) != MBB.end()) { + std::next(FirstUncondOrIndirectBr)->eraseFromParent(); + NumTerminators--; + } + I = FirstUncondOrIndirectBr; + } + + // We can't handle blocks that end in an indirect branch. + if (I->getDesc().isIndirectBranch()) + return true; + + // We can't handle blocks with more than 2 terminators. + if (NumTerminators > 2) + return true; + + // Handle a single unconditional branch. + if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) { + TBB = getBranchDestBlock(*I); + return false; + } + + // Handle a single conditional branch. + if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) { + parseCondBranch(*I, TBB, Cond); + return false; + } + + // Handle a conditional branch followed by an unconditional branch. + if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() && + I->getDesc().isUnconditionalBranch()) { + parseCondBranch(*std::prev(I), TBB, Cond); + FBB = getBranchDestBlock(*I); + return false; + } + + // Otherwise, we can't handle this. + return true; +} + +unsigned CSKYInstrInfo::insertBranch( + MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, + ArrayRef Cond, const DebugLoc &DL, int *BytesAdded) const { + if (BytesAdded) + *BytesAdded = 0; + + // Shouldn't be a fall through. + assert(TBB && "insertBranch must not be told to insert a fallthrough"); + assert((Cond.size() == 2 || Cond.size() == 0) && + "CSKY branch conditions have two components!"); + + // Unconditional branch. + if (Cond.empty()) { + MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(TBB); + if (BytesAdded) + *BytesAdded += getInstSizeInBytes(MI); + return 1; + } + + // Either a one or two-way conditional branch. + unsigned Opc = Cond[0].getImm(); + MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).addMBB(TBB); + if (BytesAdded) + *BytesAdded += getInstSizeInBytes(CondMI); + + // One-way conditional branch. + if (!FBB) + return 1; + + // Two-way conditional branch. + MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(FBB); + if (BytesAdded) + *BytesAdded += getInstSizeInBytes(MI); + return 2; +} + +bool CSKYInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { + auto &MBB = *MI.getParent(); + auto DL = MI.getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + CSKYMachineFunctionInfo *CFI = MF->getInfo(); + MachineConstantPool *MCP = MF->getConstantPool(); + + switch (MI.getOpcode()) { + case CSKY::GETGOT32: { + CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create( + MF->getFunction().getContext(), "_GLOBAL_OFFSET_TABLE_", + CFI->createPICLabelUId(), 0); + unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4)); + + MachineMemOperand *MO = + MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(*MF), + MachineMemOperand::MOLoad, 4, Align(4)); + BuildMI(MBB, MI, DL, get(CSKY::LRW32), MI.getOperand(0).getReg()) + .addConstantPoolIndex(CPI) + .addMemOperand(MO); + + MBB.erase(MI); + return true; + } + } + return false; +} + +// This function is only used by BranchRelaxation. +// Since we need to reserve constant pool for each branch instruction, +// there is no need to do branch relaxation before constant island pass. +unsigned int CSKYInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB, + MachineBasicBlock &NewDestBB, + const DebugLoc &DL, + int64_t BrOffset, + RegScavenger *RS) const { + assert(MBB.empty() && + "new block should be inserted for expanding unconditional branch"); + assert(MBB.pred_size() == 1); + + MachineFunction *MF = MBB.getParent(); + CSKYMachineFunctionInfo *CFI = MF->getInfo(); + MachineConstantPool *MCP = MF->getConstantPool(); + + unsigned PCLabelID = CFI->createPICLabelUId(); + CSKYConstantPoolValue *CPV = CSKYConstantPoolMBB::Create( + MF->getFunction().getContext(), &NewDestBB, PCLabelID, 0); + unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4)); + /* + jmpi [(cp - pc) >> 2] + cp: (DestBB) + */ + BuildMI(&MBB, DL, get(CSKY::JMPI32)).addConstantPoolIndex(CPI); + + return 4; +} + +unsigned CSKYInstrInfo::removeBranch(MachineBasicBlock &MBB, + int *BytesRemoved) const { + if (BytesRemoved) + *BytesRemoved = 0; + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); + if (I == MBB.end()) + return 0; + + if (!I->getDesc().isUnconditionalBranch() && + !I->getDesc().isConditionalBranch()) + return 0; + + // Remove the branch. + if (BytesRemoved) + *BytesRemoved += getInstSizeInBytes(*I); + I->eraseFromParent(); + + I = MBB.end(); + + if (I == MBB.begin()) + return 1; + --I; + if (!I->getDesc().isConditionalBranch()) + return 1; + + // Remove the branch. + if (BytesRemoved) + *BytesRemoved += getInstSizeInBytes(*I); + I->eraseFromParent(); + return 2; +} + +MachineBasicBlock * +CSKYInstrInfo::getBranchDestBlock(const MachineInstr &MI) const { + assert(MI.getDesc().isBranch() && "Unexpected opcode!"); + // The branch target is always the last operand. + int NumOp = MI.getNumExplicitOperands(); + assert(MI.getOperand(NumOp - 1).isMBB() && "Expected MBB!"); + return MI.getOperand(NumOp - 1).getMBB(); +} + +bool CSKYInstrInfo::isBranchOffsetInRange(unsigned BranchOp, + int64_t BrOffset) const { + switch (BranchOp) { + default: + llvm_unreachable("Unexpected opcode!"); + case CSKY::BR32: + case CSKY::BT32: + case CSKY::BF32: + case CSKY::BHZ32: + case CSKY::BHSZ32: + case CSKY::BLZ32: + case CSKY::BLSZ32: + case CSKY::BNEZ32: + case CSKY::BEZ32: + return isIntN(16, BrOffset / 2); + } +} + +static unsigned getOppositeBranchOpc(unsigned Opcode) { + switch (Opcode) { + default: + llvm_unreachable("Unknown conditional branch!"); + case CSKY::BT32: + return CSKY::BF32; + case CSKY::BF32: + return CSKY::BT32; + case CSKY::BHZ32: + return CSKY::BLSZ32; + case CSKY::BHSZ32: + return CSKY::BLZ32; + case CSKY::BLZ32: + return CSKY::BHSZ32; + case CSKY::BLSZ32: + return CSKY::BHZ32; + case CSKY::BNEZ32: + return CSKY::BEZ32; + case CSKY::BEZ32: + return CSKY::BNEZ32; + } +} + +bool CSKYInstrInfo::reverseBranchCondition( + SmallVectorImpl &Cond) const { + assert((Cond.size() == 2) && "Invalid branch condition!"); + Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); + return false; +} + +Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { + CSKYMachineFunctionInfo *MFI = MF->getInfo(); + Register GlobalBaseReg = MFI->getGlobalBaseReg(); + if (GlobalBaseReg != 0) + return GlobalBaseReg; + + // We use r28 as a global base register + GlobalBaseReg = CSKY::GP; + + // Insert a pseudo instruction to set the GlobalBaseReg into the first + // MBB of the function + MachineBasicBlock &FirstMBB = MF->front(); + MachineBasicBlock::iterator MBBI = FirstMBB.begin(); + DebugLoc Dl; + BuildMI(FirstMBB, MBBI, Dl, get(CSKY::GETGOT32), GlobalBaseReg); + MFI->setGlobalBaseReg(GlobalBaseReg); + return GlobalBaseReg; +} + +unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { + switch (MI.getOpcode()) { + default: + return MI.getDesc().getSize(); + case CSKY::CONSTPOOL_ENTRY: + return MI.getOperand(2).getImm(); + case TargetOpcode::INLINEASM: { + const MachineFunction *MF = MI.getParent()->getParent(); + const char *AsmStr = MI.getOperand(0).getSymbolName(); + return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); + } + } +} Index: llvm/lib/Target/CSKY/CSKYInstrInfo.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrInfo.td @@ -0,0 +1,611 @@ +//===-- CSKYInstrInfo.td - Target Description for CSKY -----*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the CSKY instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// CSKY specific DAG Nodes. +//===----------------------------------------------------------------------===// + +// Target-independent type requirements, but with target-specific formats. +def SDT_CallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; +def SDT_CallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; + +// Target-dependent type requirement. +def SDT_CSKYCall : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; + +// Target-independent nodes, but with target-specific formats. +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, + [SDNPHasChain, SDNPOutGlue]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; + +// Target-dependent nodes. +def CSKY_RET : SDNode<"CSKYISD::RET", SDTNone, + [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; + +def CSKY_CALL : SDNode<"CSKYISD::CALL", SDT_CSKYCall, + [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; + +def CSKY_JMP : SDNode<"CSKYISD::JMP", SDT_CSKYCall, + [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>; + +def CSKY_BITCAST : SDNode<"CSKYISD::BITCAST", SDTUnaryOp>; + +def SDT_BITCAST_FROM_LOHI : SDTypeProfile<1, 2, [ + SDTCisSameAs<1, 2> +]>; +def CSKY_BITCAST_FROM_LOHI : SDNode<"CSKYISD::BITCAST_FROM_LOHI", SDT_BITCAST_FROM_LOHI>; + +def SDT_BITCAST_TO_LOHI : SDTypeProfile<2, 1, [ + SDTCisSameAs<0, 1> +]>; +def CSKY_BITCAST_TO_LOHI : SDNode<"CSKYISD::BITCAST_TO_LOHI", SDT_BITCAST_TO_LOHI>; + +def CSKY_JT_CP_WRAP : SDNode<"CSKYISD::JT_CP_WRAP", SDTIntBinOp>; + +// Predicates + +def eqToAdd : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs), [{ + return isOrEquivalentToAdd(N); +}]>; + +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +// Addressing modes. +// Necessary because a frameindex can't be matched directly in a pattern. +def AddrFI : ComplexPattern; + +def frameindex_to_targetframeindex : SDNodeXForm(N); + return CurDAG->getTargetFrameIndex(FI->getIndex(), TLI->getPointerTy(CurDAG->getDataLayout())); +}]>; + + +def imm32_not_XFORM : SDNodeXFormgetTargetConstant(~N->getZExtValue(), SDLoc(N), MVT::i32); +}]>; + +foreach N1 = 1 - 31 in { + foreach N2 = 1 - 31 in { + def imm#N1#_sr#N2#_XFORM : SDNodeXFormgetTargetConstant(N->getAPIntValue().lshr("#N2#").getLoBits("#N1#"), SDLoc(N), MVT::i32);">; + + def uimm#N1#"_"#N2: Operand, ImmLeaf(Imm);", !cast(imm#N1#_sr#N2#_XFORM)>{ + let EncoderMethod = "getImmOpValue"; + } + } + + def imm#N1#_sr0_XFORM : SDNodeXFormgetTargetConstant(N->getAPIntValue().getLoBits("#N1#"), SDLoc(N), MVT::i32);">; + def uimm#N1: Operand, ImmLeaf(Imm);", !cast(imm#N1#_sr0_XFORM)>{ + let EncoderMethod = "getImmOpValue"; + } +} + +foreach N1 = 1 - 32 in { + foreach N2 = 1 - 31 in { + def fpimm#N1#_sr#N2#_XFORM : SDNodeXFormgetTargetConstant(N->getValueAPF().bitcastToAPInt().lshr("#N2#").getLoBits("#N1#"), SDLoc(N), MVT::i32);">; + + def fpimm#N1#"_"#N2: Operand, FPImmLeaf(Imm.bitcastToAPInt().getZExtValue());">; + } + + def fpimm#N1#_sr0_XFORM : SDNodeXFormgetTargetConstant(N->getValueAPF().bitcastToAPInt().getLoBits("#N1#"), SDLoc(N), MVT::i32);">; + def fpimm#N1: Operand, FPImmLeaf(Imm.bitcastToAPInt().getZExtValue());">; +} + +def neg_imm : SDNodeXFormgetTargetConstant(-(N->getAPIntValue()), SDLoc(N), N->getValueType(0)); +}]>; + +def call_target : Operand { + let EncoderMethod = "getCalltargetOpValue"; +} + +def br_target : Operand { + let EncoderMethod = "getBranchtargetOpValue"; +} + +// An operand for the CONSTPOOL_ENTRY pseudo-instruction. +def cpinst_operand : Operand { +} + +def oimm12 : Operand, ImmLeaf(Imm - 1); }]> { + let EncoderMethod = "getOImm"; +} + +def neg_oimm12 : Operand, + ImmLeaf(-Imm - 1); }]>; + +def nimm12 : Operand, + ImmLeaf(~Imm); }], imm32_not_XFORM>; + + + +def oimm4 : Operand, ImmLeaf(Imm - 1); }]> { + let EncoderMethod = "getOImm"; +} + + + +include "CSKYInstrFormats.td" + +class TriOpFrag : PatFrag<(ops node: $LHS, node:$MHS, node:$RHS), res>; +class BinOpFrag : PatFrag<(ops node:$LHS, node:$RHS), res>; +class UnOpFrag : PatFrag<(ops node:$Src), res>; + +let Defs = [ SP ], Uses = [ SP ], hasSideEffects = 1 in { + def ADJCALLSTACKDOWN : CSKYPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), + "!ADJCALLSTACKDOWN $amt1, $amt2", [(callseq_start timm:$amt1, timm:$amt2)]>; + def ADJCALLSTACKUP : CSKYPseudo<(outs), (ins i32imm : $amt1, i32imm:$amt2), + "!ADJCALLSTACKUP $amt1", [(callseq_end timm:$amt1, timm:$amt2)] >; +} + +def CONSTPOOL_ENTRY : CSKYPseudo<(outs), + (ins cpinst_operand:$instid, cpinst_operand:$cpidx, i32imm:$size), "", []>; +def JUMPTABLE_ADDRS : CSKYPseudo<(outs), + (ins cpinst_operand:$instid, cpinst_operand:$cpidx, i32imm:$size), "", []>; + +let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in +def JMP32 : I_16_JX<0x6, "jmp32", [(brind GPR:$rx)]>; // jmp to register +def JMPI32 : I_16_L<0x16, (outs), (ins br_target:$imm16), "jmpi32", []>; + +def BSR32 : J<0x38, (outs), (ins call_target:$offset), "bsr32", + []> { + let isCall = 1; + let Defs = [ LR ]; +} +def JSR32 : I_16_JX<0x7, "jsr32", [(CSKY_CALL GPR:$rx)]> { + let isCall = 1; + let Defs = [ LR ]; +} +def JSRI32: I_16_L<0x17, (outs), (ins uimm16_2:$imm16), "jsri32", []> { + let isCall = 1; + let Defs = [ LR ]; +} + +def RTS32 : I_16_RET<0x6, 0xF, "rts32", [(CSKY_RET)]>; + +def CMPNEI32 : I_16_X<0x1A, "cmpnei32">; +def CMPHSI32 : I_16_X<0x18, "cmphsi32">; +def CMPLTI32 : I_16_X<0x19, "cmplti32">; +def CMPNE32 : R_YX<0x1, 0x4, "cmpne32">; +def CMPHS32 : R_YX<0x1, 0x1, "cmphs32">; +def CMPLT32 : R_YX<0x1, 0x2, "cmplt32">; + +def SETC32 : CSKY32Inst { + let Inst{25 - 21} = 0; //rx + let Inst{20 - 16} = 0; //ry + let Inst{15 - 10} = 0x1; + let Inst{9 - 5} = 0x1; + let Inst{4 - 0} = 0; + let isCompare = 1; +} +def CLRC32 : CSKY32Inst { + let Inst{25 - 21} = 0; //rx + let Inst{20 - 16} = 0; //ry + let Inst{15 - 10} = 0x1; + let Inst{9 - 5} = 0x4; + let Inst{4 - 0} = 0; + let isCompare = 1; +} + +def TST32 : R_YX<0x8, 0x4, "tst32">; +def BTSTI32 : I_5_X<0x0A, 0x4, "btsti32", uimm5, []>; + +let isBranch = 1, isTerminator = 1 in { + let isBarrier = 1, isPredicable = 1 in + def BR32 : I_16_L<0x0, (outs), (ins br_target:$imm16), "br32", [(br bb:$imm16)]>; + def BT32 : I_16_L<0x3, (outs), (ins CARRY:$ca, br_target:$imm16), "bt32", [(brcond CARRY:$ca, bb:$imm16)]>; + def BF32 : I_16_L<0x2, (outs), (ins CARRY:$ca, br_target:$imm16), "bf32", []>; +} + +def BEZ32 : I_16_X_L<0x8, "bez32", br_target>; +def BNEZ32 : I_16_X_L<0x9, "bnez32", br_target>; +def BHZ32 : I_16_X_L<0xA, "bhz32", br_target>; +def BLSZ32 : I_16_X_L<0xB, "blsz32", br_target>; +def BLZ32 : I_16_X_L<0xC, "blz32", br_target>; +def BHSZ32 : I_16_X_L<0xD, "bhsz32", br_target>; + +def MVC32 : R_Z_1<0x1, 0x8, "mvc32">; +def MVCV32 : R_Z_1<0x1, 0x10, "mvcv32">; +def MOVT32 : R_ZX<0x3, 0x2, "movt32", []>; +def MOVF32 : R_ZX<0x3, 0x1, "movf32", []>; +def MOV32 : R_XZ<0x12, 0x1, "mov32">; + +def MOVI32 : I_16_MOV<0x10, "movi32", uimm16>; +def MOVIH32 : I_16_MOV<0x11, "movih32", uimm16_16>; +def ORI32 : I_16_ZX<"ori32", uimm16, + [(set GPR:$rz, (or GPR:$rx, uimm16:$imm16))]>; +def LRW32 : I_16_Z_L<0x14, "lrw32", uimm16_2, []>; +def GRS32 : I_18_Z_L<0x14, "grs32", uimm18_1, []>; + +def ADDI32 : I_12<0x0, "addi32", add, oimm12>; +def SUBI32 : I_12<0x1, "subi32", sub, oimm12>; +def ANDI32 : I_12<0x2, "andi32", and, uimm12>; +def ANDNI32 : I_12<0x3, "andni32", and, nimm12>; +def XORI32 : I_12<0x4, "xori32", xor, uimm12>; + +def CLRT32 : R_Z_2<0xB, 0x2, "clrt32", [(set GPR:$rz, (select CARRY:$ca, 0, GPR:$false))]>; +def CLRF32 : R_Z_2<0xB, 0x1, "clrf32", [(set GPR:$rz, (select CARRY:$ca, GPR:$false, 0))]>; + +def LSLI32 : I_5_XZ<0x12, 0x1, "lsli32", (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (shl GPR:$rx, uimm5:$imm5))]>; +def LSRI32 : I_5_XZ<0x12, 0x2, "lsri32", (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (srl GPR:$rx, uimm5:$imm5))]>; +def ASRI32 : I_5_XZ<0x12, 0x4, "asri32", (outs GPR:$rz), (ins GPR:$rx, uimm5:$imm5), + [(set GPR:$rz, (sra GPR:$rx, uimm5:$imm5))]>; + +def ZEXTB32 : I_5_XZ_UZ<0x15, 0, 7, "zext32", 255>; +def ZEXTH32 : I_5_XZ_UZ<0x15, 0, 15, "zext32", 65535>; +def SEXTB32 : I_5_XZ_US<0x16, 0, 7, "sext32", sext_inreg, i8>; +def SEXTH32 : I_5_XZ_US<0x16, 0, 15, "sext32", sext_inreg, i16>; +def SEXTBIT32 : I_5_XZ_US<0x16, 0, 0, "sext32", sext_inreg, i1>; + +let TwoOperandAliasConstraint = "$rz = $rx" in { + def ADDU32 : R_YXZ_SP_F1<0x0, 0x1, + BinOpFrag<(add node:$LHS, node:$RHS)>, "addu32", 1>; + def SUBU32 : R_YXZ_SP_F1<0x0, 0x4, + BinOpFrag<(sub node:$LHS, node:$RHS)>, "subu32">; + def AND32 : R_YXZ_SP_F1<0x8, 0x1, + BinOpFrag<(and node:$LHS, node:$RHS)>, "and32", 1>; + def ANDN32 : R_YXZ_SP_F1<0x8, 0x2, + BinOpFrag<(and node:$LHS, (not node:$RHS))>, "andn32">; + def OR32: R_YXZ_SP_F1<0x9, 0x1, + BinOpFrag<(or node:$LHS, node:$RHS)>, "or32", 1>; + def XOR32 : R_YXZ_SP_F1<0x9, 0x2, + BinOpFrag<(xor node:$LHS, node:$RHS)>, "xor32", 1>; + def NOR32 : R_YXZ_SP_F1<0x9, 0x4, + BinOpFrag<(not (or node:$LHS, node:$RHS))>, "nor32", 1>; + def LSL32 : R_YXZ_SP_F1<0x10, 0x1, + BinOpFrag<(shl node:$LHS, node:$RHS)>, "lsl32">; + def LSR32 : R_YXZ_SP_F1<0x10, 0x2, + BinOpFrag<(srl node:$LHS, node:$RHS)>, "lsr32">; + def ASR32 : R_YXZ_SP_F1<0x10, 0x4, + BinOpFrag<(sra node:$LHS, node:$RHS)>, "asr32">; + def MULT32 : R_YXZ_SP_F1<0x21, 0x1, + BinOpFrag<(mul node:$LHS, node:$RHS)>, "mult32", 1>; + def DIVS32 : R_YXZ_SP_F1<0x20, 0x2, + BinOpFrag<(sdiv node:$LHS, node:$RHS)>, "divs32">; + def DIVU32 : R_YXZ_SP_F1<0x20, 0x1, + BinOpFrag<(udiv node:$LHS, node:$RHS)>, "divu32">; +} + +def NOT32 : R_XXZ<0b001001, 0b00100, (outs GPR:$rz), (ins GPR:$rx), "not", + [(set GPR:$rz, (not GPR:$rx))]>; + +let Constraints = "$rd = $rz" in +def MULA32L : R_YXZ<0x3e, 0x21, 0x2, (outs GPR:$rd), (ins GPR:$rz, GPR:$rx, GPR:$ry), "mula.32.l", + [(set GPR:$rd, (add GPR:$rz, (mul GPR:$rx, GPR:$ry)))]>; + +def IXH32 : R_YXZ_SP_F1<0x2, 0x1, + BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 1)))>, "ixh32">; +def IXW32 : R_YXZ_SP_F1<0x2, 0x2, + BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 2)))>, "ixw32">; +def IXD32 : R_YXZ_SP_F1<0x2, 0x4, + BinOpFrag<(add node:$LHS, (shl node:$RHS, (i32 3)))>, "ixd32">; + +let DisableEncoding = "$cout,$cin" in { + let isCommutable = 1 in + def ADDC32 : R_YXZ<0x31, 0x0, 0x2, (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, GPR:$ry, CARRY:$cin), "addc32", []>; + + def SUBC32 : R_YXZ<0x31, 0x0, 0x8, (outs GPR:$rz, CARRY:$cout), (ins GPR:$rx, GPR:$ry, CARRY:$cin), "subc32", []>; +} + +let isCommutable = 1 in { + def MULU32 : R_YXZ<0x3E, 0x20, 0x0, (outs GPRPair:$rz), (ins GPR:$rx, GPR:$ry), "mul.u32", []>; + def MULS32 : R_YXZ<0x3E, 0x20, 0x10, (outs GPRPair:$rz), (ins GPR:$rx, GPR:$ry), "mul.s32", []>; +} + +def DIVF : R_YXZ<0x3E, 0x3C, 0x0, (outs GPRPair:$rz), (ins GPR:$rx, GPR:$ry), "divf", []>; + + +// SPILL_CR - Indicate that we're dumping the CR register, so we'll need to +// scavenge a register for it. +let mayStore = 1 in { +def SPILL_CARRY : CSKYPseudo<(outs), (ins CARRY:$cond, GPR:$rx, uimm12_2:$imm), + "!SPILL_CARRY $cond, $rx, $imm", []>; +} + +// RESTORE_CR - Indicate that we're restoring the CR register (previously +// spilled), so we'll need to scavenge a register for it. +let mayLoad = 1 in { +def RESTORE_CARRY : CSKYPseudo<(outs CARRY:$cond), (ins GPR:$rx, uimm12_2:$imm), + "!RESTORE_CARRY $cond, $rx, $imm", []>; +} + +// Load & Store +def LD32B : I_LD; +def LD32H : I_LD; +def LD32W : I_LD; +def LD32BS : I_LD; +def LD32HS : I_LD; +def ST32B : I_ST; +def ST32H : I_ST; +def ST32W : I_ST; + + +let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in +def LDM32_2 : I_5_YX<0b110100, (outs GPRPair:$ry), (ins GPR:$rx), "ldm32", [], 1>; +let mayStore = 1, hasExtraSrcRegAllocReq = 1 in +def STM32_2 : I_5_YX<0b110101, (outs), (ins GPRPair:$ry, GPR:$rx), "stm32", [], 1>; + +def LDEX32W : I_LD; +def : Pat<(int_csky_ldex_w GPR:$rs1), (LDEX32W GPR:$rs1, 0)>; + +let Constraints = "$rd = $rz" in +def STEX32W : I_LDST; +def : Pat<(int_csky_stex_w GPR:$rz, GPR:$rx), (STEX32W GPR:$rz, GPR:$rx, 0)>; + +def LDR32B0 : I_LDR<0x0, 0x01, "ldr32.b", 0>; +def LDR32B1 : I_LDR<0x0, 0x02, "ldr32.b", 1>; +def LDR32B2 : I_LDR<0x0, 0x04, "ldr32.b", 2>; +def LDR32B3 : I_LDR<0x0, 0x08, "ldr32.b", 3>; +def LDR32BS0 : I_LDR<0x4, 0x01, "ldr32.bs", 0>; +def LDR32BS1 : I_LDR<0x4, 0x02, "ldr32.bs", 1>; +def LDR32BS2 : I_LDR<0x4, 0x04, "ldr32.bs", 2>; +def LDR32BS3 : I_LDR<0x4, 0x08, "ldr32.bs", 3>; +def LDR32H0 : I_LDR<0x1, 0x01, "ldr32.h", 0>; +def LDR32H1 : I_LDR<0x1, 0x02, "ldr32.h", 1>; +def LDR32H2 : I_LDR<0x1, 0x04, "ldr32.h", 2>; +def LDR32H3 : I_LDR<0x1, 0x08, "ldr32.h", 3>; +def LDR32HS0 : I_LDR<0x5, 0x01, "ldr32.hs", 0>; +def LDR32HS1 : I_LDR<0x5, 0x02, "ldr32.hs", 1>; +def LDR32HS2 : I_LDR<0x5, 0x04, "ldr32.hs", 2>; +def LDR32HS3 : I_LDR<0x5, 0x08, "ldr32.hs", 3>; +def LDR32W0 : I_LDR<0x2, 0x01, "ldr32.w", 0>; +def LDR32W1 : I_LDR<0x2, 0x02, "ldr32.w", 1>; +def LDR32W2 : I_LDR<0x2, 0x04, "ldr32.w", 2>; +def LDR32W3 : I_LDR<0x2, 0x08, "ldr32.w", 3>; + +def STR32B0 : I_STR<0x0, 0x01, "str32.b", 0>; +def STR32B1 : I_STR<0x0, 0x02, "str32.b", 1>; +def STR32B2 : I_STR<0x0, 0x04, "str32.b", 2>; +def STR32B3 : I_STR<0x0, 0x08, "str32.b", 3>; +def STR32H0 : I_STR<0x1, 0x01, "str32.h", 0>; +def STR32H1 : I_STR<0x1, 0x02, "str32.h", 1>; +def STR32H2 : I_STR<0x1, 0x04, "str32.h", 2>; +def STR32H3 : I_STR<0x1, 0x08, "str32.h", 3>; +def STR32W0 : I_STR<0x2, 0x01, "str32.w", 0>; +def STR32W1 : I_STR<0x2, 0x02, "str32.w", 1>; +def STR32W2 : I_STR<0x2, 0x04, "str32.w", 2>; +def STR32W3 : I_STR<0x2, 0x08, "str32.w", 3>; + + + + +multiclass LdPat { + def : Pat<(Type (LoadOp GPR:$rs1)), (Inst GPR:$rs1, 0)>; + def : Pat<(Type (LoadOp AddrFI:$rs1)), (Inst GPR:$rs1, 0)>; + def : Pat<(Type (LoadOp (add GPR:$rs1, imm_type:$uimm))), + (Inst GPR:$rs1, imm_type:$uimm)>; + def : Pat<(Type (LoadOp (add AddrFI:$rs1, imm_type:$uimm))), + (Inst AddrFI:$rs1, imm_type:$uimm)>; + def : Pat<(Type (LoadOp (eqToAdd AddrFI:$rs1, imm_type:$uimm))), + (Inst AddrFI:$rs1, imm_type:$uimm)>; + def : Pat<(Type (LoadOp (add GPR:$rs1, tglobaladdr:$gd))), + (Inst GPR:$rs1, tglobaladdr:$gd)>; +} + +multiclass LdrPat { + def : Pat<(Type (LoadOp (add GPR:$rs1, GPR:$rs2))), (!cast(Inst # "0") GPR:$rs1, GPR:$rs2)>; + def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 1))))), (!cast(Inst # "1") GPR:$rs1, GPR:$rs2)>; + def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 2))))), (!cast(Inst # "2") GPR:$rs1, GPR:$rs2)>; + def : Pat<(Type (LoadOp (add GPR:$rs1, (shl GPR:$rs2, (i32 3))))), (!cast(Inst # "3") GPR:$rs1, GPR:$rs2)>; +} + +defm : LdPat; +defm : LdPat; +defm : LdPat; +defm : LdPat; +defm : LdPat; +defm : LdPat; +defm : LdPat; +defm : LdrPat; +defm : LdrPat; +defm : LdrPat; +defm : LdrPat; +defm : LdrPat; +defm : LdrPat; +defm : LdrPat; + + +multiclass StPat { + def : Pat<(StoreOp Type:$rs2, GPR:$rs1), (Inst Type:$rs2, GPR:$rs1, 0)>; + def : Pat<(StoreOp Type:$rs2, AddrFI:$rs1), (Inst Type:$rs2, AddrFI:$rs1, 0)>; + def : Pat<(StoreOp Type:$rs2, (add GPR:$rs1, imm_type:$uimm12)), + (Inst Type:$rs2, GPR:$rs1, imm_type:$uimm12)>; + def : Pat<(StoreOp Type:$rs2, (add AddrFI:$rs1, imm_type:$uimm12)), + (Inst Type:$rs2, AddrFI:$rs1, imm_type:$uimm12)>; + def : Pat<(StoreOp Type:$rs2, (eqToAdd AddrFI:$rs1, imm_type:$uimm12)), + (Inst Type:$rs2, AddrFI:$rs1, imm_type:$uimm12)>; +} + +multiclass StrPat { + def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, GPR:$rs2)), (!cast(Inst # "0") Type:$rz, GPR:$rs1, GPR:$rs2)>; + def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 1)))), (!cast(Inst # "1") Type:$rz, GPR:$rs1, GPR:$rs2)>; + def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 2)))), (!cast(Inst # "2") Type:$rz, GPR:$rs1, GPR:$rs2)>; + def : Pat<(StoreOp Type:$rz, (add GPR:$rs1, (shl GPR:$rs2, (i32 3)))), (!cast(Inst # "3") Type:$rz, GPR:$rs1, GPR:$rs2)>; +} + +defm : StPat; +defm : StPat; +defm : StPat; +defm : StrPat; +defm : StrPat; +defm : StrPat; + +def : Pat<(i32 imm:$imm), (ORI32 (MOVIH32 uimm16_16:$imm), uimm16:$imm)>; + +def : Pat<(i32 tglobaladdr:$dst), + (ORI32 (MOVIH32 (imm16_sr16_XFORM tglobaladdr:$dst)), (imm16_sr0_XFORM tglobaladdr:$dst))>; +def : Pat<(i32 tconstpool:$dst), + (ORI32 (MOVIH32 (imm16_sr16_XFORM tconstpool:$dst)), (imm16_sr0_XFORM tconstpool:$dst))>; +def : Pat<(frameindex:$fi), + (ADDI32 (frameindex_to_targetframeindex tframeindex:$fi), 0)>; + +def : Pat<(load tconstpool:$dst), + (LRW32 tconstpool:$dst)>; +def : Pat<(load tjumptable:$dst), + (GRS32 tjumptable:$dst)>; + +let Defs = [GP], hasSideEffects = 0 in + def GETGOT32 : CSKYPseudo<(outs GPR:$rz), (ins), "!GETGOT32", []>; + +def LRWJT32 : CSKYPseudo<(outs GPR:$rz), (ins uimm18_1:$label1, uimm18_1:$label2), "!LRWJT32", []>; +def : Pat<(CSKY_JT_CP_WRAP tjumptable:$dst0, tconstpool:$dst1), (LRWJT32 tjumptable:$dst0, tconstpool:$dst1)>; + +def : Pat<(add i32:$rs, neg_oimm12:$imm), (SUBI32 GPR:$rs, (neg_imm imm:$imm))>; + + +def : Pat<(CSKY_CALL tglobaladdr:$func), (BSR32 tglobaladdr:$func)>; +def : Pat<(CSKY_CALL texternalsym:$func), (BSR32 texternalsym:$func)>; +def : Pat<(CSKY_CALL (load tconstpool:$func)), (JSRI32 tconstpool:$func)>; +def : Pat<(CSKY_JMP tglobaladdr:$func), (BR32 tglobaladdr:$func)>; +def : Pat<(CSKY_JMP texternalsym:$func), (BR32 texternalsym:$func)>; +def : Pat<(CSKY_JMP GPR:$rx), (JMP32 GPR:$rx)>; + +// ------- +def : Pat<(brcond CARRY:$ca, bb:$imm16), + (BT32 CARRY:$ca, bb:$imm16)>; + +def : Pat<(brcond (i32 (setne GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BT32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setne GPR:$rs1, uimm16:$rs2)), bb:$imm16), + (BT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (seteq GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BF32 (CMPNE32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (seteq GPR:$rs1, uimm16:$rs2)), bb:$imm16), + (BF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setuge GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BT32 (CMPHS32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setuge GPR:$rs1, uimm16:$rs2)), bb:$imm16), + (BT32 (CMPHSI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setule GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BT32 (CMPHS32 GPR:$rs2, GPR:$rs1), bb:$imm16)>; +def : Pat<(brcond (i32 (setult GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BF32 (CMPHS32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setult GPR:$rs1, uimm16:$rs2)), bb:$imm16), + (BF32 (CMPHSI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setugt GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BF32 (CMPHS32 GPR:$rs2, GPR:$rs1), bb:$imm16)>; +def : Pat<(brcond (i32 (setlt GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BT32 (CMPLT32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setlt GPR:$rs1, uimm16:$rs2)), bb:$imm16), + (BT32 (CMPLTI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setgt GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BT32 (CMPLT32 GPR:$rs2, GPR:$rs1), bb:$imm16)>; +def : Pat<(brcond (i32 (setge GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BF32 (CMPLT32 GPR:$rs1, GPR:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setge GPR:$rs1, uimm16:$rs2)), bb:$imm16), + (BF32 (CMPLTI32 GPR:$rs1, uimm16:$rs2), bb:$imm16)>; +def : Pat<(brcond (i32 (setle GPR:$rs1, GPR:$rs2)), bb:$imm16), + (BF32 (CMPLT32 GPR:$rs2, GPR:$rs1), bb:$imm16)>; + +// ------- +def : Pat<(brcond (i32 (seteq GPR:$rs1, (i32 0))), bb:$imm16), + (BEZ32 GPR:$rs1, bb:$imm16)>; +def : Pat<(brcond (i32 (setne GPR:$rs1, (i32 0))), bb:$imm16), + (BNEZ32 GPR:$rs1, bb:$imm16)>; +def : Pat<(brcond (i32 (setlt GPR:$rs1, (i32 0))), bb:$imm16), + (BLZ32 GPR:$rs1, bb:$imm16)>; +def : Pat<(brcond (i32 (setge GPR:$rs1, (i32 0))), bb:$imm16), + (BHSZ32 GPR:$rs1, bb:$imm16)>; +def : Pat<(brcond (i32 (setgt GPR:$rs1, (i32 0))), bb:$imm16), + (BHZ32 GPR:$rs1, bb:$imm16)>; +def : Pat<(brcond (i32 (setle GPR:$rs1, (i32 0))), bb:$imm16), + (BLSZ32 GPR:$rs1, bb:$imm16)>; + +// ------- + +def : Pat<(setne GPR:$rs1, GPR:$rs2), + (MVC32 (CMPNE32 GPR:$rs1, GPR:$rs2))>; +def : Pat<(setne GPR:$rs1, uimm16:$rs2), + (MVC32 (CMPNEI32 GPR:$rs1, uimm16:$rs2))>; +def : Pat<(seteq GPR:$rs1, GPR:$rs2), + (MVCV32 (CMPNE32 GPR:$rs1, GPR:$rs2))>; +def : Pat<(seteq GPR:$rs1, uimm16:$rs2), + (MVCV32 (CMPNEI32 GPR:$rs1, uimm16:$rs2))>; +def : Pat<(setuge GPR:$rs1, GPR:$rs2), + (MVC32 (CMPHS32 GPR:$rs1, GPR:$rs2))>; +def : Pat<(setuge GPR:$rs1, uimm16:$rs2), + (MVC32 (CMPHSI32 GPR:$rs1, uimm16:$rs2))>; +def : Pat<(setule GPR:$rs1, GPR:$rs2), + (MVC32 (CMPHS32 GPR:$rs2, GPR:$rs1))>; +def : Pat<(setult GPR:$rs1, GPR:$rs2), + (MVCV32 (CMPHS32 GPR:$rs1, GPR:$rs2))>; +def : Pat<(setult GPR:$rs1, uimm16:$rs2), + (MVCV32 (CMPHSI32 GPR:$rs1, uimm16:$rs2))>; +def : Pat<(setugt GPR:$rs1, GPR:$rs2), + (MVCV32 (CMPHS32 GPR:$rs2, GPR:$rs1))>; +def : Pat<(setlt GPR:$rs1, GPR:$rs2), + (MVC32 (CMPLT32 GPR:$rs1, GPR:$rs2))>; +def : Pat<(setlt GPR:$rs1, uimm16:$rs2), + (MVC32 (CMPLTI32 GPR:$rs1, uimm16:$rs2))>; +def : Pat<(setgt GPR:$rs1, GPR:$rs2), + (MVC32 (CMPLT32 GPR:$rs2, GPR:$rs1))>; +def : Pat<(setge GPR:$rs1, GPR:$rs2), + (MVCV32 (CMPLT32 GPR:$rs1, GPR:$rs2))>; +def : Pat<(setge GPR:$rs1, uimm16:$rs2), + (MVCV32 (CMPLTI32 GPR:$rs1, uimm16:$rs2))>; +def : Pat<(setle GPR:$rs1, GPR:$rs2), + (MVCV32 (CMPLT32 GPR:$rs2, GPR:$rs1))>; + +// ------- +def : Pat<(select CARRY:$ca, GPR:$rx, GPR:$false), + (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>; +def : Pat<(select (and CARRY:$ca, 1), GPR:$rx, GPR:$false), + (MOVT32 CARRY:$ca, GPR:$rx, GPR:$false)>; + +def : Pat<(select (i32 (setne GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setne GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (seteq GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPNE32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (seteq GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPNEI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>; + +def : Pat<(select (i32 (setuge GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPHS32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setuge GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPHSI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setule GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPHS32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setult GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPHS32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setult GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPHSI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setugt GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPHS32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>; + +def : Pat<(select (i32 (setlt GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPLT32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setlt GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPLTI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setgt GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVT32 (CMPLT32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setge GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPLT32 GPR:$rs1, GPR:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setge GPR:$rs1, uimm16:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPLTI32 GPR:$rs1, uimm16:$rs2), GPR:$rx, GPR:$false)>; +def : Pat<(select (i32 (setle GPR:$rs1, GPR:$rs2)), GPR:$rx, GPR:$false), + (MOVF32 (CMPLT32 GPR:$rs2, GPR:$rs1), GPR:$rx, GPR:$false)>; + + +include "CSKYInstrInfoF1.td" +include "CSKYInstrInfoF2.td" Index: llvm/lib/Target/CSKY/CSKYInstrInfoF1.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrInfoF1.td @@ -0,0 +1,295 @@ +//===- CSKYInstrInfoF1.td - CSKY Instruction Float1.0 ------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the CSKY instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + + +include "CSKYInstrFormatsF1.td" + +def bitcast_fpimm_to_i32l16 : SDNodeXFormgetTargetConstant( + N->getValueAPF().bitcastToAPInt().getZExtValue() & 0xFFFFUL, + SDLoc(N), MVT::i32); +}]>; + +def bitcast_fpimm_to_i32h16 : SDNodeXFormgetTargetConstant( + N->getValueAPF().bitcastToAPInt().getZExtValue() & 0xFFFF0000UL, + SDLoc(N), MVT::i32); +}]>; + +def bitcast_fpimm_to_i64_hi32l16 : SDNodeXFormgetTargetConstant( + (N->getValueAPF().bitcastToAPInt().getZExtValue() >> 32) & 0xFFFFUL, + SDLoc(N), MVT::i32); +}]>; + +def bitcast_fpimm_to_i64_hi32h16 : SDNodeXFormgetTargetConstant( + (N->getValueAPF().bitcastToAPInt().getZExtValue() >> 32) & 0xFFFF0000UL, + SDLoc(N), MVT::i32); +}]>; + +def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>; + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +//arithmetic + +defm FABS : FT_XZ<0b000110, "fabs", UnOpFrag<(fabs node:$Src)>>; +defm FNEG : FT_XZ<0b000111, "fneg", UnOpFrag<(fneg node:$Src)>>; +defm FSQRT : FT_XZ<0b011010, "fsqrt", UnOpFrag<(fsqrt node:$Src)>>; + +defm FADD : FT_XYZ<0b000000, "fadd", BinOpFrag<(fadd node:$LHS, node:$RHS)>>; +defm FSUB : FT_XYZ<0b000001, "fsub", BinOpFrag<(fsub node:$LHS, node:$RHS)>>; +defm FDIV : FT_XYZ<0b011000, "fdiv", BinOpFrag<(fdiv node:$LHS, node:$RHS)>>; +defm FMUL : FT_XYZ<0b010000, "fmul", BinOpFrag<(fmul node:$LHS, node:$RHS)>>; +defm FNMUL : FT_XYZ<0b010001, "fnmul", BinOpFrag<(fneg (fmul node:$LHS, node:$RHS))>>; +defm FMAC : FT_ACCUM_XYZ<0b010100, "fmac", TriOpFrag<(fadd node:$LHS, (fmul node:$MHS, node:$RHS))>>; +defm FMSC : FT_ACCUM_XYZ<0b010101, "fmsc", TriOpFrag<(fsub (fmul node:$MHS, node:$RHS), node:$LHS)>>; +defm FNMAC : FT_ACCUM_XYZ<0b010110, "fnmac", TriOpFrag<(fsub node:$LHS, (fmul node:$MHS, node:$RHS))>>; +defm FNMSC : FT_ACCUM_XYZ<0b010111, "fnmsc", TriOpFrag<(fneg (fadd node:$LHS, (fmul node:$MHS, node:$RHS)))>>; + +defm FCMPHS : FT_CMPXY<0b001100, "fcmphs">; +defm FCMPLT : FT_CMPXY<0b001101, "fcmplt">; +defm FCMPNE : FT_CMPXY<0b001110, "fcmpne">; +defm FCMPUO : FT_CMPXY<0b001111, "fcmpuo">; +defm FCMPZHS : FT_CMPZX<0b001000, "fcmpzhs">; +defm FCMPZLS : FT_CMPZX<0b001001, "fcmpzls">; +defm FCMPZNE : FT_CMPZX<0b001010, "fcmpzne">; +defm FCMPZUO : FT_CMPZX<0b001011, "fcmpzuo">; + +//fmov, fmtvr, fmfvr +defm FMOV : FT_MOV<0b000100, "fmov">; +def FMFVRL : F_XZ_GF<3, 0b011001, (outs GPR:$rz), (ins sFPR32:$vrx), + "fmfvrl\t$rz, $vrx", [(set GPR:$rz, (bitconvert sFPR32:$vrx))]>; +def FMTVRL : F_XZ_FG<3, 0b011011, (outs sFPR32:$vrz), (ins GPR:$rx), + "fmtvrl\t$vrz, $rx", [(set sFPR32:$vrz, (bitconvert GPR:$rx))]>; + +let Predicates = [HasFPUv2_DF] in { + def FMFVRL_D : F_XZ_GF<3, 0b011001, (outs GPR:$rz), (ins sFPR64:$vrx), + "fmfvrl\t$rz, $vrx", []>; + def FMFVRH_D : F_XZ_GF<3, 0b011000, (outs GPR:$rz), (ins sFPR64:$vrx), + "fmfvrh\t$rz, $vrx", []>; + def FMTVRL_D : F_XZ_FG<3, 0b011011, (outs sFPR64:$vrz), (ins GPR:$rx), + "fmtvrl\t$vrz, $rx", []>; +let Constraints = "$vrZ = $vrz" in + def FMTVRH_D : F_XZ_FG<3, 0b011010, (outs sFPR64:$vrz), (ins sFPR64:$vrZ, GPR:$rx), + "fmtvrh\t$vrz, $rx", []>; +} + +//fcvt + +def FSITOS : F_XZ_TRANS<0b010000, "fsitos", sFPR32, sFPR32>; +def : Pat<(f32 (sint_to_fp GPR:$a)), + (FSITOS (COPY_TO_REGCLASS GPR:$a, sFPR32))>, + Requires<[HasFPUv2_SF]>; + +def FUITOS : F_XZ_TRANS<0b010001, "fuitos", sFPR32, sFPR32>; +def : Pat<(f32 (uint_to_fp GPR:$a)), + (FUITOS (COPY_TO_REGCLASS GPR:$a, sFPR32))>, + Requires<[HasFPUv2_SF]>; + +def FSITOD : F_XZ_TRANS<0b010100, "fsitod", sFPR64, sFPR64>; +def : Pat<(f64 (sint_to_fp GPR:$a)), + (FSITOD (COPY_TO_REGCLASS GPR:$a, sFPR64))>, + Requires<[HasFPUv2_DF]>; + +def FUITOD : F_XZ_TRANS<0b010101, "fuitod", sFPR64, sFPR64>; +def : Pat<(f64 (uint_to_fp GPR:$a)), + (FUITOD (COPY_TO_REGCLASS GPR:$a, sFPR64))>, + Requires<[HasFPUv2_DF]>; + +let Predicates = [HasFPUv2_DF] in { +def FDTOS : F_XZ_TRANS_DS<0b010110,"fdtos", UnOpFrag<(fpround node:$Src)>>; +def FSTOD : F_XZ_TRANS_SD<0b010111,"fstod", UnOpFrag<(fpextend node:$Src)>>; +} + +def rpiFSTOSI : F_XZ_TRANS<0b000010, "fstosi.rpi", sFPR32, sFPR32>; +def rpiFSTOUI : F_XZ_TRANS<0b000110, "fstoui.rpi", sFPR32, sFPR32>; +def rzFSTOSI : F_XZ_TRANS<0b000001, "fstosi.rz", sFPR32, sFPR32>; +def rzFSTOUI : F_XZ_TRANS<0b000101, "fstoui.rz", sFPR32, sFPR32>; +def rnFSTOSI : F_XZ_TRANS<0b000000, "fstosi.rn", sFPR32, sFPR32>; +def rnFSTOUI : F_XZ_TRANS<0b000100, "fstoui.rn", sFPR32, sFPR32>; +def rniFSTOSI : F_XZ_TRANS<0b000011, "fstosi.rni", sFPR32, sFPR32>; +def rniFSTOUI : F_XZ_TRANS<0b000111, "fstoui.rni", sFPR32, sFPR32>; + +let Predicates = [HasFPUv2_DF] in { +def rpiFDTOSI : F_XZ_TRANS<0b001010, "fdtosi.rpi", sFPR64, sFPR64>; +def rpiFDTOUI : F_XZ_TRANS<0b001110, "fdtoui.rpi", sFPR64, sFPR64>; +def rzFDTOSI : F_XZ_TRANS<0b001001, "fdtosi.rz", sFPR64, sFPR64>; +def rzFDTOUI : F_XZ_TRANS<0b001101, "fdtoui.rz", sFPR64, sFPR64>; +def rnFDTOSI : F_XZ_TRANS<0b001000, "fdtosi.rn", sFPR64, sFPR64>; +def rnFDTOUI : F_XZ_TRANS<0b001100, "fdtoui.rn", sFPR64, sFPR64>; +def rniFDTOSI : F_XZ_TRANS<0b001011, "fdtosi.rni", sFPR64, sFPR64>; +def rniFDTOUI : F_XZ_TRANS<0b001111, "fdtoui.rni", sFPR64, sFPR64>; +} + +multiclass FPToIntegerPats { + def : Pat<(i32 (fp_to_sint (round sFPR32:$Rn))), + (COPY_TO_REGCLASS (!cast(SUFFIX # FSTOSI) sFPR32:$Rn), GPR)>, + Requires<[HasFPUv2_SF]>; + def : Pat<(i32 (fp_to_uint (round sFPR32:$Rn))), + (COPY_TO_REGCLASS (!cast(SUFFIX # FSTOUI) sFPR32:$Rn), GPR)>, + Requires<[HasFPUv2_SF]>; + def : Pat<(i32 (fp_to_sint (round sFPR64:$Rn))), + (COPY_TO_REGCLASS (!cast(SUFFIX # FDTOSI) sFPR64:$Rn), GPR)>, + Requires<[HasFPUv2_DF]>; + def : Pat<(i32 (fp_to_uint (round sFPR64:$Rn))), + (COPY_TO_REGCLASS (!cast(SUFFIX # FDTOUI) sFPR64:$Rn), GPR)>, + Requires<[HasFPUv2_DF]>; +} + +defm: FPToIntegerPats; +defm: FPToIntegerPats; +defm: FPToIntegerPats; + +multiclass FPToIntegerTowardszeroPats { + def : Pat<(i32 (fp_to_sint sFPR32:$Rn)), + (COPY_TO_REGCLASS (!cast(SUFFIX # FSTOSI) sFPR32:$Rn), GPR)>, + Requires<[HasFPUv2_SF]>; + def : Pat<(i32 (fp_to_uint sFPR32:$Rn)), + (COPY_TO_REGCLASS (!cast(SUFFIX # FSTOUI) sFPR32:$Rn), GPR)>, + Requires<[HasFPUv2_SF]>; + def : Pat<(i32 (fp_to_sint sFPR64:$Rn)), + (COPY_TO_REGCLASS (!cast(SUFFIX # FDTOSI) sFPR64:$Rn), GPR)>, + Requires<[HasFPUv2_DF]>; + def : Pat<(i32 (fp_to_uint sFPR64:$Rn)), + (COPY_TO_REGCLASS (!cast(SUFFIX # FDTOUI) sFPR64:$Rn), GPR)>, + Requires<[HasFPUv2_DF]>; +} + +defm: FPToIntegerTowardszeroPats<"rz">; + +//fld, fst +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { + defm FLD : FT_XYAI_LD<0b0010000, "fld">; + defm FLDR : FT_XYAR_LD<0b0010100, "fldr", 0>; + defm FLDR : FT_XYAR_LD<0b0010100, "fldr", 1>; + defm FLDR : FT_XYAR_LD<0b0010100, "fldr", 2>; + defm FLDR : FT_XYAR_LD<0b0010100, "fldr", 3>; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { + defm FST : FT_XYAI_ST<0b0010010, "fst">; + defm FSTR : FT_XYAR_ST<0b0010110, "fstr", 0>; + defm FSTR : FT_XYAR_ST<0b0010110, "fstr", 1>; + defm FSTR : FT_XYAR_ST<0b0010110, "fstr", 2>; + defm FSTR : FT_XYAR_ST<0b0010110, "fstr", 3>; +} + + +defm : LdPat, Requires<[HasFPUv2_SF]>; +defm : LdPat, Requires<[HasFPUv2_DF]>; +defm : LdrPat, Requires<[HasFPUv2_SF]>; +defm : LdrPat, Requires<[HasFPUv2_DF]>; + +defm : StPat, Requires<[HasFPUv2_SF]>; +defm : StPat, Requires<[HasFPUv2_DF]>; +defm : StrPat, Requires<[HasFPUv2_SF]>; +defm : StrPat, Requires<[HasFPUv2_DF]>; + + +def : Pat<(f32 fpimm:$imm),(COPY_TO_REGCLASS (ORI32 (MOVIH32 (fpimm16_sr16_XFORM fpimm:$imm)), (fpimm16_sr0_XFORM fpimm:$imm)),sFPR32)>, + Requires<[HasFPUv2_SF]>; +def : Pat<(f32 fpimm16_16:$imm),(COPY_TO_REGCLASS (MOVIH32 (fpimm16_sr16_XFORM fpimm16_16:$imm)), sFPR32)>, + Requires<[HasFPUv2_SF]>; +def : Pat<(f32 fpimm16:$imm),(COPY_TO_REGCLASS (MOVI32 (fpimm16_sr0_XFORM fpimm16:$imm)), sFPR32)>, + Requires<[HasFPUv2_SF]>; + +def : Pat<(f64(CSKY_BITCAST_FROM_LOHI GPR:$rs1, GPR:$rs2)), (FMTVRH_D(FMTVRL_D GPR:$rs1), GPR:$rs2)>, + Requires<[HasFPUv2_DF]>; + + +multiclass BRCond_Bin { + let Predicates = [HasFPUv2_SF] in + def : Pat<(brcond (i32 (setcc sFPR32:$rs1, sFPR32:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_S) sFPR32:$rs1, sFPR32:$rs2), bb:$imm16)>; + let Predicates = [HasFPUv2_DF] in + def : Pat<(brcond (i32 (setcc sFPR64:$rs1, sFPR64:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_D) sFPR64:$rs1, sFPR64:$rs2), bb:$imm16)>; + + let Predicates = [HasFPUv2_SF] in + def : Pat<(i32 (setcc sFPR32:$rs1, sFPR32:$rs2, CC)), + (MV (!cast(Instr#_S) sFPR32:$rs1, sFPR32:$rs2))>; + let Predicates = [HasFPUv2_DF] in + def : Pat<(i32 (setcc sFPR64:$rs1, sFPR64:$rs2, CC)), + (MV (!cast(Instr#_D) sFPR64:$rs1, sFPR64:$rs2))>; +} + +multiclass BRCond_Bin_SWAP { + let Predicates = [HasFPUv2_SF] in + def : Pat<(brcond (i32 (setcc sFPR32:$rs1, sFPR32:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_S) sFPR32:$rs2, sFPR32:$rs1), bb:$imm16)>; + let Predicates = [HasFPUv2_DF] in + def : Pat<(brcond (i32 (setcc sFPR64:$rs1, sFPR64:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_D) sFPR64:$rs2, sFPR64:$rs1), bb:$imm16)>; + + let Predicates = [HasFPUv2_SF] in + def : Pat<(i32 (setcc sFPR32:$rs1, sFPR32:$rs2, CC)), + (MV (!cast(Instr#_S) sFPR32:$rs2, sFPR32:$rs1))>; + let Predicates = [HasFPUv2_DF] in + def : Pat<(i32 (setcc sFPR64:$rs1, sFPR64:$rs2, CC)), + (MV (!cast(Instr#_D) sFPR64:$rs2, sFPR64:$rs1))>; +} + +multiclass BRCond_Un { + let Predicates = [HasFPUv2_SF] in + def : Pat<(brcond (i32 (setcc sFPR32:$rs1, FConstant, CC)), bb:$imm16), + (Br (!cast(Instr#_S) sFPR32:$rs1), bb:$imm16)>; + let Predicates = [HasFPUv2_DF] in + def : Pat<(brcond (i32 (setcc sFPR64:$rs1, (CSKY_BITCAST_FROM_LOHI IConstant, IConstant), CC)), bb:$imm16), + (Br (!cast(Instr#_D) sFPR64:$rs1), bb:$imm16)>; + + let Predicates = [HasFPUv2_SF] in + def : Pat<(i32 (setcc sFPR32:$rs1, FConstant, CC)), + (MV (!cast(Instr#_S) sFPR32:$rs1))>; + let Predicates = [HasFPUv2_DF] in + def : Pat<(i32 (setcc sFPR64:$rs1, (CSKY_BITCAST_FROM_LOHI IConstant, IConstant), CC)), + (MV (!cast(Instr#_D) sFPR64:$rs1))>; +} + +// inverse (order && compare) to (unorder || inverse(compare)) + +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin_SWAP; +defm : BRCond_Bin_SWAP; + +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin; +defm : BRCond_Bin_SWAP; +defm : BRCond_Bin_SWAP; + +// ----------- + +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; + +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; +defm : BRCond_Un; \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYInstrInfoF2.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYInstrInfoF2.td @@ -0,0 +1,361 @@ +//===- CSKYInstrInfoF2.td - CSKY Instruction Float2.0 ------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the CSKY instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + + +include "CSKYInstrFormatsF2.td" + +// Predicates +def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{ + return isOrEquivalentToAdd(N); +}]>; + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +defm f2FADD : F2_XYZ_T<0b000000, "fadd", BinOpFrag<(fadd node:$LHS, node:$RHS)>>; +defm f2FSUB : F2_XYZ_T<0b000001, "fsub", BinOpFrag<(fsub node:$LHS, node:$RHS)>>; +defm f2FDIV : F2_XYZ_T<0b011000, "fdiv", BinOpFrag<(fdiv node:$LHS, node:$RHS)>>; +defm f2FMUL : F2_XYZ_T<0b010000, "fmul", BinOpFrag<(fmul node:$LHS, node:$RHS)>>; + +defm f2FMAXNM : F2_XYZ_T<0b101000, "fmaxnm", BinOpFrag<(fmaxnum node:$LHS, node:$RHS)>>; +defm f2FMINNM : F2_XYZ_T<0b101001, "fminnm", BinOpFrag<(fminnum node:$LHS, node:$RHS)>>; + +defm f2FABS : F2_XZ_T<0b000110, "fabs", fabs>; +defm f2FNEG : F2_XZ_T<0b000111, "fneg", fneg>; +defm f2FSQRT : F2_XZ_T<0b011010, "fsqrt", fsqrt>; +defm f2FMOV : F2_XZ_SET_T<0b000100, "fmov">; + +// fld/fst +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { + def f2FLD_S : F2_LDST_S<0b0, "fld", (outs FPR32:$vrz), (ins GPR:$rx, uimm8_2:$imm8)>; + let Predicates = [HasFPUv3_DF] in + def f2FLD_D : F2_LDST_D<0b0, "fld", (outs FPR64:$vrz), (ins GPR:$rx, uimm8_2:$imm8)>; +} +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { + def f2FST_S : F2_LDST_S<0b1, "fst", (outs), (ins FPR32:$vrz, GPR:$rx, uimm8_2:$imm8)>; + let Predicates = [HasFPUv3_DF] in + def f2FST_D : F2_LDST_D<0b1, "fst", (outs), (ins FPR64:$vrz, GPR:$rx, uimm8_2:$imm8)>; +} + +multiclass FLSR shift> { + let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { + def FLDR_S#!cast(shift) : F2_LDSTR_S<0b0, "fldr", (outs FPR32:$rz), (ins GPR:$rx, GPR:$ry), shift>; + let Predicates = [HasFPUv3_DF] in + def FLDR_D#!cast(shift) : F2_LDSTR_D<0b0, "fldr", (outs FPR64:$rz), (ins GPR:$rx, GPR:$ry), shift>; + } + let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { + def FSTR_S#!cast(shift) : F2_LDSTR_S<0b1, "fstr", (outs), (ins FPR32:$rz, GPR:$rx, GPR:$ry), shift>; + let Predicates = [HasFPUv3_DF] in + def FSTR_D#!cast(shift) : F2_LDSTR_D<0b1, "fstr", (outs), (ins FPR64:$rz, GPR:$rx, GPR:$ry), shift>; + } +} + +defm f2: FLSR<0>; +defm f2: FLSR<1>; +defm f2: FLSR<2>; +defm f2: FLSR<3>; + + +defm : LdPat, Requires<[HasFPUv3_SF]>; +defm : LdPat, Requires<[HasFPUv3_DF]>; +defm : LdrPat, Requires<[HasFPUv3_SF]>; +defm : LdrPat, Requires<[HasFPUv3_DF]>; + +defm : StPat, Requires<[HasFPUv3_SF]>; +defm : StPat, Requires<[HasFPUv3_DF]>; +defm : StrPat, Requires<[HasFPUv3_SF]>; +defm : StrPat, Requires<[HasFPUv3_DF]>; + +// fmfvr +let vry = 0 in +def f2FMFVRL : F2_XYZ<0b00011, 0b011001, "fmfvr.32.1\t$vrz, $vrx", + (outs GPR:$vrz), (ins FPR32:$vrx), + [(set GPR:$vrz, (bitconvert FPR32:$vrx))]>; +// TODO: vrz and vrz+1 +def f2FMFVRL_2 : F2_XYZ<0b00011, 0b011010, "fmfvr.32.2\t$vrz, $vry, $vrx", + (outs GPR:$vrz, GPR:$vry), (ins FPR64:$vrx), + []>; + +let vry = 0 in +def f2FMFVR_HF : F2_XYZ<0b00011, 0b111001, "fmfvr.16\t$vrz, $vrx", + (outs GPR:$vrz), (ins FPR32:$vrx), + []>; + +let Predicates = [HasFPUv3_DF] in { +let vry = 0 in { +def f2FMFVRL_D : F2_XYZ<0b00011, 0b011001, "fmfvr.32.1\t$vrz, $vrx", + (outs GPR:$vrz), (ins FPR64:$vrx), + []>; +def f2FMFVRH_D : F2_XYZ<0b00011, 0b011000, "fmfvrh\t$vrz, $vrx", + (outs GPR:$vrz), (ins FPR64:$vrx), + []>; +} +def f2FMFVR_D : F2_XYZ<0b00011, 0b111000, "fmfvr.64\t$vrz, $rx, $ry", + (outs GPR:$rx, GPR:$ry), (ins FPR64:$vrz), + [(set GPR:$rx, GPR:$ry, (CSKY_BITCAST_TO_LOHI FPR64:$vrz))]>; +} + +// fmtvr +def f2FMTVRL : F2_XZ_P<0b00011, 0b011011, "fmtvr.32.1", + [(set FPR32:$vrz, (bitconvert GPR:$vrx))], + (outs FPR32:$vrz), (ins GPR:$vrx)>; +// TODO: vrz and vrz+1 +def f2FMTVRL_2 : F2_XYZ<0b00011, 0b011110, "fmtvr.32.2\t$vrz, $vrx, $vry", + (outs FPR32:$vrz), (ins GPR:$vrx, GPR:$vry), + []>; + +def f2FMTVR_HF : F2_XYZ<0b00011, 0b111101, "fmtvr.16\t$vrz, $vrx", + (outs FPR32:$vrz), (ins GPR:$vrx), + []>; + +let Predicates = [HasFPUv3_DF] in { +def f2FMTVRL_D : F2_XZ_P<0b00011, 0b011011, "fmtvr.32.1", + [], + (outs FPR64:$vrz), (ins GPR:$vrx)>; +let Constraints = "$vrZ = $vrz" in +def f2FMTVRH_D : F2_XZ_P<0b00011, 0b011010, "fmtvrh", + [], + (outs FPR64:$vrz), (ins FPR64:$vrZ, GPR:$vrx)>; +def f2FMTVR_D : F2_XYZ<0b00011, 0b111100, "fmtvr.64\t$vrz, $rx, $ry", + (outs FPR64:$vrz), (ins GPR:$rx, GPR:$ry), + [(set FPR64:$vrz, (CSKY_BITCAST_FROM_LOHI GPR:$rx, GPR:$ry))]>; +} + +// fcmp + +defm f2FCMPHS: F2_CXY_T<0b001100, "fcmphs">; +defm f2FCMPLT: F2_CXY_T<0b001101, "fcmplt">; +defm f2FCMPNE: F2_CXY_T<0b001110, "fcmpne">; +defm f2FCMPUO: F2_CXY_T<0b001111, "fcmpuo">; + +defm f2FCMPHSZ: F2_CX_T<0b001000, "fcmphsz">; +defm f2FCMPHZ : F2_CX_T<0b101010, "fcmphz">; +defm f2FCMPLSZ: F2_CX_T<0b101011, "fcmplsz">; +defm f2FCMPLTZ: F2_CX_T<0b001001, "fcmpltz">; +defm f2FCMPNEZ: F2_CX_T<0b001010, "fcmpnez">; +defm f2FCMPUOZ: F2_CX_T<0b001011, "fcmpuoz">; + +// fcvt +def f2FFTOS32_S : F2_XZ_P<0b01000, 0b011011, "fftoi.f32.s32", [], (outs FPR32:$vrz), (ins FPR32:$vrx)>; +def f2FFTOU32_S : F2_XZ_P<0b01000, 0b011010, "fftoi.f32.u32", [], (outs FPR32:$vrz), (ins FPR32:$vrx)>; +def f2FS32TOF_S : F2_XZ_P<0b01001, 0b011011, "fitof.s32.f32", [], (outs FPR32:$vrz), (ins FPR32:$vrx)>; +def f2FU32TOF_S : F2_XZ_P<0b01001, 0b011010, "fitof.u32.f32", [], (outs FPR32:$vrz), (ins FPR32:$vrx)>; +let Predicates = [HasFPUv3_DF] in { +def f2FFTOS32_D : F2_XZ_P<0b01000, 0b011101, "fftoi.f64.s32", [], (outs FPR32:$vrz), (ins FPR64:$vrx)>; +def f2FFTOU32_D : F2_XZ_P<0b01000, 0b011100, "fftoi.f64.u32", [], (outs FPR32:$vrz), (ins FPR64:$vrx)>; +def f2FS32TOF_D : F2_XZ_P<0b01001, 0b011101, "fitof.s32.f64", [], (outs FPR64:$vrz), (ins FPR32:$vrx)>; +def f2FU32TOF_D : F2_XZ_P<0b01001, 0b011100, "fitof.u32.f64", [], (outs FPR64:$vrz), (ins FPR32:$vrx)>; +} + +defm f2FF16TOSI32 : F2_XZ_RM<0b1000, "fftoi.f16.s32", (outs FPR32:$vrz), (ins FPR32:$vrx)>; +defm f2FF16TOUI32 : F2_XZ_RM<0b1001, "fftoi.f16.u32", (outs FPR32:$vrz), (ins FPR32:$vrx)>; +defm f2FF32TOSI32 : F2_XZ_RM<0b0000, "fftoi.f32.s32", (outs FPR32:$vrz), (ins FPR32:$vrx)>; +defm f2FF32TOUI32 : F2_XZ_RM<0b0001, "fftoi.f32.u32", (outs FPR32:$vrz), (ins FPR32:$vrx)>; +let Predicates = [HasFPUv3_DF] in { +defm f2FF64TOSI32 : F2_XZ_RM<0b0010, "fftoi.f64.s32", (outs FPR32:$vrz), (ins FPR64:$vrx)>; +defm f2FF64TOUI32 : F2_XZ_RM<0b0011, "fftoi.f64.u32", (outs FPR32:$vrz), (ins FPR64:$vrx)>; +} + +def : Pat<(i32 (fp_to_sint (fround FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOSI32_RN $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_uint (fround FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOUI32_RN $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_sint (fceil FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOSI32_RPI $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_uint (fceil FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOUI32_RPI $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_sint (ffloor FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOSI32_RNI $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_uint (ffloor FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOUI32_RNI $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_sint (ftrunc FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOSI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_uint (ftrunc FPR32:$vrx))), (COPY_TO_REGCLASS (f2FF32TOUI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_sint FPR32:$vrx)), (COPY_TO_REGCLASS (f2FF32TOSI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_SF]>; +def : Pat<(i32 (fp_to_uint FPR32:$vrx)), (COPY_TO_REGCLASS (f2FF32TOUI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_SF]>; + +def : Pat<(i32 (fp_to_sint (fround FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOSI32_RN $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_uint (fround FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOUI32_RN $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_sint (fceil FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOSI32_RPI $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_uint (fceil FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOUI32_RPI $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_sint (ffloor FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOSI32_RNI $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_uint (ffloor FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOUI32_RNI $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_sint (ftrunc FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOSI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_uint (ftrunc FPR64:$vrx))), (COPY_TO_REGCLASS (f2FF64TOUI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_sint FPR64:$vrx)), (COPY_TO_REGCLASS (f2FF64TOSI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_DF]>; +def : Pat<(i32 (fp_to_uint FPR64:$vrx)), (COPY_TO_REGCLASS (f2FF64TOUI32_RZ $vrx), GPR)>, Requires<[HasFPUv3_DF]>; + +def : Pat<(sint_to_fp GPR:$vrx), (f2FS32TOF_S (COPY_TO_REGCLASS $vrx, FPR32))>, Requires<[HasFPUv3_SF]>; +def : Pat<(uint_to_fp GPR:$vrx), (f2FU32TOF_S (COPY_TO_REGCLASS $vrx, FPR32))>, Requires<[HasFPUv3_SF]>; +def : Pat<(sint_to_fp GPR:$vrx), (f2FS32TOF_D (COPY_TO_REGCLASS $vrx, FPR32))>, Requires<[HasFPUv3_DF]>; +def : Pat<(uint_to_fp GPR:$vrx), (f2FU32TOF_D (COPY_TO_REGCLASS $vrx, FPR32))>, Requires<[HasFPUv3_DF]>; + +let Predicates = [HasFPUv3_DF] in { +def f2FDTOS : F2_XZ_P<0b00011, 0b010110, "fdtos", [(set FPR32:$vrz, (fpround FPR64:$vrx))], (outs FPR32:$vrz), + (ins FPR64:$vrx)>; +def f2FSTOD : F2_XZ_P<0b00011, 0b010111, "fstod", [(set FPR64:$vrz, (fpextend FPR32:$vrx))], (outs FPR64:$vrz), + (ins FPR32:$vrx)>; +} + +// fsel +defm f2FSEL: F2_CXYZ_T<0b111001, "fsel">; + +def : Pat<(f32 fpimm:$imm),(COPY_TO_REGCLASS (ORI32 (MOVIH32 (fpimm16_sr16_XFORM fpimm:$imm)), (fpimm16_sr0_XFORM fpimm:$imm)), FPR32)>, + Requires<[HasFPUv3_SF]>; +def : Pat<(f32 fpimm16_16:$imm),(COPY_TO_REGCLASS (MOVIH32 (fpimm16_sr16_XFORM fpimm16_16:$imm)), FPR32)>, + Requires<[HasFPUv3_SF]>; +def : Pat<(f32 fpimm16:$imm),(COPY_TO_REGCLASS (MOVI32 (fpimm16_sr0_XFORM fpimm16:$imm)), FPR32)>, + Requires<[HasFPUv3_SF]>; + + + + + +multiclass BRCond_Bin_F2 { + let Predicates = [HasFPUv3_SF] in + def : Pat<(brcond (i32 (setcc FPR32:$rs1, FPR32:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_S) FPR32:$rs1, FPR32:$rs2), bb:$imm16)>; + let Predicates = [HasFPUv3_DF] in + def : Pat<(brcond (i32 (setcc FPR64:$rs1, FPR64:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_D) FPR64:$rs1, FPR64:$rs2), bb:$imm16)>; + + let Predicates = [HasFPUv3_SF] in + def : Pat<(i32 (setcc FPR32:$rs1, FPR32:$rs2, CC)), + (MV (!cast(Instr#_S) FPR32:$rs1, FPR32:$rs2))>; + let Predicates = [HasFPUv3_DF] in + def : Pat<(i32 (setcc FPR64:$rs1, FPR64:$rs2, CC)), + (MV (!cast(Instr#_D) FPR64:$rs1, FPR64:$rs2))>; + + let Predicates = [HasFPUv3_SF] in { + def : Pat<(select (i32 (setcc FPR32:$rs1, FPR32:$rs2, CC)), FPR32:$rx, FPR32:$false), + !if( + !eq(IsSelectSwap, 0), + (f2FSEL_S (!cast(Instr#_S) FPR32:$rs1, FPR32:$rs2), FPR32:$rx, FPR32:$false), + (f2FSEL_S (!cast(Instr#_S) FPR32:$rs1, FPR32:$rs2), FPR32:$false, FPR32:$rx) + )>; + } + let Predicates = [HasFPUv3_DF] in { + def : Pat<(select (i32 (setcc FPR64:$rs1, FPR64:$rs2, CC)), FPR64:$rx, FPR64:$false), + !if( + !eq(IsSelectSwap, 0), + (f2FSEL_D (!cast(Instr#_D) FPR64:$rs1, FPR64:$rs2), FPR64:$rx, FPR64:$false), + (f2FSEL_D (!cast(Instr#_D) FPR64:$rs1, FPR64:$rs2), FPR64:$false, FPR64:$rx) + )>; + } +} + +multiclass BRCond_Bin_SWAP_F2 { + let Predicates = [HasFPUv3_SF] in + def : Pat<(brcond (i32 (setcc FPR32:$rs1, FPR32:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_S) FPR32:$rs2, FPR32:$rs1), bb:$imm16)>; + let Predicates = [HasFPUv3_DF] in + def : Pat<(brcond (i32 (setcc FPR64:$rs1, FPR64:$rs2, CC)), bb:$imm16), + (Br (!cast(Instr#_D) FPR64:$rs2, FPR64:$rs1), bb:$imm16)>; + + let Predicates = [HasFPUv3_SF] in + def : Pat<(i32 (setcc FPR32:$rs1, FPR32:$rs2, CC)), + (MV (!cast(Instr#_S) FPR32:$rs2, FPR32:$rs1))>; + let Predicates = [HasFPUv3_DF] in + def : Pat<(i32 (setcc FPR64:$rs1, FPR64:$rs2, CC)), + (MV (!cast(Instr#_D) FPR64:$rs2, FPR64:$rs1))>; + + let Predicates = [HasFPUv3_SF] in { + def : Pat<(select (i32 (setcc FPR32:$rs1, FPR32:$rs2, CC)), FPR32:$rx, FPR32:$false), + !if( + !eq(IsSelectSwap, 0), + (f2FSEL_S (!cast(Instr#_S) FPR32:$rs2, FPR32:$rs1), FPR32:$rx, FPR32:$false), + (f2FSEL_S (!cast(Instr#_S) FPR32:$rs2, FPR32:$rs1), FPR32:$false, FPR32:$rx) + )>; + } + let Predicates = [HasFPUv3_DF] in { + def : Pat<(select (i32 (setcc FPR64:$rs1, FPR64:$rs2, CC)), FPR64:$rx, FPR64:$false), + !if( + !eq(IsSelectSwap, 0), + (f2FSEL_D (!cast(Instr#_D) FPR64:$rs1, FPR64:$rs2), FPR64:$rx, FPR64:$false), + (f2FSEL_D (!cast(Instr#_D) FPR64:$rs2, FPR64:$rs1), FPR64:$false, FPR64:$rx) + )>; + } +} + +multiclass BRCond_Un_F2 { + let Predicates = [HasFPUv3_SF] in + def : Pat<(brcond (i32 (setcc FPR32:$rs1, FConstant, CC)), bb:$imm16), + (Br (!cast(Instr#_S) FPR32:$rs1), bb:$imm16)>; + let Predicates = [HasFPUv3_DF] in + def : Pat<(brcond (i32 (setcc FPR64:$rs1, (CSKY_BITCAST_FROM_LOHI IConstant, IConstant), CC)), bb:$imm16), + (Br (!cast(Instr#_D) FPR64:$rs1), bb:$imm16)>; + + let Predicates = [HasFPUv3_SF] in + def : Pat<(i32 (setcc FPR32:$rs1, FConstant, CC)), + (MV (!cast(Instr#_S) FPR32:$rs1))>; + let Predicates = [HasFPUv3_DF] in + def : Pat<(i32 (setcc FPR64:$rs1, (CSKY_BITCAST_FROM_LOHI IConstant, IConstant), CC)), + (MV (!cast(Instr#_D) FPR64:$rs1))>; + + let Predicates = [HasFPUv3_SF] in { + def : Pat<(select (i32 (setcc FPR32:$rs1, FConstant, CC)), FPR32:$rx, FPR32:$false), + !if( + !eq(IsSelectSwap, 0), + (f2FSEL_S (!cast(Instr#_S) FPR32:$rs1), FPR32:$rx, FPR32:$false), + (f2FSEL_S (!cast(Instr#_S) FPR32:$rs1), FPR32:$false, FPR32:$rx) + )>; + } + let Predicates = [HasFPUv3_DF] in { + def : Pat<(select (i32 (setcc FPR64:$rs1, (CSKY_BITCAST_FROM_LOHI IConstant, IConstant), CC)), FPR64:$rx, FPR64:$false), + !if( + !eq(IsSelectSwap, 0), + (f2FSEL_D (!cast(Instr#_D) FPR64:$rs1), FPR64:$rx, FPR64:$false), + (f2FSEL_D (!cast(Instr#_D) FPR64:$rs1), FPR64:$false, FPR64:$rx) + )>; + } +} + +// inverse (order && compare) to (unorder || inverse(compare)) + +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_SWAP_F2; +defm : BRCond_Bin_SWAP_F2; + +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_F2; +defm : BRCond_Bin_SWAP_F2; +defm : BRCond_Bin_SWAP_F2; + +// ------ + +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; + +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; +defm : BRCond_Un_F2; + +// ---- + +def : Pat<(select CARRY:$ca, FPR32:$rx, FPR32:$false), + (f2FSEL_S CARRY:$ca, FPR32:$rx, FPR32:$false)>; +def : Pat<(select (and CARRY:$ca, 1), FPR32:$rx, FPR32:$false), + (f2FSEL_S CARRY:$ca, FPR32:$rx, FPR32:$false)>; +def : Pat<(select CARRY:$ca, FPR64:$rx, FPR64:$false), + (f2FSEL_D CARRY:$ca, FPR64:$rx, FPR64:$false)>; +def : Pat<(select (and CARRY:$ca, 1), FPR64:$rx, FPR64:$false), + (f2FSEL_D CARRY:$ca, FPR64:$rx, FPR64:$false)>; \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYMCInstLower.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYMCInstLower.h @@ -0,0 +1,35 @@ +//===-- CSKYMCInstLower.cpp - Convert CSKY MachineInstr to an MCInst --------=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYMCINSTLOWER_H +#define LLVM_LIB_TARGET_CSKY_CSKYMCINSTLOWER_H + +namespace llvm { +class AsmPrinter; +class MCContext; +class MachineInstr; +class MCInst; +class MachineOperand; +class MCOperand; +class MCSymbol; + +class CSKYMCInstLower { + MCContext &Ctx; + AsmPrinter &Printer; + +public: + CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer); + + void Lower(const MachineInstr *MI, MCInst &OutMI) const; + bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const; + MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYMCINSTLOWER_H Index: llvm/lib/Target/CSKY/CSKYMCInstLower.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYMCInstLower.cpp @@ -0,0 +1,124 @@ +//===-- CSKYMCInstLower.cpp - Convert CSKY MachineInstr to an MCInst --------=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower CSKY MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCInstLower.h" +#include "MCTargetDesc/CSKYMCExpr.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/MC/MCExpr.h" +#include + +using namespace llvm; + +CSKYMCInstLower::CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer) + : Ctx(Ctx), Printer(Printer) {} + +void CSKYMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { + OutMI.setOpcode(MI->getOpcode()); + + for (const MachineOperand &MO : MI->operands()) { + MCOperand MCOp; + if (lowerOperand(MO, MCOp)) + OutMI.addOperand(MCOp); + } +} + +bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO, + MCOperand &MCOp) const { + switch (MO.getType()) { + default: + llvm_unreachable("unknown operand type"); + case MachineOperand::MO_RegisterMask: + break; + case MachineOperand::MO_Immediate: + MCOp = MCOperand::createImm(MO.getImm()); + break; + case MachineOperand::MO_Register: + if (MO.isImplicit()) + return false; + MCOp = MCOperand::createReg(MO.getReg()); + break; + case MachineOperand::MO_MachineBasicBlock: + MCOp = MCOperand::createExpr( + MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); + break; + case MachineOperand::MO_GlobalAddress: + MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal())); + break; + case MachineOperand::MO_BlockAddress: + MCOp = lowerSymbolOperand( + MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress())); + break; + case MachineOperand::MO_ExternalSymbol: + MCOp = lowerSymbolOperand( + MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName())); + break; + case MachineOperand::MO_ConstantPoolIndex: + MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex())); + break; + case MachineOperand::MO_JumpTableIndex: + MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex())); + break; + } + return true; +} + +MCOperand CSKYMCInstLower::lowerSymbolOperand(const MachineOperand &MO, + MCSymbol *Sym) const { + CSKYMCExpr::VariantKind Kind; + MCContext &Ctx = Printer.OutContext; + + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag."); + case CSKYII::MO_None: + Kind = CSKYMCExpr::VK_CSKY_None; + break; + case CSKYII::MO_GOT_HI16: + Kind = CSKYMCExpr::VK_CSKY_GOT_HI; + break; + case CSKYII::MO_GOT_LO16: + Kind = CSKYMCExpr::VK_CSKY_GOT_LO; + break; + case CSKYII::MO_GOTOFF_HI16: + Kind = CSKYMCExpr::VK_CSKY_GOTOFF_HI; + break; + case CSKYII::MO_GOTOFF_LO16: + Kind = CSKYMCExpr::VK_CSKY_GOTOFF_LO; + break; + case CSKYII::MO_ADDR_HI16: + Kind = CSKYMCExpr::VK_CSKY_ADDR_HI; + break; + case CSKYII::MO_ADDR_LO16: + Kind = CSKYMCExpr::VK_CSKY_ADDR_LO; + break; + case CSKYII::MO_ADDR32: + Kind = CSKYMCExpr::VK_CSKY_ADDR; + break; + case CSKYII::MO_GOT32: + Kind = CSKYMCExpr::VK_CSKY_GOT; + break; + case CSKYII::MO_GOTOFF32: + Kind = CSKYMCExpr::VK_CSKY_GOTOFF; + break; + case CSKYII::MO_GOT12: + Kind = CSKYMCExpr::VK_CSKY_GOT12; + break; + } + const MCExpr *ME = + MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); + + if (Kind != CSKYMCExpr::VK_CSKY_None) + ME = CSKYMCExpr::create(ME, Kind, Ctx); + + return MCOperand::createExpr(ME); +} Index: llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.h @@ -0,0 +1,65 @@ +//=- CSKYMachineFunctionInfo.h - CSKY machine function info -------*- C++ -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares CSKY-specific per-machine-function information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYMACHINEFUNCTIONINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYMACHINEFUNCTIONINFO_H + +#include "llvm/CodeGen/MachineFunction.h" + +namespace llvm { + +class CSKYMachineFunctionInfo : public MachineFunctionInfo { + MachineFunction &MF; + + // True if this function has a stack frame. + bool HasStackFrame = false; + // Size of callee saved registers. + unsigned CSRSize = 0; + // Size of registers for byval arg and vararg. + unsigned ArgSize = 0; + // FrameIndex of varargs. + int VarArgsFrameIndex = 0; + + unsigned PICLabelUId = 0; + + bool SpillsCR = false; + + Register GlobalBaseReg = 0; + +public: + CSKYMachineFunctionInfo(MachineFunction &MF) : MF(MF) {} + + bool hasStackFrame() const { return HasStackFrame; } + void setHasStackFrame(bool v) { HasStackFrame = v; } + + unsigned getCSRSize() const { return CSRSize; } + void setCSRSize(unsigned int size) { CSRSize = size; } + + void setSpillsCR() { SpillsCR = true; } + bool isCRSpilled() const { return SpillsCR; } + + unsigned getArgRegsSaveSize() const { return ArgSize; } + void setArgRegsSaveSize(unsigned size) { ArgSize = size; } + + void setVarArgsFrameIndex(int v) { VarArgsFrameIndex = v; } + int getVarArgsFrameIndex() { return VarArgsFrameIndex; } + + void initPICLabelUId(unsigned UId) { PICLabelUId = UId; } + unsigned createPICLabelUId() { return PICLabelUId++; } + + Register getGlobalBaseReg() const { return GlobalBaseReg; } + void setGlobalBaseReg(Register Reg) { GlobalBaseReg = Reg; } +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYMACHINEFUNCTIONINFO_H Index: llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYMachineFunctionInfo.cpp @@ -0,0 +1,11 @@ +//===-- CSKYMachineFunctionInfo.cpp - CSKY machine function info ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYMachineFunctionInfo.h" + +using namespace llvm; Index: llvm/lib/Target/CSKY/CSKYRegisterInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYRegisterInfo.h @@ -0,0 +1,60 @@ +//===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYREGISTERINFO_H +#define LLVM_LIB_TARGET_CSKY_CSKYREGISTERINFO_H + +#include "llvm/CodeGen/TargetRegisterInfo.h" + +#define GET_REGINFO_HEADER +#include "CSKYGenRegisterInfo.inc" + +namespace llvm { +class CSKYInstrInfo; + +class CSKYRegisterInfo : public CSKYGenRegisterInfo { +public: + CSKYRegisterInfo(); + + const uint32_t *getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID id) const override; + + BitVector getReservedRegs(const MachineFunction &MF) const override; + + Register getFrameRegister(const MachineFunction &MF) const override; + + Register getBaseRegister() const; + + const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; + + void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, + unsigned FIOperandNum, + RegScavenger *RS) const override; + + bool rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIndex, + Register FrameReg, int &Offset, + const CSKYInstrInfo *TII) const; + + bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override { + return true; + } + bool requiresRegisterScavenging(const MachineFunction &MF) const override { + return true; + } + bool requiresFrameIndexScavenging(const MachineFunction &MF) const override { + return true; + } +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYREGISTERINFO_H Index: llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp @@ -0,0 +1,158 @@ +//===-- CSKYRegisterInfo.h - CSKY Register Information Impl ---*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the CSKY implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYRegisterInfo.h" +#include "CSKY.h" +#include "CSKYSubtarget.h" +#include "Utils/CSKYBaseInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/RegisterScavenging.h" + +#define GET_REGINFO_TARGET_DESC +#include "CSKYGenRegisterInfo.inc" + +using namespace llvm; + +CSKYRegisterInfo::CSKYRegisterInfo() : CSKYGenRegisterInfo(CSKY::LR, 0, 0, 0) {} + +const uint32_t * +CSKYRegisterInfo::getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID Id) const { + const CSKYSubtarget &STI = MF.getSubtarget(); + if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat()) + return CSR_GPR_FPR64_RegMask; + if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) + return CSR_GPR_FPR32_RegMask; + return CSR_I32_RegMask; +} + +BitVector CSKYRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + markSuperRegs(Reserved, CSKY::SP); + markSuperRegs(Reserved, CSKY::R26); + markSuperRegs(Reserved, CSKY::R27); + markSuperRegs(Reserved, CSKY::GP); + markSuperRegs(Reserved, CSKY::R29); + markSuperRegs(Reserved, CSKY::R30); + markSuperRegs(Reserved, CSKY::R31); + // TODO: FP, BP + assert(checkAllSuperRegsMarked(Reserved)); + return Reserved; +} + +Register CSKYRegisterInfo::getFrameRegister(const MachineFunction &MF) const { + // TODO: FP + return CSKY::SP; +} + +Register CSKYRegisterInfo::getBaseRegister() const { return CSKY::R9; } + +const MCPhysReg * +CSKYRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + const CSKYSubtarget &STI = MF->getSubtarget(); + if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat()) + return CSR_GPR_FPR64_SaveList; + if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) + return CSR_GPR_FPR32_SaveList; + return CSR_I32_SaveList; +} + +void CSKYRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, unsigned FIOperandNum, + RegScavenger *RS) const { + assert(!SPAdj && "Unexpected zero SPAdj."); + + MachineInstr *MI = &*II; + auto DL = MI->getDebugLoc(); + MachineBasicBlock &MBB = *MI->getParent(); + MachineFunction &MF = *MBB.getParent(); + const CSKYFrameLowering *CFI = getFrameLowering(MF); + const CSKYInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + + MachineInstr *NewMI = nullptr; + switch (MI->getOpcode()) { + default: + break; + case CSKY::RESTORE_CARRY: { + + Register NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); + + NewMI = BuildMI(MBB, II, DL, TII->get(CSKY::LD32W), NewReg) + .add(MI->getOperand(1)) + .add(MI->getOperand(2)) + .getInstr(); + + BuildMI(MBB, II, DL, TII->get(CSKY::BTSTI32)) + .add(MI->getOperand(0)) + .addReg(NewReg, getKillRegState(true)) + .addImm(0); + + MBB.erase(MI->getIterator()); + break; + } + case CSKY::SPILL_CARRY: { + Register NewReg = MRI.createVirtualRegister(&CSKY::GPRRegClass); + BuildMI(MBB, II, DL, TII->get(CSKY::MVC32), NewReg).add(MI->getOperand(0)); + + NewMI = BuildMI(MBB, II, DL, TII->get(CSKY::ST32W)) + .addReg(NewReg, getKillRegState(true)) + .add(MI->getOperand(1)) + .add(MI->getOperand(2)) + .getInstr(); + + MBB.erase(MI->getIterator()); + + break; + } + } + + if (NewMI != nullptr) + MI = NewMI; + + Register FrameReg; + int FrameIndex = MI->getOperand(FIOperandNum).getIndex(); + int Offset = CFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg, SPAdj); + + if (rewriteFrameIndex(*MI, FIOperandNum, FrameReg, Offset, TII)) + return; + + // TODO:: use sratchReg +} + +bool CSKYRegisterInfo::rewriteFrameIndex(MachineInstr &MI, + unsigned FrameRegIndex, + Register FrameReg, int &Offset, + const CSKYInstrInfo *TII) const { + unsigned Opcode = MI.getOpcode(); + + MachineOperand *RegOp = nullptr; + MachineOperand *ImmOp = nullptr; + + switch (Opcode) { + default: + RegOp = &MI.getOperand(FrameRegIndex); + ImmOp = &MI.getOperand(FrameRegIndex + 1); + break; + case CSKY::LDM32_2: + case CSKY::STM32_2: + RegOp = &MI.getOperand(FrameRegIndex); + break; + } + + if (RegOp != nullptr) + RegOp->ChangeToRegister(FrameReg, false); + if (ImmOp != nullptr) + ImmOp->ChangeToImmediate(Offset); + + return true; +} Index: llvm/lib/Target/CSKY/CSKYRegisterInfo.td =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYRegisterInfo.td @@ -0,0 +1,195 @@ +//===-- CSKYRegisterInfo.td - CSKY Register defs -----------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Declarations that describe the CSKY register files +//===----------------------------------------------------------------------===// + +let Namespace = "CSKY" in { + class CSKYReg Enc, string n, list alt = []> : Register { + let HWEncoding{5 - 0} = Enc; + let AltNames = alt; + } + + class CSKYFReg32 Enc, string n, list alt = []> : Register { + let HWEncoding{4 - 0} = Enc; + let AltNames = alt; + } + + // Because CSKYFReg64 register have AsmName and AltNames that alias with their + // 32-bit sub-register, CSKYAsmParser will need to coerce a register number + // from a CSKYFReg32 to the equivalent CSKYFReg64 when appropriate. + def sub32_0 : SubRegIndex<32, 0>; + def sub32_32 : SubRegIndex<32, 32>; + def sub64_0 : SubRegIndex<64, 0>; + def sub64_64 : SubRegIndex<64,64>; + + + class CSKYFReg64 : Register<""> { + let HWEncoding{4 - 0} = subreg.HWEncoding{4 - 0}; + let SubRegs = [subreg]; + let SubRegIndices = [sub32_0]; + let AsmName = subreg.AsmName; + let AltNames = subreg.AltNames; + } + + class CSKYFReg128 : Register<""> { + let HWEncoding{4 - 0} = subreg.HWEncoding{4 - 0}; + let SubRegs = [subreg]; + let SubRegIndices = [sub64_0]; + let AsmName = subreg.AsmName; + let AltNames = subreg.AltNames; + } + + def ABIRegAltName : RegAltNameIndex; +} // Namespace = "CSKY" + +let RegAltNameIndices = [ABIRegAltName] in { + def R0 : CSKYReg<0, "r0", ["a0"]>, DwarfRegNum<[0]>; + def R1 : CSKYReg<1, "r1", ["a1"]>, DwarfRegNum<[1]>; + def R2 : CSKYReg<2, "r2", ["a2"]>, DwarfRegNum<[2]>; + def R3 : CSKYReg<3, "r3", ["a3"]>, DwarfRegNum<[3]>; + def R4 : CSKYReg<4, "r4", ["l0"]>, DwarfRegNum<[4]>; + def R5 : CSKYReg<5, "r5", ["l1"]>, DwarfRegNum<[5]>; + def R6 : CSKYReg<6, "r6", ["l2"]>, DwarfRegNum<[6]>; + def R7 : CSKYReg<7, "r7", ["l3"]>, DwarfRegNum<[7]>; + def R8 : CSKYReg<8, "r8", ["l4"]>, DwarfRegNum<[8]>; + def R9 : CSKYReg<9, "r9", ["l5"]>, DwarfRegNum<[9]>; + def R10 : CSKYReg<10, "r10", ["l6"]>, DwarfRegNum<[10]>; + def R11 : CSKYReg<11, "r11", ["l7"]>, DwarfRegNum<[11]>; + def R12 : CSKYReg<12, "r12", ["t0"]>, DwarfRegNum<[12]>; + def R13 : CSKYReg<13, "r13", ["t1"]>, DwarfRegNum<[13]>; + def R14 : CSKYReg<14, "r14", ["sp"]>, DwarfRegNum<[14]>; + def R15 : CSKYReg<15, "r15", ["lr"]>, DwarfRegNum<[15]>; + def R16 : CSKYReg<16, "r16", ["l8"]>, DwarfRegNum<[16]>; + def R17 : CSKYReg<17, "r17", ["l9"]>, DwarfRegNum<[17]>; + def R18 : CSKYReg<18, "r18", ["t2"]>, DwarfRegNum<[18]>; + def R19 : CSKYReg<19, "r19", ["t3"]>, DwarfRegNum<[19]>; + def R20 : CSKYReg<20, "r20", ["t4"]>, DwarfRegNum<[20]>; + def R21 : CSKYReg<21, "r21", ["t5"]>, DwarfRegNum<[21]>; + def R22 : CSKYReg<22, "r22", ["t6"]>, DwarfRegNum<[22]>; + def R23 : CSKYReg<23, "r23", ["t7"]>, DwarfRegNum<[23]>; + def R24 : CSKYReg<24, "r24", ["t8"]>, DwarfRegNum<[24]>; + def R25 : CSKYReg<25, "r25", ["t9"]>, DwarfRegNum<[25]>; + def R26 : CSKYReg<26, "r26", ["r26"]>, DwarfRegNum<[26]>; + def R27 : CSKYReg<27, "r27", ["r27"]>, DwarfRegNum<[27]>; + def R28 : CSKYReg<28, "r28", ["rgb"]>, DwarfRegNum<[28]>; + def R29 : CSKYReg<29, "r29", ["rtb"]>, DwarfRegNum<[29]>; + def R30 : CSKYReg<30, "r30", ["svbr"]>, DwarfRegNum<[30]>; + def R31 : CSKYReg<31, "r31", ["tls"]>, DwarfRegNum<[31]>; + def CR0 : CSKYReg<33, "cr0", ["psr"]>; + def HI : CSKYReg<34, "hi", ["hi"]>, DwarfRegNum<[36]>; + def LO : CSKYReg<35, "lo", ["lo"]>, DwarfRegNum<[37]>; + + let Aliases = [R14] in def SP : CSKYReg<14, "r14", ["sp"]>, DwarfRegNum<[14]>; + let Aliases = [R15] in def LR : CSKYReg<15, "r15", ["lr"]>, DwarfRegNum<[15]>; + let Aliases = [R28] in def GP : CSKYReg<28, "r28", ["rgb"]>, + DwarfRegNum<[28]>; +} + +// The order of registers represents the preferred allocation sequence. +// Registers are listed in the order caller-save, callee-save, specials. +def GPR : RegisterClass<"CSKY", [i32], 32, + (add(sequence "R%u", 0, 3), (sequence "R%u", 12, 13), + (sequence "R%u", 18, 25), LR, (sequence "R%u", 4, 11), + (sequence "R%u", 16, 17), (sequence "R%u", 26, 27), GP, + (sequence "R%u", 29, 30), SP, R31)> { + let Size = 32; +} + +let Namespace = "CSKY" in { + def GPRSubReg0 : SubRegIndex<32, 0>; + def GPRSubReg1 : SubRegIndex<32, 32>; +} + +def GPRTuple + : RegisterTuples< + [GPRSubReg0, GPRSubReg1], + [(add(sequence "R%u", 0, 30)), (add(sequence "R%u", 1, 31))], [ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30" + ]>; + +def GPRPair : RegisterClass<"CSKY", [untyped], 32, (add GPRTuple)> { + let Size = 64; +} + +def CARRY : RegisterClass<"CSKY", [i32], 32, (add CR0)> { + let Size = 32; + let CopyCost = -1; +} + +// Floating point registers +let RegAltNameIndices = [ABIRegAltName] in { + def F0_32 : CSKYFReg32<0, "fr0", ["vr0"]>, DwarfRegNum<[74]>; + def F1_32 : CSKYFReg32<1, "fr1", ["vr1"]>, DwarfRegNum<[78]>; + def F2_32 : CSKYFReg32<2, "fr2", ["vr2"]>, DwarfRegNum<[82]>; + def F3_32 : CSKYFReg32<3, "fr3", ["vr3"]>, DwarfRegNum<[86]>; + def F4_32 : CSKYFReg32<4, "fr4", ["vr4"]>, DwarfRegNum<[90]>; + def F5_32 : CSKYFReg32<5, "fr5", ["vr5"]>, DwarfRegNum<[94]>; + def F6_32 : CSKYFReg32<6, "fr6", ["vr6"]>, DwarfRegNum<[98]>; + def F7_32 : CSKYFReg32<7, "fr7", ["vr7"]>, DwarfRegNum<[102]>; + def F8_32 : CSKYFReg32<8, "fr8", ["vr8"]>, DwarfRegNum<[106]>; + def F9_32 : CSKYFReg32<9, "fr9", ["vr9"]>, DwarfRegNum<[110]>; + def F10_32 : CSKYFReg32<10, "fr10", ["vr10"]>, DwarfRegNum<[114]>; + def F11_32 : CSKYFReg32<11, "fr11", ["vr11"]>, DwarfRegNum<[118]>; + def F12_32 : CSKYFReg32<12, "fr12", ["vr12"]>, DwarfRegNum<[122]>; + def F13_32 : CSKYFReg32<13, "fr13", ["vr13"]>, DwarfRegNum<[126]>; + def F14_32 : CSKYFReg32<14, "fr14", ["vr14"]>, DwarfRegNum<[130]>; + def F15_32 : CSKYFReg32<15, "fr15", ["vr15"]>, DwarfRegNum<[134]>; + def F16_32 : CSKYFReg32<16, "fr16", ["vr16"]>, DwarfRegNum<[138]>; + def F17_32 : CSKYFReg32<17, "fr17", ["vr17"]>, DwarfRegNum<[142]>; + def F18_32 : CSKYFReg32<18, "fr18", ["vr18"]>, DwarfRegNum<[146]>; + def F19_32 : CSKYFReg32<19, "fr19", ["vr19"]>, DwarfRegNum<[150]>; + def F20_32 : CSKYFReg32<20, "fr20", ["vr20"]>, DwarfRegNum<[154]>; + def F21_32 : CSKYFReg32<21, "fr21", ["vr21"]>, DwarfRegNum<[158]>; + def F22_32 : CSKYFReg32<22, "fr22", ["vr22"]>, DwarfRegNum<[162]>; + def F23_32 : CSKYFReg32<23, "fr23", ["vr23"]>, DwarfRegNum<[166]>; + def F24_32 : CSKYFReg32<24, "fr24", ["vr24"]>, DwarfRegNum<[170]>; + def F25_32 : CSKYFReg32<25, "fr25", ["vr25"]>, DwarfRegNum<[174]>; + def F26_32 : CSKYFReg32<26, "fr26", ["vr26"]>, DwarfRegNum<[178]>; + def F27_32 : CSKYFReg32<27, "fr27", ["vr27"]>, DwarfRegNum<[182]>; + def F28_32 : CSKYFReg32<28, "fr28", ["vr28"]>, DwarfRegNum<[186]>; + def F29_32 : CSKYFReg32<29, "fr29", ["vr29"]>, DwarfRegNum<[190]>; + def F30_32 : CSKYFReg32<30, "fr30", ["vr30"]>, DwarfRegNum<[194]>; + def F31_32 : CSKYFReg32<31, "fr31", ["vr31"]>, DwarfRegNum<[198]>; + + foreach Index = 0 - 31 in { + def F #Index#_64 : CSKYFReg64("F" #Index #"_32")>, + DwarfRegNum<[!add(!shl(Index, 2), 74)]>; + + def F#Index#_128 : CSKYFReg128("F"#Index#"_64")>, + DwarfRegNum<[!add(!shl(Index, 2), 74)]>; + } +} + +// The order of registers represents the preferred allocation sequence. +// Registers are listed in the order caller-save, callee-save, specials. +def FPR32 : RegisterClass<"CSKY", [f32], 32, (add(sequence "F%u_32", 0, 31))>; +def sFPR32 : RegisterClass<"CSKY", [f32], 32, (add(sequence "F%u_32", 0, 15))>; + +def FPR64 : RegisterClass<"CSKY", [f64], 64, (add(sequence "F%u_64", 0, 31))>; +def sFPR64 : RegisterClass<"CSKY", [f64], 64, (add(sequence "F%u_64", 0, 15))>; + +def FPR128 : RegisterClass<"CSKY", + [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 128, (add + (sequence "F%u_128", 0, 31))>; + +def sFPR128 : RegisterClass<"CSKY", + [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 128, (add + (sequence "F%u_128", 0, 15))>; + +def GPR_DSP : RegisterClass<"CSKY", [v4i8, v2i16], 32, (add + GPR + )>; + +def GPR_DSP_ALL : RegisterClass<"CSKY", [i32, v4i8, v2i16], 32, (add + GPR + )>; \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYSubtarget.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYSubtarget.h @@ -0,0 +1,102 @@ +//===-- CSKYSubtarget.h - Define Subtarget for the CSKY----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CSKY specific subclass of TargetSubtargetInfo. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYSUBTARGET_H +#define LLVM_LIB_TARGET_CSKY_CSKYSUBTARGET_H + +#include "CSKYFrameLowering.h" +#include "CSKYISelLowering.h" +#include "CSKYInstrInfo.h" +#include "CSKYRegisterInfo.h" +#include "Utils/CSKYBaseInfo.h" +#include "llvm/CodeGen/SelectionDAGTargetInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Target/TargetMachine.h" + +#define GET_SUBTARGETINFO_HEADER +#include "CSKYGenSubtargetInfo.inc" + +namespace llvm { +class StringRef; + +class CSKYSubtarget : public CSKYGenSubtargetInfo { + CSKYFrameLowering FrameLowering; + CSKYInstrInfo InstrInfo; + CSKYRegisterInfo RegInfo; + CSKYTargetLowering TLInfo; + SelectionDAGTargetInfo TSInfo; + + bool HasFPUv2SingleFloat; + bool HasFPUv2DoubleFloat; + bool HasFPUv2; + bool HasFPUv3HalfWord; + bool HasFPUv3HalfFloat; + bool HasFPUv3SingleFloat; + bool HasFPUv3DoubleFloat; + bool HasFPUv3; + + bool HasFdivdu; + + bool UseSoftFloat; + + bool Has3E3r1; + +public: + CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef FS, + const TargetMachine &TM); + + const CSKYFrameLowering *getFrameLowering() const override { + return &FrameLowering; + } + const CSKYInstrInfo *getInstrInfo() const override { return &InstrInfo; } + const CSKYRegisterInfo *getRegisterInfo() const override { return &RegInfo; } + const CSKYTargetLowering *getTargetLowering() const override { + return &TLInfo; + } + const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { + return &TSInfo; + } + + void initializeEnvironment(); + /// Initializes using the passed in CPU and feature strings so that we can + /// use initializer lists for subtarget initialization. + CSKYSubtarget &initializeSubtargetDependencies(const Triple &TT, + StringRef CPU, StringRef FS); + + // Generated by inc file + void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); + + bool hasFPUv2SingleFloat() const { return HasFPUv2SingleFloat; } + bool hasFPUv2DoubleFloat() const { return HasFPUv2DoubleFloat; } + bool hasFPUv2() const { return HasFPUv2; } + bool hasFPUv3HalfWord() const { return HasFPUv3HalfWord; } + bool hasFPUv3HalfFloat() const { return HasFPUv3HalfFloat; } + bool hasFPUv3SingleFloat() const { return HasFPUv3SingleFloat; } + bool hasFPUv3DoubleFloat() const { return HasFPUv3DoubleFloat; } + bool hasFPUv3() const { return HasFPUv3; } + + bool hasFdivdu() const { return HasFdivdu; } + + bool useSoftFloat() const { + if (TLInfo.getTargetMachine().Options.FloatABIType == FloatABI::Default) + return UseSoftFloat; + else + return TLInfo.getTargetMachine().Options.FloatABIType == FloatABI::Soft; + } + + bool has3E3r1() const { return Has3E3r1; } + + bool useConstantIslands() const; +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYSUBTARGET_H Index: llvm/lib/Target/CSKY/CSKYSubtarget.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYSubtarget.cpp @@ -0,0 +1,63 @@ +//===-- CSKYSubtarget.h - Define Subtarget for the CSKY----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CSKY specific subclass of TargetSubtargetInfo. +// +//===----------------------------------------------------------------------===// + +#include "CSKYSubtarget.h" + +using namespace llvm; + +#define DEBUG_TYPE "csky-subtarget" +#define GET_SUBTARGETINFO_TARGET_DESC +#define GET_SUBTARGETINFO_CTOR +#include "CSKYGenSubtargetInfo.inc" + +static cl::opt + CSKYConstantIslands("csky-constant-islands", cl::NotHidden, + cl::desc("Enable csky constant islands."), + cl::init(true)); + +void CSKYSubtarget::initializeEnvironment() { + HasFPUv2SingleFloat = false; + HasFPUv2DoubleFloat = false; + HasFPUv2 = false; + HasFPUv3HalfWord = false; + HasFPUv3HalfFloat = false; + HasFPUv3SingleFloat = false; + HasFPUv3DoubleFloat = false; + HasFPUv3 = false; + + HasFdivdu = false; + + UseSoftFloat = true; + + Has3E3r1 = false; +} + +bool CSKYSubtarget::useConstantIslands() const { return CSKYConstantIslands; } + +CSKYSubtarget &CSKYSubtarget::initializeSubtargetDependencies(const Triple &TT, + StringRef CPU, + StringRef FS) { + + initializeEnvironment(); + + if (CPU.empty()) + CPU = "generic-csky"; + + ParseSubtargetFeatures(CPU, CPU, FS); + return *this; +} + +CSKYSubtarget::CSKYSubtarget(const Triple &TT, StringRef CPU, StringRef FS, + const TargetMachine &TM) + : CSKYGenSubtargetInfo(TT, CPU, CPU, FS), + FrameLowering(initializeSubtargetDependencies(TT, CPU, FS)), + InstrInfo(*this), RegInfo(), TLInfo(TM, *this) {} Index: llvm/lib/Target/CSKY/CSKYTargetMachine.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYTargetMachine.h @@ -0,0 +1,43 @@ +//===--- CSKYTargetMachine.h - Define TargetMachine for CSKY ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the CSKY specific subclass of TargetMachine. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYTARGETMACHINE_H +#define LLVM_LIB_TARGET_CSKY_CSKYTARGETMACHINE_H + +#include "CSKYSubtarget.h" +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +class CSKYTargetMachine : public LLVMTargetMachine { + std::unique_ptr TLOF; + mutable StringMap> SubtargetMap; + +public: + CSKYTargetMachine(const Target &T, const Triple &TT, StringRef CPU, + StringRef FS, const TargetOptions &Options, + Optional RM, Optional CM, + CodeGenOpt::Level OL, bool JIT); + + const CSKYSubtarget *getSubtargetImpl(const Function &F) const override; + const CSKYSubtarget *getSubtargetImpl() const = delete; + + TargetPassConfig *createPassConfig(PassManagerBase &PM) override; + + TargetLoweringObjectFile *getObjFileLowering() const override { + return TLOF.get(); + } +}; +} // namespace llvm + +#endif \ No newline at end of file Index: llvm/lib/Target/CSKY/CSKYTargetMachine.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYTargetMachine.cpp @@ -0,0 +1,155 @@ +//===--- CSKYTargetMachine.cpp - Define TargetMachine for CSKY ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implements the info about CSKY target spec. +// +//===----------------------------------------------------------------------===// + +#include "CSKYTargetMachine.h" +#include "CSKY.h" +#include "CSKYTargetObjectFile.h" +#include "TargetInfo/CSKYTargetInfo.h" +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" +#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTarget() { + RegisterTargetMachine X(getTheCSKYTarget()); + PassRegistry *Registry = PassRegistry::getPassRegistry(); + + // TODO: Initialize pass + initializeCSKYConstantIslandsPass(*Registry); +} + +using namespace llvm; + +// Specifies how data is to be laid out in memory. +// The layout specification consists of a list of specifications separated by +// the minus sign character ('-'). +static std::string computeDataLayout(const Triple &TT) { + std::string Ret; + + // Specifies target lays out data in Big or Little endian form. + Ret += "e"; + + // S Specifies the natural alignment of the stack in bits. + Ret += "-S32"; + + Ret += DataLayout::getManglingComponent(TT); + + // p[n]:::: + // Specifies the size of a pointer and its and erred alignments + // for address space n. + Ret += "-p:32:32"; + // i:: + // This specifies the alignment for an integer type of a given bit . + Ret += "-i32:32:32"; + Ret += "-i64:32:32"; + // f:: + // This specifies the alignment for a floating-point type of a given bit + // . + Ret += "-f32:32:32"; + Ret += "-f64:32:32"; + // v:: + // This specifies the alignment for a vector type of a given bit . + Ret += "-v64:32:32"; + Ret += "-v128:32:32"; + // S Specifies the natural alignment of the stack in bits. + Ret += "-S32"; + // a:: This specifies the alignment for an object of aggregate + // type. + Ret += "-a:0:32"; + // F Specifies the alignment for function pointers. + Ret += "-Fi32"; + // n::... Specifies a set of native integer widths for + // target. + Ret += "-n32"; + + return Ret; +} + +static Reloc::Model getEffectiveRelocModel(const Triple &TT, + Optional RM) { + if (!RM.hasValue()) + return Reloc::Static; + return *RM; +} + +CSKYTargetMachine::CSKYTargetMachine(const Target &T, const Triple &TT, + StringRef CPU, StringRef FS, + const TargetOptions &Options, + Optional RM, + Optional CM, + CodeGenOpt::Level OL, bool JIT) + : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, + getEffectiveRelocModel(TT, RM), + getEffectiveCodeModel(CM, CodeModel::Small), OL), + TLOF(std::make_unique()) { + initAsmInfo(); +} + +const CSKYSubtarget * +CSKYTargetMachine::getSubtargetImpl(const Function &F) const { + Attribute CPUAttr = F.getFnAttribute("target-cpu"); + Attribute FSAttr = F.getFnAttribute("target-features"); + + std::string CPU = + CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; + std::string FS = + FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; + + std::string Key = CPU + FS; + auto &I = SubtargetMap[Key]; + if (!I) { + // This needs to be done before we create a new subtarget since any + // creation will depend on the TM and the code generation flags on the + // function that reside in TargetOptions. + resetTargetOptions(F); + I = std::make_unique(TargetTriple, CPU, FS, *this); + } + return I.get(); +} + +namespace { +class CSKYPassConfig : public TargetPassConfig { +public: + CSKYPassConfig(CSKYTargetMachine &TM, PassManagerBase &PM) + : TargetPassConfig(TM, PM) {} + + CSKYTargetMachine &getCSKYTargetMachine() const { + return getTM(); + } + + // TODO: override add pass API + bool addInstSelector() override; + void addIRPasses() override; + void addPreEmitPass() override; +}; + +void CSKYPassConfig::addIRPasses() { + addPass(createAtomicExpandPass()); + TargetPassConfig::addIRPasses(); +} + +bool CSKYPassConfig::addInstSelector() { + addPass(createCSKYISelDag(getCSKYTargetMachine())); + return false; +} + +void CSKYPassConfig::addPreEmitPass() { + addPass(createCSKYConstantIslandPass()); + addPass(&BranchRelaxationPassID); +} + +} // namespace + +TargetPassConfig *CSKYTargetMachine::createPassConfig(PassManagerBase &PM) { + return new CSKYPassConfig(*this, PM); +} Index: llvm/lib/Target/CSKY/CSKYTargetObjectFile.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYTargetObjectFile.h @@ -0,0 +1,23 @@ +//===-- CSKYTargetObjectFile.h - CSKY Object Info -*- C++ ---------------*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_CSKYTARGETOBJECTFILE_H +#define LLVM_LIB_TARGET_CSKY_CSKYTARGETOBJECTFILE_H + +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" + +namespace llvm { + +class CSKYELFTargetObjectFile : public TargetLoweringObjectFileELF { +public: + void Initialize(MCContext &Ctx, const TargetMachine &TM) override; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_CSKYTARGETOBJECTFILE_H Index: llvm/lib/Target/CSKY/CSKYTargetObjectFile.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/CSKYTargetObjectFile.cpp @@ -0,0 +1,18 @@ +//===-- CSKYTargetObjectFile.h - CSKY Object Info -*- C++ ---------------*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYTargetObjectFile.h" +#include "CSKYTargetMachine.h" + +using namespace llvm; + +void CSKYELFTargetObjectFile::Initialize(MCContext &Ctx, + const TargetMachine &TM) { + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); +} Index: llvm/lib/Target/CSKY/Disassembler/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Disassembler/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMCSKYDisassembler + CSKYDisassembler.cpp + ) Index: llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp @@ -0,0 +1,11 @@ +//===-- CSKYDisassembler.cpp - Disassembler for CSKY ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the CSKYDisassembler class. +// +//===----------------------------------------------------------------------===// Index: llvm/lib/Target/CSKY/Disassembler/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Disassembler/LLVMBuild.txt @@ -0,0 +1,23 @@ +;===- ./lib/Target/CSKY/Disassembler/LLVMBuild.txt -------------*- Conf -*--===; +; +; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = CSKYDisassembler +parent = CSKY +required_libraries = MCDisassembler Support +add_to_library_groups = CSKY + Index: llvm/lib/Target/CSKY/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/LLVMBuild.txt @@ -0,0 +1,32 @@ +;===----- ./lib/Target/CSKY/LLVMBuild.txt ----------------------*- Conf -*--===; +; +; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[common] +subdirectories = TargetInfo MCTargetDesc Utils + +[component_0] +type = TargetGroup +name = CSKY +parent = Target +has_asmprinter = 1 + +[component_1] +type = Library +name = CSKYCodeGen +parent = CSKY +required_libraries = AsmPrinter Core CodeGen CSKYInfo Support + Target MC SelectionDAG CSKYUtils +add_to_library_groups = CSKY Index: llvm/lib/Target/CSKY/MCTargetDesc/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CMakeLists.txt @@ -0,0 +1,12 @@ +add_llvm_library(LLVMCSKYDesc + CSKYMCTargetDesc.cpp + CSKYAsmBackend.cpp + CSKYMCAsmInfo.cpp + CSKYInstPrinter.cpp + CSKYMCCodeEmitter.cpp + CSKYELFObjectWriter.cpp + CSKYTargetStreamer.cpp + CSKYTargetAsmStreamer.cpp + CSKYTargetELFStreamer.cpp + CSKYMCExpr.cpp +) Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.h @@ -0,0 +1,40 @@ +//===-- CSKYAsmBackend.h - CSKY Assembler Backend -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/MC/MCAsmBackend.h" + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYASMBACKEND_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYASMBACKEND_H + +namespace llvm { +class CSKYAsmBackend : public MCAsmBackend { +public: + CSKYAsmBackend(const MCSubtargetInfo &STI, const MCTargetOptions &OP) + : MCAsmBackend(support::little) {} + + unsigned int getNumFixupKinds() const override; + void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, MutableArrayRef Data, + uint64_t Value, bool IsResolved, + const MCSubtargetInfo *STI) const override; + bool mayNeedRelaxation(const MCInst &Inst, + const MCSubtargetInfo &STI) const override; + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override; + void relaxInstruction(MCInst &Inst, + const MCSubtargetInfo &STI) const override; + bool writeNopData(raw_ostream &OS, uint64_t Count) const override; + std::unique_ptr + createObjectTargetWriter() const override; + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYASMBACKEND_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp @@ -0,0 +1,241 @@ +//===-- CSKYAsmBackend.cpp - CSKY Assembler Backend -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYAsmBackend.h" +#include "CSKYFixupKinds.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "csky-asmbackend" + +using namespace llvm; + +static unsigned getFixupKindNumBytes(unsigned Kind) { + switch (Kind) { + default: + LLVM_DEBUG(dbgs() << "fixup kind = " << Kind << "\n"); + llvm_unreachable("Unknown fixup kind!"); + case FK_Data_1: + return 1; + + case FK_Data_2: + return 2; + + case FK_Data_4: + case CSKY::fixup_csky_pcrel_imm16_scale2: + case CSKY::fixup_csky_pcrel_imm16_scale4: + case CSKY::fixup_csky_pcrel_uimm16_scale4: + case CSKY::fixup_csky_pcrel_imm26_scale2: + case CSKY::fixup_csky_pcrel_jsr_imm26_scale2: + case CSKY::fixup_csky_got_imm18_scale4: + case CSKY::fixup_csky_plt_imm18_scale4: + case CSKY::fixup_csky_addr_hi16: + case CSKY::fixup_csky_addr_lo16: + case CSKY::fixup_csky_addr32: + case CSKY::fixup_csky_gotpc: + case CSKY::fixup_csky_gotoff: + case CSKY::fixup_csky_pcrel_imm18_scale2: + case CSKY::fixup_csky_got_hi16: + case CSKY::fixup_csky_got_lo16: + case CSKY::fixup_csky_got32: + case CSKY::fixup_csky_gotoff_hi16: + case CSKY::fixup_csky_gotoff_lo16: + case CSKY::fixup_csky_got12: + return 4; + } +} + +static bool isInstFixupKind(unsigned Kind) { + switch (Kind) { + default: + LLVM_DEBUG(dbgs() << "fixup kind = " << Kind << "\n"); + llvm_unreachable("Unknown fixup kind!"); + + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + return false; + + case CSKY::fixup_csky_pcrel_imm16_scale2: + case CSKY::fixup_csky_pcrel_imm16_scale4: + case CSKY::fixup_csky_pcrel_uimm16_scale4: + case CSKY::fixup_csky_pcrel_imm26_scale2: + case CSKY::fixup_csky_pcrel_jsr_imm26_scale2: + case CSKY::fixup_csky_got_imm18_scale4: + case CSKY::fixup_csky_plt_imm18_scale4: + case CSKY::fixup_csky_addr_hi16: + case CSKY::fixup_csky_addr_lo16: + case CSKY::fixup_csky_addr32: + case CSKY::fixup_csky_gotpc: + case CSKY::fixup_csky_gotoff: + case CSKY::fixup_csky_pcrel_imm18_scale2: + case CSKY::fixup_csky_got_hi16: + case CSKY::fixup_csky_got_lo16: + case CSKY::fixup_csky_got32: + case CSKY::fixup_csky_gotoff_hi16: + case CSKY::fixup_csky_gotoff_lo16: + case CSKY::fixup_csky_got12: + return true; + } +} + +static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, + const MCFixupKindInfo &Info, MCContext &Ctx) { + int64_t Bits = Info.TargetSize; + + switch (Fixup.getTargetKind()) { + default: + LLVM_DEBUG(dbgs() << "fixup kind = " << Fixup.getTargetKind() << "\n"); + llvm_unreachable("Unknown fixup kind!"); + case FK_Data_1: + case FK_Data_2: + case FK_Data_4: + break; + case CSKY::fixup_csky_addr_lo16: + return Value & 0xFFFF; + case CSKY::fixup_csky_addr_hi16: + return (Value >> 16) & 0xFFFF; + case CSKY::fixup_csky_pcrel_imm16_scale2: + case CSKY::fixup_csky_pcrel_imm18_scale2: + case CSKY::fixup_csky_pcrel_imm26_scale2: + if (!isIntN(Bits + 1, Value)) + Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); + if (Value & 0x1) + Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned."); + + return ((Value >> 1) & APInt::getMaxValue(Bits)).getZExtValue(); + case CSKY::fixup_csky_pcrel_imm16_scale4: + if (!isIntN(Bits + 2, Value)) + Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); + if (Value & 0x3) + Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned."); + + return ((Value >> 2) & APInt::getMaxValue(Bits)).getZExtValue(); + case CSKY::fixup_csky_pcrel_uimm16_scale4: + if (!isUIntN(Bits + 2, Value)) + Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value."); + if (Value & 0x3) + Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned."); + + return ((Value >> 2) & APInt::getMaxValue(Bits)).getZExtValue(); + } + + return 0; +} + +std::unique_ptr +CSKYAsmBackend::createObjectTargetWriter() const { + return createCSKYELFObjectWriter(); +} + +unsigned int CSKYAsmBackend::getNumFixupKinds() const { + return CSKY::NumTargetFixupKinds; +} + +void CSKYAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, + MutableArrayRef Data, uint64_t Value, + bool IsResolved, + const MCSubtargetInfo *STI) const { + MCFixupKind Kind = Fixup.getKind(); + if (Kind >= FirstLiteralRelocationKind) + return; + unsigned NumBytes = getFixupKindNumBytes(Kind); + bool IsInstFixup = isInstFixupKind(Fixup.getKind()); + bool IsLittleEndian = (Endian == support::little); + MCContext &Ctx = Asm.getContext(); + MCFixupKindInfo Info = getFixupKindInfo(Kind); + Value = adjustFixupValue(Fixup, Value, Info, Ctx); + if (!Value) + return; // Doesn't change encoding. + + unsigned Offset = Fixup.getOffset(); + + // For each byte of the fragment that the fixup touches, mask in the bits from + // the fixup value. The Value has been "split up" into the appropriate + // bitfields above. + // The 32-bit CSKY instructions should be handled as two 16-bit parts in the + // processing of endian model. + if (IsLittleEndian && IsInstFixup && (NumBytes == 4)) { + Data[Offset + 0] |= uint8_t((Value >> 16) & 0xff); + Data[Offset + 1] |= uint8_t((Value >> 24) & 0xff); + Data[Offset + 2] |= uint8_t(Value & 0xff); + Data[Offset + 3] |= uint8_t((Value >> 8) & 0xff); + } else { + for (unsigned I = 0; I != NumBytes; I++) { + unsigned Idx = IsLittleEndian ? I : (NumBytes - 1 - I); + Data[Offset + Idx] |= uint8_t((Value >> (I * 8)) & 0xff); + } + } +} + +bool CSKYAsmBackend::mayNeedRelaxation(const MCInst &Inst, + const MCSubtargetInfo &STI) const { + return false; +} + +bool CSKYAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const { + return false; +} + +void CSKYAsmBackend::relaxInstruction(MCInst &Inst, + const MCSubtargetInfo &STI) const {} + +bool CSKYAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const { + if (Count % 2) + return false; + + // MOV32 r0, r0 + while (Count >= 4) { + OS.write("\xc4\x00\x48\x20", 4); + Count -= 4; + } + // MOV16 r0, r0 + if (Count) + OS.write("\x6c\x03", 2); + + return true; +} + +const MCFixupKindInfo & +CSKYAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { + + static llvm::DenseMap Infos = { + {CSKY::Fixups::fixup_csky_pcrel_imm16_scale2, + {"fixup_csky_pcrel_imm16_scale2", 0, 16, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_pcrel_imm16_scale4, + {"fixup_csky_pcrel_imm16_scale4", 0, 16, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_pcrel_uimm16_scale4, + {"fixup_csky_pcrel_uimm16_scale4", 0, 16, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_pcrel_imm26_scale2, + {"fixup_csky_pcrel_imm26_scale2", 0, 26, MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_pcrel_jsr_imm26_scale2, + {"fixup_csky_pcrel_jsr_imm26_scale2", 0, 26, + MCFixupKindInfo::FKF_IsPCRel}}, + {CSKY::Fixups::fixup_csky_got_imm18_scale4, + {"fixup_csky_got_imm18_scale4", 0, 18, 0}}, + {CSKY::Fixups::fixup_csky_plt_imm18_scale4, + {"fixup_csky_plt_imm18_scale4", 0, 18, 0}}, + {CSKY::Fixups::fixup_csky_addr_hi16, {"fixup_csky_addr_hi16", 0, 16, 0}}, + {CSKY::Fixups::fixup_csky_addr_lo16, {"fixup_csky_addr_lo16", 0, 16, 0}}, + {CSKY::Fixups::fixup_csky_gotpc, {"fixup_csky_gotpc", 0, 16, 0}}, + {CSKY::Fixups::fixup_csky_pcrel_imm18_scale2, + {"fixup_csky_pcrel_imm18_scale2", 0, 18, MCFixupKindInfo::FKF_IsPCRel}}}; + + if (Kind < FirstTargetFixupKind) + return MCAsmBackend::getFixupKindInfo(Kind); + + assert((unsigned(Kind - FirstTargetFixupKind)) < getNumFixupKinds() && + "Invalid kind!"); + return Infos[Kind]; +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp @@ -0,0 +1,96 @@ +//===-- CSKYELFObjectWriter.cpp - CSKY ELF Writer -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYFixupKinds.h" +#include "CSKYMCExpr.h" +#include "CSKYMCTargetDesc.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCObjectWriter.h" + +using namespace llvm; + +namespace { + +class CSKYELFObjectWriter : public MCELFObjectTargetWriter { +public: + CSKYELFObjectWriter(uint8_t OSABI = 0) + : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){}; + ~CSKYELFObjectWriter() {} + + unsigned int getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsPCRel) const override { + + const MCExpr *Expr = Fixup.getValue(); + // Determine the type of the relocation + unsigned Kind = Fixup.getTargetKind(); + if (IsPCRel) { + switch (Kind) { + default: + printf("Kind1 = %d\n", Kind); + Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); + return ELF::R_CKCORE_NONE; + case FK_Data_4: + case FK_PCRel_4: + return ELF::R_CKCORE_PCREL32; + case CSKY::fixup_csky_pcrel_uimm16_scale4: + case CSKY::fixup_csky_pcrel_imm16_scale4: + return ELF::R_CKCORE_PCREL_IMM16_4; + case CSKY::fixup_csky_pcrel_imm26_scale2: + return ELF::R_CKCORE_PCREL_IMM26_2; + } + } + + switch (Kind) { + default: + printf("Kind2 = %d\n", Kind); + Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type"); + return ELF::R_CKCORE_NONE; + case FK_Data_1: + Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); + return ELF::R_CKCORE_NONE; + case FK_Data_2: + Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported"); + return ELF::R_CKCORE_NONE; + case FK_Data_4: + if (Expr->getKind() == MCExpr::Target) { + auto TK = cast(Expr)->getKind(); + if (TK == CSKYMCExpr::VK_CSKY_GOT) + return ELF::R_CKCORE_GOT32; + if (TK == CSKYMCExpr::VK_CSKY_GOTOFF) + return ELF::R_CKCORE_GOTOFF; + } + return ELF::R_CKCORE_ADDR32; + case FK_Data_8: + Ctx.reportError(Fixup.getLoc(), "8-byte data relocations not supported"); + return ELF::R_CKCORE_NONE; + case CSKY::fixup_csky_addr32: + return ELF::R_CKCORE_ADDR32; + case CSKY::fixup_csky_addr_hi16: + return ELF::R_CKCORE_ADDR_HI16; + case CSKY::fixup_csky_addr_lo16: + return ELF::R_CKCORE_ADDR_LO16; + case CSKY::fixup_csky_got_hi16: + return ELF::R_CKCORE_GOT_HI16; + case CSKY::fixup_csky_got_lo16: + return ELF::R_CKCORE_GOT_LO16; + case CSKY::fixup_csky_gotoff_hi16: + return ELF::R_CKCORE_GOTOFF_HI16; + case CSKY::fixup_csky_gotoff_lo16: + return ELF::R_CKCORE_GOTOFF_LO16; + case CSKY::fixup_csky_got12: + return ELF::R_CKCORE_GOT12; + } + } +}; + +} // namespace + +std::unique_ptr llvm::createCSKYELFObjectWriter() { + return std::make_unique(); +} \ No newline at end of file Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYFixupKinds.h @@ -0,0 +1,63 @@ +//===-- CSKYFixupKinds.h - CSKY Specific Fixup Entries ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYFIXUPKINDS_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +namespace llvm { +namespace CSKY { +// TODO: add comments +enum Fixups { + fixup_csky_pcrel_imm16_scale2 = FirstTargetFixupKind, + + fixup_csky_pcrel_imm16_scale4, + + fixup_csky_pcrel_uimm16_scale4, + + fixup_csky_pcrel_imm26_scale2, + + fixup_csky_pcrel_jsr_imm26_scale2, + + fixup_csky_got_imm18_scale4, + + fixup_csky_plt_imm18_scale4, + + fixup_csky_addr_hi16, + + fixup_csky_addr_lo16, + + fixup_csky_addr32, + + fixup_csky_gotpc, + + fixup_csky_gotoff, + + fixup_csky_pcrel_imm18_scale2, + + fixup_csky_got_hi16, + + fixup_csky_got_lo16, + + fixup_csky_got32, + + fixup_csky_gotoff_hi16, + + fixup_csky_gotoff_lo16, + + fixup_csky_got12, + + // Marker + fixup_csky_invalid, + NumTargetFixupKinds = fixup_csky_invalid - FirstTargetFixupKind +}; +} // end namespace CSKY +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYFIXUPKINDS_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.h @@ -0,0 +1,42 @@ +//===-- CSKYInstPrinter.h - Convert CSKY MCInst to asm syntax ---*- C++ -*----// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class prints a CSKY MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYINSTPRINTER_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYINSTPRINTER_H + +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + +class CSKYInstPrinter : public MCInstPrinter { +public: + CSKYInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} + + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &OS) override; + void printRegName(raw_ostream &O, unsigned RegNo) const override; + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, + const char *Modifier = nullptr); + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); + + static const char *getRegisterName(unsigned RegNo); + static const char *getRegisterName(unsigned RegNo, unsigned AltIdx); +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYINSTPRINTER_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp @@ -0,0 +1,56 @@ +//===-- CSKYInstPrinter.cpp - Convert CSKY MCInst to asm syntax -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class prints an CSKY MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#include "CSKYInstPrinter.h" +#include "Utils/CSKYBaseInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FormattedStream.h" + +using namespace llvm; + +#include "CSKYGenAsmWriter.inc" + +static cl::opt + ArchRegNames("csky-arch-reg-names", + cl::desc("Print architectural register names rather than the " + "ABI names (such as r0 instead of a0)"), + cl::init(false), cl::Hidden); + +void CSKYInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, const MCSubtargetInfo &STI, + raw_ostream &OS) { + printInstruction(MI, Address, OS); + printAnnotation(OS, Annot); +} + +void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, const char *Modifier) { + assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); + const MCOperand &MO = MI->getOperand(OpNo); + if (MO.isReg()) { + printRegName(O, MO.getReg()); + return; + } + if (MO.isImm()) { + O << MO.getImm(); + return; + } + assert(MO.isExpr() && "Unknown operand kind in printOperand"); + MO.getExpr()->print(O, &MAI); +} + +void CSKYInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { + O << getRegisterName(RegNo, + ArchRegNames ? CSKY::NoRegAltName : CSKY::ABIRegAltName); +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.h @@ -0,0 +1,27 @@ +//===-- CSKYMCAsmInfo.h - CSKY Asm Info ------------------------*- C++ -*--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the CSKYMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCASMINFO_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCASMINFO_H + +#include "llvm/MC/MCAsmInfoELF.h" + +namespace llvm { +class Triple; + +class CSKYMCAsmInfo : public MCAsmInfoELF { +public: + explicit CSKYMCAsmInfo(const Triple &TargetTriple); +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCASMINFO_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCAsmInfo.cpp @@ -0,0 +1,17 @@ +//===-- CSKYMCAsmInfo.cpp - CSKY Asm properties ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the CSKYMCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCAsmInfo.h" + +using namespace llvm; + +CSKYMCAsmInfo::CSKYMCAsmInfo(const Triple &TargetTriple) {} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.h @@ -0,0 +1,66 @@ +//===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the CSKYMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H + +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCContext.h" + +namespace llvm { + +class CSKYMCCodeEmitter : public MCCodeEmitter { + MCContext &Ctx; + const MCInstrInfo &MII; + +public: + CSKYMCCodeEmitter(MCContext &Ctx, const MCInstrInfo &MII) + : Ctx(Ctx), MII(MII) {} + + ~CSKYMCCodeEmitter() {} + + void encodeInstruction(const MCInst &Inst, raw_ostream &OS, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const override; + + // Generated by tablegen. + uint64_t getBinaryCodeForInstr(const MCInst &MI, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + // Default encoding method used by tablegen. + unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getCalltargetOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getBranchtargetOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + unsigned getOImm(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + + void EmitInstruction(uint64_t Bin, unsigned Size, raw_ostream &OS) const; +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCCODEEMITTER_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCCodeEmitter.cpp @@ -0,0 +1,165 @@ +//===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the CSKYMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCCodeEmitter.h" +#include "CSKYFixupKinds.h" +#include "CSKYMCExpr.h" +#include "Utils/CSKYBaseInfo.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/Support/EndianStream.h" + +#define DEBUG_TYPE "mccodeemitter" + +STATISTIC(MCNumFixups, "Number of MC fixups created"); + +using namespace llvm; + +void CSKYMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCInstrDesc &Desc = MII.get(MI.getOpcode()); + int Size = Desc.getSize(); + assert((Size == 2 || Size == 4) && "Unexpected MI Size."); + + uint64_t Bin = getBinaryCodeForInstr(MI, Fixups, STI); + EmitInstruction(Bin, Size, OS); +} + +unsigned +CSKYMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + if (MO.isReg()) + return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); + + if (MO.isImm()) + return static_cast(MO.getImm()); + + llvm_unreachable("Unexpected MO type."); +} + +unsigned +CSKYMCCodeEmitter::getCalltargetOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isExpr() && "Unexpected MO type."); + MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm26_scale2); + Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); + return 0; +} + +unsigned +CSKYMCCodeEmitter::getBranchtargetOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isExpr() && "Unexpected MO type."); + MCFixupKind Kind = MCFixupKind(CSKY::fixup_csky_pcrel_imm16_scale2); + Fixups.push_back(MCFixup::create(0, MO.getExpr(), Kind, MI.getLoc())); + return 0; +} + +unsigned CSKYMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + + // If the destination is an immediate, there is nothing to do. + if (MO.isImm()) + return MO.getImm(); + + assert(MO.isExpr() && "getImmOpValue expects only expressions or immediates"); + const MCExpr *Expr = MO.getExpr(); + MCExpr::ExprKind Kind = Expr->getKind(); + CSKY::Fixups FixupKind = CSKY::fixup_csky_invalid; + + if (Kind == MCExpr::Target) { + const CSKYMCExpr *CSKYExpr = cast(Expr); + + switch (CSKYExpr->getKind()) { + default: + llvm_unreachable("can not reach here"); + case CSKYMCExpr::VK_CSKY_None: + llvm_unreachable("Unhandled fixup kind!"); + case CSKYMCExpr::VK_CSKY_GOT_HI: + FixupKind = CSKY::fixup_csky_got_hi16; + break; + case CSKYMCExpr::VK_CSKY_GOT_LO: + FixupKind = CSKY::fixup_csky_got_lo16; + break; + case CSKYMCExpr::VK_CSKY_GOTOFF_HI: + FixupKind = CSKY::fixup_csky_gotoff_hi16; + break; + case CSKYMCExpr::VK_CSKY_GOTOFF_LO: + FixupKind = CSKY::fixup_csky_gotoff_lo16; + break; + case CSKYMCExpr::VK_CSKY_ADDR_HI: + FixupKind = CSKY::fixup_csky_addr_hi16; + break; + case CSKYMCExpr::VK_CSKY_ADDR_LO: + FixupKind = CSKY::fixup_csky_addr_lo16; + break; + case CSKYMCExpr::VK_CSKY_ADDR: + FixupKind = CSKY::fixup_csky_addr32; + break; + case CSKYMCExpr::VK_CSKY_GOT: + FixupKind = CSKY::fixup_csky_got32; + break; + case CSKYMCExpr::VK_CSKY_GOTOFF: + FixupKind = CSKY::fixup_csky_gotoff; + break; + case CSKYMCExpr::VK_CSKY_GOT12: + FixupKind = CSKY::fixup_csky_got12; + break; + } + } else if (Kind == MCExpr::SymbolRef && + cast(Expr)->getKind() == + MCSymbolRefExpr::VK_None) { + if (MI.getOpcode() == CSKY::LRW32) { + FixupKind = CSKY::fixup_csky_pcrel_uimm16_scale4; + } else if (MI.getOpcode() == CSKY::JSRI32) { + FixupKind = CSKY::fixup_csky_pcrel_uimm16_scale4; + } else { + assert(0); + } + } + + assert(FixupKind != CSKY::fixup_csky_invalid && "Unhandled expression!"); + + Fixups.push_back( + MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc())); + ++MCNumFixups; + + return 0; +} + +unsigned CSKYMCCodeEmitter::getOImm(const MCInst &MI, unsigned Idx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(Idx); + assert(MO.isImm() && "Unexpected MO type."); + return MO.getImm() - 1; +} + +void CSKYMCCodeEmitter::EmitInstruction(uint64_t Bin, unsigned Size, + raw_ostream &OS) const { + uint16_t LO16 = static_cast(Bin); + uint16_t HI16 = static_cast(Bin >> 16); + if (Size == 4) { + support::endian::write(OS, HI16, support::little); + } + support::endian::write(OS, LO16, support::little); +} + +#include "CSKYGenMCCodeEmitter.inc" Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.h @@ -0,0 +1,70 @@ +//===-- CSKYMCExpr.h - CSKY specific MC expression classes -*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCEXPR_H +#define LLVM_LIB_TARGET_LANAI_MCTARGETDESC_LANAIMCEXPR_H + +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" + +namespace llvm { + +class CSKYMCExpr : public MCTargetExpr { +public: + enum VariantKind { + VK_CSKY_None, + VK_CSKY_GOT_LO, + VK_CSKY_GOT_HI, + VK_CSKY_ADDR_LO, + VK_CSKY_ADDR_HI, + VK_CSKY_GOTOFF_LO, + VK_CSKY_GOTOFF_HI, + VK_CSKY_ADDR, + VK_CSKY_GOT, + VK_CSKY_GOTOFF, + VK_CSKY_GOT12, + VK_CSKY_TLSGD, + VK_CSKY_TPOFF, + VK_CSKY_GOTTPOFF + }; + +private: + const VariantKind Kind; + const MCExpr *Expr; + + explicit CSKYMCExpr(VariantKind Kind, const MCExpr *Expr) + : Kind(Kind), Expr(Expr) {} + +public: + static const CSKYMCExpr *create(const MCExpr *Expr, VariantKind Kind, + MCContext &Ctx); + + // Returns the kind of this expression. + VariantKind getKind() const { return Kind; } + + // Returns the child of this expression. + const MCExpr *getSubExpr() const { return Expr; } + + void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; + bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, + const MCFixup *Fixup) const override; + void visitUsedExpr(MCStreamer &Streamer) const override; + MCFragment *findAssociatedFragment() const override { + return getSubExpr()->findAssociatedFragment(); + } + + // There are no TLS CSKYMCExprs at the moment. + void fixELFSymbolsInTLSFixups(MCAssembler & /*Asm*/) const override {} + + static bool classof(const MCExpr *E) { + return E->getKind() == MCExpr::Target; + } +}; +} // end namespace llvm + +#endif Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp @@ -0,0 +1,82 @@ +//===-- CSKYMCExpr.cpp - CSKY specific MC expression classes -*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYMCExpr.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCStreamer.h" +using namespace llvm; + +#define DEBUG_TYPE "cskymcexpr" + +const CSKYMCExpr *CSKYMCExpr::create(const MCExpr *Expr, VariantKind Kind, + MCContext &Ctx) { + return new (Ctx) CSKYMCExpr(Kind, Expr); +} + +void CSKYMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { + + Expr->print(OS, MAI); + + switch (Kind) { + default: + LLVM_DEBUG(dbgs() << "Kind = " << Kind << "."); + llvm_unreachable("Invalid kind!"); + case VK_CSKY_None: + break; + case VK_CSKY_ADDR_HI: + OS << "@hi"; + break; + case VK_CSKY_ADDR_LO: + OS << "@lo"; + break; + case VK_CSKY_GOT_HI: + OS << "@GOT_HI16"; + break; + case VK_CSKY_GOT_LO: + OS << "@GOT_LO16"; + break; + case VK_CSKY_GOTOFF_HI: + OS << "@GOTOFF_HI16"; + break; + case VK_CSKY_GOTOFF_LO: + OS << "@GOTOFF_LO16"; + break; + case VK_CSKY_GOT: + case VK_CSKY_GOT12: + OS << "@GOT"; + break; + case VK_CSKY_GOTOFF: + OS << "@GOTOFF"; + break; + case VK_CSKY_ADDR: + break; + case VK_CSKY_TLSGD: + break; + case VK_CSKY_TPOFF: + break; + case VK_CSKY_GOTTPOFF: + break; + } +} + +void CSKYMCExpr::visitUsedExpr(MCStreamer &Streamer) const { + Streamer.visitUsedExpr(*getSubExpr()); +} + +bool CSKYMCExpr::evaluateAsRelocatableImpl(MCValue &Res, + const MCAsmLayout *Layout, + const MCFixup *Fixup) const { + if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) + return false; + + Res = + MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); + + return true; +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.h @@ -0,0 +1,44 @@ +//===-- CSKYMCTargetDesc.h - CSKY Target Descriptions -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides CSKY specific target descriptions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H + +#include "llvm/MC/MCTargetOptions.h" +#include + +namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCInstrInfo; +class MCRegisterInfo; +class MCObjectTargetWriter; +class MCRegisterInfo; +class MCSubtargetInfo; +class Target; +class Triple; + +std::unique_ptr createCSKYELFObjectWriter(); + +} // namespace llvm + +#define GET_REGINFO_ENUM +#include "CSKYGenRegisterInfo.inc" + +#define GET_INSTRINFO_ENUM +#include "CSKYGenInstrInfo.inc" + +#define GET_SUBTARGETINFO_ENUM +#include "CSKYGenSubtargetInfo.inc" + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYMCTARGETDESC_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp @@ -0,0 +1,111 @@ +//===-- CSKYMCTargetDesc.cpp - CSKY Target Descriptions -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// This file provides CSKY specific target descriptions. +/// +//===----------------------------------------------------------------------===// + +#include "CSKYMCTargetDesc.h" +#include "CSKYAsmBackend.h" +#include "CSKYInstPrinter.h" +#include "CSKYMCAsmInfo.h" +#include "CSKYMCCodeEmitter.h" +#include "CSKYTargetAsmStreamer.h" +#include "CSKYTargetELFStreamer.h" +#include "TargetInfo/CSKYTargetInfo.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/TargetRegistry.h" + +#define GET_INSTRINFO_MC_DESC +#include "CSKYGenInstrInfo.inc" + +#define GET_REGINFO_MC_DESC +#include "CSKYGenRegisterInfo.inc" + +#define GET_SUBTARGETINFO_MC_DESC +#include "CSKYGenSubtargetInfo.inc" + +using namespace llvm; + +static MCAsmBackend *createCSKYAsmBackend(const Target &T, + const MCSubtargetInfo &STI, + const MCRegisterInfo &MRI, + const MCTargetOptions &Options) { + return new CSKYAsmBackend(STI, Options); +} + +static MCAsmInfo *createCSKYMCAsmInfo(const MCRegisterInfo &MRI, + const Triple &TT, + const MCTargetOptions &Options) { + // TODO: add initial frame state + return new CSKYMCAsmInfo(TT); +} + +static MCInstrInfo *createCSKYMCInstrInfo() { + MCInstrInfo *Info = new MCInstrInfo(); + InitCSKYMCInstrInfo(Info); + return Info; +} + +static MCRegisterInfo *createCSKYMCRegisterInfo(const Triple &TT) { + MCRegisterInfo *Info = new MCRegisterInfo(); + InitCSKYMCRegisterInfo(Info, CSKY::LR); + return Info; +} + +static MCInstPrinter *createCSKYMCInstPrinter(const Triple &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) { + return new CSKYInstPrinter(MAI, MII, MRI); +} + +static MCCodeEmitter *createCSKYMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, + MCContext &Ctx) { + return new CSKYMCCodeEmitter(Ctx, MCII); +} + +static MCSubtargetInfo *createCSKYMCSubtargetInfo(const Triple &TT, + StringRef CPU, StringRef FS) { + return createCSKYMCSubtargetInfoImpl(TT, CPU, CPU, FS); +} + +static MCTargetStreamer * +createCSKYObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { + const Triple &TT = STI.getTargetTriple(); + if (TT.isOSBinFormatELF()) + return new CSKYTargetELFStreamer(S); + return nullptr; +} + +static MCTargetStreamer *createCSKYAsmTargetStreamer(MCStreamer &S, + formatted_raw_ostream &OS, + MCInstPrinter *InstPrinter, + bool IsVerboseAsm) { + return new CSKYTargetAsmStreamer(S); +} + +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYTargetMC() { + auto &CSKYTarget = getTheCSKYTarget(); + TargetRegistry::RegisterMCAsmBackend(CSKYTarget, createCSKYAsmBackend); + TargetRegistry::RegisterMCAsmInfo(CSKYTarget, createCSKYMCAsmInfo); + TargetRegistry::RegisterMCInstrInfo(CSKYTarget, createCSKYMCInstrInfo); + TargetRegistry::RegisterMCRegInfo(CSKYTarget, createCSKYMCRegisterInfo); + TargetRegistry::RegisterMCInstPrinter(CSKYTarget, createCSKYMCInstPrinter); + TargetRegistry::RegisterMCCodeEmitter(CSKYTarget, createCSKYMCCodeEmitter); + TargetRegistry::RegisterMCSubtargetInfo(CSKYTarget, + createCSKYMCSubtargetInfo); + TargetRegistry::RegisterObjectTargetStreamer(CSKYTarget, + createCSKYObjectTargetStreamer); + TargetRegistry::RegisterAsmTargetStreamer(CSKYTarget, + createCSKYAsmTargetStreamer); +} Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetAsmStreamer.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetAsmStreamer.h @@ -0,0 +1,23 @@ +//===-- CSKYTargetAsmStreamer.h - CSKY Target Asm Streamer ---*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETASMSTREAMER_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETASMSTREAMER_H + +#include "CSKYTargetStreamer.h" + +namespace llvm { + +class CSKYTargetAsmStreamer : public CSKYTargetStreamer { +public: + CSKYTargetAsmStreamer(MCStreamer &S) : CSKYTargetStreamer(S) {} +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETASMSTREAMER_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetAsmStreamer.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetAsmStreamer.cpp @@ -0,0 +1,11 @@ +//===-- CSKYTargetAsmStreamer.h - CSKY Target Asm Streamer ---*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYTargetAsmStreamer.h" + +using namespace llvm; Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetELFStreamer.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetELFStreamer.h @@ -0,0 +1,23 @@ +//===-- CSKYTargetELFStreamer.h - CSKY Target ELF Streamer ---*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETELFSTREAMER_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETELFSTREAMER_H + +#include "CSKYTargetStreamer.h" + +namespace llvm { + +class CSKYTargetELFStreamer : public CSKYTargetStreamer { +public: + CSKYTargetELFStreamer(MCStreamer &S) : CSKYTargetStreamer(S) {} +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETELFSTREAMER_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetELFStreamer.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetELFStreamer.cpp @@ -0,0 +1,11 @@ +//===-- CSKYTargetELFStreamer.h - CSKY Target ELF Streamer ---*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYTargetELFStreamer.h" + +using namespace llvm; \ No newline at end of file Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetStreamer.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetStreamer.h @@ -0,0 +1,23 @@ +//===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETSTREAMER_H +#define LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETSTREAMER_H + +#include "llvm/MC/MCStreamer.h" + +namespace llvm { + +class CSKYTargetStreamer : public MCTargetStreamer { +public: + CSKYTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} +}; + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_MCTARGETDESC_CSKYTARGETSTREAMER_H Index: llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetStreamer.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/CSKYTargetStreamer.cpp @@ -0,0 +1,11 @@ +//===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CSKYTargetStreamer.h" + +using namespace llvm; Index: llvm/lib/Target/CSKY/MCTargetDesc/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/MCTargetDesc/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===-- ./lib/Target/CSKY/MCTargetDesc/LLVMBuild.txt ------------*- Conf -*--===; +; +; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = CSKYDesc +parent = CSKY +required_libraries = MC CSKYInfo Support +add_to_library_groups = CSKY Index: llvm/lib/Target/CSKY/README.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/README.txt @@ -0,0 +1,20 @@ +//===- README.txt - Notes for improving CSKY-specific backend ---------===// + +TODO: +* Refine register list for CR series and related DwarfRegNum +* Refine the utils/UpdateTestChecks/asm.py script for csky target instead + of using existing target config +* Refine the ABI series functions LowerCall/LowerFormalArguments/LowerReturn +* Opt the s/udiv and s/urem instrs sequence(like strength reduction) +* Opt the material sequence of constant num such as the there is const op + in s/udiv and s/urem +* Add expanding support about SHL_PARTS/SRL_PARTS/SRA_PARTS instead of libcall. + May promote the expanding into target-independent logics +* Opt carry register spill sequence because only 1 carry register when multiple + setcc ops. See icmp.ll for Long Long type +* Enhance EH feature support +* Enhance va_arg feature support +* Enhance atomic feature support +* Enhance PIC and codemodel feature support +===-------------------------------------------------------------------------=== + Index: llvm/lib/Target/CSKY/TargetInfo/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/TargetInfo/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMCSKYInfo + CSKYTargetInfo.cpp + ) Index: llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.h @@ -0,0 +1,20 @@ +//===-- CSKYTargetInfo.cpp - CSKY Target Implementation -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_TARGETINFO_CSKYTARGETINFO_H +#define LLVM_LIB_TARGET_CSKY_TARGETINFO_CSKYTARGETINFO_H + +namespace llvm { + +class Target; + +Target &getTheCSKYTarget(); + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_TARGETINFO_CSKYTARGETINFO_H Index: llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/TargetInfo/CSKYTargetInfo.cpp @@ -0,0 +1,23 @@ +//===-- CSKYTargetInfo.cpp - CSKY Target Implementation -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TargetInfo/CSKYTargetInfo.h" +#include "llvm/Support/TargetRegistry.h" +using namespace llvm; + +Target &llvm::getTheCSKYTarget() { + static Target TheCSKYTarget; + return TheCSKYTarget; +} + +extern "C" void LLVMInitializeCSKYTargetInfo() { + RegisterTarget X(getTheCSKYTarget(), "csky", "CSKY", "CSKY"); +} + +extern "C" void LLVMInitializeCSKYDisassembler() {} +extern "C" void LLVMInitializeCSKYAsmParser() {} \ No newline at end of file Index: llvm/lib/Target/CSKY/TargetInfo/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/TargetInfo/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===-- ./lib/Target/CSKY/TargetInfo/LLVMBuild.txt --------------*- Conf -*--===; +; +; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = CSKYInfo +parent = CSKY +required_libraries = Support +add_to_library_groups = CSKY Index: llvm/lib/Target/CSKY/Utils/CMakeLists.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Utils/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_component_library(LLVMCSKYUtils + CSKYBaseInfo.cpp + ) \ No newline at end of file Index: llvm/lib/Target/CSKY/Utils/CSKYBaseInfo.h =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Utils/CSKYBaseInfo.h @@ -0,0 +1,62 @@ +//===-- CSKYBaseInfo.h - Top level definitions for CSKY ---*- C++ -*-------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the CSKY target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core +// code gen types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_CSKY_UTILS_CSKYBASEINFO_H +#define LLVM_LIB_TARGET_CSKY_UTILS_CSKYBASEINFO_H + +#include "MCTargetDesc/CSKYMCTargetDesc.h" +#include "llvm/MC/MCInstrDesc.h" + +namespace llvm { + +// CSKYII - This namespace holds all of the target specific flags that +// instruction info tracks. All definitions must match CSKYInstrFormats.td. +namespace CSKYII { + +enum AddrMode { + AddrModeNone = 0, + AddrMode32B = 1, // ld32.b, ld32.bs, st32.b, st32.bs, +4kb + AddrMode32H = 2, // ld32.h, ld32.hs, st32.h, st32.hs, +8kb + AddrMode32WD = 3, // ld32.w, st32.w, ld32.d, st32.d, +16kb + AddrMode16B = 4, // ld16.b, +32b + AddrMode16H = 5, // ld16.h, +64b + AddrMode16W = 6, // ld16.w, +128b or +1kb + AddrMode32SDF = 7, // flds, fldd, +1kb +}; + +// CSKY Specific MachineOperand Flags. +enum TOF { + MO_None = 0, + MO_GOT_LO16, + MO_GOT_HI16, + MO_GOTOFF_LO16, + MO_GOTOFF_HI16, + MO_ADDR_LO16, + MO_ADDR_HI16, + MO_ADDR32, + MO_GOT32, + MO_GOTOFF32, + MO_GOT12 +}; + +enum { + AddrModeMask = 0x1f, +}; + +} // namespace CSKYII + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_CSKY_UTILS_CSKYBASEINFO_H Index: llvm/lib/Target/CSKY/Utils/CSKYBaseInfo.cpp =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Utils/CSKYBaseInfo.cpp @@ -0,0 +1,18 @@ +//===-- CSKYBaseInfo.h - Top level definitions for CSKY ---*- C++ -*-------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the CSKY target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core +// code gen types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#include "CSKYBaseInfo.h" + +using namespace llvm; Index: llvm/lib/Target/CSKY/Utils/LLVMBuild.txt =================================================================== --- /dev/null +++ llvm/lib/Target/CSKY/Utils/LLVMBuild.txt @@ -0,0 +1,21 @@ +;===- ./lib/Target/CSKY/Utils/LLVMBuild.txt ----------------*- Conf -*------===; +; +; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +; See https://llvm.org/LICENSE.txt for license information. +; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = CSKYUtils +parent = CSKY +add_to_library_groups = CSKY Index: llvm/lib/Target/LLVMBuild.txt =================================================================== --- llvm/lib/Target/LLVMBuild.txt +++ llvm/lib/Target/LLVMBuild.txt @@ -24,6 +24,7 @@ ARM AVR BPF + CSKY Hexagon Lanai MSP430 Index: llvm/test/CodeGen/CSKY/add.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/add.ll @@ -0,0 +1,120 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @addRR(i32 %x, i32 %y) { +; CHECK-LABEL: addRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i32 %y, %x + ret i32 %add +} + +define i32 @addRI(i32 %x) { +; CHECK-LABEL: addRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i32 %x, 10 + ret i32 %add +} + +define i32 @addRI_X(i32 %x) { +; CHECK-LABEL: addRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 4097 +; CHECK-NEXT: addu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i32 %x, 4097 + ret i32 %add +} + +define i64 @ADD_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: ADD_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: clrc +; CHECK-NEXT: addc32 a0, a2, a0 +; CHECK-NEXT: addc32 a1, a3, a1 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i64 %y, %x + ret i64 %add +} + +define i64 @ADD_LONG_I(i64 %x) { +; CHECK-LABEL: ADD_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: clrc +; CHECK-NEXT: movi32 a2, 1 +; CHECK-NEXT: addc32 a0, a0, a2 +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: addc32 a1, a1, a2 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i64 %x, 1 + ret i64 %add +} + +define i16 @ADD_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: ADD_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i16 %y, %x + ret i16 %add +} + +define i16 @ADD_SHORT_I(i16 %x) { +; CHECK-LABEL: ADD_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i16 %x, 1 + ret i16 %add +} + +define i8 @ADD_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: ADD_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i8 %y, %x + ret i8 %add +} + +define i8 @ADD_CHAR_I(i8 %x) { +; CHECK-LABEL: ADD_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i8 %x, 1 + ret i8 %add +} + +define i1 @ADD_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: ADD_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i1 %y, %x + ret i1 %add +} + +define i1 @ADD_BIT_I(i1 %x) { +; CHECK-LABEL: ADD_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %add = add nsw i1 %x, 1 + ret i1 %add +} + Index: llvm/test/CodeGen/CSKY/and.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/and.ll @@ -0,0 +1,115 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @andRR(i32 %x, i32 %y) { +; CHECK-LABEL: andRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: and32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %and = and i32 %y, %x + ret i32 %and +} + +define i32 @andRI(i32 %x) { +; CHECK-LABEL: andRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %and = and i32 %x, 10 + ret i32 %and +} + +define i32 @andRI_X(i32 %x) { +; CHECK-LABEL: andRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 4097 +; CHECK-NEXT: and32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %and = and i32 %x, 4097 + ret i32 %and +} + +define i64 @AND_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: AND_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: and32 a0, a2, a0 +; CHECK-NEXT: and32 a1, a3, a1 +; CHECK-NEXT: rts32 +entry: + %and = and i64 %y, %x + ret i64 %and +} + +define i64 @AND_LONG_I(i64 %x) { +; CHECK-LABEL: AND_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %and = and i64 %x, 1 + ret i64 %and +} + +define i16 @AND_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: AND_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: and32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %and = and i16 %y, %x + ret i16 %and +} + +define i16 @AND_SHORT_I(i16 %x) { +; CHECK-LABEL: AND_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %and = and i16 %x, 1 + ret i16 %and +} + +define i8 @AND_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: AND_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: and32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %and = and i8 %y, %x + ret i8 %and +} + +define i8 @AND_CHAR_I(i8 %x) { +; CHECK-LABEL: AND_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %and = and i8 %x, 1 + ret i8 %and +} + +define i1 @AND_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: AND_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: and32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %and = and i1 %y, %x + ret i1 %and +} + +define i1 @AND_BIT_I(i1 %x) { +; CHECK-LABEL: AND_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %and = and i1 %x, 1 + ret i1 %and +} + Index: llvm/test/CodeGen/CSKY/ashr.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/ashr.ll @@ -0,0 +1,123 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @ashrRR(i32 %x, i32 %y) { +; CHECK-LABEL: ashrRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: asr32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i32 %y, %x + ret i32 %ashr +} + +define i32 @ashrRI(i32 %x) { +; CHECK-LABEL: ashrRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: asri32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i32 %x, 10 + ret i32 %ashr +} + +define i64 @ASHR_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: ASHR_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: st32.w lr, (sp, 0) +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: mov32 a3, a0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a2, a3 +; CHECK-NEXT: jsri32 .LCPI2_0 +; CHECK-NEXT: ld32.w lr, (sp, 0) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: .LCPI2_0: +; CHECK-NEXT: .long __ashrdi3 +entry: + %ashr = ashr i64 %y, %x + ret i64 %ashr +} + +define i64 @ASHR_LONG_I(i64 %x) { +; CHECK-LABEL: ASHR_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsli32 a2, a1, 25 +; CHECK-NEXT: lsri32 a0, a0, 7 +; CHECK-NEXT: or32 a0, a0, a2 +; CHECK-NEXT: asri32 a1, a1, 7 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i64 %x, 7 + ret i64 %ashr +} + +define i16 @ASHR_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: ASHR_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: asr32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i16 %y, %x + ret i16 %ashr +} + +define i16 @ASHR_SHORT_I(i16 %x) { +; CHECK-LABEL: ASHR_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: asri32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i16 %x, 1 + ret i16 %ashr +} + +define i8 @ASHR_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: ASHR_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: asr32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i8 %y, %x + ret i8 %ashr +} + +define i8 @ASHR_CHAR_I(i8 %x) { +; CHECK-LABEL: ASHR_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: asri32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i8 %x, 1 + ret i8 %ashr +} + +define i1 @ASHR_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: ASHR_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i1 %y, %x + ret i1 %ashr +} + +define i1 @ASHR_BIT_I(i1 %x) { +; CHECK-LABEL: ASHR_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ashr = ashr i1 %x, 1 + ret i1 %ashr +} + Index: llvm/test/CodeGen/CSKY/atomicrmw.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/atomicrmw.ll @@ -0,0 +1,3329 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define i32 @atomicrmw_i32_xchg(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_xchg: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: .LBB0_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB0_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_xchg: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: .LBB0_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB0_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_xchg: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: .LBB0_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB0_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_xchg: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: .LBB0_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB0_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_xchg: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: .LBB0_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB0_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw xchg i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_add(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_add: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB1_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: addi32 a2, a1, 1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB1_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_add: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB1_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: addi32 a2, a1, 1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB1_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_add: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB1_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: addi32 a2, a1, 1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB1_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_add: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB1_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: addi32 a2, a1, 1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB1_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_add: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB1_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: addi32 a2, a1, 1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB1_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw add i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_sub(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_sub: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB2_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: subi32 a2, a1, 1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB2_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_sub: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB2_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: subi32 a2, a1, 1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB2_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_sub: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB2_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: subi32 a2, a1, 1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB2_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_sub: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB2_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: subi32 a2, a1, 1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB2_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_sub: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB2_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: subi32 a2, a1, 1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB2_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw sub i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_and(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_and: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB3_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: andi32 a2, a1, 1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB3_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_and: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB3_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: andi32 a2, a1, 1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB3_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_and: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB3_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: andi32 a2, a1, 1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB3_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_and: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB3_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: andi32 a2, a1, 1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB3_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_and: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB3_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: andi32 a2, a1, 1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB3_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw and i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_nand(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_nand: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a2, a1, 65534 +; CHECK-SOFT-NEXT: .LBB4_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: not a3, a1 +; CHECK-SOFT-NEXT: or32 a3, a3, a2 +; CHECK-SOFT-NEXT: mov32 t0, a0 +; CHECK-SOFT-NEXT: stex32.w t0, (a3, 0) +; CHECK-SOFT-NEXT: cmpnei32 t0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB4_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_nand: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a2, a1, 65534 +; CHECK-SF-NEXT: .LBB4_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: not a3, a1 +; CHECK-SF-NEXT: or32 a3, a3, a2 +; CHECK-SF-NEXT: mov32 t0, a0 +; CHECK-SF-NEXT: stex32.w t0, (a3, 0) +; CHECK-SF-NEXT: cmpnei32 t0, 1 +; CHECK-SF-NEXT: bt32 .LBB4_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_nand: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a1, 65535 +; CHECK-DF-NEXT: ori32 a2, a1, 65534 +; CHECK-DF-NEXT: .LBB4_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: not a3, a1 +; CHECK-DF-NEXT: or32 a3, a3, a2 +; CHECK-DF-NEXT: mov32 t0, a0 +; CHECK-DF-NEXT: stex32.w t0, (a3, 0) +; CHECK-DF-NEXT: cmpnei32 t0, 1 +; CHECK-DF-NEXT: bt32 .LBB4_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_nand: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a2, a1, 65534 +; CHECK-SF2-NEXT: .LBB4_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: not a3, a1 +; CHECK-SF2-NEXT: or32 a3, a3, a2 +; CHECK-SF2-NEXT: mov32 t0, a0 +; CHECK-SF2-NEXT: stex32.w t0, (a3, 0) +; CHECK-SF2-NEXT: cmpnei32 t0, 1 +; CHECK-SF2-NEXT: bt32 .LBB4_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_nand: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a1, 65535 +; CHECK-DF2-NEXT: ori32 a2, a1, 65534 +; CHECK-DF2-NEXT: .LBB4_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: not a3, a1 +; CHECK-DF2-NEXT: or32 a3, a3, a2 +; CHECK-DF2-NEXT: mov32 t0, a0 +; CHECK-DF2-NEXT: stex32.w t0, (a3, 0) +; CHECK-DF2-NEXT: cmpnei32 t0, 1 +; CHECK-DF2-NEXT: bt32 .LBB4_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw nand i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_or(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_or: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB5_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: ori32 a2, a1, 1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB5_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_or: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB5_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: ori32 a2, a1, 1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB5_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_or: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB5_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: ori32 a2, a1, 1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB5_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_or: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB5_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: ori32 a2, a1, 1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB5_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_or: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB5_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: ori32 a2, a1, 1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB5_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw or i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_xor(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_xor: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB6_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: xori32 a2, a1, 1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB6_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_xor: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB6_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: xori32 a2, a1, 1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB6_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_xor: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB6_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: xori32 a2, a1, 1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB6_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_xor: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB6_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: xori32 a2, a1, 1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB6_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_xor: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB6_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: xori32 a2, a1, 1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB6_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw xor i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_max(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_max: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: .LBB7_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: cmplt32 a2, a1 +; CHECK-SOFT-NEXT: movi32 a3, 1 +; CHECK-SOFT-NEXT: movt32 a3, a1 +; CHECK-SOFT-NEXT: mov32 t0, a0 +; CHECK-SOFT-NEXT: stex32.w t0, (a3, 0) +; CHECK-SOFT-NEXT: cmpnei32 t0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB7_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_max: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: .LBB7_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: cmplt32 a2, a1 +; CHECK-SF-NEXT: movi32 a3, 1 +; CHECK-SF-NEXT: movt32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a0 +; CHECK-SF-NEXT: stex32.w t0, (a3, 0) +; CHECK-SF-NEXT: cmpnei32 t0, 1 +; CHECK-SF-NEXT: bt32 .LBB7_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_max: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: .LBB7_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: cmplt32 a2, a1 +; CHECK-DF-NEXT: movi32 a3, 1 +; CHECK-DF-NEXT: movt32 a3, a1 +; CHECK-DF-NEXT: mov32 t0, a0 +; CHECK-DF-NEXT: stex32.w t0, (a3, 0) +; CHECK-DF-NEXT: cmpnei32 t0, 1 +; CHECK-DF-NEXT: bt32 .LBB7_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_max: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: .LBB7_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: cmplt32 a2, a1 +; CHECK-SF2-NEXT: movi32 a3, 1 +; CHECK-SF2-NEXT: movt32 a3, a1 +; CHECK-SF2-NEXT: mov32 t0, a0 +; CHECK-SF2-NEXT: stex32.w t0, (a3, 0) +; CHECK-SF2-NEXT: cmpnei32 t0, 1 +; CHECK-SF2-NEXT: bt32 .LBB7_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_max: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: .LBB7_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: cmplt32 a2, a1 +; CHECK-DF2-NEXT: movi32 a3, 1 +; CHECK-DF2-NEXT: movt32 a3, a1 +; CHECK-DF2-NEXT: mov32 t0, a0 +; CHECK-DF2-NEXT: stex32.w t0, (a3, 0) +; CHECK-DF2-NEXT: cmpnei32 t0, 1 +; CHECK-DF2-NEXT: bt32 .LBB7_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw max i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_min(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_min: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB8_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: cmplti32 a1, 2 +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: movt32 a2, a1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB8_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_min: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB8_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: cmplti32 a1, 2 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: movt32 a2, a1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB8_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_min: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB8_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: cmplti32 a1, 2 +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: movt32 a2, a1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB8_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_min: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB8_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: cmplti32 a1, 2 +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: movt32 a2, a1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB8_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_min: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB8_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: cmplti32 a1, 2 +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: movt32 a2, a1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB8_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw min i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_umax(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_umax: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: .LBB9_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: cmphs32 a2, a1 +; CHECK-SOFT-NEXT: movi32 a3, 1 +; CHECK-SOFT-NEXT: movf32 a3, a1 +; CHECK-SOFT-NEXT: mov32 t0, a0 +; CHECK-SOFT-NEXT: stex32.w t0, (a3, 0) +; CHECK-SOFT-NEXT: cmpnei32 t0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB9_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_umax: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: .LBB9_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: cmphs32 a2, a1 +; CHECK-SF-NEXT: movi32 a3, 1 +; CHECK-SF-NEXT: movf32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a0 +; CHECK-SF-NEXT: stex32.w t0, (a3, 0) +; CHECK-SF-NEXT: cmpnei32 t0, 1 +; CHECK-SF-NEXT: bt32 .LBB9_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_umax: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: .LBB9_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: cmphs32 a2, a1 +; CHECK-DF-NEXT: movi32 a3, 1 +; CHECK-DF-NEXT: movf32 a3, a1 +; CHECK-DF-NEXT: mov32 t0, a0 +; CHECK-DF-NEXT: stex32.w t0, (a3, 0) +; CHECK-DF-NEXT: cmpnei32 t0, 1 +; CHECK-DF-NEXT: bt32 .LBB9_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_umax: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: .LBB9_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: cmphs32 a2, a1 +; CHECK-SF2-NEXT: movi32 a3, 1 +; CHECK-SF2-NEXT: movf32 a3, a1 +; CHECK-SF2-NEXT: mov32 t0, a0 +; CHECK-SF2-NEXT: stex32.w t0, (a3, 0) +; CHECK-SF2-NEXT: cmpnei32 t0, 1 +; CHECK-SF2-NEXT: bt32 .LBB9_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_umax: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: .LBB9_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: cmphs32 a2, a1 +; CHECK-DF2-NEXT: movi32 a3, 1 +; CHECK-DF2-NEXT: movf32 a3, a1 +; CHECK-DF2-NEXT: mov32 t0, a0 +; CHECK-DF2-NEXT: stex32.w t0, (a3, 0) +; CHECK-DF2-NEXT: cmpnei32 t0, 1 +; CHECK-DF2-NEXT: bt32 .LBB9_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw umax i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define i32 @atomicrmw_i32_umin(i32* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i32_umin: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: .LBB10_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: cmphsi32 a1, 2 +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: movf32 a2, a1 +; CHECK-SOFT-NEXT: mov32 a3, a0 +; CHECK-SOFT-NEXT: stex32.w a3, (a2, 0) +; CHECK-SOFT-NEXT: cmpnei32 a3, 1 +; CHECK-SOFT-NEXT: bt32 .LBB10_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: atomicrmw_i32_umin: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: .LBB10_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF-NEXT: cmphsi32 a1, 2 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: movf32 a2, a1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB10_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_i32_umin: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: .LBB10_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF-NEXT: cmphsi32 a1, 2 +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: movf32 a2, a1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB10_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: mov32 a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_i32_umin: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: .LBB10_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-SF2-NEXT: cmphsi32 a1, 2 +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: movf32 a2, a1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB10_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_i32_umin: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: .LBB10_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a1, (a0, 0) +; CHECK-DF2-NEXT: cmphsi32 a1, 2 +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: movf32 a2, a1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB10_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: mov32 a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw umin i32* %ptr, i32 1 acquire ; yields i32 + ret i32 %old +} + +define float @atomicrmw_float_fadd(float* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_float_fadd: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: .LBB11_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w l1, (l0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: movih32 a1, 16256 +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: stex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: cmpnei32 a1, 1 +; CHECK-SOFT-NEXT: bt32 .LBB11_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: atomicrmw_float_fadd: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a1, 16256 +; CHECK-SF-NEXT: .LBB11_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a2, (a0, 0) +; CHECK-SF-NEXT: fmtvrl vr0, a2 +; CHECK-SF-NEXT: fmtvrl vr1, a1 +; CHECK-SF-NEXT: fadds vr1, vr0, vr1 +; CHECK-SF-NEXT: fmfvrl a2, vr1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB11_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_float_fadd: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a1, 16256 +; CHECK-DF-NEXT: .LBB11_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a2, (a0, 0) +; CHECK-DF-NEXT: fmtvrl vr0, a2 +; CHECK-DF-NEXT: fmtvrl vr1, a1 +; CHECK-DF-NEXT: fadds vr1, vr0, vr1 +; CHECK-DF-NEXT: fmfvrl a2, vr1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB11_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_float_fadd: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a1, 16256 +; CHECK-SF2-NEXT: .LBB11_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a2, (a0, 0) +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a2 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a1 +; CHECK-SF2-NEXT: fadd.32 vr1, vr0, vr1 +; CHECK-SF2-NEXT: fmfvr.32.1 a2, vr1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB11_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_float_fadd: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a1, 16256 +; CHECK-DF2-NEXT: .LBB11_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a2, (a0, 0) +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a2 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a1 +; CHECK-DF2-NEXT: fadd.32 vr1, vr0, vr1 +; CHECK-DF2-NEXT: fmfvr.32.1 a2, vr1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB11_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw fadd float* %ptr, float 1.0 acquire ; yields i32 + ret float %old +} + +define float @atomicrmw_float_fsub(float* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_float_fsub: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movih32 a0, 49024 +; CHECK-SOFT-NEXT: ori32 l1, a0, 0 +; CHECK-SOFT-NEXT: .LBB12_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: ldex32.w l2, (l0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: stex32.w a1, (a0, 0) +; CHECK-SOFT-NEXT: cmpnei32 a1, 1 +; CHECK-SOFT-NEXT: bt32 .LBB12_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: atomicrmw_float_fsub: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a1, 49024 +; CHECK-SF-NEXT: .LBB12_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: ldex32.w a2, (a0, 0) +; CHECK-SF-NEXT: fmtvrl vr0, a2 +; CHECK-SF-NEXT: fmtvrl vr1, a1 +; CHECK-SF-NEXT: fadds vr1, vr0, vr1 +; CHECK-SF-NEXT: fmfvrl a2, vr1 +; CHECK-SF-NEXT: mov32 a3, a0 +; CHECK-SF-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF-NEXT: cmpnei32 a3, 1 +; CHECK-SF-NEXT: bt32 .LBB12_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: atomicrmw_float_fsub: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a1, 49024 +; CHECK-DF-NEXT: .LBB12_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: ldex32.w a2, (a0, 0) +; CHECK-DF-NEXT: fmtvrl vr0, a2 +; CHECK-DF-NEXT: fmtvrl vr1, a1 +; CHECK-DF-NEXT: fadds vr1, vr0, vr1 +; CHECK-DF-NEXT: fmfvrl a2, vr1 +; CHECK-DF-NEXT: mov32 a3, a0 +; CHECK-DF-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF-NEXT: cmpnei32 a3, 1 +; CHECK-DF-NEXT: bt32 .LBB12_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: atomicrmw_float_fsub: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a1, 49024 +; CHECK-SF2-NEXT: .LBB12_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: ldex32.w a2, (a0, 0) +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a2 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a1 +; CHECK-SF2-NEXT: fadd.32 vr1, vr0, vr1 +; CHECK-SF2-NEXT: fmfvr.32.1 a2, vr1 +; CHECK-SF2-NEXT: mov32 a3, a0 +; CHECK-SF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-SF2-NEXT: cmpnei32 a3, 1 +; CHECK-SF2-NEXT: bt32 .LBB12_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: atomicrmw_float_fsub: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a1, 49024 +; CHECK-DF2-NEXT: .LBB12_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: ldex32.w a2, (a0, 0) +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a2 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a1 +; CHECK-DF2-NEXT: fadd.32 vr1, vr0, vr1 +; CHECK-DF2-NEXT: fmfvr.32.1 a2, vr1 +; CHECK-DF2-NEXT: mov32 a3, a0 +; CHECK-DF2-NEXT: stex32.w a3, (a2, 0) +; CHECK-DF2-NEXT: cmpnei32 a3, 1 +; CHECK-DF2-NEXT: bt32 .LBB12_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: rts32 +entry: + %old = atomicrmw fsub float* %ptr, float 1.0 acquire ; yields i32 + ret float %old +} + +define i64 @atomicrmw_i64_xchg(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_xchg: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __atomic_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_xchg: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI13_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI13_0: +; CHECK-SF-NEXT: .long __atomic_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_xchg: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI13_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI13_0: +; CHECK-DF-NEXT: .long __atomic_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_xchg: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI13_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI13_0: +; CHECK-SF2-NEXT: .long __atomic_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_xchg: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI13_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI13_0: +; CHECK-DF2-NEXT: .long __atomic_exchange_8 +entry: + %old = atomicrmw xchg i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_add(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_add: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __atomic_fetch_add_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_add: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI14_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI14_0: +; CHECK-SF-NEXT: .long __atomic_fetch_add_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_add: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI14_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI14_0: +; CHECK-DF-NEXT: .long __atomic_fetch_add_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_add: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI14_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI14_0: +; CHECK-SF2-NEXT: .long __atomic_fetch_add_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_add: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI14_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI14_0: +; CHECK-DF2-NEXT: .long __atomic_fetch_add_8 +entry: + %old = atomicrmw add i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_sub(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_sub: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI15_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI15_0: +; CHECK-SOFT-NEXT: .long __atomic_fetch_sub_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_sub: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI15_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI15_0: +; CHECK-SF-NEXT: .long __atomic_fetch_sub_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_sub: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI15_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI15_0: +; CHECK-DF-NEXT: .long __atomic_fetch_sub_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_sub: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI15_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI15_0: +; CHECK-SF2-NEXT: .long __atomic_fetch_sub_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_sub: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI15_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI15_0: +; CHECK-DF2-NEXT: .long __atomic_fetch_sub_8 +entry: + %old = atomicrmw sub i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_and(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_and: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI16_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI16_0: +; CHECK-SOFT-NEXT: .long __atomic_fetch_and_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_and: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI16_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI16_0: +; CHECK-SF-NEXT: .long __atomic_fetch_and_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_and: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI16_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI16_0: +; CHECK-DF-NEXT: .long __atomic_fetch_and_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_and: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI16_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI16_0: +; CHECK-SF2-NEXT: .long __atomic_fetch_and_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_and: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI16_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI16_0: +; CHECK-DF2-NEXT: .long __atomic_fetch_and_8 +entry: + %old = atomicrmw and i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_nand(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_nand: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI17_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI17_0: +; CHECK-SOFT-NEXT: .long __atomic_fetch_nand_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_nand: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI17_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI17_0: +; CHECK-SF-NEXT: .long __atomic_fetch_nand_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_nand: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI17_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI17_0: +; CHECK-DF-NEXT: .long __atomic_fetch_nand_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_nand: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI17_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI17_0: +; CHECK-SF2-NEXT: .long __atomic_fetch_nand_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_nand: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI17_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI17_0: +; CHECK-DF2-NEXT: .long __atomic_fetch_nand_8 +entry: + %old = atomicrmw nand i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_or(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_or: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI18_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI18_0: +; CHECK-SOFT-NEXT: .long __atomic_fetch_or_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_or: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI18_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI18_0: +; CHECK-SF-NEXT: .long __atomic_fetch_or_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_or: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI18_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI18_0: +; CHECK-DF-NEXT: .long __atomic_fetch_or_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_or: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI18_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI18_0: +; CHECK-SF2-NEXT: .long __atomic_fetch_or_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_or: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI18_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI18_0: +; CHECK-DF2-NEXT: .long __atomic_fetch_or_8 +entry: + %old = atomicrmw or i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_xor(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_xor: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 1 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 2 +; CHECK-SOFT-NEXT: jsri32 .LCPI19_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI19_0: +; CHECK-SOFT-NEXT: .long __atomic_fetch_xor_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_xor: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a1, 1 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 2 +; CHECK-SF-NEXT: jsri32 .LCPI19_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI19_0: +; CHECK-SF-NEXT: .long __atomic_fetch_xor_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_xor: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movi32 a1, 1 +; CHECK-DF-NEXT: movi32 a2, 0 +; CHECK-DF-NEXT: movi32 a3, 2 +; CHECK-DF-NEXT: jsri32 .LCPI19_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI19_0: +; CHECK-DF-NEXT: .long __atomic_fetch_xor_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_xor: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a1, 1 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 2 +; CHECK-SF2-NEXT: jsri32 .LCPI19_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI19_0: +; CHECK-SF2-NEXT: .long __atomic_fetch_xor_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_xor: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movi32 a1, 1 +; CHECK-DF2-NEXT: movi32 a2, 0 +; CHECK-DF2-NEXT: movi32 a3, 2 +; CHECK-DF2-NEXT: jsri32 .LCPI19_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI19_0: +; CHECK-DF2-NEXT: .long __atomic_fetch_xor_8 +entry: + %old = atomicrmw xor i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_max(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_max: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 36) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 32) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 28) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 24) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 16) +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (a0, 1) +; CHECK-SOFT-NEXT: ld32.w a0, (a0, 0) +; CHECK-SOFT-NEXT: movi32 l2, 1 +; CHECK-SOFT-NEXT: movi32 l3, 0 +; CHECK-SOFT-NEXT: movi32 l4, 2 +; CHECK-SOFT-NEXT: addi32 l1, sp, 8 +; CHECK-SOFT-NEXT: .LBB20_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: cmphs32 l2, a0 +; CHECK-SOFT-NEXT: mvcv32 a2 +; CHECK-SOFT-NEXT: cmplt32 l3, a1 +; CHECK-SOFT-NEXT: mvc32 a3 +; CHECK-SOFT-NEXT: cmpnei32 a1, 0 +; CHECK-SOFT-NEXT: movf32 a3, a2 +; CHECK-SOFT-NEXT: btsti32 a3, 0 +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: movt32 a2, a0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: movt32 a3, a1 +; CHECK-SOFT-NEXT: st32.w a0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w a1, (sp, 8) +; CHECK-SOFT-NEXT: mov32 a0, sp +; CHECK-SOFT-NEXT: st32.w l4, (a0, 1) +; CHECK-SOFT-NEXT: st32.w l4, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI20_0 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w a0, (sp, 8) +; CHECK-SOFT-NEXT: bez32 a2, .LBB20_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 36) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 32) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 28) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 24) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 16) +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI20_0: +; CHECK-SOFT-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_max: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 24 +; CHECK-SF-NEXT: st32.w lr, (sp, 36) +; CHECK-SF-NEXT: st32.w l0, (sp, 32) +; CHECK-SF-NEXT: st32.w l1, (sp, 28) +; CHECK-SF-NEXT: st32.w l2, (sp, 24) +; CHECK-SF-NEXT: st32.w l3, (sp, 20) +; CHECK-SF-NEXT: st32.w l4, (sp, 16) +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: mov32 l0, a0 +; CHECK-SF-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF-NEXT: movi32 l2, 1 +; CHECK-SF-NEXT: movi32 l3, 0 +; CHECK-SF-NEXT: movi32 l4, 2 +; CHECK-SF-NEXT: addi32 l1, sp, 8 +; CHECK-SF-NEXT: .LBB20_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: cmphs32 l2, a0 +; CHECK-SF-NEXT: mvcv32 a2 +; CHECK-SF-NEXT: cmplt32 l3, a1 +; CHECK-SF-NEXT: mvc32 a3 +; CHECK-SF-NEXT: cmpnei32 a1, 0 +; CHECK-SF-NEXT: movf32 a3, a2 +; CHECK-SF-NEXT: btsti32 a3, 0 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: movt32 a2, a0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: movt32 a3, a1 +; CHECK-SF-NEXT: st32.w a0, (sp, 8) +; CHECK-SF-NEXT: st32.w a1, (sp, 8) +; CHECK-SF-NEXT: mov32 a0, sp +; CHECK-SF-NEXT: st32.w l4, (a0, 1) +; CHECK-SF-NEXT: st32.w l4, (a0, 0) +; CHECK-SF-NEXT: mov32 a0, l0 +; CHECK-SF-NEXT: mov32 a1, l1 +; CHECK-SF-NEXT: jsri32 .LCPI20_0 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: ld32.w a1, (sp, 8) +; CHECK-SF-NEXT: ld32.w a0, (sp, 8) +; CHECK-SF-NEXT: bez32 a2, .LBB20_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: ld32.w lr, (sp, 36) +; CHECK-SF-NEXT: ld32.w l0, (sp, 32) +; CHECK-SF-NEXT: ld32.w l1, (sp, 28) +; CHECK-SF-NEXT: ld32.w l2, (sp, 24) +; CHECK-SF-NEXT: ld32.w l3, (sp, 20) +; CHECK-SF-NEXT: ld32.w l4, (sp, 16) +; CHECK-SF-NEXT: addi32 sp, sp, 24 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.3: +; CHECK-SF-NEXT: .LCPI20_0: +; CHECK-SF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_max: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 24 +; CHECK-DF-NEXT: st32.w lr, (sp, 36) +; CHECK-DF-NEXT: st32.w l0, (sp, 32) +; CHECK-DF-NEXT: st32.w l1, (sp, 28) +; CHECK-DF-NEXT: st32.w l2, (sp, 24) +; CHECK-DF-NEXT: st32.w l3, (sp, 20) +; CHECK-DF-NEXT: st32.w l4, (sp, 16) +; CHECK-DF-NEXT: subi32 sp, sp, 16 +; CHECK-DF-NEXT: mov32 l0, a0 +; CHECK-DF-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF-NEXT: movi32 l2, 1 +; CHECK-DF-NEXT: movi32 l3, 0 +; CHECK-DF-NEXT: movi32 l4, 2 +; CHECK-DF-NEXT: addi32 l1, sp, 8 +; CHECK-DF-NEXT: .LBB20_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: cmphs32 l2, a0 +; CHECK-DF-NEXT: mvcv32 a2 +; CHECK-DF-NEXT: cmplt32 l3, a1 +; CHECK-DF-NEXT: mvc32 a3 +; CHECK-DF-NEXT: cmpnei32 a1, 0 +; CHECK-DF-NEXT: movf32 a3, a2 +; CHECK-DF-NEXT: btsti32 a3, 0 +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: movt32 a2, a0 +; CHECK-DF-NEXT: movi32 a3, 0 +; CHECK-DF-NEXT: movt32 a3, a1 +; CHECK-DF-NEXT: st32.w a0, (sp, 8) +; CHECK-DF-NEXT: st32.w a1, (sp, 8) +; CHECK-DF-NEXT: mov32 a0, sp +; CHECK-DF-NEXT: st32.w l4, (a0, 1) +; CHECK-DF-NEXT: st32.w l4, (a0, 0) +; CHECK-DF-NEXT: mov32 a0, l0 +; CHECK-DF-NEXT: mov32 a1, l1 +; CHECK-DF-NEXT: jsri32 .LCPI20_0 +; CHECK-DF-NEXT: mov32 a2, a0 +; CHECK-DF-NEXT: ld32.w a1, (sp, 8) +; CHECK-DF-NEXT: ld32.w a0, (sp, 8) +; CHECK-DF-NEXT: bez32 a2, .LBB20_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: addi32 sp, sp, 16 +; CHECK-DF-NEXT: ld32.w lr, (sp, 36) +; CHECK-DF-NEXT: ld32.w l0, (sp, 32) +; CHECK-DF-NEXT: ld32.w l1, (sp, 28) +; CHECK-DF-NEXT: ld32.w l2, (sp, 24) +; CHECK-DF-NEXT: ld32.w l3, (sp, 20) +; CHECK-DF-NEXT: ld32.w l4, (sp, 16) +; CHECK-DF-NEXT: addi32 sp, sp, 24 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.3: +; CHECK-DF-NEXT: .LCPI20_0: +; CHECK-DF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_max: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, (sp, 36) +; CHECK-SF2-NEXT: st32.w l0, (sp, 32) +; CHECK-SF2-NEXT: st32.w l1, (sp, 28) +; CHECK-SF2-NEXT: st32.w l2, (sp, 24) +; CHECK-SF2-NEXT: st32.w l3, (sp, 20) +; CHECK-SF2-NEXT: st32.w l4, (sp, 16) +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: mov32 l0, a0 +; CHECK-SF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF2-NEXT: movi32 l2, 1 +; CHECK-SF2-NEXT: movi32 l3, 0 +; CHECK-SF2-NEXT: movi32 l4, 2 +; CHECK-SF2-NEXT: addi32 l1, sp, 8 +; CHECK-SF2-NEXT: .LBB20_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: cmphs32 l2, a0 +; CHECK-SF2-NEXT: mvcv32 a2 +; CHECK-SF2-NEXT: cmplt32 l3, a1 +; CHECK-SF2-NEXT: mvc32 a3 +; CHECK-SF2-NEXT: cmpnei32 a1, 0 +; CHECK-SF2-NEXT: movf32 a3, a2 +; CHECK-SF2-NEXT: btsti32 a3, 0 +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: movt32 a2, a0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: movt32 a3, a1 +; CHECK-SF2-NEXT: st32.w a0, (sp, 8) +; CHECK-SF2-NEXT: st32.w a1, (sp, 8) +; CHECK-SF2-NEXT: mov32 a0, sp +; CHECK-SF2-NEXT: st32.w l4, (a0, 1) +; CHECK-SF2-NEXT: st32.w l4, (a0, 0) +; CHECK-SF2-NEXT: mov32 a0, l0 +; CHECK-SF2-NEXT: mov32 a1, l1 +; CHECK-SF2-NEXT: jsri32 .LCPI20_0 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: ld32.w a1, (sp, 8) +; CHECK-SF2-NEXT: ld32.w a0, (sp, 8) +; CHECK-SF2-NEXT: bez32 a2, .LBB20_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 36) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 32) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 28) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 24) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 16) +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.3: +; CHECK-SF2-NEXT: .LCPI20_0: +; CHECK-SF2-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_max: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 24 +; CHECK-DF2-NEXT: st32.w lr, (sp, 36) +; CHECK-DF2-NEXT: st32.w l0, (sp, 32) +; CHECK-DF2-NEXT: st32.w l1, (sp, 28) +; CHECK-DF2-NEXT: st32.w l2, (sp, 24) +; CHECK-DF2-NEXT: st32.w l3, (sp, 20) +; CHECK-DF2-NEXT: st32.w l4, (sp, 16) +; CHECK-DF2-NEXT: subi32 sp, sp, 16 +; CHECK-DF2-NEXT: mov32 l0, a0 +; CHECK-DF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF2-NEXT: movi32 l2, 1 +; CHECK-DF2-NEXT: movi32 l3, 0 +; CHECK-DF2-NEXT: movi32 l4, 2 +; CHECK-DF2-NEXT: addi32 l1, sp, 8 +; CHECK-DF2-NEXT: .LBB20_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: cmphs32 l2, a0 +; CHECK-DF2-NEXT: mvcv32 a2 +; CHECK-DF2-NEXT: cmplt32 l3, a1 +; CHECK-DF2-NEXT: mvc32 a3 +; CHECK-DF2-NEXT: cmpnei32 a1, 0 +; CHECK-DF2-NEXT: movf32 a3, a2 +; CHECK-DF2-NEXT: btsti32 a3, 0 +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: movt32 a2, a0 +; CHECK-DF2-NEXT: movi32 a3, 0 +; CHECK-DF2-NEXT: movt32 a3, a1 +; CHECK-DF2-NEXT: st32.w a0, (sp, 8) +; CHECK-DF2-NEXT: st32.w a1, (sp, 8) +; CHECK-DF2-NEXT: mov32 a0, sp +; CHECK-DF2-NEXT: st32.w l4, (a0, 1) +; CHECK-DF2-NEXT: st32.w l4, (a0, 0) +; CHECK-DF2-NEXT: mov32 a0, l0 +; CHECK-DF2-NEXT: mov32 a1, l1 +; CHECK-DF2-NEXT: jsri32 .LCPI20_0 +; CHECK-DF2-NEXT: mov32 a2, a0 +; CHECK-DF2-NEXT: ld32.w a1, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a0, (sp, 8) +; CHECK-DF2-NEXT: bez32 a2, .LBB20_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: addi32 sp, sp, 16 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 36) +; CHECK-DF2-NEXT: ld32.w l0, (sp, 32) +; CHECK-DF2-NEXT: ld32.w l1, (sp, 28) +; CHECK-DF2-NEXT: ld32.w l2, (sp, 24) +; CHECK-DF2-NEXT: ld32.w l3, (sp, 20) +; CHECK-DF2-NEXT: ld32.w l4, (sp, 16) +; CHECK-DF2-NEXT: addi32 sp, sp, 24 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.3: +; CHECK-DF2-NEXT: .LCPI20_0: +; CHECK-DF2-NEXT: .long __atomic_compare_exchange_8 +entry: + %old = atomicrmw max i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_min(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_min: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 32) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 28) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 24) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 20) +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (a0, 1) +; CHECK-SOFT-NEXT: ld32.w a0, (a0, 0) +; CHECK-SOFT-NEXT: movi32 l2, 2 +; CHECK-SOFT-NEXT: addi32 l1, sp, 12 +; CHECK-SOFT-NEXT: .LBB21_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: cmphsi32 a0, 2 +; CHECK-SOFT-NEXT: mvcv32 a2 +; CHECK-SOFT-NEXT: cmpnei32 a1, 0 +; CHECK-SOFT-NEXT: mvc32 a3 +; CHECK-SOFT-NEXT: st32.w a3, (sp, 8) +; CHECK-SOFT-NEXT: cmplti32 a1, 0 +; CHECK-SOFT-NEXT: mvc32 a3 +; CHECK-SOFT-NEXT: ld32.w t0, (sp, 8) +; CHECK-SOFT-NEXT: btsti32 t0, 0 +; CHECK-SOFT-NEXT: movf32 a3, a2 +; CHECK-SOFT-NEXT: btsti32 a3, 0 +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: movt32 a2, a0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: movt32 a3, a1 +; CHECK-SOFT-NEXT: st32.w a0, (sp, 12) +; CHECK-SOFT-NEXT: st32.w a1, (sp, 12) +; CHECK-SOFT-NEXT: mov32 a0, sp +; CHECK-SOFT-NEXT: st32.w l2, (a0, 1) +; CHECK-SOFT-NEXT: st32.w l2, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI21_0 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w a0, (sp, 12) +; CHECK-SOFT-NEXT: bez32 a2, .LBB21_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 32) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 28) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 24) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 20) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI21_0: +; CHECK-SOFT-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_min: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 32) +; CHECK-SF-NEXT: st32.w l0, (sp, 28) +; CHECK-SF-NEXT: st32.w l1, (sp, 24) +; CHECK-SF-NEXT: st32.w l2, (sp, 20) +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: mov32 l0, a0 +; CHECK-SF-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF-NEXT: movi32 l2, 2 +; CHECK-SF-NEXT: addi32 l1, sp, 12 +; CHECK-SF-NEXT: .LBB21_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: cmphsi32 a0, 2 +; CHECK-SF-NEXT: mvcv32 a2 +; CHECK-SF-NEXT: cmpnei32 a1, 0 +; CHECK-SF-NEXT: mvc32 a3 +; CHECK-SF-NEXT: st32.w a3, (sp, 8) +; CHECK-SF-NEXT: cmplti32 a1, 0 +; CHECK-SF-NEXT: mvc32 a3 +; CHECK-SF-NEXT: ld32.w t0, (sp, 8) +; CHECK-SF-NEXT: btsti32 t0, 0 +; CHECK-SF-NEXT: movf32 a3, a2 +; CHECK-SF-NEXT: btsti32 a3, 0 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: movt32 a2, a0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: movt32 a3, a1 +; CHECK-SF-NEXT: st32.w a0, (sp, 12) +; CHECK-SF-NEXT: st32.w a1, (sp, 12) +; CHECK-SF-NEXT: mov32 a0, sp +; CHECK-SF-NEXT: st32.w l2, (a0, 1) +; CHECK-SF-NEXT: st32.w l2, (a0, 0) +; CHECK-SF-NEXT: mov32 a0, l0 +; CHECK-SF-NEXT: mov32 a1, l1 +; CHECK-SF-NEXT: jsri32 .LCPI21_0 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: ld32.w a1, (sp, 12) +; CHECK-SF-NEXT: ld32.w a0, (sp, 12) +; CHECK-SF-NEXT: bez32 a2, .LBB21_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: ld32.w lr, (sp, 32) +; CHECK-SF-NEXT: ld32.w l0, (sp, 28) +; CHECK-SF-NEXT: ld32.w l1, (sp, 24) +; CHECK-SF-NEXT: ld32.w l2, (sp, 20) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.3: +; CHECK-SF-NEXT: .LCPI21_0: +; CHECK-SF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_min: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 16 +; CHECK-DF-NEXT: st32.w lr, (sp, 32) +; CHECK-DF-NEXT: st32.w l0, (sp, 28) +; CHECK-DF-NEXT: st32.w l1, (sp, 24) +; CHECK-DF-NEXT: st32.w l2, (sp, 20) +; CHECK-DF-NEXT: subi32 sp, sp, 20 +; CHECK-DF-NEXT: mov32 l0, a0 +; CHECK-DF-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF-NEXT: movi32 l2, 2 +; CHECK-DF-NEXT: addi32 l1, sp, 12 +; CHECK-DF-NEXT: .LBB21_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: cmphsi32 a0, 2 +; CHECK-DF-NEXT: mvcv32 a2 +; CHECK-DF-NEXT: cmpnei32 a1, 0 +; CHECK-DF-NEXT: mvc32 a3 +; CHECK-DF-NEXT: st32.w a3, (sp, 8) +; CHECK-DF-NEXT: cmplti32 a1, 0 +; CHECK-DF-NEXT: mvc32 a3 +; CHECK-DF-NEXT: ld32.w t0, (sp, 8) +; CHECK-DF-NEXT: btsti32 t0, 0 +; CHECK-DF-NEXT: movf32 a3, a2 +; CHECK-DF-NEXT: btsti32 a3, 0 +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: movt32 a2, a0 +; CHECK-DF-NEXT: movi32 a3, 0 +; CHECK-DF-NEXT: movt32 a3, a1 +; CHECK-DF-NEXT: st32.w a0, (sp, 12) +; CHECK-DF-NEXT: st32.w a1, (sp, 12) +; CHECK-DF-NEXT: mov32 a0, sp +; CHECK-DF-NEXT: st32.w l2, (a0, 1) +; CHECK-DF-NEXT: st32.w l2, (a0, 0) +; CHECK-DF-NEXT: mov32 a0, l0 +; CHECK-DF-NEXT: mov32 a1, l1 +; CHECK-DF-NEXT: jsri32 .LCPI21_0 +; CHECK-DF-NEXT: mov32 a2, a0 +; CHECK-DF-NEXT: ld32.w a1, (sp, 12) +; CHECK-DF-NEXT: ld32.w a0, (sp, 12) +; CHECK-DF-NEXT: bez32 a2, .LBB21_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: addi32 sp, sp, 20 +; CHECK-DF-NEXT: ld32.w lr, (sp, 32) +; CHECK-DF-NEXT: ld32.w l0, (sp, 28) +; CHECK-DF-NEXT: ld32.w l1, (sp, 24) +; CHECK-DF-NEXT: ld32.w l2, (sp, 20) +; CHECK-DF-NEXT: addi32 sp, sp, 16 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.3: +; CHECK-DF-NEXT: .LCPI21_0: +; CHECK-DF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_min: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 32) +; CHECK-SF2-NEXT: st32.w l0, (sp, 28) +; CHECK-SF2-NEXT: st32.w l1, (sp, 24) +; CHECK-SF2-NEXT: st32.w l2, (sp, 20) +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: mov32 l0, a0 +; CHECK-SF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF2-NEXT: movi32 l2, 2 +; CHECK-SF2-NEXT: addi32 l1, sp, 12 +; CHECK-SF2-NEXT: .LBB21_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: cmphsi32 a0, 2 +; CHECK-SF2-NEXT: mvcv32 a2 +; CHECK-SF2-NEXT: cmpnei32 a1, 0 +; CHECK-SF2-NEXT: mvc32 a3 +; CHECK-SF2-NEXT: st32.w a3, (sp, 8) +; CHECK-SF2-NEXT: cmplti32 a1, 0 +; CHECK-SF2-NEXT: mvc32 a3 +; CHECK-SF2-NEXT: ld32.w t0, (sp, 8) +; CHECK-SF2-NEXT: btsti32 t0, 0 +; CHECK-SF2-NEXT: movf32 a3, a2 +; CHECK-SF2-NEXT: btsti32 a3, 0 +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: movt32 a2, a0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: movt32 a3, a1 +; CHECK-SF2-NEXT: st32.w a0, (sp, 12) +; CHECK-SF2-NEXT: st32.w a1, (sp, 12) +; CHECK-SF2-NEXT: mov32 a0, sp +; CHECK-SF2-NEXT: st32.w l2, (a0, 1) +; CHECK-SF2-NEXT: st32.w l2, (a0, 0) +; CHECK-SF2-NEXT: mov32 a0, l0 +; CHECK-SF2-NEXT: mov32 a1, l1 +; CHECK-SF2-NEXT: jsri32 .LCPI21_0 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: ld32.w a1, (sp, 12) +; CHECK-SF2-NEXT: ld32.w a0, (sp, 12) +; CHECK-SF2-NEXT: bez32 a2, .LBB21_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 32) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 28) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 24) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 20) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.3: +; CHECK-SF2-NEXT: .LCPI21_0: +; CHECK-SF2-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_min: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 16 +; CHECK-DF2-NEXT: st32.w lr, (sp, 32) +; CHECK-DF2-NEXT: st32.w l0, (sp, 28) +; CHECK-DF2-NEXT: st32.w l1, (sp, 24) +; CHECK-DF2-NEXT: st32.w l2, (sp, 20) +; CHECK-DF2-NEXT: subi32 sp, sp, 20 +; CHECK-DF2-NEXT: mov32 l0, a0 +; CHECK-DF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF2-NEXT: movi32 l2, 2 +; CHECK-DF2-NEXT: addi32 l1, sp, 12 +; CHECK-DF2-NEXT: .LBB21_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: cmphsi32 a0, 2 +; CHECK-DF2-NEXT: mvcv32 a2 +; CHECK-DF2-NEXT: cmpnei32 a1, 0 +; CHECK-DF2-NEXT: mvc32 a3 +; CHECK-DF2-NEXT: st32.w a3, (sp, 8) +; CHECK-DF2-NEXT: cmplti32 a1, 0 +; CHECK-DF2-NEXT: mvc32 a3 +; CHECK-DF2-NEXT: ld32.w t0, (sp, 8) +; CHECK-DF2-NEXT: btsti32 t0, 0 +; CHECK-DF2-NEXT: movf32 a3, a2 +; CHECK-DF2-NEXT: btsti32 a3, 0 +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: movt32 a2, a0 +; CHECK-DF2-NEXT: movi32 a3, 0 +; CHECK-DF2-NEXT: movt32 a3, a1 +; CHECK-DF2-NEXT: st32.w a0, (sp, 12) +; CHECK-DF2-NEXT: st32.w a1, (sp, 12) +; CHECK-DF2-NEXT: mov32 a0, sp +; CHECK-DF2-NEXT: st32.w l2, (a0, 1) +; CHECK-DF2-NEXT: st32.w l2, (a0, 0) +; CHECK-DF2-NEXT: mov32 a0, l0 +; CHECK-DF2-NEXT: mov32 a1, l1 +; CHECK-DF2-NEXT: jsri32 .LCPI21_0 +; CHECK-DF2-NEXT: mov32 a2, a0 +; CHECK-DF2-NEXT: ld32.w a1, (sp, 12) +; CHECK-DF2-NEXT: ld32.w a0, (sp, 12) +; CHECK-DF2-NEXT: bez32 a2, .LBB21_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: addi32 sp, sp, 20 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 32) +; CHECK-DF2-NEXT: ld32.w l0, (sp, 28) +; CHECK-DF2-NEXT: ld32.w l1, (sp, 24) +; CHECK-DF2-NEXT: ld32.w l2, (sp, 20) +; CHECK-DF2-NEXT: addi32 sp, sp, 16 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.3: +; CHECK-DF2-NEXT: .LCPI21_0: +; CHECK-DF2-NEXT: .long __atomic_compare_exchange_8 +entry: + %old = atomicrmw min i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_umax(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_umax: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 32) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 28) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 24) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 16) +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (a0, 1) +; CHECK-SOFT-NEXT: ld32.w a0, (a0, 0) +; CHECK-SOFT-NEXT: movi32 l2, 1 +; CHECK-SOFT-NEXT: movi32 l3, 2 +; CHECK-SOFT-NEXT: addi32 l1, sp, 8 +; CHECK-SOFT-NEXT: .LBB22_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: cmphs32 l2, a0 +; CHECK-SOFT-NEXT: mvcv32 a2 +; CHECK-SOFT-NEXT: cmpnei32 a1, 0 +; CHECK-SOFT-NEXT: mvc32 a3 +; CHECK-SOFT-NEXT: movf32 a3, a2 +; CHECK-SOFT-NEXT: btsti32 a3, 0 +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: movt32 a2, a0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: movt32 a3, a1 +; CHECK-SOFT-NEXT: st32.w a0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w a1, (sp, 8) +; CHECK-SOFT-NEXT: mov32 a0, sp +; CHECK-SOFT-NEXT: st32.w l3, (a0, 1) +; CHECK-SOFT-NEXT: st32.w l3, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI22_0 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w a0, (sp, 8) +; CHECK-SOFT-NEXT: bez32 a2, .LBB22_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 32) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 28) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 24) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 16) +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI22_0: +; CHECK-SOFT-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_umax: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, (sp, 32) +; CHECK-SF-NEXT: st32.w l0, (sp, 28) +; CHECK-SF-NEXT: st32.w l1, (sp, 24) +; CHECK-SF-NEXT: st32.w l2, (sp, 20) +; CHECK-SF-NEXT: st32.w l3, (sp, 16) +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: mov32 l0, a0 +; CHECK-SF-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF-NEXT: movi32 l2, 1 +; CHECK-SF-NEXT: movi32 l3, 2 +; CHECK-SF-NEXT: addi32 l1, sp, 8 +; CHECK-SF-NEXT: .LBB22_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: cmphs32 l2, a0 +; CHECK-SF-NEXT: mvcv32 a2 +; CHECK-SF-NEXT: cmpnei32 a1, 0 +; CHECK-SF-NEXT: mvc32 a3 +; CHECK-SF-NEXT: movf32 a3, a2 +; CHECK-SF-NEXT: btsti32 a3, 0 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: movt32 a2, a0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: movt32 a3, a1 +; CHECK-SF-NEXT: st32.w a0, (sp, 8) +; CHECK-SF-NEXT: st32.w a1, (sp, 8) +; CHECK-SF-NEXT: mov32 a0, sp +; CHECK-SF-NEXT: st32.w l3, (a0, 1) +; CHECK-SF-NEXT: st32.w l3, (a0, 0) +; CHECK-SF-NEXT: mov32 a0, l0 +; CHECK-SF-NEXT: mov32 a1, l1 +; CHECK-SF-NEXT: jsri32 .LCPI22_0 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: ld32.w a1, (sp, 8) +; CHECK-SF-NEXT: ld32.w a0, (sp, 8) +; CHECK-SF-NEXT: bez32 a2, .LBB22_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: ld32.w lr, (sp, 32) +; CHECK-SF-NEXT: ld32.w l0, (sp, 28) +; CHECK-SF-NEXT: ld32.w l1, (sp, 24) +; CHECK-SF-NEXT: ld32.w l2, (sp, 20) +; CHECK-SF-NEXT: ld32.w l3, (sp, 16) +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.3: +; CHECK-SF-NEXT: .LCPI22_0: +; CHECK-SF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_umax: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 20 +; CHECK-DF-NEXT: st32.w lr, (sp, 32) +; CHECK-DF-NEXT: st32.w l0, (sp, 28) +; CHECK-DF-NEXT: st32.w l1, (sp, 24) +; CHECK-DF-NEXT: st32.w l2, (sp, 20) +; CHECK-DF-NEXT: st32.w l3, (sp, 16) +; CHECK-DF-NEXT: subi32 sp, sp, 16 +; CHECK-DF-NEXT: mov32 l0, a0 +; CHECK-DF-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF-NEXT: movi32 l2, 1 +; CHECK-DF-NEXT: movi32 l3, 2 +; CHECK-DF-NEXT: addi32 l1, sp, 8 +; CHECK-DF-NEXT: .LBB22_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: cmphs32 l2, a0 +; CHECK-DF-NEXT: mvcv32 a2 +; CHECK-DF-NEXT: cmpnei32 a1, 0 +; CHECK-DF-NEXT: mvc32 a3 +; CHECK-DF-NEXT: movf32 a3, a2 +; CHECK-DF-NEXT: btsti32 a3, 0 +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: movt32 a2, a0 +; CHECK-DF-NEXT: movi32 a3, 0 +; CHECK-DF-NEXT: movt32 a3, a1 +; CHECK-DF-NEXT: st32.w a0, (sp, 8) +; CHECK-DF-NEXT: st32.w a1, (sp, 8) +; CHECK-DF-NEXT: mov32 a0, sp +; CHECK-DF-NEXT: st32.w l3, (a0, 1) +; CHECK-DF-NEXT: st32.w l3, (a0, 0) +; CHECK-DF-NEXT: mov32 a0, l0 +; CHECK-DF-NEXT: mov32 a1, l1 +; CHECK-DF-NEXT: jsri32 .LCPI22_0 +; CHECK-DF-NEXT: mov32 a2, a0 +; CHECK-DF-NEXT: ld32.w a1, (sp, 8) +; CHECK-DF-NEXT: ld32.w a0, (sp, 8) +; CHECK-DF-NEXT: bez32 a2, .LBB22_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: addi32 sp, sp, 16 +; CHECK-DF-NEXT: ld32.w lr, (sp, 32) +; CHECK-DF-NEXT: ld32.w l0, (sp, 28) +; CHECK-DF-NEXT: ld32.w l1, (sp, 24) +; CHECK-DF-NEXT: ld32.w l2, (sp, 20) +; CHECK-DF-NEXT: ld32.w l3, (sp, 16) +; CHECK-DF-NEXT: addi32 sp, sp, 20 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.3: +; CHECK-DF-NEXT: .LCPI22_0: +; CHECK-DF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_umax: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, (sp, 32) +; CHECK-SF2-NEXT: st32.w l0, (sp, 28) +; CHECK-SF2-NEXT: st32.w l1, (sp, 24) +; CHECK-SF2-NEXT: st32.w l2, (sp, 20) +; CHECK-SF2-NEXT: st32.w l3, (sp, 16) +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: mov32 l0, a0 +; CHECK-SF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF2-NEXT: movi32 l2, 1 +; CHECK-SF2-NEXT: movi32 l3, 2 +; CHECK-SF2-NEXT: addi32 l1, sp, 8 +; CHECK-SF2-NEXT: .LBB22_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: cmphs32 l2, a0 +; CHECK-SF2-NEXT: mvcv32 a2 +; CHECK-SF2-NEXT: cmpnei32 a1, 0 +; CHECK-SF2-NEXT: mvc32 a3 +; CHECK-SF2-NEXT: movf32 a3, a2 +; CHECK-SF2-NEXT: btsti32 a3, 0 +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: movt32 a2, a0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: movt32 a3, a1 +; CHECK-SF2-NEXT: st32.w a0, (sp, 8) +; CHECK-SF2-NEXT: st32.w a1, (sp, 8) +; CHECK-SF2-NEXT: mov32 a0, sp +; CHECK-SF2-NEXT: st32.w l3, (a0, 1) +; CHECK-SF2-NEXT: st32.w l3, (a0, 0) +; CHECK-SF2-NEXT: mov32 a0, l0 +; CHECK-SF2-NEXT: mov32 a1, l1 +; CHECK-SF2-NEXT: jsri32 .LCPI22_0 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: ld32.w a1, (sp, 8) +; CHECK-SF2-NEXT: ld32.w a0, (sp, 8) +; CHECK-SF2-NEXT: bez32 a2, .LBB22_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 32) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 28) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 24) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 16) +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.3: +; CHECK-SF2-NEXT: .LCPI22_0: +; CHECK-SF2-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_umax: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 20 +; CHECK-DF2-NEXT: st32.w lr, (sp, 32) +; CHECK-DF2-NEXT: st32.w l0, (sp, 28) +; CHECK-DF2-NEXT: st32.w l1, (sp, 24) +; CHECK-DF2-NEXT: st32.w l2, (sp, 20) +; CHECK-DF2-NEXT: st32.w l3, (sp, 16) +; CHECK-DF2-NEXT: subi32 sp, sp, 16 +; CHECK-DF2-NEXT: mov32 l0, a0 +; CHECK-DF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF2-NEXT: movi32 l2, 1 +; CHECK-DF2-NEXT: movi32 l3, 2 +; CHECK-DF2-NEXT: addi32 l1, sp, 8 +; CHECK-DF2-NEXT: .LBB22_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: cmphs32 l2, a0 +; CHECK-DF2-NEXT: mvcv32 a2 +; CHECK-DF2-NEXT: cmpnei32 a1, 0 +; CHECK-DF2-NEXT: mvc32 a3 +; CHECK-DF2-NEXT: movf32 a3, a2 +; CHECK-DF2-NEXT: btsti32 a3, 0 +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: movt32 a2, a0 +; CHECK-DF2-NEXT: movi32 a3, 0 +; CHECK-DF2-NEXT: movt32 a3, a1 +; CHECK-DF2-NEXT: st32.w a0, (sp, 8) +; CHECK-DF2-NEXT: st32.w a1, (sp, 8) +; CHECK-DF2-NEXT: mov32 a0, sp +; CHECK-DF2-NEXT: st32.w l3, (a0, 1) +; CHECK-DF2-NEXT: st32.w l3, (a0, 0) +; CHECK-DF2-NEXT: mov32 a0, l0 +; CHECK-DF2-NEXT: mov32 a1, l1 +; CHECK-DF2-NEXT: jsri32 .LCPI22_0 +; CHECK-DF2-NEXT: mov32 a2, a0 +; CHECK-DF2-NEXT: ld32.w a1, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a0, (sp, 8) +; CHECK-DF2-NEXT: bez32 a2, .LBB22_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: addi32 sp, sp, 16 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 32) +; CHECK-DF2-NEXT: ld32.w l0, (sp, 28) +; CHECK-DF2-NEXT: ld32.w l1, (sp, 24) +; CHECK-DF2-NEXT: ld32.w l2, (sp, 20) +; CHECK-DF2-NEXT: ld32.w l3, (sp, 16) +; CHECK-DF2-NEXT: addi32 sp, sp, 20 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.3: +; CHECK-DF2-NEXT: .LCPI22_0: +; CHECK-DF2-NEXT: .long __atomic_compare_exchange_8 +entry: + %old = atomicrmw umax i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define i64 @atomicrmw_i64_umin(i64* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_i64_umin: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 28) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 24) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 16) +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (a0, 1) +; CHECK-SOFT-NEXT: ld32.w a0, (a0, 0) +; CHECK-SOFT-NEXT: movi32 l2, 2 +; CHECK-SOFT-NEXT: addi32 l1, sp, 8 +; CHECK-SOFT-NEXT: .LBB23_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: cmphsi32 a0, 2 +; CHECK-SOFT-NEXT: mvcv32 a2 +; CHECK-SOFT-NEXT: cmpnei32 a1, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: movf32 a3, a2 +; CHECK-SOFT-NEXT: btsti32 a3, 0 +; CHECK-SOFT-NEXT: movi32 a2, 1 +; CHECK-SOFT-NEXT: movt32 a2, a0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: movt32 a3, a1 +; CHECK-SOFT-NEXT: st32.w a0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w a1, (sp, 8) +; CHECK-SOFT-NEXT: mov32 a0, sp +; CHECK-SOFT-NEXT: st32.w l2, (a0, 1) +; CHECK-SOFT-NEXT: st32.w l2, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI23_0 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: ld32.w a1, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w a0, (sp, 8) +; CHECK-SOFT-NEXT: bez32 a2, .LBB23_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 28) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 24) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 16) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI23_0: +; CHECK-SOFT-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_i64_umin: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 28) +; CHECK-SF-NEXT: st32.w l0, (sp, 24) +; CHECK-SF-NEXT: st32.w l1, (sp, 20) +; CHECK-SF-NEXT: st32.w l2, (sp, 16) +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: mov32 l0, a0 +; CHECK-SF-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF-NEXT: movi32 l2, 2 +; CHECK-SF-NEXT: addi32 l1, sp, 8 +; CHECK-SF-NEXT: .LBB23_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: cmphsi32 a0, 2 +; CHECK-SF-NEXT: mvcv32 a2 +; CHECK-SF-NEXT: cmpnei32 a1, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: movf32 a3, a2 +; CHECK-SF-NEXT: btsti32 a3, 0 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: movt32 a2, a0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: movt32 a3, a1 +; CHECK-SF-NEXT: st32.w a0, (sp, 8) +; CHECK-SF-NEXT: st32.w a1, (sp, 8) +; CHECK-SF-NEXT: mov32 a0, sp +; CHECK-SF-NEXT: st32.w l2, (a0, 1) +; CHECK-SF-NEXT: st32.w l2, (a0, 0) +; CHECK-SF-NEXT: mov32 a0, l0 +; CHECK-SF-NEXT: mov32 a1, l1 +; CHECK-SF-NEXT: jsri32 .LCPI23_0 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: ld32.w a1, (sp, 8) +; CHECK-SF-NEXT: ld32.w a0, (sp, 8) +; CHECK-SF-NEXT: bez32 a2, .LBB23_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: ld32.w lr, (sp, 28) +; CHECK-SF-NEXT: ld32.w l0, (sp, 24) +; CHECK-SF-NEXT: ld32.w l1, (sp, 20) +; CHECK-SF-NEXT: ld32.w l2, (sp, 16) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.3: +; CHECK-SF-NEXT: .LCPI23_0: +; CHECK-SF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_i64_umin: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 16 +; CHECK-DF-NEXT: st32.w lr, (sp, 28) +; CHECK-DF-NEXT: st32.w l0, (sp, 24) +; CHECK-DF-NEXT: st32.w l1, (sp, 20) +; CHECK-DF-NEXT: st32.w l2, (sp, 16) +; CHECK-DF-NEXT: subi32 sp, sp, 16 +; CHECK-DF-NEXT: mov32 l0, a0 +; CHECK-DF-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF-NEXT: movi32 l2, 2 +; CHECK-DF-NEXT: addi32 l1, sp, 8 +; CHECK-DF-NEXT: .LBB23_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: cmphsi32 a0, 2 +; CHECK-DF-NEXT: mvcv32 a2 +; CHECK-DF-NEXT: cmpnei32 a1, 0 +; CHECK-DF-NEXT: movi32 a3, 0 +; CHECK-DF-NEXT: movf32 a3, a2 +; CHECK-DF-NEXT: btsti32 a3, 0 +; CHECK-DF-NEXT: movi32 a2, 1 +; CHECK-DF-NEXT: movt32 a2, a0 +; CHECK-DF-NEXT: movi32 a3, 0 +; CHECK-DF-NEXT: movt32 a3, a1 +; CHECK-DF-NEXT: st32.w a0, (sp, 8) +; CHECK-DF-NEXT: st32.w a1, (sp, 8) +; CHECK-DF-NEXT: mov32 a0, sp +; CHECK-DF-NEXT: st32.w l2, (a0, 1) +; CHECK-DF-NEXT: st32.w l2, (a0, 0) +; CHECK-DF-NEXT: mov32 a0, l0 +; CHECK-DF-NEXT: mov32 a1, l1 +; CHECK-DF-NEXT: jsri32 .LCPI23_0 +; CHECK-DF-NEXT: mov32 a2, a0 +; CHECK-DF-NEXT: ld32.w a1, (sp, 8) +; CHECK-DF-NEXT: ld32.w a0, (sp, 8) +; CHECK-DF-NEXT: bez32 a2, .LBB23_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: addi32 sp, sp, 16 +; CHECK-DF-NEXT: ld32.w lr, (sp, 28) +; CHECK-DF-NEXT: ld32.w l0, (sp, 24) +; CHECK-DF-NEXT: ld32.w l1, (sp, 20) +; CHECK-DF-NEXT: ld32.w l2, (sp, 16) +; CHECK-DF-NEXT: addi32 sp, sp, 16 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.3: +; CHECK-DF-NEXT: .LCPI23_0: +; CHECK-DF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_i64_umin: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 28) +; CHECK-SF2-NEXT: st32.w l0, (sp, 24) +; CHECK-SF2-NEXT: st32.w l1, (sp, 20) +; CHECK-SF2-NEXT: st32.w l2, (sp, 16) +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: mov32 l0, a0 +; CHECK-SF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-SF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-SF2-NEXT: movi32 l2, 2 +; CHECK-SF2-NEXT: addi32 l1, sp, 8 +; CHECK-SF2-NEXT: .LBB23_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: cmphsi32 a0, 2 +; CHECK-SF2-NEXT: mvcv32 a2 +; CHECK-SF2-NEXT: cmpnei32 a1, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: movf32 a3, a2 +; CHECK-SF2-NEXT: btsti32 a3, 0 +; CHECK-SF2-NEXT: movi32 a2, 1 +; CHECK-SF2-NEXT: movt32 a2, a0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: movt32 a3, a1 +; CHECK-SF2-NEXT: st32.w a0, (sp, 8) +; CHECK-SF2-NEXT: st32.w a1, (sp, 8) +; CHECK-SF2-NEXT: mov32 a0, sp +; CHECK-SF2-NEXT: st32.w l2, (a0, 1) +; CHECK-SF2-NEXT: st32.w l2, (a0, 0) +; CHECK-SF2-NEXT: mov32 a0, l0 +; CHECK-SF2-NEXT: mov32 a1, l1 +; CHECK-SF2-NEXT: jsri32 .LCPI23_0 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: ld32.w a1, (sp, 8) +; CHECK-SF2-NEXT: ld32.w a0, (sp, 8) +; CHECK-SF2-NEXT: bez32 a2, .LBB23_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 28) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 24) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 16) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.3: +; CHECK-SF2-NEXT: .LCPI23_0: +; CHECK-SF2-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_i64_umin: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 16 +; CHECK-DF2-NEXT: st32.w lr, (sp, 28) +; CHECK-DF2-NEXT: st32.w l0, (sp, 24) +; CHECK-DF2-NEXT: st32.w l1, (sp, 20) +; CHECK-DF2-NEXT: st32.w l2, (sp, 16) +; CHECK-DF2-NEXT: subi32 sp, sp, 16 +; CHECK-DF2-NEXT: mov32 l0, a0 +; CHECK-DF2-NEXT: ld32.w a1, (a0, 1) +; CHECK-DF2-NEXT: ld32.w a0, (a0, 0) +; CHECK-DF2-NEXT: movi32 l2, 2 +; CHECK-DF2-NEXT: addi32 l1, sp, 8 +; CHECK-DF2-NEXT: .LBB23_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: cmphsi32 a0, 2 +; CHECK-DF2-NEXT: mvcv32 a2 +; CHECK-DF2-NEXT: cmpnei32 a1, 0 +; CHECK-DF2-NEXT: movi32 a3, 0 +; CHECK-DF2-NEXT: movf32 a3, a2 +; CHECK-DF2-NEXT: btsti32 a3, 0 +; CHECK-DF2-NEXT: movi32 a2, 1 +; CHECK-DF2-NEXT: movt32 a2, a0 +; CHECK-DF2-NEXT: movi32 a3, 0 +; CHECK-DF2-NEXT: movt32 a3, a1 +; CHECK-DF2-NEXT: st32.w a0, (sp, 8) +; CHECK-DF2-NEXT: st32.w a1, (sp, 8) +; CHECK-DF2-NEXT: mov32 a0, sp +; CHECK-DF2-NEXT: st32.w l2, (a0, 1) +; CHECK-DF2-NEXT: st32.w l2, (a0, 0) +; CHECK-DF2-NEXT: mov32 a0, l0 +; CHECK-DF2-NEXT: mov32 a1, l1 +; CHECK-DF2-NEXT: jsri32 .LCPI23_0 +; CHECK-DF2-NEXT: mov32 a2, a0 +; CHECK-DF2-NEXT: ld32.w a1, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a0, (sp, 8) +; CHECK-DF2-NEXT: bez32 a2, .LBB23_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: addi32 sp, sp, 16 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 28) +; CHECK-DF2-NEXT: ld32.w l0, (sp, 24) +; CHECK-DF2-NEXT: ld32.w l1, (sp, 20) +; CHECK-DF2-NEXT: ld32.w l2, (sp, 16) +; CHECK-DF2-NEXT: addi32 sp, sp, 16 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.3: +; CHECK-DF2-NEXT: .LCPI23_0: +; CHECK-DF2-NEXT: .long __atomic_compare_exchange_8 +entry: + %old = atomicrmw umin i64* %ptr, i64 1 acquire ; yields i64 + ret i64 %old +} + +define double @atomicrmw_double_fadd(double* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_double_fadd: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 36) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 32) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 28) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 24) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 16) +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: ld32.w l2, (a0, 1) +; CHECK-SOFT-NEXT: ld32.w l3, (a0, 0) +; CHECK-SOFT-NEXT: movi32 l4, 2 +; CHECK-SOFT-NEXT: addi32 l1, sp, 8 +; CHECK-SOFT-NEXT: .LBB24_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: mov32 a0, l3 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16368 +; CHECK-SOFT-NEXT: jsri32 .LCPI24_0 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: st32.w l3, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: mov32 a0, sp +; CHECK-SOFT-NEXT: st32.w l4, (a0, 1) +; CHECK-SOFT-NEXT: st32.w l4, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI24_1 +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 8) +; CHECK-SOFT-NEXT: bez32 a0, .LBB24_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, l3 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 36) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 32) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 28) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 24) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 16) +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI24_0: +; CHECK-SOFT-NEXT: .long __adddf3 +; CHECK-SOFT-NEXT: .LCPI24_1: +; CHECK-SOFT-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_double_fadd: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 24 +; CHECK-SF-NEXT: st32.w lr, (sp, 36) +; CHECK-SF-NEXT: st32.w l0, (sp, 32) +; CHECK-SF-NEXT: st32.w l1, (sp, 28) +; CHECK-SF-NEXT: st32.w l2, (sp, 24) +; CHECK-SF-NEXT: st32.w l3, (sp, 20) +; CHECK-SF-NEXT: st32.w l4, (sp, 16) +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: mov32 l0, a0 +; CHECK-SF-NEXT: ld32.w l2, (a0, 1) +; CHECK-SF-NEXT: ld32.w l3, (a0, 0) +; CHECK-SF-NEXT: movi32 l4, 2 +; CHECK-SF-NEXT: addi32 l1, sp, 8 +; CHECK-SF-NEXT: .LBB24_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16368 +; CHECK-SF-NEXT: jsri32 .LCPI24_0 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: st32.w l3, (sp, 8) +; CHECK-SF-NEXT: st32.w l2, (sp, 8) +; CHECK-SF-NEXT: mov32 a0, sp +; CHECK-SF-NEXT: st32.w l4, (a0, 1) +; CHECK-SF-NEXT: st32.w l4, (a0, 0) +; CHECK-SF-NEXT: mov32 a0, l0 +; CHECK-SF-NEXT: mov32 a1, l1 +; CHECK-SF-NEXT: jsri32 .LCPI24_1 +; CHECK-SF-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF-NEXT: ld32.w l3, (sp, 8) +; CHECK-SF-NEXT: bez32 a0, .LBB24_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: ld32.w lr, (sp, 36) +; CHECK-SF-NEXT: ld32.w l0, (sp, 32) +; CHECK-SF-NEXT: ld32.w l1, (sp, 28) +; CHECK-SF-NEXT: ld32.w l2, (sp, 24) +; CHECK-SF-NEXT: ld32.w l3, (sp, 20) +; CHECK-SF-NEXT: ld32.w l4, (sp, 16) +; CHECK-SF-NEXT: addi32 sp, sp, 24 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.3: +; CHECK-SF-NEXT: .LCPI24_0: +; CHECK-SF-NEXT: .long __adddf3 +; CHECK-SF-NEXT: .LCPI24_1: +; CHECK-SF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_double_fadd: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 24 +; CHECK-DF-NEXT: st32.w lr, (sp, 44) +; CHECK-DF-NEXT: st32.w l0, (sp, 40) +; CHECK-DF-NEXT: st32.w l1, (sp, 36) +; CHECK-DF-NEXT: st32.w l2, (sp, 32) +; CHECK-DF-NEXT: st32.w l3, (sp, 28) +; CHECK-DF-NEXT: st32.w l4, (sp, 24) +; CHECK-DF-NEXT: subi32 sp, sp, 24 +; CHECK-DF-NEXT: mov32 l0, a0 +; CHECK-DF-NEXT: fldd vr0, (a0, 0) +; CHECK-DF-NEXT: movi32 l2, 0 +; CHECK-DF-NEXT: movih32 l3, 16368 +; CHECK-DF-NEXT: movi32 l4, 2 +; CHECK-DF-NEXT: addi32 l1, sp, 16 +; CHECK-DF-NEXT: .LBB24_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: fmtvrl vr1, l2 +; CHECK-DF-NEXT: fmtvrh vr1, l3 +; CHECK-DF-NEXT: faddd vr1, vr0, vr1 +; CHECK-DF-NEXT: fstd vr0, (sp, 16) +; CHECK-DF-NEXT: fstd vr1, (sp, 8) +; CHECK-DF-NEXT: ld32.w a2, (sp, 8) +; CHECK-DF-NEXT: ld32.w a3, (sp, 8) +; CHECK-DF-NEXT: mov32 a0, sp +; CHECK-DF-NEXT: st32.w l4, (a0, 1) +; CHECK-DF-NEXT: st32.w l4, (a0, 0) +; CHECK-DF-NEXT: mov32 a0, l0 +; CHECK-DF-NEXT: mov32 a1, l1 +; CHECK-DF-NEXT: jsri32 .LCPI24_0 +; CHECK-DF-NEXT: fldd vr0, (sp, 16) +; CHECK-DF-NEXT: bez32 a0, .LBB24_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: addi32 sp, sp, 24 +; CHECK-DF-NEXT: ld32.w lr, (sp, 44) +; CHECK-DF-NEXT: ld32.w l0, (sp, 40) +; CHECK-DF-NEXT: ld32.w l1, (sp, 36) +; CHECK-DF-NEXT: ld32.w l2, (sp, 32) +; CHECK-DF-NEXT: ld32.w l3, (sp, 28) +; CHECK-DF-NEXT: ld32.w l4, (sp, 24) +; CHECK-DF-NEXT: addi32 sp, sp, 24 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.3: +; CHECK-DF-NEXT: .LCPI24_0: +; CHECK-DF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_double_fadd: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, (sp, 36) +; CHECK-SF2-NEXT: st32.w l0, (sp, 32) +; CHECK-SF2-NEXT: st32.w l1, (sp, 28) +; CHECK-SF2-NEXT: st32.w l2, (sp, 24) +; CHECK-SF2-NEXT: st32.w l3, (sp, 20) +; CHECK-SF2-NEXT: st32.w l4, (sp, 16) +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: mov32 l0, a0 +; CHECK-SF2-NEXT: ld32.w l2, (a0, 1) +; CHECK-SF2-NEXT: ld32.w l3, (a0, 0) +; CHECK-SF2-NEXT: movi32 l4, 2 +; CHECK-SF2-NEXT: addi32 l1, sp, 8 +; CHECK-SF2-NEXT: .LBB24_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: mov32 a0, l3 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16368 +; CHECK-SF2-NEXT: jsri32 .LCPI24_0 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: st32.w l3, (sp, 8) +; CHECK-SF2-NEXT: st32.w l2, (sp, 8) +; CHECK-SF2-NEXT: mov32 a0, sp +; CHECK-SF2-NEXT: st32.w l4, (a0, 1) +; CHECK-SF2-NEXT: st32.w l4, (a0, 0) +; CHECK-SF2-NEXT: mov32 a0, l0 +; CHECK-SF2-NEXT: mov32 a1, l1 +; CHECK-SF2-NEXT: jsri32 .LCPI24_1 +; CHECK-SF2-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 8) +; CHECK-SF2-NEXT: bez32 a0, .LBB24_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, l3 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 36) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 32) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 28) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 24) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 16) +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.3: +; CHECK-SF2-NEXT: .LCPI24_0: +; CHECK-SF2-NEXT: .long __adddf3 +; CHECK-SF2-NEXT: .LCPI24_1: +; CHECK-SF2-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_double_fadd: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 24 +; CHECK-DF2-NEXT: st32.w lr, (sp, 44) +; CHECK-DF2-NEXT: st32.w l0, (sp, 40) +; CHECK-DF2-NEXT: st32.w l1, (sp, 36) +; CHECK-DF2-NEXT: st32.w l2, (sp, 32) +; CHECK-DF2-NEXT: fst.64 vr8, (sp, 24) +; CHECK-DF2-NEXT: subi32 sp, sp, 24 +; CHECK-DF2-NEXT: mov32 l0, a0 +; CHECK-DF2-NEXT: fld.64 vr0, (a0, 0) +; CHECK-DF2-NEXT: movih32 a0, 16368 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr8, a1, a0 +; CHECK-DF2-NEXT: movi32 l2, 2 +; CHECK-DF2-NEXT: addi32 l1, sp, 16 +; CHECK-DF2-NEXT: .LBB24_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: fadd.64 vr1, vr0, vr8 +; CHECK-DF2-NEXT: fst.64 vr0, (sp, 16) +; CHECK-DF2-NEXT: fst.64 vr1, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a2, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a3, (sp, 8) +; CHECK-DF2-NEXT: mov32 a0, sp +; CHECK-DF2-NEXT: st32.w l2, (a0, 1) +; CHECK-DF2-NEXT: st32.w l2, (a0, 0) +; CHECK-DF2-NEXT: mov32 a0, l0 +; CHECK-DF2-NEXT: mov32 a1, l1 +; CHECK-DF2-NEXT: jsri32 .LCPI24_0 +; CHECK-DF2-NEXT: fld.64 vr0, (sp, 16) +; CHECK-DF2-NEXT: bez32 a0, .LBB24_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: addi32 sp, sp, 24 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 44) +; CHECK-DF2-NEXT: ld32.w l0, (sp, 40) +; CHECK-DF2-NEXT: ld32.w l1, (sp, 36) +; CHECK-DF2-NEXT: ld32.w l2, (sp, 32) +; CHECK-DF2-NEXT: fld.64 vr8, (sp, 24) +; CHECK-DF2-NEXT: addi32 sp, sp, 24 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.3: +; CHECK-DF2-NEXT: .LCPI24_0: +; CHECK-DF2-NEXT: .long __atomic_compare_exchange_8 +entry: + %old = atomicrmw fadd double* %ptr, double 1.0 acquire ; yields i64 + ret double %old +} + +define double @atomicrmw_double_fsub(double* %ptr) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: atomicrmw_double_fsub: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 28 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 40) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 36) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 32) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 28) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 24) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l5, (sp, 16) +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: ld32.w l3, (a0, 1) +; CHECK-SOFT-NEXT: ld32.w l4, (a0, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49136 +; CHECK-SOFT-NEXT: ori32 l1, a0, 0 +; CHECK-SOFT-NEXT: movi32 l5, 2 +; CHECK-SOFT-NEXT: addi32 l2, sp, 8 +; CHECK-SOFT-NEXT: .LBB25_1: # %atomicrmw.start +; CHECK-SOFT-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SOFT-NEXT: mov32 a0, l4 +; CHECK-SOFT-NEXT: mov32 a1, l3 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: mov32 a3, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI25_0 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: st32.w l4, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 8) +; CHECK-SOFT-NEXT: mov32 a0, sp +; CHECK-SOFT-NEXT: st32.w l5, (a0, 1) +; CHECK-SOFT-NEXT: st32.w l5, (a0, 0) +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI25_1 +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 8) +; CHECK-SOFT-NEXT: bez32 a0, .LBB25_1 +; CHECK-SOFT-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SOFT-NEXT: mov32 a0, l4 +; CHECK-SOFT-NEXT: mov32 a1, l3 +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 40) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 36) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 32) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 28) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 24) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l5, (sp, 16) +; CHECK-SOFT-NEXT: addi32 sp, sp, 28 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.3: +; CHECK-SOFT-NEXT: .LCPI25_0: +; CHECK-SOFT-NEXT: .long __adddf3 +; CHECK-SOFT-NEXT: .LCPI25_1: +; CHECK-SOFT-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF-LABEL: atomicrmw_double_fsub: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 28 +; CHECK-SF-NEXT: st32.w lr, (sp, 40) +; CHECK-SF-NEXT: st32.w l0, (sp, 36) +; CHECK-SF-NEXT: st32.w l1, (sp, 32) +; CHECK-SF-NEXT: st32.w l2, (sp, 28) +; CHECK-SF-NEXT: st32.w l3, (sp, 24) +; CHECK-SF-NEXT: st32.w l4, (sp, 20) +; CHECK-SF-NEXT: st32.w l5, (sp, 16) +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: mov32 l0, a0 +; CHECK-SF-NEXT: ld32.w l3, (a0, 1) +; CHECK-SF-NEXT: ld32.w l4, (a0, 0) +; CHECK-SF-NEXT: movih32 a0, 49136 +; CHECK-SF-NEXT: ori32 l1, a0, 0 +; CHECK-SF-NEXT: movi32 l5, 2 +; CHECK-SF-NEXT: addi32 l2, sp, 8 +; CHECK-SF-NEXT: .LBB25_1: # %atomicrmw.start +; CHECK-SF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF-NEXT: mov32 a0, l4 +; CHECK-SF-NEXT: mov32 a1, l3 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: mov32 a3, l1 +; CHECK-SF-NEXT: jsri32 .LCPI25_0 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: st32.w l4, (sp, 8) +; CHECK-SF-NEXT: st32.w l3, (sp, 8) +; CHECK-SF-NEXT: mov32 a0, sp +; CHECK-SF-NEXT: st32.w l5, (a0, 1) +; CHECK-SF-NEXT: st32.w l5, (a0, 0) +; CHECK-SF-NEXT: mov32 a0, l0 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: jsri32 .LCPI25_1 +; CHECK-SF-NEXT: ld32.w l3, (sp, 8) +; CHECK-SF-NEXT: ld32.w l4, (sp, 8) +; CHECK-SF-NEXT: bez32 a0, .LBB25_1 +; CHECK-SF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF-NEXT: mov32 a0, l4 +; CHECK-SF-NEXT: mov32 a1, l3 +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: ld32.w lr, (sp, 40) +; CHECK-SF-NEXT: ld32.w l0, (sp, 36) +; CHECK-SF-NEXT: ld32.w l1, (sp, 32) +; CHECK-SF-NEXT: ld32.w l2, (sp, 28) +; CHECK-SF-NEXT: ld32.w l3, (sp, 24) +; CHECK-SF-NEXT: ld32.w l4, (sp, 20) +; CHECK-SF-NEXT: ld32.w l5, (sp, 16) +; CHECK-SF-NEXT: addi32 sp, sp, 28 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.3: +; CHECK-SF-NEXT: .LCPI25_0: +; CHECK-SF-NEXT: .long __adddf3 +; CHECK-SF-NEXT: .LCPI25_1: +; CHECK-SF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF-LABEL: atomicrmw_double_fsub: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 24 +; CHECK-DF-NEXT: st32.w lr, (sp, 44) +; CHECK-DF-NEXT: st32.w l0, (sp, 40) +; CHECK-DF-NEXT: st32.w l1, (sp, 36) +; CHECK-DF-NEXT: st32.w l2, (sp, 32) +; CHECK-DF-NEXT: st32.w l3, (sp, 28) +; CHECK-DF-NEXT: st32.w l4, (sp, 24) +; CHECK-DF-NEXT: subi32 sp, sp, 24 +; CHECK-DF-NEXT: mov32 l0, a0 +; CHECK-DF-NEXT: fldd vr0, (a0, 0) +; CHECK-DF-NEXT: movih32 a0, 49136 +; CHECK-DF-NEXT: ori32 l2, a0, 0 +; CHECK-DF-NEXT: movi32 l3, 0 +; CHECK-DF-NEXT: movi32 l4, 2 +; CHECK-DF-NEXT: addi32 l1, sp, 16 +; CHECK-DF-NEXT: .LBB25_1: # %atomicrmw.start +; CHECK-DF-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF-NEXT: fmtvrl vr1, l3 +; CHECK-DF-NEXT: fmtvrh vr1, l2 +; CHECK-DF-NEXT: faddd vr1, vr0, vr1 +; CHECK-DF-NEXT: fstd vr0, (sp, 16) +; CHECK-DF-NEXT: fstd vr1, (sp, 8) +; CHECK-DF-NEXT: ld32.w a2, (sp, 8) +; CHECK-DF-NEXT: ld32.w a3, (sp, 8) +; CHECK-DF-NEXT: mov32 a0, sp +; CHECK-DF-NEXT: st32.w l4, (a0, 1) +; CHECK-DF-NEXT: st32.w l4, (a0, 0) +; CHECK-DF-NEXT: mov32 a0, l0 +; CHECK-DF-NEXT: mov32 a1, l1 +; CHECK-DF-NEXT: jsri32 .LCPI25_0 +; CHECK-DF-NEXT: fldd vr0, (sp, 16) +; CHECK-DF-NEXT: bez32 a0, .LBB25_1 +; CHECK-DF-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF-NEXT: addi32 sp, sp, 24 +; CHECK-DF-NEXT: ld32.w lr, (sp, 44) +; CHECK-DF-NEXT: ld32.w l0, (sp, 40) +; CHECK-DF-NEXT: ld32.w l1, (sp, 36) +; CHECK-DF-NEXT: ld32.w l2, (sp, 32) +; CHECK-DF-NEXT: ld32.w l3, (sp, 28) +; CHECK-DF-NEXT: ld32.w l4, (sp, 24) +; CHECK-DF-NEXT: addi32 sp, sp, 24 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.3: +; CHECK-DF-NEXT: .LCPI25_0: +; CHECK-DF-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-SF2-LABEL: atomicrmw_double_fsub: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 28 +; CHECK-SF2-NEXT: st32.w lr, (sp, 40) +; CHECK-SF2-NEXT: st32.w l0, (sp, 36) +; CHECK-SF2-NEXT: st32.w l1, (sp, 32) +; CHECK-SF2-NEXT: st32.w l2, (sp, 28) +; CHECK-SF2-NEXT: st32.w l3, (sp, 24) +; CHECK-SF2-NEXT: st32.w l4, (sp, 20) +; CHECK-SF2-NEXT: st32.w l5, (sp, 16) +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: mov32 l0, a0 +; CHECK-SF2-NEXT: ld32.w l3, (a0, 1) +; CHECK-SF2-NEXT: ld32.w l4, (a0, 0) +; CHECK-SF2-NEXT: movih32 a0, 49136 +; CHECK-SF2-NEXT: ori32 l1, a0, 0 +; CHECK-SF2-NEXT: movi32 l5, 2 +; CHECK-SF2-NEXT: addi32 l2, sp, 8 +; CHECK-SF2-NEXT: .LBB25_1: # %atomicrmw.start +; CHECK-SF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-SF2-NEXT: mov32 a0, l4 +; CHECK-SF2-NEXT: mov32 a1, l3 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: mov32 a3, l1 +; CHECK-SF2-NEXT: jsri32 .LCPI25_0 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: st32.w l4, (sp, 8) +; CHECK-SF2-NEXT: st32.w l3, (sp, 8) +; CHECK-SF2-NEXT: mov32 a0, sp +; CHECK-SF2-NEXT: st32.w l5, (a0, 1) +; CHECK-SF2-NEXT: st32.w l5, (a0, 0) +; CHECK-SF2-NEXT: mov32 a0, l0 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI25_1 +; CHECK-SF2-NEXT: ld32.w l3, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 8) +; CHECK-SF2-NEXT: bez32 a0, .LBB25_1 +; CHECK-SF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-SF2-NEXT: mov32 a0, l4 +; CHECK-SF2-NEXT: mov32 a1, l3 +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 40) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 36) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 32) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 28) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 24) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l5, (sp, 16) +; CHECK-SF2-NEXT: addi32 sp, sp, 28 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.3: +; CHECK-SF2-NEXT: .LCPI25_0: +; CHECK-SF2-NEXT: .long __adddf3 +; CHECK-SF2-NEXT: .LCPI25_1: +; CHECK-SF2-NEXT: .long __atomic_compare_exchange_8 +; +; CHECK-DF2-LABEL: atomicrmw_double_fsub: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 24 +; CHECK-DF2-NEXT: st32.w lr, (sp, 44) +; CHECK-DF2-NEXT: st32.w l0, (sp, 40) +; CHECK-DF2-NEXT: st32.w l1, (sp, 36) +; CHECK-DF2-NEXT: st32.w l2, (sp, 32) +; CHECK-DF2-NEXT: fst.64 vr8, (sp, 24) +; CHECK-DF2-NEXT: subi32 sp, sp, 24 +; CHECK-DF2-NEXT: mov32 l0, a0 +; CHECK-DF2-NEXT: fld.64 vr0, (a0, 0) +; CHECK-DF2-NEXT: movih32 a0, 49136 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr8, a1, a0 +; CHECK-DF2-NEXT: movi32 l2, 2 +; CHECK-DF2-NEXT: addi32 l1, sp, 16 +; CHECK-DF2-NEXT: .LBB25_1: # %atomicrmw.start +; CHECK-DF2-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-DF2-NEXT: fadd.64 vr1, vr0, vr8 +; CHECK-DF2-NEXT: fst.64 vr0, (sp, 16) +; CHECK-DF2-NEXT: fst.64 vr1, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a2, (sp, 8) +; CHECK-DF2-NEXT: ld32.w a3, (sp, 8) +; CHECK-DF2-NEXT: mov32 a0, sp +; CHECK-DF2-NEXT: st32.w l2, (a0, 1) +; CHECK-DF2-NEXT: st32.w l2, (a0, 0) +; CHECK-DF2-NEXT: mov32 a0, l0 +; CHECK-DF2-NEXT: mov32 a1, l1 +; CHECK-DF2-NEXT: jsri32 .LCPI25_0 +; CHECK-DF2-NEXT: fld.64 vr0, (sp, 16) +; CHECK-DF2-NEXT: bez32 a0, .LBB25_1 +; CHECK-DF2-NEXT: # %bb.2: # %atomicrmw.end +; CHECK-DF2-NEXT: addi32 sp, sp, 24 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 44) +; CHECK-DF2-NEXT: ld32.w l0, (sp, 40) +; CHECK-DF2-NEXT: ld32.w l1, (sp, 36) +; CHECK-DF2-NEXT: ld32.w l2, (sp, 32) +; CHECK-DF2-NEXT: fld.64 vr8, (sp, 24) +; CHECK-DF2-NEXT: addi32 sp, sp, 24 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.3: +; CHECK-DF2-NEXT: .LCPI25_0: +; CHECK-DF2-NEXT: .long __atomic_compare_exchange_8 +entry: + %old = atomicrmw fsub double* %ptr, double 1.0 acquire ; yields i64 + ret double %old +} + Index: llvm/test/CodeGen/CSKY/br-double.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/br-double.ll @@ -0,0 +1,5371 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +;OEQ +define i32 @brRR_oeq(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB0_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB0_3 +; CHECK-SOFT-NEXT: .LBB0_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB0_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __nedf2 +; +; CHECK-SF-LABEL: brRR_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB0_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB0_3 +; CHECK-SF-NEXT: .LBB0_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB0_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __nedf2 +; +; CHECK-DF-LABEL: brRR_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB0_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB0_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB0_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB0_3 +; CHECK-SF2-NEXT: .LBB0_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB0_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __nedf2 +; +; CHECK-DF2-LABEL: brRR_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB0_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB0_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_oeq(double %x) { +; CHECK-SOFT-LABEL: brRI_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB1_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB1_3 +; CHECK-SOFT-NEXT: .LBB1_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB1_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __nedf2 +; +; CHECK-SF-LABEL: brRI_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI1_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB1_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB1_3 +; CHECK-SF-NEXT: .LBB1_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB1_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI1_0: +; CHECK-SF-NEXT: .long __nedf2 +; +; CHECK-DF-LABEL: brRI_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB1_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB1_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI1_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB1_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB1_3 +; CHECK-SF2-NEXT: .LBB1_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB1_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI1_0: +; CHECK-SF2-NEXT: .long __nedf2 +; +; CHECK-DF2-LABEL: brRI_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB1_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB1_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_oeq(double %x) { +; CHECK-SOFT-LABEL: brR0_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB2_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB2_3 +; CHECK-SOFT-NEXT: .LBB2_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB2_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __nedf2 +; +; CHECK-SF-LABEL: brR0_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI2_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB2_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB2_3 +; CHECK-SF-NEXT: .LBB2_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB2_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI2_0: +; CHECK-SF-NEXT: .long __nedf2 +; +; CHECK-DF-LABEL: brR0_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: bt32 .LBB2_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB2_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI2_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB2_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB2_3 +; CHECK-SF2-NEXT: .LBB2_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB2_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI2_0: +; CHECK-SF2-NEXT: .long __nedf2 +; +; CHECK-DF2-LABEL: brR0_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: bt32 .LBB2_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB2_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;NE +define i32 @brRR_one(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l4 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB3_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB3_3 +; CHECK-SOFT-NEXT: .LBB3_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB3_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI3_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRR_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 24 +; CHECK-SF-NEXT: st32.w lr, (sp, 20) +; CHECK-SF-NEXT: st32.w l0, (sp, 16) +; CHECK-SF-NEXT: st32.w l1, (sp, 12) +; CHECK-SF-NEXT: st32.w l2, (sp, 8) +; CHECK-SF-NEXT: st32.w l3, (sp, 4) +; CHECK-SF-NEXT: st32.w l4, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l2, a1 +; CHECK-SF-NEXT: mov32 l3, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l4 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI3_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l4 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB3_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB3_3 +; CHECK-SF-NEXT: .LBB3_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB3_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 24 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI3_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRR_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB3_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB3_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, (sp, 20) +; CHECK-SF2-NEXT: st32.w l0, (sp, 16) +; CHECK-SF2-NEXT: st32.w l1, (sp, 12) +; CHECK-SF2-NEXT: st32.w l2, (sp, 8) +; CHECK-SF2-NEXT: st32.w l3, (sp, 4) +; CHECK-SF2-NEXT: st32.w l4, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI3_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l4 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB3_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB3_3 +; CHECK-SF2-NEXT: .LBB3_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB3_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI3_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRR_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB3_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB3_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_one(double %x) { +; CHECK-SOFT-LABEL: brRI_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l2 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB4_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB4_3 +; CHECK-SOFT-NEXT: .LBB4_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB4_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI4_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRI_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 12) +; CHECK-SF-NEXT: st32.w l0, (sp, 8) +; CHECK-SF-NEXT: st32.w l1, (sp, 4) +; CHECK-SF-NEXT: st32.w l2, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a1 +; CHECK-SF-NEXT: mov32 l1, a0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l2 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI4_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l2 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB4_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB4_3 +; CHECK-SF-NEXT: .LBB4_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB4_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI4_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRI_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr1 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: or32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB4_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB4_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 12) +; CHECK-SF2-NEXT: st32.w l0, (sp, 8) +; CHECK-SF2-NEXT: st32.w l1, (sp, 4) +; CHECK-SF2-NEXT: st32.w l2, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a1 +; CHECK-SF2-NEXT: mov32 l1, a0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI4_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l2 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB4_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB4_3 +; CHECK-SF2-NEXT: .LBB4_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB4_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI4_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRI_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr1 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: or32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB4_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB4_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_one(double %x) { +; CHECK-SOFT-LABEL: brR0_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l2 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB5_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB5_3 +; CHECK-SOFT-NEXT: .LBB5_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB5_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI5_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI5_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brR0_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 12) +; CHECK-SF-NEXT: st32.w l0, (sp, 8) +; CHECK-SF-NEXT: st32.w l1, (sp, 4) +; CHECK-SF-NEXT: st32.w l2, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a1 +; CHECK-SF-NEXT: mov32 l1, a0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI5_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l2 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI5_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l2 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB5_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB5_3 +; CHECK-SF-NEXT: .LBB5_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB5_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI5_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI5_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brR0_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB5_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB5_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 12) +; CHECK-SF2-NEXT: st32.w l0, (sp, 8) +; CHECK-SF2-NEXT: st32.w l1, (sp, 4) +; CHECK-SF2-NEXT: st32.w l2, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a1 +; CHECK-SF2-NEXT: mov32 l1, a0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI5_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI5_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l2 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB5_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB5_3 +; CHECK-SF2-NEXT: .LBB5_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB5_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI5_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI5_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brR0_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB5_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB5_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UGT +define i32 @brRR_ugt(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI6_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB6_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB6_3 +; CHECK-SOFT-NEXT: .LBB6_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB6_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI6_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: brRR_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI6_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB6_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB6_3 +; CHECK-SF-NEXT: .LBB6_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB6_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI6_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: brRR_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB6_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB6_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI6_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: bt32 .LBB6_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB6_3 +; CHECK-SF2-NEXT: .LBB6_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB6_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI6_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: brRR_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB6_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB6_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ugt(double %x) { +; CHECK-SOFT-LABEL: brRI_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI7_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB7_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB7_3 +; CHECK-SOFT-NEXT: .LBB7_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB7_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI7_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: brRI_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI7_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB7_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB7_3 +; CHECK-SF-NEXT: .LBB7_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB7_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI7_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: brRI_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB7_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB7_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI7_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: bt32 .LBB7_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB7_3 +; CHECK-SF2-NEXT: .LBB7_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB7_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI7_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: brRI_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB7_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB7_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ugt(double %x) { +; CHECK-SOFT-LABEL: brR0_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI8_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB8_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB8_3 +; CHECK-SOFT-NEXT: .LBB8_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB8_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI8_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: brR0_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI8_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB8_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB8_3 +; CHECK-SF-NEXT: .LBB8_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB8_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI8_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: brR0_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: bt32 .LBB8_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB8_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI8_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: bt32 .LBB8_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB8_3 +; CHECK-SF2-NEXT: .LBB8_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB8_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI8_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: brR0_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.64 vr0 +; CHECK-DF2-NEXT: bt32 .LBB8_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB8_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UGE +define i32 @brRR_uge(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI9_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB9_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB9_3 +; CHECK-SOFT-NEXT: .LBB9_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB9_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI9_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: brRR_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI9_0 +; CHECK-SF-NEXT: blz32 a0, .LBB9_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB9_3 +; CHECK-SF-NEXT: .LBB9_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB9_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI9_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: brRR_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB9_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB9_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI9_0 +; CHECK-SF2-NEXT: blz32 a0, .LBB9_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB9_3 +; CHECK-SF2-NEXT: .LBB9_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB9_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI9_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: brRR_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB9_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB9_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_uge(double %x) { +; CHECK-SOFT-LABEL: brRI_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB10_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB10_3 +; CHECK-SOFT-NEXT: .LBB10_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB10_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: brRI_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI10_0 +; CHECK-SF-NEXT: blz32 a0, .LBB10_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB10_3 +; CHECK-SF-NEXT: .LBB10_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB10_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI10_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: brRI_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB10_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB10_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI10_0 +; CHECK-SF2-NEXT: blz32 a0, .LBB10_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB10_3 +; CHECK-SF2-NEXT: .LBB10_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB10_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI10_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: brRI_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB10_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB10_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_uge(double %x) { +; CHECK-SOFT-LABEL: brR0_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB11_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB11_3 +; CHECK-SOFT-NEXT: .LBB11_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB11_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: brR0_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI11_0 +; CHECK-SF-NEXT: blz32 a0, .LBB11_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB11_3 +; CHECK-SF-NEXT: .LBB11_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB11_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI11_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: brR0_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: bf32 .LBB11_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB11_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI11_0 +; CHECK-SF2-NEXT: blz32 a0, .LBB11_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB11_3 +; CHECK-SF2-NEXT: .LBB11_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB11_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI11_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: brR0_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.64 vr0 +; CHECK-DF2-NEXT: bt32 .LBB11_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB11_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;ULT +define i32 @brRR_ult(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB12_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB12_3 +; CHECK-SOFT-NEXT: .LBB12_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB12_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: brRR_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI12_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB12_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB12_3 +; CHECK-SF-NEXT: .LBB12_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB12_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI12_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: brRR_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB12_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB12_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI12_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: bt32 .LBB12_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB12_3 +; CHECK-SF2-NEXT: .LBB12_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB12_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI12_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: brRR_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB12_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB12_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ult(double %x) { +; CHECK-SOFT-LABEL: brRI_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB13_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB13_3 +; CHECK-SOFT-NEXT: .LBB13_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB13_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: brRI_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI13_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB13_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB13_3 +; CHECK-SF-NEXT: .LBB13_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB13_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI13_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: brRI_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB13_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB13_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI13_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: bt32 .LBB13_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB13_3 +; CHECK-SF2-NEXT: .LBB13_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB13_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI13_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: brRI_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB13_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB13_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ult(double %x) { +; CHECK-SOFT-LABEL: brR0_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB14_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB14_3 +; CHECK-SOFT-NEXT: .LBB14_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB14_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: brR0_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI14_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB14_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB14_3 +; CHECK-SF-NEXT: .LBB14_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB14_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI14_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: brR0_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: bt32 .LBB14_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB14_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI14_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: bt32 .LBB14_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB14_3 +; CHECK-SF2-NEXT: .LBB14_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB14_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI14_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: brR0_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.64 vr0 +; CHECK-DF2-NEXT: bt32 .LBB14_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB14_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;ULE +define i32 @brRR_ule(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI15_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB15_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB15_3 +; CHECK-SOFT-NEXT: .LBB15_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB15_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI15_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: brRR_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI15_0 +; CHECK-SF-NEXT: bhz32 a0, .LBB15_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB15_3 +; CHECK-SF-NEXT: .LBB15_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB15_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI15_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: brRR_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB15_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB15_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI15_0 +; CHECK-SF2-NEXT: bhz32 a0, .LBB15_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB15_3 +; CHECK-SF2-NEXT: .LBB15_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB15_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI15_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: brRR_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB15_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB15_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ule(double %x) { +; CHECK-SOFT-LABEL: brRI_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI16_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB16_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB16_3 +; CHECK-SOFT-NEXT: .LBB16_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB16_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI16_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: brRI_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI16_0 +; CHECK-SF-NEXT: bhz32 a0, .LBB16_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB16_3 +; CHECK-SF-NEXT: .LBB16_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB16_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI16_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: brRI_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB16_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB16_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI16_0 +; CHECK-SF2-NEXT: bhz32 a0, .LBB16_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB16_3 +; CHECK-SF2-NEXT: .LBB16_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB16_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI16_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: brRI_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB16_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB16_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ule(double %x) { +; CHECK-SOFT-LABEL: brR0_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI17_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB17_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB17_3 +; CHECK-SOFT-NEXT: .LBB17_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB17_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI17_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: brR0_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI17_0 +; CHECK-SF-NEXT: bhz32 a0, .LBB17_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB17_3 +; CHECK-SF-NEXT: .LBB17_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB17_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI17_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: brR0_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: bf32 .LBB17_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB17_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI17_0 +; CHECK-SF2-NEXT: bhz32 a0, .LBB17_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB17_3 +; CHECK-SF2-NEXT: .LBB17_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB17_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI17_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: brR0_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.64 vr0 +; CHECK-DF2-NEXT: bt32 .LBB17_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB17_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SGT +define i32 @brRR_ogt(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI18_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB18_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB18_3 +; CHECK-SOFT-NEXT: .LBB18_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB18_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI18_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: brRR_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI18_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB18_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB18_3 +; CHECK-SF-NEXT: .LBB18_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB18_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI18_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: brRR_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB18_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB18_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI18_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: bt32 .LBB18_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB18_3 +; CHECK-SF2-NEXT: .LBB18_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB18_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI18_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: brRR_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB18_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB18_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ogt(double %x) { +; CHECK-SOFT-LABEL: brRI_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI19_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB19_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB19_3 +; CHECK-SOFT-NEXT: .LBB19_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB19_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI19_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: brRI_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI19_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB19_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB19_3 +; CHECK-SF-NEXT: .LBB19_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB19_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI19_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: brRI_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB19_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB19_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI19_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: bt32 .LBB19_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB19_3 +; CHECK-SF2-NEXT: .LBB19_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB19_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI19_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: brRI_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB19_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB19_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ogt(double %x) { +; CHECK-SOFT-LABEL: brR0_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI20_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB20_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB20_3 +; CHECK-SOFT-NEXT: .LBB20_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB20_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI20_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: brR0_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI20_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB20_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB20_3 +; CHECK-SF-NEXT: .LBB20_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB20_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI20_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: brR0_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB20_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB20_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI20_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: bt32 .LBB20_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB20_3 +; CHECK-SF2-NEXT: .LBB20_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB20_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI20_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: brR0_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB20_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB20_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SGE +define i32 @brRR_oge(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI21_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB21_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB21_3 +; CHECK-SOFT-NEXT: .LBB21_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB21_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI21_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: brRR_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI21_0 +; CHECK-SF-NEXT: blz32 a0, .LBB21_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB21_3 +; CHECK-SF-NEXT: .LBB21_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB21_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI21_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: brRR_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB21_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB21_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI21_0 +; CHECK-SF2-NEXT: blz32 a0, .LBB21_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB21_3 +; CHECK-SF2-NEXT: .LBB21_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB21_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI21_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: brRR_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB21_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB21_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_oge(double %x) { +; CHECK-SOFT-LABEL: brRI_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI22_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB22_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB22_3 +; CHECK-SOFT-NEXT: .LBB22_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB22_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI22_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: brRI_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI22_0 +; CHECK-SF-NEXT: blz32 a0, .LBB22_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB22_3 +; CHECK-SF-NEXT: .LBB22_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB22_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI22_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: brRI_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB22_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB22_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI22_0 +; CHECK-SF2-NEXT: blz32 a0, .LBB22_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB22_3 +; CHECK-SF2-NEXT: .LBB22_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB22_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI22_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: brRI_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB22_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB22_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_oge(double %x) { +; CHECK-SOFT-LABEL: brR0_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI23_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB23_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB23_3 +; CHECK-SOFT-NEXT: .LBB23_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB23_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI23_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: brR0_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI23_0 +; CHECK-SF-NEXT: blz32 a0, .LBB23_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB23_3 +; CHECK-SF-NEXT: .LBB23_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB23_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI23_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: brR0_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB23_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB23_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI23_0 +; CHECK-SF2-NEXT: blz32 a0, .LBB23_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB23_3 +; CHECK-SF2-NEXT: .LBB23_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB23_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI23_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: brR0_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB23_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB23_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SLT +define i32 @brRR_olt(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI24_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB24_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB24_3 +; CHECK-SOFT-NEXT: .LBB24_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB24_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI24_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: brRR_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI24_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB24_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB24_3 +; CHECK-SF-NEXT: .LBB24_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB24_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI24_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: brRR_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB24_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB24_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI24_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: bt32 .LBB24_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB24_3 +; CHECK-SF2-NEXT: .LBB24_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB24_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI24_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: brRR_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB24_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB24_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_olt(double %x) { +; CHECK-SOFT-LABEL: brRI_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI25_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB25_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB25_3 +; CHECK-SOFT-NEXT: .LBB25_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB25_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI25_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: brRI_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI25_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB25_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB25_3 +; CHECK-SF-NEXT: .LBB25_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB25_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI25_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: brRI_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB25_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB25_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI25_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: bt32 .LBB25_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB25_3 +; CHECK-SF2-NEXT: .LBB25_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB25_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI25_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: brRI_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB25_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB25_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_olt(double %x) { +; CHECK-SOFT-LABEL: brR0_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI26_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB26_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB26_3 +; CHECK-SOFT-NEXT: .LBB26_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB26_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI26_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: brR0_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI26_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB26_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB26_3 +; CHECK-SF-NEXT: .LBB26_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB26_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI26_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: brR0_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB26_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB26_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI26_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: bt32 .LBB26_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB26_3 +; CHECK-SF2-NEXT: .LBB26_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB26_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI26_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: brR0_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB26_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB26_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SLE +define i32 @brRR_ole(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI27_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB27_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB27_3 +; CHECK-SOFT-NEXT: .LBB27_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB27_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI27_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: brRR_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI27_0 +; CHECK-SF-NEXT: bhz32 a0, .LBB27_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB27_3 +; CHECK-SF-NEXT: .LBB27_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB27_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI27_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: brRR_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB27_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB27_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI27_0 +; CHECK-SF2-NEXT: bhz32 a0, .LBB27_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB27_3 +; CHECK-SF2-NEXT: .LBB27_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB27_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI27_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: brRR_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB27_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB27_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ole(double %x) { +; CHECK-SOFT-LABEL: brRI_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI28_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB28_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB28_3 +; CHECK-SOFT-NEXT: .LBB28_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB28_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI28_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: brRI_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI28_0 +; CHECK-SF-NEXT: bhz32 a0, .LBB28_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB28_3 +; CHECK-SF-NEXT: .LBB28_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB28_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI28_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: brRI_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB28_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB28_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI28_0 +; CHECK-SF2-NEXT: bhz32 a0, .LBB28_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB28_3 +; CHECK-SF2-NEXT: .LBB28_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB28_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI28_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: brRI_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB28_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB28_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ole(double %x) { +; CHECK-SOFT-LABEL: brR0_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI29_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB29_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB29_3 +; CHECK-SOFT-NEXT: .LBB29_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB29_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI29_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: brR0_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI29_0 +; CHECK-SF-NEXT: bhz32 a0, .LBB29_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB29_3 +; CHECK-SF-NEXT: .LBB29_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB29_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI29_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: brR0_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB29_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB29_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI29_0 +; CHECK-SF2-NEXT: bhz32 a0, .LBB29_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB29_3 +; CHECK-SF2-NEXT: .LBB29_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB29_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI29_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: brR0_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB29_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB29_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;False +define i32 @brRR_false(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB30_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB30_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRR_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB30_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB30_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB30_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB30_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB30_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB30_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB30_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB30_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_false(double %x) { +; CHECK-SOFT-LABEL: brRI_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB31_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB31_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRI_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB31_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB31_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB31_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB31_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB31_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB31_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB31_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB31_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_false(double %x) { +; CHECK-SOFT-LABEL: brR0_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB32_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB32_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brR0_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB32_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB32_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB32_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB32_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB32_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB32_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB32_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB32_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +;ORD +define i32 @brRR_ord(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI33_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB33_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB33_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB33_3: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB33_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI33_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRR_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI33_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB33_3 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: .LBB33_2: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB33_3: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: br32 .LBB33_2 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI33_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRR_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB33_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB33_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI33_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB33_3 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: .LBB33_2: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB33_3: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: br32 .LBB33_2 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI33_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRR_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB33_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB33_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ord(double %x) { +; CHECK-SOFT-LABEL: brRI_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: jsri32 .LCPI34_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB34_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB34_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB34_3: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB34_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI34_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRI_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: jsri32 .LCPI34_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB34_3 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: .LBB34_2: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB34_3: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: br32 .LBB34_2 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI34_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRI_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB34_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB34_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: jsri32 .LCPI34_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB34_3 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: .LBB34_2: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB34_3: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: br32 .LBB34_2 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI34_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRI_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB34_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB34_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ord(double %x) { +; CHECK-SOFT-LABEL: brR0_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: jsri32 .LCPI35_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB35_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB35_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB35_3: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB35_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI35_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brR0_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: jsri32 .LCPI35_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB35_3 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: .LBB35_2: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB35_3: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: br32 .LBB35_2 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI35_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brR0_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB35_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB35_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: jsri32 .LCPI35_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB35_3 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: .LBB35_2: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB35_3: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: br32 .LBB35_2 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI35_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brR0_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB35_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB35_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +;UEQ +define i32 @brRR_ueq(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI36_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI36_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l4 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bf32 .LBB36_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB36_3 +; CHECK-SOFT-NEXT: .LBB36_2: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB36_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI36_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI36_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRR_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 24 +; CHECK-SF-NEXT: st32.w lr, (sp, 20) +; CHECK-SF-NEXT: st32.w l0, (sp, 16) +; CHECK-SF-NEXT: st32.w l1, (sp, 12) +; CHECK-SF-NEXT: st32.w l2, (sp, 8) +; CHECK-SF-NEXT: st32.w l3, (sp, 4) +; CHECK-SF-NEXT: st32.w l4, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l2, a1 +; CHECK-SF-NEXT: mov32 l3, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI36_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l4 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI36_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l4 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bf32 .LBB36_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: br32 .LBB36_3 +; CHECK-SF-NEXT: .LBB36_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: .LBB36_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 24 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI36_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI36_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRR_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bf32 .LBB36_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB36_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, (sp, 20) +; CHECK-SF2-NEXT: st32.w l0, (sp, 16) +; CHECK-SF2-NEXT: st32.w l1, (sp, 12) +; CHECK-SF2-NEXT: st32.w l2, (sp, 8) +; CHECK-SF2-NEXT: st32.w l3, (sp, 4) +; CHECK-SF2-NEXT: st32.w l4, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI36_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI36_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l4 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bf32 .LBB36_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: br32 .LBB36_3 +; CHECK-SF2-NEXT: .LBB36_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: .LBB36_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI36_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI36_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRR_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bf32 .LBB36_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB36_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ueq(double %x) { +; CHECK-SOFT-LABEL: brRI_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI37_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI37_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l2 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bf32 .LBB37_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB37_3 +; CHECK-SOFT-NEXT: .LBB37_2: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB37_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI37_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI37_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRI_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 12) +; CHECK-SF-NEXT: st32.w l0, (sp, 8) +; CHECK-SF-NEXT: st32.w l1, (sp, 4) +; CHECK-SF-NEXT: st32.w l2, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a1 +; CHECK-SF-NEXT: mov32 l1, a0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI37_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l2 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI37_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l2 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bf32 .LBB37_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: br32 .LBB37_3 +; CHECK-SF-NEXT: .LBB37_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: .LBB37_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI37_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI37_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRI_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: and32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bf32 .LBB37_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB37_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 12) +; CHECK-SF2-NEXT: st32.w l0, (sp, 8) +; CHECK-SF2-NEXT: st32.w l1, (sp, 4) +; CHECK-SF2-NEXT: st32.w l2, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a1 +; CHECK-SF2-NEXT: mov32 l1, a0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI37_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI37_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l2 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bf32 .LBB37_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: br32 .LBB37_3 +; CHECK-SF2-NEXT: .LBB37_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: .LBB37_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI37_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI37_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRI_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: and32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bf32 .LBB37_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB37_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ueq(double %x) { +; CHECK-SOFT-LABEL: brR0_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI38_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI38_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l2 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bf32 .LBB38_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB38_3 +; CHECK-SOFT-NEXT: .LBB38_2: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB38_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI38_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI38_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brR0_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 12) +; CHECK-SF-NEXT: st32.w l0, (sp, 8) +; CHECK-SF-NEXT: st32.w l1, (sp, 4) +; CHECK-SF-NEXT: st32.w l2, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a1 +; CHECK-SF-NEXT: mov32 l1, a0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI38_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l2 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI38_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l2 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bf32 .LBB38_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: br32 .LBB38_3 +; CHECK-SF-NEXT: .LBB38_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: .LBB38_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI38_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI38_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brR0_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bf32 .LBB38_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB38_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 12) +; CHECK-SF2-NEXT: st32.w l0, (sp, 8) +; CHECK-SF2-NEXT: st32.w l1, (sp, 4) +; CHECK-SF2-NEXT: st32.w l2, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a1 +; CHECK-SF2-NEXT: mov32 l1, a0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI38_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI38_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l2 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bf32 .LBB38_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: br32 .LBB38_3 +; CHECK-SF2-NEXT: .LBB38_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: .LBB38_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI38_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI38_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brR0_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bf32 .LBB38_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB38_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UNE +define i32 @brRR_une(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI39_0 +; CHECK-SOFT-NEXT: bez32 a0, .LBB39_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB39_3 +; CHECK-SOFT-NEXT: .LBB39_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB39_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI39_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; +; CHECK-SF-LABEL: brRR_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI39_0 +; CHECK-SF-NEXT: bez32 a0, .LBB39_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB39_3 +; CHECK-SF-NEXT: .LBB39_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB39_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI39_0: +; CHECK-SF-NEXT: .long __eqdf2 +; +; CHECK-DF-LABEL: brRR_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: bf32 .LBB39_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB39_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI39_0 +; CHECK-SF2-NEXT: bez32 a0, .LBB39_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB39_3 +; CHECK-SF2-NEXT: .LBB39_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB39_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI39_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; +; CHECK-DF2-LABEL: brRR_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: bf32 .LBB39_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB39_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_une(double %x) { +; CHECK-SOFT-LABEL: brRI_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: jsri32 .LCPI40_0 +; CHECK-SOFT-NEXT: bez32 a0, .LBB40_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB40_3 +; CHECK-SOFT-NEXT: .LBB40_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB40_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI40_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; +; CHECK-SF-LABEL: brRI_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: jsri32 .LCPI40_0 +; CHECK-SF-NEXT: bez32 a0, .LBB40_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB40_3 +; CHECK-SF-NEXT: .LBB40_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB40_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI40_0: +; CHECK-SF-NEXT: .long __eqdf2 +; +; CHECK-DF-LABEL: brRI_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr1 +; CHECK-DF-NEXT: bf32 .LBB40_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB40_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: jsri32 .LCPI40_0 +; CHECK-SF2-NEXT: bez32 a0, .LBB40_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB40_3 +; CHECK-SF2-NEXT: .LBB40_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB40_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI40_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; +; CHECK-DF2-LABEL: brRI_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr1 +; CHECK-DF2-NEXT: bf32 .LBB40_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB40_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_une(double %x) { +; CHECK-SOFT-LABEL: brR0_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI41_0 +; CHECK-SOFT-NEXT: bez32 a0, .LBB41_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB41_3 +; CHECK-SOFT-NEXT: .LBB41_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB41_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI41_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; +; CHECK-SF-LABEL: brR0_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI41_0 +; CHECK-SF-NEXT: bez32 a0, .LBB41_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB41_3 +; CHECK-SF-NEXT: .LBB41_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB41_3: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI41_0: +; CHECK-SF-NEXT: .long __eqdf2 +; +; CHECK-DF-LABEL: brR0_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: bf32 .LBB41_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB41_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI41_0 +; CHECK-SF2-NEXT: bez32 a0, .LBB41_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB41_3 +; CHECK-SF2-NEXT: .LBB41_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB41_3: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI41_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; +; CHECK-DF2-LABEL: brR0_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: bf32 .LBB41_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB41_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UNO +define i32 @brRR_uno(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI42_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB42_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB42_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB42_3: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB42_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI42_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRR_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI42_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB42_3 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB42_2: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB42_3: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB42_2 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI42_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRR_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB42_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB42_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI42_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB42_3 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB42_2: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB42_3: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB42_2 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI42_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRR_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB42_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB42_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_uno(double %x) { +; CHECK-SOFT-LABEL: brRI_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: jsri32 .LCPI43_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB43_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB43_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB43_3: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB43_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI43_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brRI_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: jsri32 .LCPI43_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB43_3 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB43_2: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB43_3: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB43_2 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI43_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brRI_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB43_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB43_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: jsri32 .LCPI43_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB43_3 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB43_2: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB43_3: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB43_2 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI43_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brRI_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB43_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB43_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_uno(double %x) { +; CHECK-SOFT-LABEL: brR0_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: jsri32 .LCPI44_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB44_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB44_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB44_3: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB44_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI44_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: brR0_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: jsri32 .LCPI44_0 +; CHECK-SF-NEXT: bnez32 a0, .LBB44_3 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: .LBB44_2: # %label1 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB44_3: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: br32 .LBB44_2 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.4: +; CHECK-SF-NEXT: .LCPI44_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: brR0_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB44_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB44_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: jsri32 .LCPI44_0 +; CHECK-SF2-NEXT: bnez32 a0, .LBB44_3 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: .LBB44_2: # %label1 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB44_3: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: br32 .LBB44_2 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.4: +; CHECK-SF2-NEXT: .LCPI44_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: brR0_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB44_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB44_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;True +define i32 @brRR_true(double %x, double %y) { +; CHECK-SOFT-LABEL: brRR_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB45_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB45_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRR_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB45_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB45_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB45_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB45_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB45_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB45_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB45_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB45_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_true(double %x) { +; CHECK-SOFT-LABEL: brRI_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB46_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB46_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRI_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB46_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB46_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB46_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB46_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB46_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB46_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB46_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB46_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_true(double %x) { +; CHECK-SOFT-LABEL: brR0_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB47_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB47_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brR0_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB47_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB47_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB47_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB47_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB47_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB47_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB47_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB47_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + Index: llvm/test/CodeGen/CSKY/br-float.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/br-float.ll @@ -0,0 +1,4059 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +;OEQ +define i32 @brRR_oeq(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB0_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB0_3 +; CHECK-SOFT-NEXT: .LBB0_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB0_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __nesf2 +; +; CHECK-SF-LABEL: brRR_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB0_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB0_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB0_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB0_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB0_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB0_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB0_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB0_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_oeq(float %x) { +; CHECK-SOFT-LABEL: brRI_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB1_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB1_3 +; CHECK-SOFT-NEXT: .LBB1_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB1_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __nesf2 +; +; CHECK-SF-LABEL: brRI_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB1_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB1_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB1_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB1_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: bt32 .LBB1_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB1_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB1_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB1_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_oeq(float %x) { +; CHECK-SOFT-LABEL: brR0_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB2_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB2_3 +; CHECK-SOFT-NEXT: .LBB2_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB2_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __nesf2 +; +; CHECK-SF-LABEL: brR0_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: bt32 .LBB2_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB2_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: bt32 .LBB2_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB2_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: bt32 .LBB2_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB2_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: bt32 .LBB2_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB2_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;NE +define i32 @brRR_one(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l2 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB3_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB3_3 +; CHECK-SOFT-NEXT: .LBB3_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB3_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI3_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRR_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: or32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB3_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB3_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB3_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB3_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: or32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB3_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB3_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB3_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB3_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_one(float %x) { +; CHECK-SOFT-LABEL: brRI_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l1 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB4_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB4_3 +; CHECK-SOFT-NEXT: .LBB4_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB4_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI4_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRI_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: or32 a0, a0, a1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB4_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB4_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: or32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB4_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB4_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: or32 a0, a0, a1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB4_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB4_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: or32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB4_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB4_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_one(float %x) { +; CHECK-SOFT-LABEL: brR0_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l1 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB5_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB5_3 +; CHECK-SOFT-NEXT: .LBB5_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB5_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI5_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI5_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brR0_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: or32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB5_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB5_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB5_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB5_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: or32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB5_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB5_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB5_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB5_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UGT +define i32 @brRR_ugt(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI6_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB6_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB6_3 +; CHECK-SOFT-NEXT: .LBB6_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB6_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI6_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: brRR_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB6_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB6_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB6_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB6_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: bt32 .LBB6_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB6_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB6_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB6_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ugt(float %x) { +; CHECK-SOFT-LABEL: brRI_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI7_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB7_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB7_3 +; CHECK-SOFT-NEXT: .LBB7_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB7_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI7_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: brRI_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB7_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB7_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB7_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB7_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB7_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB7_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB7_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB7_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ugt(float %x) { +; CHECK-SOFT-LABEL: brR0_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI8_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB8_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB8_3 +; CHECK-SOFT-NEXT: .LBB8_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB8_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI8_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: brR0_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: bt32 .LBB8_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB8_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: bt32 .LBB8_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB8_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplsz.32 vr0 +; CHECK-SF2-NEXT: bt32 .LBB8_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB8_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.32 vr0 +; CHECK-DF2-NEXT: bt32 .LBB8_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB8_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UGE +define i32 @brRR_uge(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI9_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB9_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB9_3 +; CHECK-SOFT-NEXT: .LBB9_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB9_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI9_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: brRR_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB9_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB9_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB9_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB9_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB9_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB9_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB9_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB9_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_uge(float %x) { +; CHECK-SOFT-LABEL: brRI_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB10_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB10_3 +; CHECK-SOFT-NEXT: .LBB10_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB10_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: brRI_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB10_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB10_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB10_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB10_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: bt32 .LBB10_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB10_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB10_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB10_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_uge(float %x) { +; CHECK-SOFT-LABEL: brR0_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB11_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB11_3 +; CHECK-SOFT-NEXT: .LBB11_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB11_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: brR0_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: bf32 .LBB11_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB11_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: bf32 .LBB11_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB11_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpltz.32 vr0 +; CHECK-SF2-NEXT: bt32 .LBB11_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB11_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.32 vr0 +; CHECK-DF2-NEXT: bt32 .LBB11_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB11_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;ULT +define i32 @brRR_ult(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB12_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB12_3 +; CHECK-SOFT-NEXT: .LBB12_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB12_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: brRR_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB12_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB12_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB12_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB12_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB12_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB12_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB12_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB12_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ult(float %x) { +; CHECK-SOFT-LABEL: brRI_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB13_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB13_3 +; CHECK-SOFT-NEXT: .LBB13_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB13_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: brRI_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB13_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB13_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB13_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB13_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: bt32 .LBB13_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB13_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB13_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB13_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ult(float %x) { +; CHECK-SOFT-LABEL: brR0_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB14_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB14_3 +; CHECK-SOFT-NEXT: .LBB14_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB14_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: brR0_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: bt32 .LBB14_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB14_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: bt32 .LBB14_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB14_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphsz.32 vr0 +; CHECK-SF2-NEXT: bt32 .LBB14_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB14_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.32 vr0 +; CHECK-DF2-NEXT: bt32 .LBB14_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB14_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;ULE +define i32 @brRR_ule(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI15_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB15_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB15_3 +; CHECK-SOFT-NEXT: .LBB15_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB15_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI15_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: brRR_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB15_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB15_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB15_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB15_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: bt32 .LBB15_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB15_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: bt32 .LBB15_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB15_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ule(float %x) { +; CHECK-SOFT-LABEL: brRI_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI16_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB16_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB16_3 +; CHECK-SOFT-NEXT: .LBB16_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB16_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI16_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: brRI_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB16_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB16_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB16_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB16_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB16_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB16_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB16_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB16_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ule(float %x) { +; CHECK-SOFT-LABEL: brR0_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI17_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB17_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB17_3 +; CHECK-SOFT-NEXT: .LBB17_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB17_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI17_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: brR0_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: bf32 .LBB17_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB17_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: bf32 .LBB17_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB17_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphz.32 vr0 +; CHECK-SF2-NEXT: bt32 .LBB17_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB17_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.32 vr0 +; CHECK-DF2-NEXT: bt32 .LBB17_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB17_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SGT +define i32 @brRR_ogt(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI18_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB18_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB18_3 +; CHECK-SOFT-NEXT: .LBB18_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB18_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI18_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: brRR_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB18_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB18_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB18_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB18_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB18_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB18_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB18_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB18_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ogt(float %x) { +; CHECK-SOFT-LABEL: brRI_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI19_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB19_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB19_3 +; CHECK-SOFT-NEXT: .LBB19_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB19_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI19_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: brRI_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB19_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB19_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB19_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB19_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB19_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB19_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB19_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB19_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ogt(float %x) { +; CHECK-SOFT-LABEL: brR0_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI20_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: bt32 .LBB20_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB20_3 +; CHECK-SOFT-NEXT: .LBB20_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB20_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI20_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: brR0_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB20_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB20_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB20_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB20_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB20_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB20_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB20_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB20_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SGE +define i32 @brRR_oge(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI21_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB21_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB21_3 +; CHECK-SOFT-NEXT: .LBB21_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB21_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI21_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: brRR_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB21_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB21_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB21_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB21_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB21_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB21_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB21_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB21_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_oge(float %x) { +; CHECK-SOFT-LABEL: brRI_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI22_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB22_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB22_3 +; CHECK-SOFT-NEXT: .LBB22_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB22_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI22_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: brRI_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB22_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB22_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB22_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB22_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB22_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB22_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB22_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB22_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_oge(float %x) { +; CHECK-SOFT-LABEL: brR0_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI23_0 +; CHECK-SOFT-NEXT: blz32 a0, .LBB23_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB23_3 +; CHECK-SOFT-NEXT: .LBB23_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB23_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI23_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: brR0_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB23_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB23_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB23_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB23_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphsz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB23_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB23_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB23_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB23_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SLT +define i32 @brRR_olt(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI24_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB24_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB24_3 +; CHECK-SOFT-NEXT: .LBB24_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB24_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI24_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: brRR_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB24_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB24_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB24_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB24_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB24_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB24_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB24_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB24_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_olt(float %x) { +; CHECK-SOFT-LABEL: brRI_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI25_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB25_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB25_3 +; CHECK-SOFT-NEXT: .LBB25_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB25_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI25_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: brRI_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB25_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB25_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB25_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB25_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB25_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB25_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB25_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB25_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_olt(float %x) { +; CHECK-SOFT-LABEL: brR0_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI26_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: bt32 .LBB26_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB26_3 +; CHECK-SOFT-NEXT: .LBB26_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB26_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI26_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: brR0_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB26_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB26_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB26_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB26_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpltz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB26_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB26_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB26_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB26_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SLE +define i32 @brRR_ole(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI27_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB27_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB27_3 +; CHECK-SOFT-NEXT: .LBB27_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB27_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI27_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: brRR_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB27_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB27_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB27_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB27_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB27_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB27_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB27_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB27_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ole(float %x) { +; CHECK-SOFT-LABEL: brRI_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI28_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB28_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB28_3 +; CHECK-SOFT-NEXT: .LBB28_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB28_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI28_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: brRI_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB28_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB28_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB28_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB28_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB28_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB28_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB28_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB28_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ole(float %x) { +; CHECK-SOFT-LABEL: brR0_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI29_0 +; CHECK-SOFT-NEXT: bhz32 a0, .LBB29_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB29_3 +; CHECK-SOFT-NEXT: .LBB29_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB29_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI29_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: brR0_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB29_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB29_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB29_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB29_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplsz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB29_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB29_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB29_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB29_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;False +define i32 @brRR_false(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB30_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB30_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRR_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB30_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB30_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB30_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB30_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB30_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB30_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB30_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB30_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_false(float %x) { +; CHECK-SOFT-LABEL: brRI_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB31_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB31_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRI_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB31_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB31_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB31_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB31_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB31_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB31_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB31_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB31_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_false(float %x) { +; CHECK-SOFT-LABEL: brR0_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB32_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB32_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brR0_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB32_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB32_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB32_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB32_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB32_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB32_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB32_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB32_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +;ORD +define i32 @brRR_ord(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI33_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB33_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB33_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB33_3: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB33_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI33_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRR_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB33_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB33_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB33_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB33_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB33_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB33_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB33_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB33_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ord(float %x) { +; CHECK-SOFT-LABEL: brRI_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI34_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB34_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB34_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB34_3: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB34_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI34_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRI_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bt32 .LBB34_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB34_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB34_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB34_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: bt32 .LBB34_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB34_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB34_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB34_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ord(float %x) { +; CHECK-SOFT-LABEL: brR0_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI35_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB35_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB35_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB35_3: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB35_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI35_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brR0_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bt32 .LBB35_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB35_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB35_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB35_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: bt32 .LBB35_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB35_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB35_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB35_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +;UEQ +define i32 @brRR_ueq(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI36_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI36_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l2 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bf32 .LBB36_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB36_3 +; CHECK-SOFT-NEXT: .LBB36_2: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB36_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI36_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI36_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRR_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: and32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bf32 .LBB36_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB36_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bf32 .LBB36_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB36_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: and32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bf32 .LBB36_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB36_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bf32 .LBB36_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB36_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ueq(float %x) { +; CHECK-SOFT-LABEL: brRI_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI37_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l1 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI37_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bf32 .LBB37_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB37_3 +; CHECK-SOFT-NEXT: .LBB37_2: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB37_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI37_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI37_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRI_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: and32 a0, a0, a1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bf32 .LBB37_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB37_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: and32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bf32 .LBB37_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB37_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: and32 a0, a0, a1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bf32 .LBB37_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB37_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: and32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bf32 .LBB37_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB37_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ueq(float %x) { +; CHECK-SOFT-LABEL: brR0_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI38_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l1 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI38_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l1 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bf32 .LBB38_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: br32 .LBB38_3 +; CHECK-SOFT-NEXT: .LBB38_2: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: .LBB38_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI38_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI38_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brR0_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: and32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bf32 .LBB38_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB38_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bf32 .LBB38_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB38_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: and32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bf32 .LBB38_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB38_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bf32 .LBB38_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB38_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UNE +define i32 @brRR_une(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI39_0 +; CHECK-SOFT-NEXT: bez32 a0, .LBB39_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB39_3 +; CHECK-SOFT-NEXT: .LBB39_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB39_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI39_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; +; CHECK-SF-LABEL: brRR_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: bf32 .LBB39_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB39_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: bf32 .LBB39_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB39_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: bf32 .LBB39_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB39_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: bf32 .LBB39_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB39_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_une(float %x) { +; CHECK-SOFT-LABEL: brRI_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI40_0 +; CHECK-SOFT-NEXT: bez32 a0, .LBB40_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB40_3 +; CHECK-SOFT-NEXT: .LBB40_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB40_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI40_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; +; CHECK-SF-LABEL: brRI_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: bf32 .LBB40_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB40_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: bf32 .LBB40_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB40_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: bf32 .LBB40_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB40_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: bf32 .LBB40_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB40_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_une(float %x) { +; CHECK-SOFT-LABEL: brR0_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI41_0 +; CHECK-SOFT-NEXT: bez32 a0, .LBB41_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB41_3 +; CHECK-SOFT-NEXT: .LBB41_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB41_3: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI41_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; +; CHECK-SF-LABEL: brR0_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: bf32 .LBB41_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB41_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: bf32 .LBB41_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB41_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: bf32 .LBB41_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB41_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: bf32 .LBB41_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB41_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UNO +define i32 @brRR_uno(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI42_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB42_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB42_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB42_3: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB42_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI42_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRR_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB42_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB42_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB42_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB42_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: bt32 .LBB42_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB42_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: bt32 .LBB42_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB42_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_uno(float %x) { +; CHECK-SOFT-LABEL: brRI_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI43_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB43_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB43_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB43_3: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB43_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI43_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brRI_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bt32 .LBB43_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB43_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB43_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB43_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: bt32 .LBB43_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB43_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB43_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB43_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_uno(float %x) { +; CHECK-SOFT-LABEL: brR0_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI44_0 +; CHECK-SOFT-NEXT: bnez32 a0, .LBB44_3 +; CHECK-SOFT-NEXT: # %bb.1: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: .LBB44_2: # %label1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB44_3: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: br32 .LBB44_2 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.4: +; CHECK-SOFT-NEXT: .LCPI44_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: brR0_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bt32 .LBB44_2 +; CHECK-SF-NEXT: # %bb.1: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB44_2: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB44_2 +; CHECK-DF-NEXT: # %bb.1: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB44_2: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: bt32 .LBB44_2 +; CHECK-SF2-NEXT: # %bb.1: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB44_2: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: bt32 .LBB44_2 +; CHECK-DF2-NEXT: # %bb.1: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB44_2: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;True +define i32 @brRR_true(float %x, float %y) { +; CHECK-SOFT-LABEL: brRR_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB45_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB45_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRR_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB45_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB45_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRR_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB45_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB45_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRR_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB45_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB45_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRR_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB45_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB45_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %y, %x + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_true(float %x) { +; CHECK-SOFT-LABEL: brRI_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB46_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB46_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brRI_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB46_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB46_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brRI_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB46_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB46_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brRI_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB46_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB46_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brRI_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB46_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB46_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %x, 10.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_true(float %x) { +; CHECK-SOFT-LABEL: brR0_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: bt32 .LBB47_2 +; CHECK-SOFT-NEXT: # %bb.1: # %label1 +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .LBB47_2: # %label2 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: brR0_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB47_2 +; CHECK-SF-NEXT: # %bb.1: # %label1 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .LBB47_2: # %label2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: brR0_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB47_2 +; CHECK-DF-NEXT: # %bb.1: # %label1 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .LBB47_2: # %label2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: brR0_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: bt32 .LBB47_2 +; CHECK-SF2-NEXT: # %bb.1: # %label1 +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .LBB47_2: # %label2 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: brR0_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: bt32 .LBB47_2 +; CHECK-DF2-NEXT: # %bb.1: # %label1 +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .LBB47_2: # %label2 +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %x, 0.0 + br i1 %fcmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + Index: llvm/test/CodeGen/CSKY/br.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/br.ll @@ -0,0 +1,3551 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +;EQ +define i32 @brRR_eq(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bt32 .LBB0_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB0_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_eq(i32 %x) { +; CHECK-LABEL: brRI_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: bt32 .LBB1_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB1_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_eq(i32 %x) { +; CHECK-LABEL: brR0_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bez32 a0, .LBB2_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB2_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;NE +define i32 @brRR_ne(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bf32 .LBB3_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB3_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ne(i32 %x) { +; CHECK-LABEL: brRI_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: bf32 .LBB4_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB4_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ne(i32 %x) { +; CHECK-LABEL: brR0_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bez32 a0, .LBB5_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB5_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UGT +define i32 @brRR_ugt(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bt32 .LBB6_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB6_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ugt(i32 %x) { +; CHECK-LABEL: brRI_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: bf32 .LBB7_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB7_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ugt(i32 %x) { +; CHECK-LABEL: brR0_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bez32 a0, .LBB8_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB8_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;UGE +define i32 @brRR_uge(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB9_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB9_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_uge(i32 %x) { +; CHECK-LABEL: brRI_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: bf32 .LBB10_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB10_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;ULT +define i32 @brRR_ult(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bt32 .LBB11_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB11_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ult(i32 %x) { +; CHECK-LABEL: brRI_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB12_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB12_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +;ULE +define i32 @brRR_ule(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bf32 .LBB13_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB13_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_ule(i32 %x) { +; CHECK-LABEL: brRI_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB14_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB14_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_ule(i32 %x) { +; CHECK-LABEL: brR0_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bnez32 a0, .LBB15_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB15_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SGT +define i32 @brRR_sgt(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bf32 .LBB16_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB16_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_sgt(i32 %x) { +; CHECK-LABEL: brRI_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: bt32 .LBB17_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB17_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_sgt(i32 %x) { +; CHECK-LABEL: brR0_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 1 +; CHECK-NEXT: bt32 .LBB18_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB18_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SGE +define i32 @brRR_sge(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB19_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB19_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_sge(i32 %x) { +; CHECK-LABEL: brRI_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: bt32 .LBB20_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB20_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_sge(i32 %x) { +; CHECK-LABEL: brR0_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: blz32 a0, .LBB21_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB21_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SLT +define i32 @brRR_slt(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB22_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB22_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_slt(i32 %x) { +; CHECK-LABEL: brRI_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB23_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB23_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_slt(i32 %x) { +; CHECK-LABEL: brR0_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 65535 +; CHECK-NEXT: ori32 a1, a1, 65535 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB24_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB24_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +;SLE +define i32 @brRR_sle(i32 %x, i32 %y) { +; CHECK-LABEL: brRR_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bt32 .LBB25_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB25_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i32 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brRI_sle(i32 %x) { +; CHECK-LABEL: brRI_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB26_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB26_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i32 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + +define i32 @brR0_sle(i32 %x) { +; CHECK-LABEL: brR0_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: bhz32 a0, .LBB27_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB27_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i32 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +define i32 @brCBit(i1 %c) { +; CHECK-LABEL: brCBit: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB28_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB28_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + br i1 %c, label %label1, label %label2 +label1: + ret i32 1 +label2: + ret i32 0 +} + + +;EQ +define i64 @brRR_i64_eq(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bnez32 a0, .LBB29_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB29_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_eq(i64 %x) { +; CHECK-LABEL: brRI_i64_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 10 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bnez32 a0, .LBB30_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB30_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_eq(i64 %x) { +; CHECK-LABEL: brR0_i64_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bez32 a0, .LBB31_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB31_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;NE +define i64 @brRR_i64_ne(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bez32 a0, .LBB32_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB32_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_ne(i64 %x) { +; CHECK-LABEL: brRI_i64_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 10 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bez32 a0, .LBB33_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB33_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_ne(i64 %x) { +; CHECK-LABEL: brR0_i64_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bez32 a0, .LBB34_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB34_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;UGT +define i64 @brRR_i64_ugt(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a1, a3 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB35_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB35_3 +; CHECK-NEXT: .LBB35_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB35_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_ugt(i64 %x) { +; CHECK-LABEL: brRI_i64_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB36_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB36_3 +; CHECK-NEXT: .LBB36_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB36_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_ugt(i64 %x) { +; CHECK-LABEL: brR0_i64_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bez32 a0, .LBB37_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB37_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;UGE +define i64 @brRR_i64_uge(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a3, a1 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB38_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB38_3 +; CHECK-NEXT: .LBB38_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB38_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_uge(i64 %x) { +; CHECK-LABEL: brRI_i64_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB39_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB39_3 +; CHECK-NEXT: .LBB39_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB39_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;ULT +define i64 @brRR_i64_ult(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a3, a1 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB40_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB40_3 +; CHECK-NEXT: .LBB40_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB40_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_ult(i64 %x) { +; CHECK-LABEL: brRI_i64_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a2, 9 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB41_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB41_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + + +;ULE +define i64 @brRR_i64_ule(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a1, a3 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB42_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB42_3 +; CHECK-NEXT: .LBB42_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB42_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_ule(i64 %x) { +; CHECK-LABEL: brRI_i64_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a2, 10 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB43_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB43_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_ule(i64 %x) { +; CHECK-LABEL: brR0_i64_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: bnez32 a0, .LBB44_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB44_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;SGT +define i64 @brRR_i64_sgt(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a1, a3 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB45_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB45_3 +; CHECK-NEXT: .LBB45_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB45_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_sgt(i64 %x) { +; CHECK-LABEL: brRI_i64_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: st32.w a2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB46_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB46_3 +; CHECK-NEXT: .LBB46_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB46_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_sgt(i64 %x) { +; CHECK-LABEL: brR0_i64_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: st32.w a2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB47_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB47_3 +; CHECK-NEXT: .LBB47_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB47_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;SGE +define i64 @brRR_i64_sge(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a3, a1 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB48_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB48_3 +; CHECK-NEXT: .LBB48_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB48_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_sge(i64 %x) { +; CHECK-LABEL: brRI_i64_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: st32.w a2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB49_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB49_3 +; CHECK-NEXT: .LBB49_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB49_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_sge(i64 %x) { +; CHECK-LABEL: brR0_i64_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: blz32 a1, .LBB50_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB50_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;SLT +define i64 @brRR_i64_slt(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a3, a1 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB51_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB51_3 +; CHECK-NEXT: .LBB51_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB51_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_slt(i64 %x) { +; CHECK-LABEL: brRI_i64_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: cmplt32 a2, a1 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 a2, a0 +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: bt32 .LBB52_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB52_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_slt(i64 %x) { +; CHECK-LABEL: brR0_i64_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65535 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bf32 .LBB53_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB53_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +;SLE +define i64 @brRR_i64_sle(i64 %x, i64 %y) { +; CHECK-LABEL: brRR_i64_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a1, a3 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: bt32 .LBB54_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB54_3 +; CHECK-NEXT: .LBB54_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB54_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i64 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brRI_i64_sle(i64 %x) { +; CHECK-LABEL: brRI_i64_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: cmplt32 a2, a1 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 a2, a0 +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: bt32 .LBB55_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB55_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i64 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + +define i64 @brR0_i64_sle(i64 %x) { +; CHECK-LABEL: brR0_i64_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: cmplt32 a2, a1 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a1, (sp, 0) +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movf32 a2, a0 +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: bt32 .LBB56_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: br32 .LBB56_3 +; CHECK-NEXT: .LBB56_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: .LBB56_3: # %label1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i64 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + + +define i64 @brCBit_i64(i1 %c) { +; CHECK-LABEL: brCBit_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB57_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB57_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + br i1 %c, label %label1, label %label2 +label1: + ret i64 1 +label2: + ret i64 0 +} + + +;EQ +define i16 @brRR_i16_eq(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bt32 .LBB58_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB58_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_eq(i16 %x) { +; CHECK-LABEL: brRI_i16_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: bt32 .LBB59_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB59_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_eq(i16 %x) { +; CHECK-LABEL: brR0_i16_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: bez32 a0, .LBB60_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB60_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;NE +define i16 @brRR_i16_ne(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bf32 .LBB61_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB61_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_ne(i16 %x) { +; CHECK-LABEL: brRI_i16_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: bf32 .LBB62_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB62_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_ne(i16 %x) { +; CHECK-LABEL: brR0_i16_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: bez32 a0, .LBB63_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB63_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;UGT +define i16 @brRR_i16_ugt(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bt32 .LBB64_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB64_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_ugt(i16 %x) { +; CHECK-LABEL: brRI_i16_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: bf32 .LBB65_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB65_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_ugt(i16 %x) { +; CHECK-LABEL: brR0_i16_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: bez32 a0, .LBB66_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB66_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;UGE +define i16 @brRR_i16_uge(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB67_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB67_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_uge(i16 %x) { +; CHECK-LABEL: brRI_i16_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: bf32 .LBB68_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB68_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;ULT +define i16 @brRR_i16_ult(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bt32 .LBB69_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB69_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_ult(i16 %x) { +; CHECK-LABEL: brRI_i16_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB70_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB70_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + + +;ULE +define i16 @brRR_i16_ule(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bf32 .LBB71_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB71_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_ule(i16 %x) { +; CHECK-LABEL: brRI_i16_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB72_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB72_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_ule(i16 %x) { +; CHECK-LABEL: brR0_i16_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: bnez32 a0, .LBB73_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB73_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;SGT +define i16 @brRR_i16_sgt(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bf32 .LBB74_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB74_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_sgt(i16 %x) { +; CHECK-LABEL: brRI_i16_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: bt32 .LBB75_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB75_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_sgt(i16 %x) { +; CHECK-LABEL: brR0_i16_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 1 +; CHECK-NEXT: bt32 .LBB76_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB76_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;SGE +define i16 @brRR_i16_sge(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB77_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB77_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_sge(i16 %x) { +; CHECK-LABEL: brRI_i16_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: bt32 .LBB78_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB78_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_sge(i16 %x) { +; CHECK-LABEL: brR0_i16_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: blz32 a0, .LBB79_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB79_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;SLT +define i16 @brRR_i16_slt(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB80_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB80_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_slt(i16 %x) { +; CHECK-LABEL: brRI_i16_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB81_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB81_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_slt(i16 %x) { +; CHECK-LABEL: brR0_i16_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movih32 a1, 65535 +; CHECK-NEXT: ori32 a1, a1, 65535 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB82_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB82_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +;SLE +define i16 @brRR_i16_sle(i16 %x, i16 %y) { +; CHECK-LABEL: brRR_i16_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bt32 .LBB83_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB83_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i16 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brRI_i16_sle(i16 %x) { +; CHECK-LABEL: brRI_i16_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB84_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB84_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i16 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + +define i16 @brR0_i16_sle(i16 %x) { +; CHECK-LABEL: brR0_i16_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: bhz32 a0, .LBB85_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB85_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i16 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + + +define i16 @brCBit_i16(i1 %c) { +; CHECK-LABEL: brCBit_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB86_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB86_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + br i1 %c, label %label1, label %label2 +label1: + ret i16 1 +label2: + ret i16 0 +} + + +;EQ +define i8 @brRR_i8_eq(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bt32 .LBB87_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB87_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_eq(i8 %x) { +; CHECK-LABEL: brRI_i8_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: bt32 .LBB88_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB88_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_eq(i8 %x) { +; CHECK-LABEL: brR0_i8_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: bez32 a0, .LBB89_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB89_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;NE +define i8 @brRR_i8_ne(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bf32 .LBB90_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB90_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_ne(i8 %x) { +; CHECK-LABEL: brRI_i8_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: bf32 .LBB91_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB91_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_ne(i8 %x) { +; CHECK-LABEL: brR0_i8_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: bez32 a0, .LBB92_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB92_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;UGT +define i8 @brRR_i8_ugt(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bt32 .LBB93_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB93_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_ugt(i8 %x) { +; CHECK-LABEL: brRI_i8_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: bf32 .LBB94_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB94_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_ugt(i8 %x) { +; CHECK-LABEL: brR0_i8_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: bez32 a0, .LBB95_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB95_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;UGE +define i8 @brRR_i8_uge(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB96_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB96_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_uge(i8 %x) { +; CHECK-LABEL: brRI_i8_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: bf32 .LBB97_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB97_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;ULT +define i8 @brRR_i8_ult(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bt32 .LBB98_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB98_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_ult(i8 %x) { +; CHECK-LABEL: brRI_i8_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB99_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB99_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + + +;ULE +define i8 @brRR_i8_ule(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bf32 .LBB100_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB100_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_ule(i8 %x) { +; CHECK-LABEL: brRI_i8_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB101_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB101_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_ule(i8 %x) { +; CHECK-LABEL: brR0_i8_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: bnez32 a0, .LBB102_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB102_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;SGT +define i8 @brRR_i8_sgt(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bf32 .LBB103_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB103_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_sgt(i8 %x) { +; CHECK-LABEL: brRI_i8_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: bt32 .LBB104_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB104_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_sgt(i8 %x) { +; CHECK-LABEL: brR0_i8_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 1 +; CHECK-NEXT: bt32 .LBB105_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB105_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;SGE +define i8 @brRR_i8_sge(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB106_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB106_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_sge(i8 %x) { +; CHECK-LABEL: brRI_i8_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: bt32 .LBB107_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB107_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_sge(i8 %x) { +; CHECK-LABEL: brR0_i8_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: blz32 a0, .LBB108_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB108_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;SLT +define i8 @brRR_i8_slt(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB109_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB109_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_slt(i8 %x) { +; CHECK-LABEL: brRI_i8_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB110_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB110_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_slt(i8 %x) { +; CHECK-LABEL: brR0_i8_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a1, 65535 +; CHECK-NEXT: ori32 a1, a1, 65535 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB111_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB111_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +;SLE +define i8 @brRR_i8_sle(i8 %x, i8 %y) { +; CHECK-LABEL: brRR_i8_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bt32 .LBB112_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB112_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i8 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brRI_i8_sle(i8 %x) { +; CHECK-LABEL: brRI_i8_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB113_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB113_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i8 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + +define i8 @brR0_i8_sle(i8 %x) { +; CHECK-LABEL: brR0_i8_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: bhz32 a0, .LBB114_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB114_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i8 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + + +define i8 @brCBit_i8(i1 %c) { +; CHECK-LABEL: brCBit_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB115_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB115_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + br i1 %c, label %label1, label %label2 +label1: + ret i8 1 +label2: + ret i8 0 +} + + +;EQ +define i1 @brRR_i1_eq(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bt32 .LBB116_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB116_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_eq(i1 %x) { +; CHECK-LABEL: brRI_i1_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bf32 .LBB117_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB117_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_eq(i1 %x) { +; CHECK-LABEL: brR0_i1_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bf32 .LBB118_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB118_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;NE +define i1 @brRR_i1_ne(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: bf32 .LBB119_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB119_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_ne(i1 %x) { +; CHECK-LABEL: brRI_i1_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB120_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB120_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_ne(i1 %x) { +; CHECK-LABEL: brR0_i1_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB121_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB121_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;UGT +define i1 @brRR_i1_ugt(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bt32 .LBB122_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB122_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_ugt(i1 %x) { +; CHECK-LABEL: brRI_i1_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB123_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB123_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_ugt(i1 %x) { +; CHECK-LABEL: brR0_i1_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB124_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB124_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ugt i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;UGE +define i1 @brRR_i1_uge(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB125_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB125_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_uge(i1 %x) { +; CHECK-LABEL: brRI_i1_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB126_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB126_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp uge i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;ULT +define i1 @brRR_i1_ult(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bt32 .LBB127_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB127_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_ult(i1 %x) { +; CHECK-LABEL: brRI_i1_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB128_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB128_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ult i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + + +;ULE +define i1 @brRR_i1_ule(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: bf32 .LBB129_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB129_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_ule(i1 %x) { +; CHECK-LABEL: brRI_i1_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB130_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB130_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_ule(i1 %x) { +; CHECK-LABEL: brR0_i1_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB131_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB131_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp ule i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;SGT +define i1 @brRR_i1_sgt(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 0, 0 +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bf32 .LBB132_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB132_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_sgt(i1 %x) { +; CHECK-LABEL: brRI_i1_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB133_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB133_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_sgt(i1 %x) { +; CHECK-LABEL: brR0_i1_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB134_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB134_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sgt i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;SGE +define i1 @brRR_i1_sge(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: sext32 a1, a1, 0, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bt32 .LBB135_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB135_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_sge(i1 %x) { +; CHECK-LABEL: brRI_i1_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB136_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB136_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_sge(i1 %x) { +; CHECK-LABEL: brR0_i1_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB137_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB137_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sge i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;SLT +define i1 @brRR_i1_slt(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: sext32 a1, a1, 0, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: bf32 .LBB138_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB138_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_slt(i1 %x) { +; CHECK-LABEL: brRI_i1_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bnez32 a0, .LBB139_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB139_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_slt(i1 %x) { +; CHECK-LABEL: brR0_i1_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bnez32 a0, .LBB140_2 +; CHECK-NEXT: # %bb.1: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB140_2: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp slt i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +;SLE +define i1 @brRR_i1_sle(i1 %x, i1 %y) { +; CHECK-LABEL: brRR_i1_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 0, 0 +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: bt32 .LBB141_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB141_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i1 %y, %x + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brRI_i1_sle(i1 %x) { +; CHECK-LABEL: brRI_i1_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB142_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB142_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i1 %x, 10 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + +define i1 @brR0_i1_sle(i1 %x) { +; CHECK-LABEL: brR0_i1_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: bt32 .LBB143_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB143_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-UGTXT: icmpu32 a0, a1, a0 +; CHECK-UGTXT: rts32 +entry: + %icmp = icmp sle i1 %x, 0 + br i1 %icmp, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + + +define i1 @brCBit_i1(i1 %c) { +; CHECK-LABEL: brCBit_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: bez32 a0, .LBB144_2 +; CHECK-NEXT: # %bb.1: # %label1 +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB144_2: # %label2 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + br i1 %c, label %label1, label %label2 +label1: + ret i1 1 +label2: + ret i1 0 +} + + Index: llvm/test/CodeGen/CSKY/call.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/call.ll @@ -0,0 +1,120 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK-PIC-SMALL +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK-PIC-LARGE + +@p_fun = global void (i32, i32)* @bar, align 8 + +declare void @bar(i32, i32) + +define void @foo(i32 %a, i32* %ptr){ +; CHECK-LABEL: foo: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w a1, (a1, 0) +; CHECK-NEXT: lrw32 a2, [.LCPI0_0] +; CHECK-NEXT: jmp32 a2 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: .LCPI0_0: +; CHECK-NEXT: .long bar +; +; CHECK-PIC-SMALL-LABEL: foo: +; CHECK-PIC-SMALL: # %bb.0: # %entry +; CHECK-PIC-SMALL-NEXT: subi32 sp, sp, 4 +; CHECK-PIC-SMALL-NEXT: st32.w rgb, (sp, 0) +; CHECK-PIC-SMALL-NEXT: lrw32 rgb, [.LCPI0_1] +; CHECK-PIC-SMALL-NEXT: ld32.w a1, (a1, 0) +; CHECK-PIC-SMALL-NEXT: lrw32 a2, [.LCPI0_0] +; CHECK-PIC-SMALL-NEXT: ldr32.w a2, (rgb, a2 << 0) +; CHECK-PIC-SMALL-NEXT: jmp32 a2 +; CHECK-PIC-SMALL-NEXT: .p2align 2 +; CHECK-PIC-SMALL-NEXT: # %bb.1: +; CHECK-PIC-SMALL-NEXT: .LCPI0_0: +; CHECK-PIC-SMALL-NEXT: .long bar@GOT +; CHECK-PIC-SMALL-NEXT: .LCPI0_1: +; CHECK-PIC-SMALL-NEXT: .long _GLOBAL_OFFSET_TABLE_ +; +; CHECK-PIC-LARGE-LABEL: foo: +; CHECK-PIC-LARGE: # %bb.0: # %entry +; CHECK-PIC-LARGE-NEXT: subi32 sp, sp, 4 +; CHECK-PIC-LARGE-NEXT: st32.w rgb, (sp, 0) +; CHECK-PIC-LARGE-NEXT: lrw32 rgb, [.LCPI0_1] +; CHECK-PIC-LARGE-NEXT: ld32.w a1, (a1, 0) +; CHECK-PIC-LARGE-NEXT: lrw32 a2, [.LCPI0_0] +; CHECK-PIC-LARGE-NEXT: ldr32.w a2, (rgb, a2 << 0) +; CHECK-PIC-LARGE-NEXT: jmp32 a2 +; CHECK-PIC-LARGE-NEXT: .p2align 2 +; CHECK-PIC-LARGE-NEXT: # %bb.1: +; CHECK-PIC-LARGE-NEXT: .LCPI0_0: +; CHECK-PIC-LARGE-NEXT: .long bar@GOT +; CHECK-PIC-LARGE-NEXT: .LCPI0_1: +; CHECK-PIC-LARGE-NEXT: .long _GLOBAL_OFFSET_TABLE_ +; CHECK-PIC-LABEL: foo: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.w a1, a1, 0 +; CHECK-PIC-NEXT: br32 bar +entry: + %0 = load i32, i32* %ptr + tail call void (i32, i32) @bar(i32 %a, i32 %0) + ret void +} + +define void @foo_indirect(i32 %a, i32* %ptr) { +; CHECK-LABEL: foo_indirect: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lrw32 a2, [.LCPI1_0] +; CHECK-NEXT: ld32.w a2, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a1, 0) +; CHECK-NEXT: jmp32 a2 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: .LCPI1_0: +; CHECK-NEXT: .long p_fun +; +; CHECK-PIC-SMALL-LABEL: foo_indirect: +; CHECK-PIC-SMALL: # %bb.0: # %entry +; CHECK-PIC-SMALL-NEXT: subi32 sp, sp, 4 +; CHECK-PIC-SMALL-NEXT: st32.w rgb, (sp, 0) +; CHECK-PIC-SMALL-NEXT: lrw32 rgb, [.LCPI1_1] +; CHECK-PIC-SMALL-NEXT: lrw32 a2, [.LCPI1_0] +; CHECK-PIC-SMALL-NEXT: ldr32.w a2, (rgb, a2 << 0) +; CHECK-PIC-SMALL-NEXT: ld32.w a2, (a2, 0) +; CHECK-PIC-SMALL-NEXT: ld32.w a1, (a1, 0) +; CHECK-PIC-SMALL-NEXT: jmp32 a2 +; CHECK-PIC-SMALL-NEXT: .p2align 2 +; CHECK-PIC-SMALL-NEXT: # %bb.1: +; CHECK-PIC-SMALL-NEXT: .LCPI1_0: +; CHECK-PIC-SMALL-NEXT: .long p_fun@GOT +; CHECK-PIC-SMALL-NEXT: .LCPI1_1: +; CHECK-PIC-SMALL-NEXT: .long _GLOBAL_OFFSET_TABLE_ +; +; CHECK-PIC-LARGE-LABEL: foo_indirect: +; CHECK-PIC-LARGE: # %bb.0: # %entry +; CHECK-PIC-LARGE-NEXT: subi32 sp, sp, 4 +; CHECK-PIC-LARGE-NEXT: st32.w rgb, (sp, 0) +; CHECK-PIC-LARGE-NEXT: lrw32 rgb, [.LCPI1_1] +; CHECK-PIC-LARGE-NEXT: lrw32 a2, [.LCPI1_0] +; CHECK-PIC-LARGE-NEXT: ldr32.w a2, (rgb, a2 << 0) +; CHECK-PIC-LARGE-NEXT: ld32.w a2, (a2, 0) +; CHECK-PIC-LARGE-NEXT: ld32.w a1, (a1, 0) +; CHECK-PIC-LARGE-NEXT: jmp32 a2 +; CHECK-PIC-LARGE-NEXT: .p2align 2 +; CHECK-PIC-LARGE-NEXT: # %bb.1: +; CHECK-PIC-LARGE-NEXT: .LCPI1_0: +; CHECK-PIC-LARGE-NEXT: .long p_fun@GOT +; CHECK-PIC-LARGE-NEXT: .LCPI1_1: +; CHECK-PIC-LARGE-NEXT: .long _GLOBAL_OFFSET_TABLE_ +; CHECK-PIC-LABEL: foo_indirect: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: movi32 a2, p_fun +; CHECK-PIC-NEXT: movih32 a3, p_fun +; CHECK-PIC-NEXT: or32 a2, a3, a2 +; CHECK-PIC-NEXT: ld32.w a2, a2, 0 +; CHECK-PIC-NEXT: ld32.w a1, a1, 0 +; CHECK-PIC-NEXT: jmp32 a2 +entry: + %0 = load void (i32, i32)*, void (i32, i32)** @p_fun, align 8 + %1 = load i32, i32* %ptr + tail call void (i32, i32) %0(i32 %a, i32 %1) + ret void +} Index: llvm/test/CodeGen/CSKY/cmpxchg.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/cmpxchg.ll @@ -0,0 +1,120 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @cmpxchg_i32(i32* %ptr) local_unnamed_addr #0 { +; CHECK-LABEL: cmpxchg_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: .LBB0_1: # %atomicrmw.start +; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: ldex32.w a1, (a0, 0) +; CHECK-NEXT: mov32 a2, a0 +; CHECK-NEXT: stex32.w a2, (a1, 0) +; CHECK-NEXT: cmpnei32 a2, 1 +; CHECK-NEXT: bt32 .LBB0_1 +; CHECK-NEXT: br32 .LBB0_3 +; CHECK-NEXT: .LBB0_2: # in Loop: Header=BB0_3 Depth=1 +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: bnez32 a2, .LBB0_7 +; CHECK-NEXT: .LBB0_3: # %loop +; CHECK-NEXT: # =>This Loop Header: Depth=1 +; CHECK-NEXT: # Child Loop BB0_4 Depth 2 +; CHECK-NEXT: mov32 a2, a1 +; CHECK-NEXT: mult32 a3, a1, a1 +; CHECK-NEXT: .LBB0_4: # %cmpxchg.start +; CHECK-NEXT: # Parent Loop BB0_3 Depth=1 +; CHECK-NEXT: # => This Inner Loop Header: Depth=2 +; CHECK-NEXT: ldex32.w a1, (a0, 0) +; CHECK-NEXT: cmpne32 a1, a2 +; CHECK-NEXT: bt32 .LBB0_2 +; CHECK-NEXT: # %bb.5: # %cmpxchg.fencedstore +; CHECK-NEXT: # in Loop: Header=BB0_4 Depth=2 +; CHECK-NEXT: mov32 t0, a0 +; CHECK-NEXT: stex32.w t0, (a3, 0) +; CHECK-NEXT: cmpnei32 t0, 1 +; CHECK-NEXT: bt32 .LBB0_4 +; CHECK-NEXT: # %bb.6: # in Loop: Header=BB0_3 Depth=1 +; CHECK-NEXT: movi32 a2, 1 +; CHECK-NEXT: bez32 a2, .LBB0_3 +; CHECK-NEXT: .LBB0_7: # %done +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %orig = load atomic i32, i32* %ptr unordered, align 4 ; yields i32 + br label %loop + +loop: + %cmp = phi i32 [ %orig, %entry ], [%value_loaded, %loop] + %squared = mul i32 %cmp, %cmp + %val_success = cmpxchg i32* %ptr, i32 %cmp, i32 %squared acq_rel monotonic ; yields { i32, i1 } + %value_loaded = extractvalue { i32, i1 } %val_success, 0 + %success = extractvalue { i32, i1 } %val_success, 1 + br i1 %success, label %done, label %loop + +done: + ret i32 %value_loaded +} + +define i64 @cmpxchg_i64(i64* %ptr) local_unnamed_addr #0 { +; CHECK-LABEL: cmpxchg_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 20 +; CHECK-NEXT: st32.w lr, (sp, 32) +; CHECK-NEXT: st32.w l0, (sp, 28) +; CHECK-NEXT: st32.w l1, (sp, 24) +; CHECK-NEXT: st32.w l2, (sp, 20) +; CHECK-NEXT: st32.w l3, (sp, 16) +; CHECK-NEXT: subi32 sp, sp, 16 +; CHECK-NEXT: mov32 l0, a0 +; CHECK-NEXT: movi32 l2, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: jsri32 .LCPI1_0 +; CHECK-NEXT: movi32 l3, 4 +; CHECK-NEXT: addi32 l1, sp, 8 +; CHECK-NEXT: .LBB1_1: # %loop +; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-NEXT: mul.u32 a2, a0, a0 +; CHECK-NEXT: mula.32.l a3, a0, a1 +; CHECK-NEXT: mula.32.l a3, a0, a1 +; CHECK-NEXT: st32.w a0, (sp, 8) +; CHECK-NEXT: st32.w a1, (sp, 8) +; CHECK-NEXT: mov32 a0, sp +; CHECK-NEXT: st32.w l2, (a0, 1) +; CHECK-NEXT: st32.w l3, (a0, 0) +; CHECK-NEXT: mov32 a0, l0 +; CHECK-NEXT: mov32 a1, l1 +; CHECK-NEXT: jsri32 .LCPI1_1 +; CHECK-NEXT: mov32 a2, a0 +; CHECK-NEXT: ld32.w a1, (sp, 8) +; CHECK-NEXT: ld32.w a0, (sp, 8) +; CHECK-NEXT: bez32 a2, .LBB1_1 +; CHECK-NEXT: # %bb.2: # %done +; CHECK-NEXT: addi32 sp, sp, 16 +; CHECK-NEXT: ld32.w lr, (sp, 32) +; CHECK-NEXT: ld32.w l0, (sp, 28) +; CHECK-NEXT: ld32.w l1, (sp, 24) +; CHECK-NEXT: ld32.w l2, (sp, 20) +; CHECK-NEXT: ld32.w l3, (sp, 16) +; CHECK-NEXT: addi32 sp, sp, 20 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: .LCPI1_0: +; CHECK-NEXT: .long __atomic_load_8 +; CHECK-NEXT: .LCPI1_1: +; CHECK-NEXT: .long __atomic_compare_exchange_8 +entry: + %orig = load atomic i64, i64* %ptr unordered, align 8 ; yields i64 + br label %loop + +loop: + %cmp = phi i64 [ %orig, %entry ], [%value_loaded, %loop] + %squared = mul i64 %cmp, %cmp + %val_success = cmpxchg i64* %ptr, i64 %cmp, i64 %squared acq_rel monotonic ; yields { i64, i1 } + %value_loaded = extractvalue { i64, i1 } %val_success, 0 + %success = extractvalue { i64, i1 } %val_success, 1 + br i1 %success, label %done, label %loop + +done: + ret i64 %value_loaded +} + Index: llvm/test/CodeGen/CSKY/fadd.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fadd.ll @@ -0,0 +1,292 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @faddRR(float %x, float %y) { +; CHECK-SOFT-LABEL: faddRR: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: faddRR: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fadds vr0, vr1, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: faddRR: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fadds vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: faddRR: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fadd.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: faddRR: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fadd.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fadd = fadd float %y, %x + ret float %fadd +} + +define float @faddRI(float %x) { +; CHECK-SOFT-LABEL: faddRI: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: faddRI: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fadds vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: faddRI: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fadds vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: faddRI: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: faddRI: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fadd = fadd float %x, 10.0 + ret float %fadd +} + +define float @faddRI_X(float %x) { +; CHECK-SOFT-LABEL: faddRI_X: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 17792 +; CHECK-SOFT-NEXT: ori32 a1, a1, 2048 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: faddRI_X: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 17792 +; CHECK-SF-NEXT: ori32 a0, a0, 2048 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fadds vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: faddRI_X: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 17792 +; CHECK-DF-NEXT: ori32 a0, a0, 2048 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fadds vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: faddRI_X: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 17792 +; CHECK-SF2-NEXT: ori32 a0, a0, 2048 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: faddRI_X: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 17792 +; CHECK-DF2-NEXT: ori32 a0, a0, 2048 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fadd = fadd float %x, 4097.0 + ret float %fadd +} + +define double @FADD_DOUBLE(double %x, double %y) { +; CHECK-SOFT-LABEL: FADD_DOUBLE: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __adddf3 +; +; CHECK-SF-LABEL: FADD_DOUBLE: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __adddf3 +; +; CHECK-DF-LABEL: FADD_DOUBLE: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: faddd vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FADD_DOUBLE: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __adddf3 +; +; CHECK-DF2-LABEL: FADD_DOUBLE: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fadd.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fadd = fadd double %y, %x + ret double %fadd +} + +define double @FADD_DOUBLE_I(double %x) { +; CHECK-SOFT-LABEL: FADD_DOUBLE_I: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a2, 49136 +; CHECK-SOFT-NEXT: ori32 a3, a2, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __adddf3 +; +; CHECK-SF-LABEL: FADD_DOUBLE_I: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a2, 49136 +; CHECK-SF-NEXT: ori32 a3, a2, 0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __adddf3 +; +; CHECK-DF-LABEL: FADD_DOUBLE_I: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49136 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a1 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: faddd vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FADD_DOUBLE_I: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a2, 49136 +; CHECK-SF2-NEXT: ori32 a3, a2, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __adddf3 +; +; CHECK-DF2-LABEL: FADD_DOUBLE_I: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49136 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fadd.64 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fadd = fadd double %x, -1.0 + ret double %fadd +} + Index: llvm/test/CodeGen/CSKY/fcmp.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fcmp.ll @@ -0,0 +1,4986 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +;false +define i1 @fcmpRR_false(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fcmpRR_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_false(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fcmpRI_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_false(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fcmpRI_X_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_false(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_false(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_false: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_false: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_false: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_false: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_false: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %x, 0.0 + ret i1 %fcmp +} + +;ueq +define i1 @fcmpRR_ueq(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI5_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI5_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRR_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: or32 a0, a1, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: or32 a0, a1, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ueq(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movih32 a0, 49440 +; CHECK-SOFT-NEXT: ori32 l1, a0, 0 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI6_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI6_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI6_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI6_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: or32 a0, a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: or32 a0, a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: or32 a0, a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: or32 a0, a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ueq(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI7_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l1 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI7_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI7_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI7_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: or32 a0, a1, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: or32 a0, a1, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ueq(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI8_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI8_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l4 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI8_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI8_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 24 +; CHECK-SF-NEXT: st32.w lr, (sp, 20) +; CHECK-SF-NEXT: st32.w l0, (sp, 16) +; CHECK-SF-NEXT: st32.w l1, (sp, 12) +; CHECK-SF-NEXT: st32.w l2, (sp, 8) +; CHECK-SF-NEXT: st32.w l3, (sp, 4) +; CHECK-SF-NEXT: st32.w l4, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l2, a1 +; CHECK-SF-NEXT: mov32 l3, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI8_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l4 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI8_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l4 +; CHECK-SF-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 24 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI8_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI8_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, (sp, 20) +; CHECK-SF2-NEXT: st32.w l0, (sp, 16) +; CHECK-SF2-NEXT: st32.w l1, (sp, 12) +; CHECK-SF2-NEXT: st32.w l2, (sp, 8) +; CHECK-SF2-NEXT: st32.w l3, (sp, 4) +; CHECK-SF2-NEXT: st32.w l4, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI8_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI8_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l4 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI8_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI8_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ueq(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ueq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI9_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI9_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI9_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI9_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ueq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 12) +; CHECK-SF-NEXT: st32.w l0, (sp, 8) +; CHECK-SF-NEXT: st32.w l1, (sp, 4) +; CHECK-SF-NEXT: st32.w l2, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a1 +; CHECK-SF-NEXT: mov32 l1, a0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI9_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l2 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI9_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l2 +; CHECK-SF-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI9_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI9_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ueq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ueq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 12) +; CHECK-SF2-NEXT: st32.w l0, (sp, 8) +; CHECK-SF2-NEXT: st32.w l1, (sp, 4) +; CHECK-SF2-NEXT: st32.w l2, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a1 +; CHECK-SF2-NEXT: mov32 l1, a0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI9_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI9_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l2 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI9_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI9_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ueq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %x, 0.0 + ret i1 %fcmp +} + +;une +define i1 @fcmpRR_une(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __nesf2 +; +; CHECK-SF-LABEL: fcmpRR_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_une(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __nesf2 +; +; CHECK-SF-LABEL: fcmpRI_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_une(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __nesf2 +; +; CHECK-SF-LABEL: fcmpRI_X_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_une(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __nedf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI13_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI13_0: +; CHECK-SF-NEXT: .long __nedf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI13_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI13_0: +; CHECK-SF2-NEXT: .long __nedf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_une(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_une: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __nedf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_une: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI14_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI14_0: +; CHECK-SF-NEXT: .long __nedf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_une: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_une: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI14_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI14_0: +; CHECK-SF2-NEXT: .long __nedf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_une: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %x, 0.0 + ret i1 %fcmp +} + +;ugt +define i1 @fcmpRR_ugt(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI15_0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI15_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: fcmpRR_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ugt(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI16_0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI16_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: fcmpRI_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ugt(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 8 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: movi32 l0, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI17_0 +; CHECK-SOFT-NEXT: cmplt32 l0, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 8 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI17_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplsz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ugt(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI18_0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI18_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI18_0 +; CHECK-SF-NEXT: movi32 a1, 0 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI18_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI18_0 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI18_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ugt(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ugt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 8 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: movi32 l0, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI19_0 +; CHECK-SOFT-NEXT: cmplt32 l0, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 8 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI19_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ugt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 8 +; CHECK-SF-NEXT: st32.w lr, (sp, 4) +; CHECK-SF-NEXT: st32.w l0, (sp, 0) +; CHECK-SF-NEXT: movi32 l0, 0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI19_0 +; CHECK-SF-NEXT: cmplt32 l0, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 4) +; CHECK-SF-NEXT: ld32.w l0, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 8 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI19_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ugt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ugt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 8 +; CHECK-SF2-NEXT: st32.w lr, (sp, 4) +; CHECK-SF2-NEXT: st32.w l0, (sp, 0) +; CHECK-SF2-NEXT: movi32 l0, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI19_0 +; CHECK-SF2-NEXT: cmplt32 l0, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 8 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI19_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ugt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %x, 0.0 + ret i1 %fcmp +} + + +;uge +define i1 @fcmpRR_uge(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI20_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI20_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: fcmpRR_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_uge(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI21_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI21_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: fcmpRI_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_uge(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI22_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI22_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpltz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_uge(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI23_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI23_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI23_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI23_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI23_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI23_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_uge(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_uge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI24_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI24_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_uge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI24_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI24_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_uge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_uge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI24_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI24_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_uge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %x, 0.0 + ret i1 %fcmp +} + + +;ult +define i1 @fcmpRR_ult(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI25_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI25_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: fcmpRR_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ult(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI26_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI26_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: fcmpRI_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ult(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI27_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI27_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphsz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ult(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI28_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI28_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI28_0 +; CHECK-SF-NEXT: cmplti32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI28_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI28_0 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI28_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ult(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ult: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI29_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI29_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ult: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI29_0 +; CHECK-SF-NEXT: cmplti32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI29_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ult: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ult: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI29_0 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI29_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ult: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %x, 0.0 + ret i1 %fcmp +} + + +;ule +define i1 @fcmpRR_ule(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI30_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI30_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: fcmpRR_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ule(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI31_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI31_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: fcmpRI_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ule(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI32_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI32_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: xori32 a0, a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ule(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI33_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI33_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI33_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI33_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI33_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI33_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ule(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ule: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI34_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI34_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ule: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI34_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI34_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ule: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ule: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI34_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI34_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ule: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: xori32 a0, a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %x, 0.0 + ret i1 %fcmp +} + + +;ogt +define i1 @fcmpRR_ogt(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI35_0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI35_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: fcmpRR_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ogt(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI36_0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI36_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: fcmpRI_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ogt(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 8 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: movi32 l0, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI37_0 +; CHECK-SOFT-NEXT: cmplt32 l0, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 8 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI37_0: +; CHECK-SOFT-NEXT: .long __gtsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ogt(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI38_0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI38_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI38_0 +; CHECK-SF-NEXT: movi32 a1, 0 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI38_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI38_0 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI38_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ogt(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ogt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 8 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: movi32 l0, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI39_0 +; CHECK-SOFT-NEXT: cmplt32 l0, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 8 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI39_0: +; CHECK-SOFT-NEXT: .long __gtdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ogt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 8 +; CHECK-SF-NEXT: st32.w lr, (sp, 4) +; CHECK-SF-NEXT: st32.w l0, (sp, 0) +; CHECK-SF-NEXT: movi32 l0, 0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI39_0 +; CHECK-SF-NEXT: cmplt32 l0, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 4) +; CHECK-SF-NEXT: ld32.w l0, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 8 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI39_0: +; CHECK-SF-NEXT: .long __gtdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ogt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ogt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 8 +; CHECK-SF2-NEXT: st32.w lr, (sp, 4) +; CHECK-SF2-NEXT: st32.w l0, (sp, 0) +; CHECK-SF2-NEXT: movi32 l0, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI39_0 +; CHECK-SF2-NEXT: cmplt32 l0, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 8 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI39_0: +; CHECK-SF2-NEXT: .long __gtdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ogt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %x, 0.0 + ret i1 %fcmp +} + +;oge +define i1 @fcmpRR_oge(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI40_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI40_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: fcmpRR_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_oge(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI41_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI41_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: fcmpRI_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_oge(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI42_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI42_0: +; CHECK-SOFT-NEXT: .long __gesf2 +; +; CHECK-SF-LABEL: fcmpRI_X_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphsz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_oge(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI43_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI43_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI43_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI43_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI43_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI43_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_oge(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_oge: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI44_0 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI44_0: +; CHECK-SOFT-NEXT: .long __gedf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_oge: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI44_0 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI44_0: +; CHECK-SF-NEXT: .long __gedf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_oge: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_oge: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI44_0 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI44_0: +; CHECK-SF2-NEXT: .long __gedf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_oge: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %x, 0.0 + ret i1 %fcmp +} + + +;olt +define i1 @fcmpRR_olt(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI45_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI45_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: fcmpRR_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_olt(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI46_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI46_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: fcmpRI_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_olt(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI47_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI47_0: +; CHECK-SOFT-NEXT: .long __ltsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpltz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_olt(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI48_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI48_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI48_0 +; CHECK-SF-NEXT: cmplti32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI48_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI48_0 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI48_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_olt(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_olt: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI49_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI49_0: +; CHECK-SOFT-NEXT: .long __ltdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_olt: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI49_0 +; CHECK-SF-NEXT: cmplti32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI49_0: +; CHECK-SF-NEXT: .long __ltdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_olt: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_olt: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI49_0 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI49_0: +; CHECK-SF2-NEXT: .long __ltdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_olt: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %x, 0.0 + ret i1 %fcmp +} + +;ole +define i1 @fcmpRR_ole(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI50_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI50_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: fcmpRR_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ole(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI51_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI51_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: fcmpRI_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ole(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI52_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI52_0: +; CHECK-SOFT-NEXT: .long __lesf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplsz.32 vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.32 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ole(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI53_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI53_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI53_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI53_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI53_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI53_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ole(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ole: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI54_0 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI54_0: +; CHECK-SOFT-NEXT: .long __ledf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ole: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI54_0 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI54_0: +; CHECK-SF-NEXT: .long __ledf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ole: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ole: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI54_0 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI54_0: +; CHECK-SF2-NEXT: .long __ledf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ole: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %x, 0.0 + ret i1 %fcmp +} + +;one +define i1 @fcmpRR_one(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI55_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI55_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI55_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI55_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRR_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: and32 a0, a1, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: and32 a0, a1, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_one(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movih32 a0, 49440 +; CHECK-SOFT-NEXT: ori32 l1, a0, 0 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI56_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: mov32 a1, l1 +; CHECK-SOFT-NEXT: jsri32 .LCPI56_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI56_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI56_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: and32 a0, a0, a1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: and32 a0, a0, a1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: and32 a0, a0, a1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: and32 a0, a0, a1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_one(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI57_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l1 +; CHECK-SOFT-NEXT: mov32 a0, l0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI57_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI57_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; CHECK-SOFT-NEXT: .LCPI57_1: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: and32 a0, a1, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: and32 a0, a1, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_one(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI58_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: jsri32 .LCPI58_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l4 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 20) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 16) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l3, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l4, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI58_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI58_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 24 +; CHECK-SF-NEXT: st32.w lr, (sp, 20) +; CHECK-SF-NEXT: st32.w l0, (sp, 16) +; CHECK-SF-NEXT: st32.w l1, (sp, 12) +; CHECK-SF-NEXT: st32.w l2, (sp, 8) +; CHECK-SF-NEXT: st32.w l3, (sp, 4) +; CHECK-SF-NEXT: st32.w l4, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l2, a1 +; CHECK-SF-NEXT: mov32 l3, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI58_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l4 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: mov32 a2, l3 +; CHECK-SF-NEXT: mov32 a3, l2 +; CHECK-SF-NEXT: jsri32 .LCPI58_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l4 +; CHECK-SF-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 24 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI58_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI58_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, (sp, 20) +; CHECK-SF2-NEXT: st32.w l0, (sp, 16) +; CHECK-SF2-NEXT: st32.w l1, (sp, 12) +; CHECK-SF2-NEXT: st32.w l2, (sp, 8) +; CHECK-SF2-NEXT: st32.w l3, (sp, 4) +; CHECK-SF2-NEXT: st32.w l4, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI58_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: jsri32 .LCPI58_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l4 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 20) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 16) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l3, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l4, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI58_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI58_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_one(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_one: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: st32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: st32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: st32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: mov32 l0, a1 +; CHECK-SOFT-NEXT: mov32 l1, a0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI59_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI59_1 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l2 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 12) +; CHECK-SOFT-NEXT: ld32.w l0, (sp, 8) +; CHECK-SOFT-NEXT: ld32.w l1, (sp, 4) +; CHECK-SOFT-NEXT: ld32.w l2, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI59_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; CHECK-SOFT-NEXT: .LCPI59_1: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_one: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 16 +; CHECK-SF-NEXT: st32.w lr, (sp, 12) +; CHECK-SF-NEXT: st32.w l0, (sp, 8) +; CHECK-SF-NEXT: st32.w l1, (sp, 4) +; CHECK-SF-NEXT: st32.w l2, (sp, 0) +; CHECK-SF-NEXT: mov32 l0, a1 +; CHECK-SF-NEXT: mov32 l1, a0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI59_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l2 +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI59_1 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l2 +; CHECK-SF-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 16 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI59_0: +; CHECK-SF-NEXT: .long __eqdf2 +; CHECK-SF-NEXT: .LCPI59_1: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_one: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_one: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 16 +; CHECK-SF2-NEXT: st32.w lr, (sp, 12) +; CHECK-SF2-NEXT: st32.w l0, (sp, 8) +; CHECK-SF2-NEXT: st32.w l1, (sp, 4) +; CHECK-SF2-NEXT: st32.w l2, (sp, 0) +; CHECK-SF2-NEXT: mov32 l0, a1 +; CHECK-SF2-NEXT: mov32 l1, a0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI59_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI59_1 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l2 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 12) +; CHECK-SF2-NEXT: ld32.w l0, (sp, 8) +; CHECK-SF2-NEXT: ld32.w l1, (sp, 4) +; CHECK-SF2-NEXT: ld32.w l2, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 16 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI59_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; CHECK-SF2-NEXT: .LCPI59_1: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_one: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %x, 0.0 + ret i1 %fcmp +} + +;oeq +define i1 @fcmpRR_oeq(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI60_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI60_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; +; CHECK-SF-LABEL: fcmpRR_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_oeq(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI61_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI61_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; +; CHECK-SF-LABEL: fcmpRI_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr1 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr1 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr1 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_oeq(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI62_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI62_0: +; CHECK-SOFT-NEXT: .long __eqsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_oeq(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI63_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI63_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI63_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI63_0: +; CHECK-SF-NEXT: .long __eqdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI63_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI63_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_oeq(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_oeq: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI64_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI64_0: +; CHECK-SOFT-NEXT: .long __eqdf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_oeq: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: jsri32 .LCPI64_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI64_0: +; CHECK-SF-NEXT: .long __eqdf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_oeq: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_oeq: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI64_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI64_0: +; CHECK-SF2-NEXT: .long __eqdf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_oeq: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %x, 0.0 + ret i1 %fcmp +} + +;ord +define i1 @fcmpRR_ord(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI65_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI65_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRR_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_ord(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI66_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI66_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_ord(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI67_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI67_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_ord(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI68_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI68_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI68_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI68_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI68_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI68_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_ord(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_ord: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: jsri32 .LCPI69_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI69_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_ord: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: jsri32 .LCPI69_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI69_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_ord: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_ord: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: jsri32 .LCPI69_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI69_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_ord: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %x, 0.0 + ret i1 %fcmp +} + +;uno +define i1 @fcmpRR_uno(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI70_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI70_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRR_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_uno(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI71_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI71_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_uno(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: jsri32 .LCPI72_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI72_0: +; CHECK-SOFT-NEXT: .long __unordsf2 +; +; CHECK-SF-LABEL: fcmpRI_X_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_uno(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI73_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI73_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI73_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI73_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI73_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI73_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_uno(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_uno: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: jsri32 .LCPI74_0 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI74_0: +; CHECK-SOFT-NEXT: .long __unorddf2 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_uno: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: jsri32 .LCPI74_0 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI74_0: +; CHECK-SF-NEXT: .long __unorddf2 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_uno: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_uno: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: jsri32 .LCPI74_0 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI74_0: +; CHECK-SF2-NEXT: .long __unorddf2 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_uno: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %x, 0.0 + ret i1 %fcmp +} + +;true +define i1 @fcmpRR_true(float %x, float %y) { +; CHECK-SOFT-LABEL: fcmpRR_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fcmpRR_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRR_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRR_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRR_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %y, %x + ret i1 %fcmp +} + +define i1 @fcmpRI_true(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fcmpRI_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %x, -10.0 + ret i1 %fcmp +} + +define i1 @fcmpRI_X_true(float %x) { +; CHECK-SOFT-LABEL: fcmpRI_X_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fcmpRI_X_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fcmpRI_X_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fcmpRI_X_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fcmpRI_X_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %x, 0.0 + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_true(double %x, double %y) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %y, %x + ret i1 %fcmp +} + +define i1 @FCMP_DOUBLE_I_true(double %x) { +; CHECK-SOFT-LABEL: FCMP_DOUBLE_I_true: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: FCMP_DOUBLE_I_true: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: FCMP_DOUBLE_I_true: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FCMP_DOUBLE_I_true: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: FCMP_DOUBLE_I_true: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %x, 0.0 + ret i1 %fcmp +} + Index: llvm/test/CodeGen/CSKY/fdiv.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fdiv.ll @@ -0,0 +1,292 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @fdivRR(float %x, float %y) { +; CHECK-SOFT-LABEL: fdivRR: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __divsf3 +; +; CHECK-SF-LABEL: fdivRR: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fdivs vr0, vr1, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fdivRR: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdivs vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fdivRR: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fdiv.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fdivRR: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fdiv.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fdiv = fdiv float %y, %x + ret float %fdiv +} + +define float @fdivRI(float %x) { +; CHECK-SOFT-LABEL: fdivRI: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __divsf3 +; +; CHECK-SF-LABEL: fdivRI: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fdivs vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fdivRI: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fdivs vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fdivRI: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fdiv.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fdivRI: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fdiv.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fdiv = fdiv float %x, 10.0 + ret float %fdiv +} + +define float @fdivRI_X(float %x) { +; CHECK-SOFT-LABEL: fdivRI_X: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 17792 +; CHECK-SOFT-NEXT: ori32 a1, a1, 2048 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __divsf3 +; +; CHECK-SF-LABEL: fdivRI_X: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 17792 +; CHECK-SF-NEXT: ori32 a0, a0, 2048 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fdivs vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fdivRI_X: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 17792 +; CHECK-DF-NEXT: ori32 a0, a0, 2048 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fdivs vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fdivRI_X: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 17792 +; CHECK-SF2-NEXT: ori32 a0, a0, 2048 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fdiv.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fdivRI_X: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 17792 +; CHECK-DF2-NEXT: ori32 a0, a0, 2048 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fdiv.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fdiv = fdiv float %x, 4097.0 + ret float %fdiv +} + +define double @FDIV_DOUBLE(double %x, double %y) { +; CHECK-SOFT-LABEL: FDIV_DOUBLE: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __divdf3 +; +; CHECK-SF-LABEL: FDIV_DOUBLE: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __divdf3 +; +; CHECK-DF-LABEL: FDIV_DOUBLE: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdivd vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FDIV_DOUBLE: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __divdf3 +; +; CHECK-DF2-LABEL: FDIV_DOUBLE: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fdiv.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fdiv = fdiv double %y, %x + ret double %fdiv +} + +define double @FDIV_DOUBLE_I(double %x) { +; CHECK-SOFT-LABEL: FDIV_DOUBLE_I: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a2, 49180 +; CHECK-SOFT-NEXT: ori32 a3, a2, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __divdf3 +; +; CHECK-SF-LABEL: FDIV_DOUBLE_I: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a2, 49180 +; CHECK-SF-NEXT: ori32 a3, a2, 0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __divdf3 +; +; CHECK-DF-LABEL: FDIV_DOUBLE_I: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49180 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a1 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fdivd vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FDIV_DOUBLE_I: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a2, 49180 +; CHECK-SF2-NEXT: ori32 a3, a2, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __divdf3 +; +; CHECK-DF2-LABEL: FDIV_DOUBLE_I: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49180 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fdiv.64 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fdiv = fdiv double %x, -7.0 + ret double %fdiv +} + Index: llvm/test/CodeGen/CSKY/fmul.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fmul.ll @@ -0,0 +1,292 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @fmulRR(float %x, float %y) { +; CHECK-SOFT-LABEL: fmulRR: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __mulsf3 +; +; CHECK-SF-LABEL: fmulRR: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmuls vr0, vr1, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fmulRR: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmuls vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fmulRR: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmul.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fmulRR: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmul.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fmul = fmul float %y, %x + ret float %fmul +} + +define float @fmulRI(float %x) { +; CHECK-SOFT-LABEL: fmulRI: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __mulsf3 +; +; CHECK-SF-LABEL: fmulRI: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fmuls vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fmulRI: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fmuls vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fmulRI: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fmul.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fmulRI: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fmul.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fmul = fmul float %x, 10.0 + ret float %fmul +} + +define float @fmulRI_X(float %x) { +; CHECK-SOFT-LABEL: fmulRI_X: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 17792 +; CHECK-SOFT-NEXT: ori32 a1, a1, 2048 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __mulsf3 +; +; CHECK-SF-LABEL: fmulRI_X: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 17792 +; CHECK-SF-NEXT: ori32 a0, a0, 2048 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fmuls vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fmulRI_X: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 17792 +; CHECK-DF-NEXT: ori32 a0, a0, 2048 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fmuls vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fmulRI_X: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 17792 +; CHECK-SF2-NEXT: ori32 a0, a0, 2048 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fmul.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fmulRI_X: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 17792 +; CHECK-DF2-NEXT: ori32 a0, a0, 2048 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fmul.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fmul = fmul float %x, 4097.0 + ret float %fmul +} + +define double @FMUL_DOUBLE(double %x, double %y) { +; CHECK-SOFT-LABEL: FMUL_DOUBLE: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __muldf3 +; +; CHECK-SF-LABEL: FMUL_DOUBLE: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __muldf3 +; +; CHECK-DF-LABEL: FMUL_DOUBLE: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmuld vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FMUL_DOUBLE: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __muldf3 +; +; CHECK-DF2-LABEL: FMUL_DOUBLE: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmul.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fmul = fmul double %y, %x + ret double %fmul +} + +define double @FMUL_DOUBLE_I(double %x) { +; CHECK-SOFT-LABEL: FMUL_DOUBLE_I: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a2, 49180 +; CHECK-SOFT-NEXT: ori32 a3, a2, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __muldf3 +; +; CHECK-SF-LABEL: FMUL_DOUBLE_I: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a2, 49180 +; CHECK-SF-NEXT: ori32 a3, a2, 0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __muldf3 +; +; CHECK-DF-LABEL: FMUL_DOUBLE_I: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49180 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a1 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: fmuld vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FMUL_DOUBLE_I: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a2, 49180 +; CHECK-SF2-NEXT: ori32 a3, a2, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __muldf3 +; +; CHECK-DF2-LABEL: FMUL_DOUBLE_I: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49180 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fmul.64 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fmul = fmul double %x, -7.0 + ret double %fmul +} + Index: llvm/test/CodeGen/CSKY/fneg.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fneg.ll @@ -0,0 +1,188 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @fnegRR(float %x) { +; CHECK-SOFT-LABEL: fnegRR: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a1, 32768 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: xor32 a0, a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fnegRR: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fnegs vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fnegRR: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fnegs vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fnegRR: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fneg.32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fnegRR: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fneg.32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fneg = fneg float %x + ret float %fneg +} + +define float @fnegRI() { +; CHECK-SOFT-LABEL: fnegRI: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 49440 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fnegRI: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fnegRI: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fnegRI: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fnegRI: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fneg = fneg float 10.0 + ret float %fneg +} + +define float @fnegRI_X() { +; CHECK-SOFT-LABEL: fnegRI_X: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 50560 +; CHECK-SOFT-NEXT: ori32 a0, a0, 2048 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fnegRI_X: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 50560 +; CHECK-SF-NEXT: ori32 a0, a0, 2048 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fnegRI_X: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 50560 +; CHECK-DF-NEXT: ori32 a0, a0, 2048 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fnegRI_X: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 50560 +; CHECK-SF2-NEXT: ori32 a0, a0, 2048 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fnegRI_X: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 50560 +; CHECK-DF2-NEXT: ori32 a0, a0, 2048 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fneg = fneg float 4097.0 + ret float %fneg +} + +define double @FNEG_DOUBLE(double %x) { +; CHECK-SOFT-LABEL: FNEG_DOUBLE: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a2, 32768 +; CHECK-SOFT-NEXT: ori32 a2, a2, 0 +; CHECK-SOFT-NEXT: xor32 a1, a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: FNEG_DOUBLE: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a2, 32768 +; CHECK-SF-NEXT: ori32 a2, a2, 0 +; CHECK-SF-NEXT: xor32 a1, a1, a2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: FNEG_DOUBLE: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fnegd vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FNEG_DOUBLE: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a2, 32768 +; CHECK-SF2-NEXT: ori32 a2, a2, 0 +; CHECK-SF2-NEXT: xor32 a1, a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: FNEG_DOUBLE: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fneg.64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fneg = fneg double %x + ret double %fneg +} + +define double @FNEG_DOUBLE_I() { +; CHECK-SOFT-LABEL: FNEG_DOUBLE_I: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16426 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: FNEG_DOUBLE_I: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16426 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: FNEG_DOUBLE_I: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16426 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FNEG_DOUBLE_I: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16426 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: FNEG_DOUBLE_I: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16426 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fneg = fneg double -13.0 + ret double %fneg +} + Index: llvm/test/CodeGen/CSKY/fpext.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fpext.ll @@ -0,0 +1,105 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +; float --> double +define double @fpextR_double_0(float %x) { +; CHECK-SOFT-LABEL: fpextR_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __extendsfdf2 +; +; CHECK-SF-LABEL: fpextR_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __extendsfdf2 +; +; CHECK-DF-LABEL: fpextR_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fpextR_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __extendsfdf2 +; +; CHECK-DF2-LABEL: fpextR_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fstod vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fpext = fpext float %x to double + ret double %fpext +} + +define double @fpextI_double_0() { +; CHECK-SOFT-LABEL: fpextI_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 49194 +; CHECK-SOFT-NEXT: ori32 a1, a0, 0 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fpextI_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49194 +; CHECK-SF-NEXT: ori32 a1, a0, 0 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fpextI_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49194 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a1 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fpextI_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49194 +; CHECK-SF2-NEXT: ori32 a1, a0, 0 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fpextI_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49194 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fpext = fpext float -13.0 to double + ret double %fpext +} + Index: llvm/test/CodeGen/CSKY/fptosi.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fptosi.ll @@ -0,0 +1,890 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +; double --> i64 +define i64 @fptosiR_double_0(double %x) { +; CHECK-SOFT-LABEL: fptosiR_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __fixdfdi +; +; CHECK-SF-LABEL: fptosiR_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __fixdfdi +; +; CHECK-DF-LABEL: fptosiR_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI0_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI0_0: +; CHECK-DF-NEXT: .long __fixdfdi +; +; CHECK-SF2-LABEL: fptosiR_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __fixdfdi +; +; CHECK-DF2-LABEL: fptosiR_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI0_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI0_0: +; CHECK-DF2-NEXT: .long __fixdfdi +entry: + %fptosi = fptosi double %x to i64 + ret i64 %fptosi +} + +define i64 @fptosiI_double_0() { +; CHECK-SOFT-LABEL: fptosiI_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a0, a1, 65523 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a0, a1, 65523 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a1, 65535 +; CHECK-DF-NEXT: ori32 a0, a1, 65523 +; CHECK-DF-NEXT: ori32 a1, a1, 65535 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a0, a1, 65523 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a1, 65535 +; CHECK-DF2-NEXT: ori32 a0, a1, 65523 +; CHECK-DF2-NEXT: ori32 a1, a1, 65535 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double -13.0 to i64 + ret i64 %fptosi +} + +; double --> i32 +define i32 @fptosiR_double_1(double %x) { +; CHECK-SOFT-LABEL: fptosiR_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __fixdfsi +; +; CHECK-SF-LABEL: fptosiR_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI2_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI2_0: +; CHECK-SF-NEXT: .long __fixdfsi +; +; CHECK-DF-LABEL: fptosiR_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI2_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI2_0: +; CHECK-SF2-NEXT: .long __fixdfsi +; +; CHECK-DF2-LABEL: fptosiR_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double %x to i32 + ret i32 %fptosi +} + +define i32 @fptosiI_double_1() { +; CHECK-SOFT-LABEL: fptosiI_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 65535 +; CHECK-SOFT-NEXT: ori32 a0, a0, 65523 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 65535 +; CHECK-SF-NEXT: ori32 a0, a0, 65523 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 65535 +; CHECK-DF-NEXT: ori32 a0, a0, 65523 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 65535 +; CHECK-SF2-NEXT: ori32 a0, a0, 65523 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 65535 +; CHECK-DF2-NEXT: ori32 a0, a0, 65523 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double -13.0 to i32 + ret i32 %fptosi +} + +; double --> i16 +define i16 @fptosiR_double_2(double %x) { +; CHECK-SOFT-LABEL: fptosiR_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __fixdfsi +; +; CHECK-SF-LABEL: fptosiR_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __fixdfsi +; +; CHECK-DF-LABEL: fptosiR_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __fixdfsi +; +; CHECK-DF2-LABEL: fptosiR_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double %x to i16 + ret i16 %fptosi +} + +define i16 @fptosiI_double_2() { +; CHECK-SOFT-LABEL: fptosiI_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 65523 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 65523 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 65523 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 65523 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 65523 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double -13.0 to i16 + ret i16 %fptosi +} + +; double --> i8 +define i8 @fptosiR_double_3(double %x) { +; CHECK-SOFT-LABEL: fptosiR_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI6_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI6_0: +; CHECK-SOFT-NEXT: .long __fixdfsi +; +; CHECK-SF-LABEL: fptosiR_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI6_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI6_0: +; CHECK-SF-NEXT: .long __fixdfsi +; +; CHECK-DF-LABEL: fptosiR_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI6_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI6_0: +; CHECK-SF2-NEXT: .long __fixdfsi +; +; CHECK-DF2-LABEL: fptosiR_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double %x to i8 + ret i8 %fptosi +} + +define i8 @fptosiI_double_3() { +; CHECK-SOFT-LABEL: fptosiI_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 243 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 243 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 243 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 243 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 243 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double -13.0 to i8 + ret i8 %fptosi +} + +; double --> i1 +define i1 @fptosiR_double_4(double %x) { +; CHECK-SOFT-LABEL: fptosiR_double_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI8_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI8_0: +; CHECK-SOFT-NEXT: .long __fixdfsi +; +; CHECK-SF-LABEL: fptosiR_double_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI8_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI8_0: +; CHECK-SF-NEXT: .long __fixdfsi +; +; CHECK-DF-LABEL: fptosiR_double_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_double_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI8_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI8_0: +; CHECK-SF2-NEXT: .long __fixdfsi +; +; CHECK-DF2-LABEL: fptosiR_double_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double %x to i1 + ret i1 %fptosi +} + +define i1 @fptosiI_double_4() { +; CHECK-SOFT-LABEL: fptosiI_double_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 65535 +; CHECK-SOFT-NEXT: ori32 a0, a0, 65523 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_double_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 65535 +; CHECK-SF-NEXT: ori32 a0, a0, 65523 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_double_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 65535 +; CHECK-DF-NEXT: ori32 a0, a0, 65523 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_double_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 65535 +; CHECK-SF2-NEXT: ori32 a0, a0, 65523 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_double_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 65535 +; CHECK-DF2-NEXT: ori32 a0, a0, 65523 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi double -13.0 to i1 + ret i1 %fptosi +} + +; float --> i64 +define i64 @fptosiR_float_0(float %x) { +; CHECK-SOFT-LABEL: fptosiR_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __fixsfdi +; +; CHECK-SF-LABEL: fptosiR_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI10_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI10_0: +; CHECK-SF-NEXT: .long __fixsfdi +; +; CHECK-DF-LABEL: fptosiR_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI10_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI10_0: +; CHECK-DF-NEXT: .long __fixsfdi +; +; CHECK-SF2-LABEL: fptosiR_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI10_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI10_0: +; CHECK-SF2-NEXT: .long __fixsfdi +; +; CHECK-DF2-LABEL: fptosiR_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI10_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI10_0: +; CHECK-DF2-NEXT: .long __fixsfdi +entry: + %fptosi = fptosi float %x to i64 + ret i64 %fptosi +} + +define i64 @fptosiI_float_0() { +; CHECK-SOFT-LABEL: fptosiI_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a0, a1, 65523 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a0, a1, 65523 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a1, 65535 +; CHECK-DF-NEXT: ori32 a0, a1, 65523 +; CHECK-DF-NEXT: ori32 a1, a1, 65535 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a0, a1, 65523 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a1, 65535 +; CHECK-DF2-NEXT: ori32 a0, a1, 65523 +; CHECK-DF2-NEXT: ori32 a1, a1, 65535 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float -13.0 to i64 + ret i64 %fptosi +} + +; float --> i32 +define i32 @fptosiR_float_1(float %x) { +; CHECK-SOFT-LABEL: fptosiR_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __fixsfsi +; +; CHECK-SF-LABEL: fptosiR_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstosi.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiR_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiR_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float %x to i32 + ret i32 %fptosi +} + +define i32 @fptosiI_float_1() { +; CHECK-SOFT-LABEL: fptosiI_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 65535 +; CHECK-SOFT-NEXT: ori32 a0, a0, 65523 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 65535 +; CHECK-SF-NEXT: ori32 a0, a0, 65523 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 65535 +; CHECK-DF-NEXT: ori32 a0, a0, 65523 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 65535 +; CHECK-SF2-NEXT: ori32 a0, a0, 65523 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 65535 +; CHECK-DF2-NEXT: ori32 a0, a0, 65523 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float -13.0 to i32 + ret i32 %fptosi +} + +; float --> i16 +define i16 @fptosiR_float_2(float %x) { +; CHECK-SOFT-LABEL: fptosiR_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __fixsfsi +; +; CHECK-SF-LABEL: fptosiR_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstosi.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiR_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiR_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float %x to i16 + ret i16 %fptosi +} + +define i16 @fptosiI_float_2() { +; CHECK-SOFT-LABEL: fptosiI_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 65523 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 65523 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 65523 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 65523 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 65523 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float -13.0 to i16 + ret i16 %fptosi +} + +; float --> i8 +define i8 @fptosiR_float_3(float %x) { +; CHECK-SOFT-LABEL: fptosiR_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI16_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI16_0: +; CHECK-SOFT-NEXT: .long __fixsfsi +; +; CHECK-SF-LABEL: fptosiR_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstosi.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiR_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiR_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float %x to i8 + ret i8 %fptosi +} + +define i8 @fptosiI_float_3() { +; CHECK-SOFT-LABEL: fptosiI_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 243 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 243 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 243 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 243 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 243 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float -13.0 to i8 + ret i8 %fptosi +} + +; float --> i1 +define i1 @fptosiR_float_4(float %x) { +; CHECK-SOFT-LABEL: fptosiR_float_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI18_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI18_0: +; CHECK-SOFT-NEXT: .long __fixsfsi +; +; CHECK-SF-LABEL: fptosiR_float_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstosi.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiR_float_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstosi.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiR_float_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiR_float_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.s32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float %x to i1 + ret i1 %fptosi +} + +define i1 @fptosiI_float_4() { +; CHECK-SOFT-LABEL: fptosiI_float_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 65535 +; CHECK-SOFT-NEXT: ori32 a0, a0, 65523 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptosiI_float_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 65535 +; CHECK-SF-NEXT: ori32 a0, a0, 65523 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptosiI_float_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 65535 +; CHECK-DF-NEXT: ori32 a0, a0, 65523 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptosiI_float_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 65535 +; CHECK-SF2-NEXT: ori32 a0, a0, 65523 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptosiI_float_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 65535 +; CHECK-DF2-NEXT: ori32 a0, a0, 65523 +; CHECK-DF2-NEXT: rts32 +entry: + %fptosi = fptosi float -13.0 to i1 + ret i1 %fptosi +} + + Index: llvm/test/CodeGen/CSKY/fptoui.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fptoui.ll @@ -0,0 +1,1222 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +; double --> i64 +define i64 @fptouiR_double_0(double %x) { +; CHECK-SOFT-LABEL: fptouiR_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __fixunsdfdi +; +; CHECK-SF-LABEL: fptouiR_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __fixunsdfdi +; +; CHECK-DF-LABEL: fptouiR_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI0_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI0_0: +; CHECK-DF-NEXT: .long __fixunsdfdi +; +; CHECK-SF2-LABEL: fptouiR_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __fixunsdfdi +; +; CHECK-DF2-LABEL: fptouiR_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI0_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI0_0: +; CHECK-DF2-NEXT: .long __fixunsdfdi +entry: + %fptoui = fptoui double %x to i64 + ret i64 %fptoui +} + +define i64 @fptouiI_double_0() { +; CHECK-SOFT-LABEL: fptouiI_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49194 +; CHECK-SOFT-NEXT: ori32 a1, a0, 0 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __fixunsdfdi +; +; CHECK-SF-LABEL: fptouiI_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 49194 +; CHECK-SF-NEXT: ori32 a1, a0, 0 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: jsri32 .LCPI1_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI1_0: +; CHECK-SF-NEXT: .long __fixunsdfdi +; +; CHECK-DF-LABEL: fptouiI_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movih32 a0, 49194 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a1 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: jsri32 .LCPI1_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI1_0: +; CHECK-DF-NEXT: .long __fixunsdfdi +; +; CHECK-SF2-LABEL: fptouiI_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 49194 +; CHECK-SF2-NEXT: ori32 a1, a0, 0 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI1_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI1_0: +; CHECK-SF2-NEXT: .long __fixunsdfdi +; +; CHECK-DF2-LABEL: fptouiI_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movih32 a0, 49194 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: jsri32 .LCPI1_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI1_0: +; CHECK-DF2-NEXT: .long __fixunsdfdi +entry: + %fptoui = fptoui double -13.0 to i64 + ret i64 %fptoui +} + +; double --> i32 +define i32 @fptouiR_double_1(double %x) { +; CHECK-SOFT-LABEL: fptouiR_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiR_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI2_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI2_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiR_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI2_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI2_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiR_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double %x to i32 + ret i32 %fptoui +} + +define i32 @fptouiI_double_1() { +; CHECK-SOFT-LABEL: fptouiI_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49194 +; CHECK-SOFT-NEXT: ori32 a1, a0, 0 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiI_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 49194 +; CHECK-SF-NEXT: ori32 a1, a0, 0 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiI_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49194 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a1 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 49194 +; CHECK-SF2-NEXT: ori32 a1, a0, 0 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiI_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49194 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double -13.0 to i32 + ret i32 %fptoui +} + +; double --> i16 +define i16 @fptouiR_double_2(double %x) { +; CHECK-SOFT-LABEL: fptouiR_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiR_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiR_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiR_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double %x to i16 + ret i16 %fptoui +} + +define i16 @fptouiI_double_2() { +; CHECK-SOFT-LABEL: fptouiI_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49194 +; CHECK-SOFT-NEXT: ori32 a1, a0, 0 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI5_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI5_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiI_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 49194 +; CHECK-SF-NEXT: ori32 a1, a0, 0 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: jsri32 .LCPI5_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI5_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiI_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49194 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a1 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 49194 +; CHECK-SF2-NEXT: ori32 a1, a0, 0 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI5_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI5_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiI_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49194 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double -13.0 to i16 + ret i16 %fptoui +} + +; double --> i8 +define i8 @fptouiR_double_3(double %x) { +; CHECK-SOFT-LABEL: fptouiR_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI6_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI6_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiR_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI6_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI6_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiR_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI6_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI6_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiR_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double %x to i8 + ret i8 %fptoui +} + +define i8 @fptouiI_double_3() { +; CHECK-SOFT-LABEL: fptouiI_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49194 +; CHECK-SOFT-NEXT: ori32 a1, a0, 0 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI7_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI7_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiI_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 49194 +; CHECK-SF-NEXT: ori32 a1, a0, 0 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: jsri32 .LCPI7_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI7_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiI_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49194 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a1 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 49194 +; CHECK-SF2-NEXT: ori32 a1, a0, 0 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI7_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI7_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiI_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49194 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double -13.0 to i8 + ret i8 %fptoui +} + +; double --> i1 +define i1 @fptouiR_double_4(double %x) { +; CHECK-SOFT-LABEL: fptouiR_double_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI8_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI8_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiR_double_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI8_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI8_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiR_double_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_double_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI8_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI8_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiR_double_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double %x to i1 + ret i1 %fptoui +} + +define i1 @fptouiI_double_4() { +; CHECK-SOFT-LABEL: fptouiI_double_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49194 +; CHECK-SOFT-NEXT: ori32 a1, a0, 0 +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI9_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI9_0: +; CHECK-SOFT-NEXT: .long __fixunsdfsi +; +; CHECK-SF-LABEL: fptouiI_double_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 49194 +; CHECK-SF-NEXT: ori32 a1, a0, 0 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: jsri32 .LCPI9_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI9_0: +; CHECK-SF-NEXT: .long __fixunsdfsi +; +; CHECK-DF-LABEL: fptouiI_double_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49194 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a1 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: fdtoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_double_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 49194 +; CHECK-SF2-NEXT: ori32 a1, a0, 0 +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI9_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI9_0: +; CHECK-SF2-NEXT: .long __fixunsdfsi +; +; CHECK-DF2-LABEL: fptouiI_double_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49194 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: fftoi.f64.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui double -13.0 to i1 + ret i1 %fptoui +} + +; float --> i64 +define i64 @fptouiR_float_0(float %x) { +; CHECK-SOFT-LABEL: fptouiR_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __fixunssfdi +; +; CHECK-SF-LABEL: fptouiR_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI10_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI10_0: +; CHECK-SF-NEXT: .long __fixunssfdi +; +; CHECK-DF-LABEL: fptouiR_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI10_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI10_0: +; CHECK-DF-NEXT: .long __fixunssfdi +; +; CHECK-SF2-LABEL: fptouiR_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI10_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI10_0: +; CHECK-SF2-NEXT: .long __fixunssfdi +; +; CHECK-DF2-LABEL: fptouiR_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI10_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI10_0: +; CHECK-DF2-NEXT: .long __fixunssfdi +entry: + %fptoui = fptoui float %x to i64 + ret i64 %fptoui +} + +define i64 @fptouiI_float_0() { +; CHECK-SOFT-LABEL: fptouiI_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49488 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __fixunssfdi +; +; CHECK-SF-LABEL: fptouiI_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 49488 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: jsri32 .LCPI11_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI11_0: +; CHECK-SF-NEXT: .long __fixunssfdi +; +; CHECK-DF-LABEL: fptouiI_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movih32 a0, 49488 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: jsri32 .LCPI11_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI11_0: +; CHECK-DF-NEXT: .long __fixunssfdi +; +; CHECK-SF2-LABEL: fptouiI_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 49488 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: jsri32 .LCPI11_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI11_0: +; CHECK-SF2-NEXT: .long __fixunssfdi +; +; CHECK-DF2-LABEL: fptouiI_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movih32 a0, 49488 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: jsri32 .LCPI11_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI11_0: +; CHECK-DF2-NEXT: .long __fixunssfdi +entry: + %fptoui = fptoui float -13.0 to i64 + ret i64 %fptoui +} + +; float --> i32 +define i32 @fptouiR_float_1(float %x) { +; CHECK-SOFT-LABEL: fptouiR_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiR_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiR_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiR_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float %x to i32 + ret i32 %fptoui +} + +define i32 @fptouiI_float_1() { +; CHECK-SOFT-LABEL: fptouiI_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49488 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiI_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49488 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiI_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49488 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49488 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiI_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49488 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float -13.0 to i32 + ret i32 %fptoui +} + +; float --> i16 +define i16 @fptouiR_float_2(float %x) { +; CHECK-SOFT-LABEL: fptouiR_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiR_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiR_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiR_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float %x to i16 + ret i16 %fptoui +} + +define i16 @fptouiI_float_2() { +; CHECK-SOFT-LABEL: fptouiI_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49488 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI15_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI15_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiI_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49488 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiI_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49488 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49488 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiI_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49488 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float -13.0 to i16 + ret i16 %fptoui +} + +; float --> i8 +define i8 @fptouiR_float_3(float %x) { +; CHECK-SOFT-LABEL: fptouiR_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI16_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI16_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiR_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiR_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiR_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float %x to i8 + ret i8 %fptoui +} + +define i8 @fptouiI_float_3() { +; CHECK-SOFT-LABEL: fptouiI_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49488 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI17_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI17_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiI_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49488 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiI_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49488 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49488 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiI_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49488 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float -13.0 to i8 + ret i8 %fptoui +} + +; float --> i1 +define i1 @fptouiR_float_4(float %x) { +; CHECK-SOFT-LABEL: fptouiR_float_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI18_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI18_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiR_float_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiR_float_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiR_float_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiR_float_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float %x to i1 + ret i1 %fptoui +} + +define i1 @fptouiI_float_4() { +; CHECK-SOFT-LABEL: fptouiI_float_4: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a0, 49488 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI19_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI19_0: +; CHECK-SOFT-NEXT: .long __fixunssfsi +; +; CHECK-SF-LABEL: fptouiI_float_4: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49488 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fstoui.rz vr0, vr0 +; CHECK-SF-NEXT: fmfvrl a0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptouiI_float_4: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49488 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fstoui.rz vr0, vr0 +; CHECK-DF-NEXT: fmfvrl a0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptouiI_float_4: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49488 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-SF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptouiI_float_4: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49488 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fftoi.f32.u32.rz vr0, vr0 +; CHECK-DF2-NEXT: fmfvr.32.1 a0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptoui = fptoui float -13.0 to i1 + ret i1 %fptoui +} + + Index: llvm/test/CodeGen/CSKY/fptrunc.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fptrunc.ll @@ -0,0 +1,97 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +; double --> float +define float @fptruncR_double_0(double %x) { +; CHECK-SOFT-LABEL: fptruncR_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __truncdfsf2 +; +; CHECK-SF-LABEL: fptruncR_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __truncdfsf2 +; +; CHECK-DF-LABEL: fptruncR_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fdtos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptruncR_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __truncdfsf2 +; +; CHECK-DF2-LABEL: fptruncR_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fdtos vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptrunc = fptrunc double %x to float + ret float %fptrunc +} + +define float @fptruncI_double_0() { +; CHECK-SOFT-LABEL: fptruncI_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 49488 +; CHECK-SOFT-NEXT: ori32 a0, a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: fptruncI_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49488 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fptruncI_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49488 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fptruncI_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49488 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fptruncI_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49488 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %fptrunc = fptrunc double -13.0 to float + ret float %fptrunc +} + Index: llvm/test/CodeGen/CSKY/frem.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/frem.ll @@ -0,0 +1,438 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @fremRR(float %x, float %y) { +; CHECK-SOFT-LABEL: fremRR: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long fmodf +; +; CHECK-SF-LABEL: fremRR: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: fmovs vr2, vr0 +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: fmovs vr1, vr2 +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long fmodf +; +; CHECK-DF-LABEL: fremRR: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: fmovs vr2, vr0 +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: fmovs vr1, vr2 +; CHECK-DF-NEXT: jsri32 .LCPI0_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI0_0: +; CHECK-DF-NEXT: .long fmodf +; +; CHECK-SF2-LABEL: fremRR: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: fmov.32 vr2, vr0 +; CHECK-SF2-NEXT: fmov.32 vr0, vr1 +; CHECK-SF2-NEXT: fmov.32 vr1, vr2 +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long fmodf +; +; CHECK-DF2-LABEL: fremRR: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: fmov.32 vr2, vr0 +; CHECK-DF2-NEXT: fmov.32 vr0, vr1 +; CHECK-DF2-NEXT: fmov.32 vr1, vr2 +; CHECK-DF2-NEXT: jsri32 .LCPI0_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI0_0: +; CHECK-DF2-NEXT: .long fmodf +entry: + %frem = frem float %y, %x + ret float %frem +} + +define float @fremRI(float %x) { +; CHECK-SOFT-LABEL: fremRI: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long fmodf +; +; CHECK-SF-LABEL: fremRI: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: jsri32 .LCPI1_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI1_0: +; CHECK-SF-NEXT: .long fmodf +; +; CHECK-DF-LABEL: fremRI: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: jsri32 .LCPI1_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI1_0: +; CHECK-DF-NEXT: .long fmodf +; +; CHECK-SF2-LABEL: fremRI: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: jsri32 .LCPI1_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI1_0: +; CHECK-SF2-NEXT: .long fmodf +; +; CHECK-DF2-LABEL: fremRI: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: jsri32 .LCPI1_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI1_0: +; CHECK-DF2-NEXT: .long fmodf +entry: + %frem = frem float %x, 10.0 + ret float %frem +} + +define float @fremRI_X(float %x) { +; CHECK-SOFT-LABEL: fremRI_X: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 17792 +; CHECK-SOFT-NEXT: ori32 a1, a1, 2048 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long fmodf +; +; CHECK-SF-LABEL: fremRI_X: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a0, 17792 +; CHECK-SF-NEXT: ori32 a0, a0, 2048 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: jsri32 .LCPI2_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI2_0: +; CHECK-SF-NEXT: .long fmodf +; +; CHECK-DF-LABEL: fremRI_X: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movih32 a0, 17792 +; CHECK-DF-NEXT: ori32 a0, a0, 2048 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: jsri32 .LCPI2_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI2_0: +; CHECK-DF-NEXT: .long fmodf +; +; CHECK-SF2-LABEL: fremRI_X: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a0, 17792 +; CHECK-SF2-NEXT: ori32 a0, a0, 2048 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: jsri32 .LCPI2_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI2_0: +; CHECK-SF2-NEXT: .long fmodf +; +; CHECK-DF2-LABEL: fremRI_X: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movih32 a0, 17792 +; CHECK-DF2-NEXT: ori32 a0, a0, 2048 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: jsri32 .LCPI2_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI2_0: +; CHECK-DF2-NEXT: .long fmodf +entry: + %frem = frem float %x, 4097.0 + ret float %frem +} + +define double @FREM_DOUBLE(double %x, double %y) { +; CHECK-SOFT-LABEL: FREM_DOUBLE: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long fmod +; +; CHECK-SF-LABEL: FREM_DOUBLE: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long fmod +; +; CHECK-DF-LABEL: FREM_DOUBLE: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: fmovd vr2, vr0 +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: fmovd vr1, vr2 +; CHECK-DF-NEXT: jsri32 .LCPI3_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI3_0: +; CHECK-DF-NEXT: .long fmod +; +; CHECK-SF2-LABEL: FREM_DOUBLE: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long fmod +; +; CHECK-DF2-LABEL: FREM_DOUBLE: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: fmov.64 vr2, vr0 +; CHECK-DF2-NEXT: fmov.64 vr0, vr1 +; CHECK-DF2-NEXT: fmov.64 vr1, vr2 +; CHECK-DF2-NEXT: jsri32 .LCPI3_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI3_0: +; CHECK-DF2-NEXT: .long fmod +entry: + %frem = frem double %y, %x + ret double %frem +} + +define double @FREM_DOUBLE_I(double %x) { +; CHECK-SOFT-LABEL: FREM_DOUBLE_I: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a2, 49180 +; CHECK-SOFT-NEXT: ori32 a3, a2, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long fmod +; +; CHECK-SF-LABEL: FREM_DOUBLE_I: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movih32 a2, 49180 +; CHECK-SF-NEXT: ori32 a3, a2, 0 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long fmod +; +; CHECK-DF-LABEL: FREM_DOUBLE_I: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: movih32 a0, 49180 +; CHECK-DF-NEXT: ori32 a0, a0, 0 +; CHECK-DF-NEXT: movi32 a1, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a1 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: jsri32 .LCPI4_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI4_0: +; CHECK-DF-NEXT: .long fmod +; +; CHECK-SF2-LABEL: FREM_DOUBLE_I: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movih32 a2, 49180 +; CHECK-SF2-NEXT: ori32 a3, a2, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long fmod +; +; CHECK-DF2-LABEL: FREM_DOUBLE_I: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: movih32 a0, 49180 +; CHECK-DF2-NEXT: ori32 a0, a0, 0 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: jsri32 .LCPI4_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI4_0: +; CHECK-DF2-NEXT: .long fmod +entry: + %frem = frem double %x, -7.0 + ret double %frem +} + Index: llvm/test/CodeGen/CSKY/fsub.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/fsub.ll @@ -0,0 +1,288 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @fsubRR(float %x, float %y) { +; CHECK-SOFT-LABEL: fsubRR: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __subsf3 +; +; CHECK-SF-LABEL: fsubRR: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fsubs vr0, vr1, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fsubRR: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fsubs vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fsubRR: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fsub.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fsubRR: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fsub.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fsub = fsub float %y, %x + ret float %fsub +} + +define float @fsubRI(float %x) { +; CHECK-SOFT-LABEL: fsubRI: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 49440 +; CHECK-SOFT-NEXT: ori32 a1, a1, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: fsubRI: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 49440 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fadds vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fsubRI: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 49440 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fadds vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fsubRI: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 49440 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fsubRI: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 49440 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fsub = fsub float %x, 10.0 + ret float %fsub +} + +define float @fsubRI_X(float %x) { +; CHECK-SOFT-LABEL: fsubRI_X: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movih32 a1, 50560 +; CHECK-SOFT-NEXT: ori32 a1, a1, 2048 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __addsf3 +; +; CHECK-SF-LABEL: fsubRI_X: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 50560 +; CHECK-SF-NEXT: ori32 a0, a0, 2048 +; CHECK-SF-NEXT: fmtvrl vr1, a0 +; CHECK-SF-NEXT: fadds vr0, vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: fsubRI_X: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 50560 +; CHECK-DF-NEXT: ori32 a0, a0, 2048 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: fadds vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: fsubRI_X: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 50560 +; CHECK-SF2-NEXT: ori32 a0, a0, 2048 +; CHECK-SF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-SF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: fsubRI_X: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 50560 +; CHECK-DF2-NEXT: ori32 a0, a0, 2048 +; CHECK-DF2-NEXT: fmtvr.32.1 vr1, a0 +; CHECK-DF2-NEXT: fadd.32 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fsub = fsub float %x, 4097.0 + ret float %fsub +} + +define double @FSUB_DOUBLE(double %x, double %y) { +; CHECK-SOFT-LABEL: FSUB_DOUBLE: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __subdf3 +; +; CHECK-SF-LABEL: FSUB_DOUBLE: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __subdf3 +; +; CHECK-DF-LABEL: FSUB_DOUBLE: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fsubd vr0, vr1, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FSUB_DOUBLE: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __subdf3 +; +; CHECK-DF2-LABEL: FSUB_DOUBLE: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fsub.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %fsub = fsub double %y, %x + ret double %fsub +} + +define double @FSUB_DOUBLE_I(double %x) { +; CHECK-SOFT-LABEL: FSUB_DOUBLE_I: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16368 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __adddf3 +; +; CHECK-SF-LABEL: FSUB_DOUBLE_I: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16368 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __adddf3 +; +; CHECK-DF-LABEL: FSUB_DOUBLE_I: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr1, a0 +; CHECK-DF-NEXT: movih32 a0, 16368 +; CHECK-DF-NEXT: fmtvrh vr1, a0 +; CHECK-DF-NEXT: faddd vr0, vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: FSUB_DOUBLE_I: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16368 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __adddf3 +; +; CHECK-DF2-LABEL: FSUB_DOUBLE_I: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16368 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr1, a1, a0 +; CHECK-DF2-NEXT: fadd.64 vr0, vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fsub = fsub double %x, -1.0 + ret double %fsub +} + Index: llvm/test/CodeGen/CSKY/icmp.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/icmp.ll @@ -0,0 +1,1457 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +;eq +define i1 @icmpRR_eq(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_eq(i32 %x) { +; CHECK-LABEL: icmpRI_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_eq(i32 %x) { +; CHECK-LABEL: icmpRI_X_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33768 +; CHECK-NEXT: cmpne32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_eq(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_eq(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_eq(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_eq(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_eq(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_eq(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_eq(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_eq(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_eq: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %x, 1 + ret i1 %icmp +} + +;ne +define i1 @icmpRR_ne(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_ne(i32 %x) { +; CHECK-LABEL: icmpRI_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_ne(i32 %x) { +; CHECK-LABEL: icmpRI_X_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33768 +; CHECK-NEXT: cmpne32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_ne(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_ne(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_ne(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_ne(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_ne(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_ne(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_ne(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_ne(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_ne: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %x, 1 + ret i1 %icmp +} + + +;ugt +define i1 @icmpRR_ugt(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_ugt(i32 %x) { +; CHECK-LABEL: icmpRI_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_ugt(i32 %x) { +; CHECK-LABEL: icmpRI_X_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33768 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_ugt(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a1, a3 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_ugt(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a2, 1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a2 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: movf32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_ugt(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_ugt(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 1 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_ugt(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_ugt(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 1 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_ugt(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: and32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_ugt(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_ugt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i1 %x, 1 + ret i1 %icmp +} + + +;uge +define i1 @icmpRR_uge(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_uge(i32 %x) { +; CHECK-LABEL: icmpRI_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_uge(i32 %x) { +; CHECK-LABEL: icmpRI_X_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33767 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_uge(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a3, a1 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_uge(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_uge(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_uge(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_uge(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_uge(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_uge(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: or32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_uge(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_uge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i1 %x, 1 + ret i1 %icmp +} + + +;ult +define i1 @icmpRR_ult(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_ult(i32 %x) { +; CHECK-LABEL: icmpRI_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_ult(i32 %x) { +; CHECK-LABEL: icmpRI_X_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33768 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_ult(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a3, a1 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_ult(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_ult(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_ult(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_ult(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_ult(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_ult(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a1, a1, 1 +; CHECK-NEXT: and32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_ult(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_ult: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i1 %x, 1 + ret i1 %icmp +} + + +;ule +define i1 @icmpRR_ule(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_ule(i32 %x) { +; CHECK-LABEL: icmpRI_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_ule(i32 %x) { +; CHECK-LABEL: icmpRI_X_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33769 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_ule(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a1, a3 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_ule(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmphsi32 a0, 2 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_ule(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_ule(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_ule(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_ule(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_ule(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a1, a1, 1 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_ule(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_ule: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i1 %x, 1 + ret i1 %icmp +} + +;sgt +define i1 @icmpRR_sgt(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_sgt(i32 %x) { +; CHECK-LABEL: icmpRI_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_sgt(i32 %x) { +; CHECK-LABEL: icmpRI_X_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33768 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_sgt(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a1, a3 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_sgt(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: cmplt32 a2, a1 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: movi32 a3, 1 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 a2, a0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_sgt(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_sgt(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 1 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_sgt(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_sgt(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 1 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_sgt(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a1, a1, 1 +; CHECK-NEXT: and32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_sgt(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_sgt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i1 %x, 1 + ret i1 %icmp +} + +;sge +define i1 @icmpRR_sge(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_sge(i32 %x) { +; CHECK-LABEL: icmpRI_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 9 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_sge(i32 %x) { +; CHECK-LABEL: icmpRI_X_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33767 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_sge(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a3, a1 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_sge(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: movi32 a2, 0 +; CHECK-NEXT: cmplt32 a2, a1 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a1, (sp, 0) +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movf32 a2, a0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_sge(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_sge(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_sge(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_sge(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_sge(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a1, a1, 1 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_sge(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_sge: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i1 %x, 1 + ret i1 %icmp +} + +;slt +define i1 @icmpRR_slt(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_slt(i32 %x) { +; CHECK-LABEL: icmpRI_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_slt(i32 %x) { +; CHECK-LABEL: icmpRI_X_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33768 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_slt(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a3, a1 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_slt(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: st32.w a2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_slt(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_slt(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_slt(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_slt(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_slt(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: and32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_slt(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_slt: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i1 %x, 1 + ret i1 %icmp +} + + +;sle +define i1 @icmpRR_sle(i32 %x, i32 %y) { +; CHECK-LABEL: icmpRR_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i32 %y, %x + ret i1 %icmp +} + +define i1 @icmpRI_sle(i32 %x) { +; CHECK-LABEL: icmpRI_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i32 %x, 10 + ret i1 %icmp +} + +define i1 @icmpRI_X_sle(i32 %x) { +; CHECK-LABEL: icmpRI_X_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 62 +; CHECK-NEXT: ori32 a1, a1, 33769 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i32 %x, 4097000 + ret i1 %icmp +} + +define i1 @ICMP_LONG_sle(i64 %x, i64 %y) { +; CHECK-LABEL: ICMP_LONG_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a1, a3 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i64 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_LONG_I_sle(i64 %x) { +; CHECK-LABEL: ICMP_LONG_I_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a2 +; CHECK-NEXT: st32.w a2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphsi32 a0, 2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i64 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_SHORT_sle(i16 %x, i16 %y) { +; CHECK-LABEL: ICMP_SHORT_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i16 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_SHORT_I_sle(i16 %x) { +; CHECK-LABEL: ICMP_SHORT_I_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i16 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_CHAR_sle(i8 %x, i8 %y) { +; CHECK-LABEL: ICMP_CHAR_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i8 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_CHAR_I_sle(i8 %x) { +; CHECK-LABEL: ICMP_CHAR_I_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i8 %x, 1 + ret i1 %icmp +} + +define i1 @ICMP_BIT_sle(i1 %x, i1 %y) { +; CHECK-LABEL: ICMP_BIT_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: or32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i1 %y, %x + ret i1 %icmp +} + +define i1 @ICMP_BIT_I_sle(i1 %x) { +; CHECK-LABEL: ICMP_BIT_I_sle: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i1 %x, 1 + ret i1 %icmp +} Index: llvm/test/CodeGen/CSKY/indirectbr.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/indirectbr.ll @@ -0,0 +1,92 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK-PIC-SMALL +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK-PIC-LARGE + +@f.a = private unnamed_addr constant [2 x i8*] [i8* blockaddress(@f, %return), i8* blockaddress(@f, %l2)], align 16 + +define i32 @f(i32 %x) #0 { +; CHECK-LABEL: f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lrw32 a1, [.LCPI0_0] +; CHECK-NEXT: ldr32.w a0, (a1, a0 << 2) +; CHECK-NEXT: jmp32 a0 +; CHECK-NEXT: .Ltmp0: # Block address taken +; CHECK-NEXT: .LBB0_1: # %return +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .Ltmp1: # Block address taken +; CHECK-NEXT: .LBB0_2: # %l2 +; CHECK-NEXT: movi32 a0, 2 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: .LCPI0_0: +; CHECK-NEXT: .long .Lf.a +; +; CHECK-PIC-SMALL-LABEL: f: +; CHECK-PIC-SMALL: # %bb.0: # %entry +; CHECK-PIC-SMALL-NEXT: subi32 sp, sp, 4 +; CHECK-PIC-SMALL-NEXT: st32.w rgb, (sp, 0) +; CHECK-PIC-SMALL-NEXT: lrw32 rgb, [.LCPI0_1] +; CHECK-PIC-SMALL-NEXT: lrw32 a1, [.LCPI0_0] +; CHECK-PIC-SMALL-NEXT: addu32 a1, rgb, a1 +; CHECK-PIC-SMALL-NEXT: ldr32.w a0, (a1, a0 << 2) +; CHECK-PIC-SMALL-NEXT: jmp32 a0 +; CHECK-PIC-SMALL-NEXT: .Ltmp0: # Block address taken +; CHECK-PIC-SMALL-NEXT: .LBB0_1: # %return +; CHECK-PIC-SMALL-NEXT: movi32 a0, 1 +; CHECK-PIC-SMALL-NEXT: br32 .LBB0_3 +; CHECK-PIC-SMALL-NEXT: .Ltmp1: # Block address taken +; CHECK-PIC-SMALL-NEXT: .LBB0_2: # %l2 +; CHECK-PIC-SMALL-NEXT: movi32 a0, 2 +; CHECK-PIC-SMALL-NEXT: .LBB0_3: # %.split +; CHECK-PIC-SMALL-NEXT: ld32.w rgb, (sp, 0) +; CHECK-PIC-SMALL-NEXT: addi32 sp, sp, 4 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .p2align 2 +; CHECK-PIC-SMALL-NEXT: # %bb.4: +; CHECK-PIC-SMALL-NEXT: .LCPI0_0: +; CHECK-PIC-SMALL-NEXT: .long .Lf.a@GOTOFF +; CHECK-PIC-SMALL-NEXT: .LCPI0_1: +; CHECK-PIC-SMALL-NEXT: .long _GLOBAL_OFFSET_TABLE_ +; +; CHECK-PIC-LARGE-LABEL: f: +; CHECK-PIC-LARGE: # %bb.0: # %entry +; CHECK-PIC-LARGE-NEXT: subi32 sp, sp, 4 +; CHECK-PIC-LARGE-NEXT: st32.w rgb, (sp, 0) +; CHECK-PIC-LARGE-NEXT: lrw32 rgb, [.LCPI0_1] +; CHECK-PIC-LARGE-NEXT: lrw32 a1, [.LCPI0_0] +; CHECK-PIC-LARGE-NEXT: addu32 a1, rgb, a1 +; CHECK-PIC-LARGE-NEXT: ldr32.w a0, (a1, a0 << 2) +; CHECK-PIC-LARGE-NEXT: jmp32 a0 +; CHECK-PIC-LARGE-NEXT: .Ltmp0: # Block address taken +; CHECK-PIC-LARGE-NEXT: .LBB0_1: # %return +; CHECK-PIC-LARGE-NEXT: movi32 a0, 1 +; CHECK-PIC-LARGE-NEXT: br32 .LBB0_3 +; CHECK-PIC-LARGE-NEXT: .Ltmp1: # Block address taken +; CHECK-PIC-LARGE-NEXT: .LBB0_2: # %l2 +; CHECK-PIC-LARGE-NEXT: movi32 a0, 2 +; CHECK-PIC-LARGE-NEXT: .LBB0_3: # %.split +; CHECK-PIC-LARGE-NEXT: ld32.w rgb, (sp, 0) +; CHECK-PIC-LARGE-NEXT: addi32 sp, sp, 4 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .p2align 2 +; CHECK-PIC-LARGE-NEXT: # %bb.4: +; CHECK-PIC-LARGE-NEXT: .LCPI0_0: +; CHECK-PIC-LARGE-NEXT: .long .Lf.a@GOTOFF +; CHECK-PIC-LARGE-NEXT: .LCPI0_1: +; CHECK-PIC-LARGE-NEXT: .long _GLOBAL_OFFSET_TABLE_ +entry: + %idxprom = sext i32 %x to i64 + %arrayidx = getelementptr inbounds [2 x i8*], [2 x i8*]* @f.a, i64 0, i64 %idxprom + %0 = load i8*, i8** %arrayidx, align 8 + indirectbr i8* %0, [label %return, label %l2] + +l2: ; preds = %entry + br label %return + +return: ; preds = %entry, %l2 + %retval.0 = phi i32 [ 2, %l2 ], [ 1, %entry ] + ret i32 %retval.0 +} Index: llvm/test/CodeGen/CSKY/inttoptr.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/inttoptr.ll @@ -0,0 +1,511 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i64* @inttoptrR_i1_0(i1 %x) { +; CHECK-LABEL: inttoptrR_i1_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 %x to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrR_i1_1(i1 %x) { +; CHECK-LABEL: inttoptrR_i1_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 %x to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrR_i1_2(i1 %x) { +; CHECK-LABEL: inttoptrR_i1_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 %x to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrR_i1_3(i1 %x) { +; CHECK-LABEL: inttoptrR_i1_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 %x to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrR_i1_4(i1 %x) { +; CHECK-LABEL: inttoptrR_i1_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 %x to i1* + ret i1* %inttoptr +} + +define i64* @inttoptrI_i1_0() { +; CHECK-LABEL: inttoptrI_i1_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 -3 to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrI_i1_1() { +; CHECK-LABEL: inttoptrI_i1_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 -3 to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrI_i1_2() { +; CHECK-LABEL: inttoptrI_i1_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 -3 to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrI_i1_3() { +; CHECK-LABEL: inttoptrI_i1_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 -3 to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrI_i1_4() { +; CHECK-LABEL: inttoptrI_i1_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i1 -3 to i1* + ret i1* %inttoptr +} + +; + +define i64* @inttoptrR_i8_0(i8 %x) { +; CHECK-LABEL: inttoptrR_i8_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 %x to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrR_i8_1(i8 %x) { +; CHECK-LABEL: inttoptrR_i8_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 %x to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrR_i8_2(i8 %x) { +; CHECK-LABEL: inttoptrR_i8_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 %x to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrR_i8_3(i8 %x) { +; CHECK-LABEL: inttoptrR_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 %x to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrR_i8_4(i8 %x) { +; CHECK-LABEL: inttoptrR_i8_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 %x to i1* + ret i1* %inttoptr +} + +define i64* @inttoptrI_i8_0() { +; CHECK-LABEL: inttoptrI_i8_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 253 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 -3 to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrI_i8_1() { +; CHECK-LABEL: inttoptrI_i8_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 253 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 -3 to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrI_i8_2() { +; CHECK-LABEL: inttoptrI_i8_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 253 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 -3 to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrI_i8_3() { +; CHECK-LABEL: inttoptrI_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 253 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 -3 to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrI_i8_4() { +; CHECK-LABEL: inttoptrI_i8_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 253 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i8 -3 to i1* + ret i1* %inttoptr +} + + +; +define i64* @inttoptrR_i16_0(i16 %x) { +; CHECK-LABEL: inttoptrR_i16_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 %x to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrR_i16_1(i16 %x) { +; CHECK-LABEL: inttoptrR_i16_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 %x to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrR_i16_2(i16 %x) { +; CHECK-LABEL: inttoptrR_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 %x to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrR_i16_3(i16 %x) { +; CHECK-LABEL: inttoptrR_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 %x to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrR_i16_4(i16 %x) { +; CHECK-LABEL: inttoptrR_i16_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 %x to i1* + ret i1* %inttoptr +} + +define i64* @inttoptrI_i16_0() { +; CHECK-LABEL: inttoptrI_i16_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 -3 to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrI_i16_1() { +; CHECK-LABEL: inttoptrI_i16_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 -3 to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrI_i16_2() { +; CHECK-LABEL: inttoptrI_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 -3 to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrI_i16_3() { +; CHECK-LABEL: inttoptrI_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 -3 to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrI_i16_4() { +; CHECK-LABEL: inttoptrI_i16_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i16 -3 to i1* + ret i1* %inttoptr +} + +; +define i64* @inttoptrR_i32_0(i32 %x) { +; CHECK-LABEL: inttoptrR_i32_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 %x to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrR_i32_1(i32 %x) { +; CHECK-LABEL: inttoptrR_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 %x to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrR_i32_2(i32 %x) { +; CHECK-LABEL: inttoptrR_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 %x to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrR_i32_3(i32 %x) { +; CHECK-LABEL: inttoptrR_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 %x to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrR_i32_4(i32 %x) { +; CHECK-LABEL: inttoptrR_i32_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 %x to i1* + ret i1* %inttoptr +} + +define i64* @inttoptrI_i32_0() { +; CHECK-LABEL: inttoptrI_i32_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 -3 to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrI_i32_1() { +; CHECK-LABEL: inttoptrI_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 -3 to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrI_i32_2() { +; CHECK-LABEL: inttoptrI_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 -3 to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrI_i32_3() { +; CHECK-LABEL: inttoptrI_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 -3 to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrI_i32_4() { +; CHECK-LABEL: inttoptrI_i32_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i32 -3 to i1* + ret i1* %inttoptr +} + +; +define i64* @inttoptrR_i64_0(i64 %x) { +; CHECK-LABEL: inttoptrR_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 %x to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrR_i64_1(i64 %x) { +; CHECK-LABEL: inttoptrR_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 %x to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrR_i64_2(i64 %x) { +; CHECK-LABEL: inttoptrR_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 %x to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrR_i64_3(i64 %x) { +; CHECK-LABEL: inttoptrR_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 %x to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrR_i64_4(i64 %x) { +; CHECK-LABEL: inttoptrR_i64_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 %x to i1* + ret i1* %inttoptr +} + +define i64* @inttoptrI_i64_0() { +; CHECK-LABEL: inttoptrI_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 -3 to i64* + ret i64* %inttoptr +} + +define i32* @inttoptrI_i64_1() { +; CHECK-LABEL: inttoptrI_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 -3 to i32* + ret i32* %inttoptr +} + +define i16* @inttoptrI_i64_2() { +; CHECK-LABEL: inttoptrI_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 -3 to i16* + ret i16* %inttoptr +} + +define i8* @inttoptrI_i64_3() { +; CHECK-LABEL: inttoptrI_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 -3 to i8* + ret i8* %inttoptr +} + +define i1* @inttoptrI_i64_4() { +; CHECK-LABEL: inttoptrI_i64_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65533 +; CHECK-NEXT: rts32 +entry: + %inttoptr = inttoptr i64 -3 to i1* + ret i1* %inttoptr +} + +; + Index: llvm/test/CodeGen/CSKY/ld-float.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/ld-float.ll @@ -0,0 +1,144 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @load_I_w(float* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: load_I_w: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w a0, (a0, 3) +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: load_I_w: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: flds vr0, (a0, 3) +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: load_I_w: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: flds vr0, (a0, 3) +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: load_I_w: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fld.32 vr0, (a0, 3) +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: load_I_w: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fld.32 vr0, (a0, 3) +; CHECK-DF2-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds float, float* %a, i64 3 + %0 = load float, float* %arrayidx, align 4 + ret float %0 +} + +define double @load_I_d(double* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: load_I_d: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w a2, (a0, 6) +; CHECK-SOFT-NEXT: ld32.w a1, (a0, 7) +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: load_I_d: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a2, (a0, 6) +; CHECK-SF-NEXT: ld32.w a1, (a0, 7) +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: load_I_d: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fldd vr0, (a0, 6) +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: load_I_d: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w a2, (a0, 6) +; CHECK-SF2-NEXT: ld32.w a1, (a0, 7) +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: load_I_d: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fld.64 vr0, (a0, 6) +; CHECK-DF2-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds double, double* %a, i64 3 + %0 = load double, double* %arrayidx, align 4 + ret double %0 +} + +define float @load_R_w(float* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: load_R_w: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ldr32.w a0, (a0, a1 << 2) +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: load_R_w: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fldrs vr0, a0, (a1 << 2) +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: load_R_w: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fldrs vr0, a0, (a1 << 2) +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: load_R_w: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fldr.32 vr0, (a0, a1 << 2) +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: load_R_w: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fldr.32 vr0, (a0, a1 << 2) +; CHECK-DF2-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds float, float* %a, i64 %idxprom + %0 = load float, float* %arrayidx, align 4 + ret float %0 +} + +define double @load_R_d(double* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: load_R_d: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ixd32 a2, a0, a1 +; CHECK-SOFT-NEXT: ldr32.w a0, (a0, a1 << 3) +; CHECK-SOFT-NEXT: ld32.w a1, (a2, 1) +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: load_R_d: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ixd32 a2, a0, a1 +; CHECK-SF-NEXT: ldr32.w a0, (a0, a1 << 3) +; CHECK-SF-NEXT: ld32.w a1, (a2, 1) +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: load_R_d: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fldrd vr0, a0, (a1 << 3) +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: load_R_d: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ixd32 a2, a0, a1 +; CHECK-SF2-NEXT: ldr32.w a0, (a0, a1 << 3) +; CHECK-SF2-NEXT: ld32.w a1, (a2, 1) +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: load_R_d: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fldr.64 vr0, (a0, a1 << 3) +; CHECK-DF2-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds double, double* %a, i64 %idxprom + %0 = load double, double* %arrayidx, align 4 + ret double %0 +} Index: llvm/test/CodeGen/CSKY/ld.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/ld.ll @@ -0,0 +1,301 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define signext i1 @load_I_bits(i1* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_bits: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.bs a0, (a0, 3) +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_bits: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.bs a0, a0, 3 +; CHECK-PIC-NEXT: sext32 a0, a0, 0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i1, i1* %a, i64 3 + %0 = load i1, i1* %arrayidx, align 1 + ret i1 %0 +} + +define zeroext i1 @load_I_bit_(i1* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_bit_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.b a0, (a0, 3) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_bit_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.b a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i1, i1* %a, i64 3 + %0 = load i1, i1* %arrayidx, align 1 + ret i1 %0 +} + +define signext i8 @load_I_bs(i8* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_bs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.bs a0, (a0, 3) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_bs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.bs a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i8, i8* %a, i64 3 + %0 = load i8, i8* %arrayidx, align 1 + ret i8 %0 +} + +define zeroext i8 @load_I_b_(i8* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_b_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.b a0, (a0, 3) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_b_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.b a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i8, i8* %a, i64 3 + %0 = load i8, i8* %arrayidx, align 1 + ret i8 %0 +} + +define signext i16 @load_I_hs(i16* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_hs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.hs a0, (a0, 3) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_hs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.hs a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i16, i16* %a, i64 3 + %0 = load i16, i16* %arrayidx, align 2 + ret i16 %0 +} + +define zeroext i16 @load_I_h_(i16* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_h_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.h a0, (a0, 3) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_h_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.h a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i16, i16* %a, i64 3 + %0 = load i16, i16* %arrayidx, align 2 + ret i16 %0 +} + +define i32 @load_I_w(i32* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_w: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w a0, (a0, 3) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_w: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.w a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i32, i32* %a, i64 3 + %0 = load i32, i32* %arrayidx, align 4 + ret i32 %0 +} + +define i64 @load_I_d(i64* nocapture readonly %a) local_unnamed_addr #0 { +; CHECK-LABEL: load_I_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w a2, (a0, 6) +; CHECK-NEXT: ld32.w a1, (a0, 7) +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_d: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.w a2, a0, 6 +; CHECK-PIC-NEXT: ld32.w a1, a0, 7 +; CHECK-PIC-NEXT: mov32 a0, a2 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i64, i64* %a, i64 3 + %0 = load i64, i64* %arrayidx, align 4 + ret i64 %0 +} + +define i8 @load_I_i8_anyext(i8* %p) { +; CHECK-LABEL: load_I_i8_anyext: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.bs a0, (a0, 0) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_I_i8_anyext: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %ret = load i8, i8* %p, align 1 + ret i8 %ret +} + +define signext i1 @load_R_bits(i1* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_bits: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.bs a0, (a0, a1 << 0) +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_bits: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: sext32 a0, a0, 0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i1, i1* %a, i64 %idxprom + %0 = load i1, i1* %arrayidx, align 1 + ret i1 %0 +} + +define zeroext i1 @load_R_bit_(i1* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_bit_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.b a0, (a0, a1 << 0) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_bit_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.b a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i1, i1* %a, i64 %idxprom + %0 = load i1, i1* %arrayidx, align 1 + ret i1 %0 +} + + +define signext i8 @load_R_bs(i8* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_bs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.bs a0, (a0, a1 << 0) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_bs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom + %0 = load i8, i8* %arrayidx, align 1 + ret i8 %0 +} + +define zeroext i8 @load_R_b_(i8* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_b_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.b a0, (a0, a1 << 0) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_b_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.b a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom + %0 = load i8, i8* %arrayidx, align 1 + ret i8 %0 +} + +define signext i16 @load_R_hs(i16* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_hs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.hs a0, (a0, a1 << 1) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_hs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixh32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.hs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom + %0 = load i16, i16* %arrayidx, align 2 + ret i16 %0 +} + +define zeroext i16 @load_R_h_(i16* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_h_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.h a0, (a0, a1 << 1) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_h_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixh32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.h a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom + %0 = load i16, i16* %arrayidx, align 2 + ret i16 %0 +} + +define i32 @load_R_w(i32* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_w: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.w a0, (a0, a1 << 2) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_w: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixw32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.w a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom + %0 = load i32, i32* %arrayidx, align 4 + ret i32 %0 +} + +define i64 @load_R_d(i64* nocapture readonly %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: load_R_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ixd32 a2, a0, a1 +; CHECK-NEXT: ldr32.w a0, (a0, a1 << 3) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: load_R_d: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixd32 a1, a0, a1 +; CHECK-PIC-NEXT: ld32.w a0, a1, 0 +; CHECK-PIC-NEXT: ld32.w a1, a1, 1 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i64, i64* %a, i64 %idxprom + %0 = load i64, i64* %arrayidx, align 4 + ret i64 %0 +} + +define i8 @loadR_i8_anyext(i8* %c, i32 %a) { +; CHECK-LABEL: loadR_i8_anyext: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldr32.bs a0, (a0, a1 << 0) +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: loadR_i8_anyext: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %a to i64 + %arrayidx = getelementptr inbounds i8, i8* %c, i64 %idxprom + %0 = load i8, i8* %arrayidx, align 1 + ret i8 %0 +} Index: llvm/test/CodeGen/CSKY/lit.local.cfg =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'CSKY' in config.root.targets: + config.unsupported = True Index: llvm/test/CodeGen/CSKY/lshr.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/lshr.ll @@ -0,0 +1,124 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @lshrRR(i32 %x, i32 %y) { +; CHECK-LABEL: lshrRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsr32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i32 %y, %x + ret i32 %lshr +} + +define i32 @lshrRI(i32 %x) { +; CHECK-LABEL: lshrRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsri32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i32 %x, 10 + ret i32 %lshr +} + +define i64 @LSHR_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: LSHR_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: st32.w lr, (sp, 0) +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: mov32 a3, a0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a2, a3 +; CHECK-NEXT: jsri32 .LCPI2_0 +; CHECK-NEXT: ld32.w lr, (sp, 0) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: .LCPI2_0: +; CHECK-NEXT: .long __lshrdi3 +entry: + %lshr = lshr i64 %y, %x + ret i64 %lshr +} + +define i64 @LSHR_LONG_I(i64 %x) { +; CHECK-LABEL: LSHR_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsli32 a2, a1, 25 +; CHECK-NEXT: lsri32 a0, a0, 7 +; CHECK-NEXT: or32 a0, a0, a2 +; CHECK-NEXT: lsri32 a1, a1, 7 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i64 %x, 7 + ret i64 %lshr +} + +define i16 @LSHR_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: LSHR_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: lsr32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i16 %y, %x + ret i16 %lshr +} + +define i16 @LSHR_SHORT_I(i16 %x) { +; CHECK-LABEL: LSHR_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 65534 +; CHECK-NEXT: and32 a0, a0, a1 +; CHECK-NEXT: lsri32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i16 %x, 1 + ret i16 %lshr +} + +define i8 @LSHR_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: LSHR_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: lsr32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i8 %y, %x + ret i8 %lshr +} + +define i8 @LSHR_CHAR_I(i8 %x) { +; CHECK-LABEL: LSHR_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 254 +; CHECK-NEXT: lsri32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i8 %x, 1 + ret i8 %lshr +} + +define i1 @LSHR_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: LSHR_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i1 %y, %x + ret i1 %lshr +} + +define i1 @LSHR_BIT_I(i1 %x) { +; CHECK-LABEL: LSHR_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %lshr = lshr i1 %x, 1 + ret i1 %lshr +} + Index: llvm/test/CodeGen/CSKY/mul.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/mul.ll @@ -0,0 +1,125 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @mulRR(i32 %x, i32 %y) { +; CHECK-LABEL: mulRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mult32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i32 %y, %x + ret i32 %mul +} + +define i32 @mulRI(i32 %x) { +; CHECK-LABEL: mulRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 10 +; CHECK-NEXT: mult32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i32 %x, 10 + ret i32 %mul +} + +define i32 @mulRI_X(i32 %x) { +; CHECK-LABEL: mulRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 4097 +; CHECK-NEXT: mult32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i32 %x, 4097 + ret i32 %mul +} + +define i64 @MUL_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: MUL_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mul.u32 t0, a2, a0 +; CHECK-NEXT: mula.32.l t1, a2, a1 +; CHECK-NEXT: mula.32.l t1, a3, a0 +; CHECK-NEXT: mov32 a0, t0 +; CHECK-NEXT: mov32 a1, t1 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i64 %y, %x + ret i64 %mul +} + +define i64 @MUL_LONG_I(i64 %x) { +; CHECK-LABEL: MUL_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 t0, 3 +; CHECK-NEXT: mul.u32 a2, a0, t0 +; CHECK-NEXT: mula.32.l a3, a1, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i64 %x, 3 + ret i64 %mul +} + +define i16 @MUL_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: MUL_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mult32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i16 %y, %x + ret i16 %mul +} + +define i16 @MUL_SHORT_I(i16 %x) { +; CHECK-LABEL: MUL_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 3 +; CHECK-NEXT: mult32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i16 %x, 3 + ret i16 %mul +} + +define i8 @MUL_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: MUL_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mult32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i8 %y, %x + ret i8 %mul +} + +define i8 @MUL_CHAR_I(i8 %x) { +; CHECK-LABEL: MUL_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 65535 +; CHECK-NEXT: ori32 a1, a1, 65533 +; CHECK-NEXT: mult32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i8 %x, -3 + ret i8 %mul +} + +define i1 @MUL_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: MUL_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mult32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i1 %y, %x + ret i1 %mul +} + +define i1 @MUL_BIT_I(i1 %x) { +; CHECK-LABEL: MUL_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %mul = mul nsw i1 %x, -1 + ret i1 %mul +} + Index: llvm/test/CodeGen/CSKY/mula.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/mula.ll @@ -0,0 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @mula(i32 %a, i32 %b) { +; CHECK-LABEL: mula: +; CHECK: # %bb.0: +; CHECK-NEXT: mula.32.l a0, a0, a1 +; CHECK-NEXT: rts32 + %mul = mul i32 %a, %b + %add = add i32 %mul, %a + ret i32 %add +} + +define i32 @mula_I(i32 %a, i32 %b) { +; CHECK-LABEL: mula_I: +; CHECK: # %bb.0: +; CHECK-NEXT: mult32 a0, a0, a1 +; CHECK-NEXT: addi32 a0, a0, 3 +; CHECK-NEXT: rts32 + %mul = mul i32 %a, %b + %add = add i32 %mul, 3 + ret i32 %add +} + +; unsupported multiply and sub +;define i32 @muls(i32 %a, i32 %b) { +; %mul = mul i32 %a, %b +; %add = sub i32 %mul, %a +; ret i32 %add +;} Index: llvm/test/CodeGen/CSKY/or.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/or.ll @@ -0,0 +1,114 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @orRR(i32 %x, i32 %y) { +; CHECK-LABEL: orRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %or = or i32 %y, %x + ret i32 %or +} + +define i32 @orRI(i32 %x) { +; CHECK-LABEL: orRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %or = or i32 %x, 10 + ret i32 %or +} + +define i32 @orRI_X(i32 %x) { +; CHECK-LABEL: orRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori32 a0, a0, 4097 +; CHECK-NEXT: rts32 +entry: + %or = or i32 %x, 4097 + ret i32 %or +} + +define i64 @OR_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: OR_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a2, a0 +; CHECK-NEXT: or32 a1, a3, a1 +; CHECK-NEXT: rts32 +entry: + %or = or i64 %y, %x + ret i64 %or +} + +define i64 @OR_LONG_I(i64 %x) { +; CHECK-LABEL: OR_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %or = or i64 %x, 1 + ret i64 %or +} + +define i16 @OR_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: OR_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %or = or i16 %y, %x + ret i16 %or +} + +define i16 @OR_SHORT_I(i16 %x) { +; CHECK-LABEL: OR_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %or = or i16 %x, 1 + ret i16 %or +} + +define i8 @OR_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: OR_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %or = or i8 %y, %x + ret i8 %or +} + +define i8 @OR_CHAR_I(i8 %x) { +; CHECK-LABEL: OR_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %or = or i8 %x, 1 + ret i8 %or +} + +define i1 @OR_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: OR_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: or32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %or = or i1 %y, %x + ret i1 %or +} + +define i1 @OR_BIT_I(i1 %x) { +; CHECK-LABEL: OR_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %or = or i1 %x, 1 + ret i1 %or +} + Index: llvm/test/CodeGen/CSKY/ptrtoint.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/ptrtoint.ll @@ -0,0 +1,234 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i64 @ptrtointR_i1ptr_0(i1* %x) { +; CHECK-LABEL: ptrtointR_i1ptr_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i1* %x to i64 + ret i64 %ptrtoint +} + +define i32 @ptrtointR_i1ptr_1(i1* %x) { +; CHECK-LABEL: ptrtointR_i1ptr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i1* %x to i32 + ret i32 %ptrtoint +} + +define i16 @ptrtointR_i1ptr_2(i1* %x) { +; CHECK-LABEL: ptrtointR_i1ptr_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i1* %x to i16 + ret i16 %ptrtoint +} + +define i8 @ptrtointR_i1ptr_3(i1* %x) { +; CHECK-LABEL: ptrtointR_i1ptr_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i1* %x to i8 + ret i8 %ptrtoint +} + +define i1 @ptrtointR_i1ptr_4(i1* %x) { +; CHECK-LABEL: ptrtointR_i1ptr_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i1* %x to i1 + ret i1 %ptrtoint +} + +define i64 @ptrtointR_i8ptr_0(i8* %x) { +; CHECK-LABEL: ptrtointR_i8ptr_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i8* %x to i64 + ret i64 %ptrtoint +} + +define i32 @ptrtointR_i8ptr_1(i8* %x) { +; CHECK-LABEL: ptrtointR_i8ptr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i8* %x to i32 + ret i32 %ptrtoint +} + +define i16 @ptrtointR_i8ptr_2(i8* %x) { +; CHECK-LABEL: ptrtointR_i8ptr_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i8* %x to i16 + ret i16 %ptrtoint +} + +define i8 @ptrtointR_i8ptr_3(i8* %x) { +; CHECK-LABEL: ptrtointR_i8ptr_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i8* %x to i8 + ret i8 %ptrtoint +} + +define i1 @ptrtointR_i8ptr_4(i8* %x) { +; CHECK-LABEL: ptrtointR_i8ptr_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i8* %x to i1 + ret i1 %ptrtoint +} + +define i64 @ptrtointR_i16ptr_0(i16* %x) { +; CHECK-LABEL: ptrtointR_i16ptr_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i16* %x to i64 + ret i64 %ptrtoint +} + +define i32 @ptrtointR_i16ptr_1(i16* %x) { +; CHECK-LABEL: ptrtointR_i16ptr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i16* %x to i32 + ret i32 %ptrtoint +} + +define i16 @ptrtointR_i16ptr_2(i16* %x) { +; CHECK-LABEL: ptrtointR_i16ptr_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i16* %x to i16 + ret i16 %ptrtoint +} + +define i8 @ptrtointR_i16ptr_3(i16* %x) { +; CHECK-LABEL: ptrtointR_i16ptr_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i16* %x to i8 + ret i8 %ptrtoint +} + +define i1 @ptrtointR_i16ptr_4(i16* %x) { +; CHECK-LABEL: ptrtointR_i16ptr_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i16* %x to i1 + ret i1 %ptrtoint +} + +define i64 @ptrtointR_i32ptr_0(i32* %x) { +; CHECK-LABEL: ptrtointR_i32ptr_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i32* %x to i64 + ret i64 %ptrtoint +} + +define i32 @ptrtointR_i32ptr_1(i32* %x) { +; CHECK-LABEL: ptrtointR_i32ptr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i32* %x to i32 + ret i32 %ptrtoint +} + +define i16 @ptrtointR_i32ptr_2(i32* %x) { +; CHECK-LABEL: ptrtointR_i32ptr_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i32* %x to i16 + ret i16 %ptrtoint +} + +define i8 @ptrtointR_i32ptr_3(i32* %x) { +; CHECK-LABEL: ptrtointR_i32ptr_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i32* %x to i8 + ret i8 %ptrtoint +} + +define i1 @ptrtointR_i32ptr_4(i32* %x) { +; CHECK-LABEL: ptrtointR_i32ptr_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i32* %x to i1 + ret i1 %ptrtoint +} + +define i64 @ptrtointR_i64ptr_0(i64* %x) { +; CHECK-LABEL: ptrtointR_i64ptr_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i64* %x to i64 + ret i64 %ptrtoint +} + +define i32 @ptrtointR_i64ptr_1(i64* %x) { +; CHECK-LABEL: ptrtointR_i64ptr_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i64* %x to i32 + ret i32 %ptrtoint +} + +define i16 @ptrtointR_i64ptr_2(i64* %x) { +; CHECK-LABEL: ptrtointR_i64ptr_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i64* %x to i16 + ret i16 %ptrtoint +} + +define i8 @ptrtointR_i64ptr_3(i64* %x) { +; CHECK-LABEL: ptrtointR_i64ptr_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i64* %x to i8 + ret i8 %ptrtoint +} + +define i1 @ptrtointR_i64ptr_4(i64* %x) { +; CHECK-LABEL: ptrtointR_i64ptr_4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %ptrtoint = ptrtoint i64* %x to i1 + ret i1 %ptrtoint +} + + Index: llvm/test/CodeGen/CSKY/sdiv.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/sdiv.ll @@ -0,0 +1,132 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @sdivRR(i32 %x, i32 %y) { +; CHECK-LABEL: sdivRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: divs32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i32 %y, %x + ret i32 %sdiv +} + +define i32 @sdivRI(i32 %x) { +; CHECK-LABEL: sdivRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 26214 +; CHECK-NEXT: ori32 a1, a1, 26215 +; CHECK-NEXT: mul.s32 a0, a0, a1 +; CHECK-NEXT: lsri32 a2, a1, 31 +; CHECK-NEXT: asri32 a0, a1, 2 +; CHECK-NEXT: addu32 a0, a0, a2 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i32 %x, 10 + ret i32 %sdiv +} + +define i32 @sdivRI_X(i32 %x) { +; CHECK-LABEL: sdivRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 255 +; CHECK-NEXT: ori32 a1, a1, 61441 +; CHECK-NEXT: mul.s32 a0, a0, a1 +; CHECK-NEXT: lsri32 a2, a1, 31 +; CHECK-NEXT: asri32 a0, a1, 4 +; CHECK-NEXT: addu32 a0, a0, a2 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i32 %x, 4097 + ret i32 %sdiv +} + +; TODO: Fix the test because it calls __divdi3 +;define i64 @SDIV_LONG(i64 %x, i64 %y) { +;entry: +; %sdiv = sdiv i64 %y, %x +; ret i64 %sdiv +;} + +; Fix the test because it calls __divdi3 +;define i64 @SDIV_LONG_I(i64 %x) { +;entry: +; %sdiv = sdiv i64 %x, 3 +; ret i64 %sdiv +;} + +define i16 @SDIV_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: SDIV_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: divs32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i16 %y, %x + ret i16 %sdiv +} + +define i16 @SDIV_SHORT_I(i16 %x) { +; CHECK-LABEL: SDIV_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movih32 a1, 21845 +; CHECK-NEXT: ori32 a1, a1, 21846 +; CHECK-NEXT: mul.s32 a0, a0, a1 +; CHECK-NEXT: lsri32 a2, a1, 31 +; CHECK-NEXT: addu32 a0, a1, a2 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i16 %x, 3 + ret i16 %sdiv +} + +define i8 @SDIV_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: SDIV_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: divs32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i8 %y, %x + ret i8 %sdiv +} + +define i8 @SDIV_CHAR_I(i8 %x) { +; CHECK-LABEL: SDIV_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a1, 21845 +; CHECK-NEXT: ori32 a1, a1, 21845 +; CHECK-NEXT: mul.s32 a1, a0, a1 +; CHECK-NEXT: subu32 a0, a2, a0 +; CHECK-NEXT: lsri32 a1, a0, 31 +; CHECK-NEXT: asri32 a0, a0, 1 +; CHECK-NEXT: addu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i8 %x, -3 + ret i8 %sdiv +} + +define i1 @SDIV_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: SDIV_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i1 %y, %x + ret i1 %sdiv +} + +define i1 @SDIV_BIT_I(i1 %x) { +; CHECK-LABEL: SDIV_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %sdiv = sdiv i1 %x, -1 + ret i1 %sdiv +} + Index: llvm/test/CodeGen/CSKY/select-float.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/select-float.ll @@ -0,0 +1,10181 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @selectRR_oeq_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_oeq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_oeq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: bf32 .LBB0_2 +; CHECK-SF-NEXT: br32 .LBB0_1 +; CHECK-SF-NEXT: .LBB0_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB0_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_oeq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: bf32 .LBB0_2 +; CHECK-DF-NEXT: br32 .LBB0_1 +; CHECK-DF-NEXT: .LBB0_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB0_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_oeq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_oeq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_oeq_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_oeq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_oeq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr3 +; CHECK-SF-NEXT: bf32 .LBB1_2 +; CHECK-SF-NEXT: br32 .LBB1_1 +; CHECK-SF-NEXT: .LBB1_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB1_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_oeq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr3 +; CHECK-DF-NEXT: bf32 .LBB1_2 +; CHECK-DF-NEXT: br32 .LBB1_1 +; CHECK-DF-NEXT: .LBB1_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB1_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_oeq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_oeq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_oeq_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_oeq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_oeq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: bf32 .LBB2_2 +; CHECK-SF-NEXT: br32 .LBB2_1 +; CHECK-SF-NEXT: .LBB2_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB2_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_oeq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: bf32 .LBB2_2 +; CHECK-DF-NEXT: br32 .LBB2_1 +; CHECK-DF-NEXT: .LBB2_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB2_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_oeq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_oeq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_oeq_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_oeq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_oeq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB3_2 +; CHECK-SF-NEXT: br32 .LBB3_1 +; CHECK-SF-NEXT: .LBB3_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB3_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_oeq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB3_2 +; CHECK-DF-NEXT: br32 .LBB3_1 +; CHECK-DF-NEXT: .LBB3_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB3_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_oeq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_oeq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_oeq_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_oeq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movf32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_oeq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: bez32 a0, .LBB4_2 +; CHECK-SF-NEXT: br32 .LBB4_1 +; CHECK-SF-NEXT: .LBB4_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB4_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_oeq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: bf32 .LBB4_2 +; CHECK-DF-NEXT: br32 .LBB4_1 +; CHECK-DF-NEXT: .LBB4_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB4_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_oeq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movf32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_oeq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_oeq_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_oeq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l3 +; CHECK-SOFT-NEXT: movf32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_oeq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: bez32 a0, .LBB5_2 +; CHECK-SF-NEXT: br32 .LBB5_1 +; CHECK-SF-NEXT: .LBB5_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB5_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_oeq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr3 +; CHECK-DF-NEXT: bf32 .LBB5_2 +; CHECK-DF-NEXT: br32 .LBB5_1 +; CHECK-DF-NEXT: .LBB5_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB5_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_oeq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movf32 l1, l3 +; CHECK-SF2-NEXT: movf32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_oeq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_oeq_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_oeq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l3 +; CHECK-SOFT-NEXT: movf32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_oeq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: bez32 a0, .LBB6_2 +; CHECK-SF-NEXT: br32 .LBB6_1 +; CHECK-SF-NEXT: .LBB6_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB6_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_oeq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: bf32 .LBB6_2 +; CHECK-DF-NEXT: br32 .LBB6_1 +; CHECK-DF-NEXT: .LBB6_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB6_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_oeq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movf32 l1, l3 +; CHECK-SF2-NEXT: movf32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_oeq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oeq double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_oeq_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_oeq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_oeq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB7_2 +; CHECK-SF-NEXT: br32 .LBB7_1 +; CHECK-SF-NEXT: .LBB7_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB7_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_oeq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB7_2 +; CHECK-DF-NEXT: br32 .LBB7_1 +; CHECK-DF-NEXT: .LBB7_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB7_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_oeq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_oeq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_false_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_false_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_false_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB8_2 +; CHECK-SF-NEXT: br32 .LBB8_1 +; CHECK-SF-NEXT: .LBB8_1: # %select.false +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: .LBB8_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_false_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB8_2 +; CHECK-DF-NEXT: br32 .LBB8_1 +; CHECK-DF-NEXT: .LBB8_1: # %select.false +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: .LBB8_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_false_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmov.32 vr0, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_false_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.32 vr0, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_false_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_false_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_false_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB9_2 +; CHECK-SF-NEXT: br32 .LBB9_1 +; CHECK-SF-NEXT: .LBB9_1: # %select.false +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: .LBB9_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_false_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB9_2 +; CHECK-DF-NEXT: br32 .LBB9_1 +; CHECK-DF-NEXT: .LBB9_1: # %select.false +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: .LBB9_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_false_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmov.32 vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_false_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.32 vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_false_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_false_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_false_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB10_2 +; CHECK-SF-NEXT: br32 .LBB10_1 +; CHECK-SF-NEXT: .LBB10_1: # %select.false +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: .LBB10_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_false_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB10_2 +; CHECK-DF-NEXT: br32 .LBB10_1 +; CHECK-DF-NEXT: .LBB10_1: # %select.false +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: .LBB10_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_false_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmov.32 vr0, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_false_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.32 vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_false_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_false_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_false_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB11_2 +; CHECK-SF-NEXT: br32 .LBB11_1 +; CHECK-SF-NEXT: .LBB11_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB11_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_false_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB11_2 +; CHECK-DF-NEXT: br32 .LBB11_1 +; CHECK-DF-NEXT: .LBB11_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB11_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_false_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_false_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_false_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_false_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w a0, sp, 0 +; CHECK-SOFT-NEXT: ld32.w a1, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_false_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a1, sp, 12 +; CHECK-SF-NEXT: ld32.w a0, sp, 8 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: btsti32 a2, 0 +; CHECK-SF-NEXT: bt32 .LBB12_2 +; CHECK-SF-NEXT: br32 .LBB12_1 +; CHECK-SF-NEXT: .LBB12_1: # %select.false +; CHECK-SF-NEXT: ld32.w a1, sp, 4 +; CHECK-SF-NEXT: ld32.w a0, sp, 0 +; CHECK-SF-NEXT: .LBB12_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_false_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB12_2 +; CHECK-DF-NEXT: br32 .LBB12_1 +; CHECK-DF-NEXT: .LBB12_1: # %select.false +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: .LBB12_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_false_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w a0, sp, 0 +; CHECK-SF2-NEXT: ld32.w a1, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_false_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.64 vr0, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_false_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_false_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_false_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a1, sp, 4 +; CHECK-SF-NEXT: ld32.w a0, sp, 0 +; CHECK-SF-NEXT: movi32 t0, 0 +; CHECK-SF-NEXT: btsti32 t0, 0 +; CHECK-SF-NEXT: bt32 .LBB13_2 +; CHECK-SF-NEXT: br32 .LBB13_1 +; CHECK-SF-NEXT: .LBB13_1: # %select.false +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: .LBB13_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_false_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB13_2 +; CHECK-DF-NEXT: br32 .LBB13_1 +; CHECK-DF-NEXT: .LBB13_1: # %select.false +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: .LBB13_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_false_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_false_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.64 vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_false_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_false_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_false_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a1, sp, 4 +; CHECK-SF-NEXT: ld32.w a0, sp, 0 +; CHECK-SF-NEXT: movi32 t0, 0 +; CHECK-SF-NEXT: btsti32 t0, 0 +; CHECK-SF-NEXT: bt32 .LBB14_2 +; CHECK-SF-NEXT: br32 .LBB14_1 +; CHECK-SF-NEXT: .LBB14_1: # %select.false +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: .LBB14_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_false_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB14_2 +; CHECK-DF-NEXT: br32 .LBB14_1 +; CHECK-DF-NEXT: .LBB14_1: # %select.false +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: .LBB14_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_false_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_false_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.64 vr0, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp false double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_false_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_false_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_false_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB15_2 +; CHECK-SF-NEXT: br32 .LBB15_1 +; CHECK-SF-NEXT: .LBB15_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB15_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_false_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB15_2 +; CHECK-DF-NEXT: br32 .LBB15_1 +; CHECK-DF-NEXT: .LBB15_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB15_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_false_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_false_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + + +define float @selectRR_ogt_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ogt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __gtsf2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ogt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB16_2 +; CHECK-SF-NEXT: br32 .LBB16_1 +; CHECK-SF-NEXT: .LBB16_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB16_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ogt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB16_2 +; CHECK-DF-NEXT: br32 .LBB16_1 +; CHECK-DF-NEXT: .LBB16_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB16_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ogt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ogt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ogt_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ogt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __gtsf2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ogt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmplts vr3, vr0 +; CHECK-SF-NEXT: bt32 .LBB17_2 +; CHECK-SF-NEXT: br32 .LBB17_1 +; CHECK-SF-NEXT: .LBB17_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB17_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ogt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmplts vr3, vr0 +; CHECK-DF-NEXT: bt32 .LBB17_2 +; CHECK-DF-NEXT: br32 .LBB17_1 +; CHECK-DF-NEXT: .LBB17_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB17_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ogt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr3, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ogt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr3, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ogt_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ogt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, sp, 12 +; CHECK-SOFT-NEXT: st32.w l0, sp, 8 +; CHECK-SOFT-NEXT: st32.w l1, sp, 4 +; CHECK-SOFT-NEXT: st32.w l2, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 l2, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __gtsf2 +; CHECK-SOFT-NEXT: cmplt32 l2, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ogt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: bf32 .LBB18_2 +; CHECK-SF-NEXT: br32 .LBB18_1 +; CHECK-SF-NEXT: .LBB18_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB18_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ogt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: bf32 .LBB18_2 +; CHECK-DF-NEXT: br32 .LBB18_1 +; CHECK-DF-NEXT: .LBB18_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB18_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ogt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ogt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ogt_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ogt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ogt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB19_2 +; CHECK-SF-NEXT: br32 .LBB19_1 +; CHECK-SF-NEXT: .LBB19_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB19_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ogt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB19_2 +; CHECK-DF-NEXT: br32 .LBB19_1 +; CHECK-DF-NEXT: .LBB19_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB19_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ogt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ogt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ogt_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ogt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __gtdf2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ogt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __gtdf2 +; CHECK-SF-NEXT: bhz32 a0, .LBB20_2 +; CHECK-SF-NEXT: br32 .LBB20_1 +; CHECK-SF-NEXT: .LBB20_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB20_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ogt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB20_2 +; CHECK-DF-NEXT: br32 .LBB20_1 +; CHECK-DF-NEXT: .LBB20_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB20_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ogt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __gtdf2 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ogt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ogt_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ogt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 24 +; CHECK-SOFT-NEXT: movi32 l4, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __gtdf2 +; CHECK-SOFT-NEXT: cmplt32 l4, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ogt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __gtdf2 +; CHECK-SF-NEXT: bhz32 a0, .LBB21_2 +; CHECK-SF-NEXT: br32 .LBB21_1 +; CHECK-SF-NEXT: .LBB21_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB21_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ogt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpltd vr3, vr0 +; CHECK-DF-NEXT: bt32 .LBB21_2 +; CHECK-DF-NEXT: br32 .LBB21_1 +; CHECK-DF-NEXT: .LBB21_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB21_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ogt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, sp, 20 +; CHECK-SF2-NEXT: st32.w l0, sp, 16 +; CHECK-SF2-NEXT: st32.w l1, sp, 12 +; CHECK-SF2-NEXT: st32.w l2, sp, 8 +; CHECK-SF2-NEXT: st32.w l3, sp, 4 +; CHECK-SF2-NEXT: st32.w l4, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 24 +; CHECK-SF2-NEXT: ld32.w l3, sp, 24 +; CHECK-SF2-NEXT: movi32 l4, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __gtdf2 +; CHECK-SF2-NEXT: cmplt32 l4, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 20 +; CHECK-SF2-NEXT: ld32.w l0, sp, 16 +; CHECK-SF2-NEXT: ld32.w l1, sp, 12 +; CHECK-SF2-NEXT: ld32.w l2, sp, 8 +; CHECK-SF2-NEXT: ld32.w l3, sp, 4 +; CHECK-SF2-NEXT: ld32.w l4, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ogt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ogt_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ogt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 24 +; CHECK-SOFT-NEXT: movi32 l4, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __gtdf2 +; CHECK-SOFT-NEXT: cmplt32 l4, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ogt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __gtdf2 +; CHECK-SF-NEXT: bhz32 a0, .LBB22_2 +; CHECK-SF-NEXT: br32 .LBB22_1 +; CHECK-SF-NEXT: .LBB22_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB22_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ogt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: bf32 .LBB22_2 +; CHECK-DF-NEXT: br32 .LBB22_1 +; CHECK-DF-NEXT: .LBB22_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB22_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ogt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, sp, 20 +; CHECK-SF2-NEXT: st32.w l0, sp, 16 +; CHECK-SF2-NEXT: st32.w l1, sp, 12 +; CHECK-SF2-NEXT: st32.w l2, sp, 8 +; CHECK-SF2-NEXT: st32.w l3, sp, 4 +; CHECK-SF2-NEXT: st32.w l4, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 24 +; CHECK-SF2-NEXT: ld32.w l3, sp, 24 +; CHECK-SF2-NEXT: movi32 l4, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __gtdf2 +; CHECK-SF2-NEXT: cmplt32 l4, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 20 +; CHECK-SF2-NEXT: ld32.w l0, sp, 16 +; CHECK-SF2-NEXT: ld32.w l1, sp, 12 +; CHECK-SF2-NEXT: ld32.w l2, sp, 8 +; CHECK-SF2-NEXT: ld32.w l3, sp, 4 +; CHECK-SF2-NEXT: ld32.w l4, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ogt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ogt double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ogt_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ogt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ogt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB23_2 +; CHECK-SF-NEXT: br32 .LBB23_1 +; CHECK-SF-NEXT: .LBB23_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB23_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ogt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB23_2 +; CHECK-DF-NEXT: br32 .LBB23_1 +; CHECK-DF-NEXT: .LBB23_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB23_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ogt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ogt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_oge_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_oge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __gesf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_oge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB24_2 +; CHECK-SF-NEXT: br32 .LBB24_1 +; CHECK-SF-NEXT: .LBB24_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB24_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_oge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB24_2 +; CHECK-DF-NEXT: br32 .LBB24_1 +; CHECK-DF-NEXT: .LBB24_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB24_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_oge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_oge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_oge_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_oge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __gesf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_oge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmphss vr0, vr3 +; CHECK-SF-NEXT: bt32 .LBB25_2 +; CHECK-SF-NEXT: br32 .LBB25_1 +; CHECK-SF-NEXT: .LBB25_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB25_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_oge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmphss vr0, vr3 +; CHECK-DF-NEXT: bt32 .LBB25_2 +; CHECK-DF-NEXT: br32 .LBB25_1 +; CHECK-DF-NEXT: .LBB25_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB25_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_oge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr3 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_oge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr3 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_oge_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_oge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __gesf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_oge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: bt32 .LBB26_2 +; CHECK-SF-NEXT: br32 .LBB26_1 +; CHECK-SF-NEXT: .LBB26_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB26_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_oge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: bt32 .LBB26_2 +; CHECK-DF-NEXT: br32 .LBB26_1 +; CHECK-DF-NEXT: .LBB26_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB26_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_oge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphsz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_oge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_oge_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_oge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_oge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB27_2 +; CHECK-SF-NEXT: br32 .LBB27_1 +; CHECK-SF-NEXT: .LBB27_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB27_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_oge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB27_2 +; CHECK-DF-NEXT: br32 .LBB27_1 +; CHECK-DF-NEXT: .LBB27_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB27_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_oge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_oge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_oge_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_oge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __gedf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_oge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __gedf2 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB28_2 +; CHECK-SF-NEXT: br32 .LBB28_1 +; CHECK-SF-NEXT: .LBB28_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB28_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_oge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB28_2 +; CHECK-DF-NEXT: br32 .LBB28_1 +; CHECK-DF-NEXT: .LBB28_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB28_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_oge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __gedf2 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_oge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_oge_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_oge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __gedf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_oge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __gedf2 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB29_2 +; CHECK-SF-NEXT: br32 .LBB29_1 +; CHECK-SF-NEXT: .LBB29_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB29_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_oge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmphsd vr0, vr3 +; CHECK-DF-NEXT: bt32 .LBB29_2 +; CHECK-DF-NEXT: br32 .LBB29_1 +; CHECK-DF-NEXT: .LBB29_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB29_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_oge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __gedf2 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_oge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_oge_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_oge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __gedf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_oge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __gedf2 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB30_2 +; CHECK-SF-NEXT: br32 .LBB30_1 +; CHECK-SF-NEXT: .LBB30_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB30_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_oge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: bt32 .LBB30_2 +; CHECK-DF-NEXT: br32 .LBB30_1 +; CHECK-DF-NEXT: .LBB30_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB30_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_oge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __gedf2 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_oge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp oge double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_oge_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_oge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_oge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB31_2 +; CHECK-SF-NEXT: br32 .LBB31_1 +; CHECK-SF-NEXT: .LBB31_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB31_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_oge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB31_2 +; CHECK-DF-NEXT: br32 .LBB31_1 +; CHECK-DF-NEXT: .LBB31_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB31_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_oge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_oge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_olt_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_olt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __ltsf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_olt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB32_2 +; CHECK-SF-NEXT: br32 .LBB32_1 +; CHECK-SF-NEXT: .LBB32_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB32_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_olt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB32_2 +; CHECK-DF-NEXT: br32 .LBB32_1 +; CHECK-DF-NEXT: .LBB32_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB32_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_olt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_olt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_olt_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_olt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __ltsf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_olt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmplts vr0, vr3 +; CHECK-SF-NEXT: bt32 .LBB33_2 +; CHECK-SF-NEXT: br32 .LBB33_1 +; CHECK-SF-NEXT: .LBB33_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB33_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_olt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmplts vr0, vr3 +; CHECK-DF-NEXT: bt32 .LBB33_2 +; CHECK-DF-NEXT: br32 .LBB33_1 +; CHECK-DF-NEXT: .LBB33_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB33_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_olt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr3 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_olt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr3 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_olt_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_olt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __ltsf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_olt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: bf32 .LBB34_2 +; CHECK-SF-NEXT: br32 .LBB34_1 +; CHECK-SF-NEXT: .LBB34_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB34_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_olt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: bf32 .LBB34_2 +; CHECK-DF-NEXT: br32 .LBB34_1 +; CHECK-DF-NEXT: .LBB34_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB34_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_olt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpltz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_olt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_olt_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_olt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_olt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB35_2 +; CHECK-SF-NEXT: br32 .LBB35_1 +; CHECK-SF-NEXT: .LBB35_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB35_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_olt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB35_2 +; CHECK-DF-NEXT: br32 .LBB35_1 +; CHECK-DF-NEXT: .LBB35_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB35_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_olt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_olt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_olt_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_olt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __ltdf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_olt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __ltdf2 +; CHECK-SF-NEXT: blz32 a0, .LBB36_2 +; CHECK-SF-NEXT: br32 .LBB36_1 +; CHECK-SF-NEXT: .LBB36_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB36_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_olt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB36_2 +; CHECK-DF-NEXT: br32 .LBB36_1 +; CHECK-DF-NEXT: .LBB36_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB36_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_olt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __ltdf2 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_olt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_olt_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_olt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __ltdf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_olt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __ltdf2 +; CHECK-SF-NEXT: blz32 a0, .LBB37_2 +; CHECK-SF-NEXT: br32 .LBB37_1 +; CHECK-SF-NEXT: .LBB37_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB37_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_olt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpltd vr0, vr3 +; CHECK-DF-NEXT: bt32 .LBB37_2 +; CHECK-DF-NEXT: br32 .LBB37_1 +; CHECK-DF-NEXT: .LBB37_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB37_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_olt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __ltdf2 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_olt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_olt_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_olt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __ltdf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_olt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __ltdf2 +; CHECK-SF-NEXT: blz32 a0, .LBB38_2 +; CHECK-SF-NEXT: br32 .LBB38_1 +; CHECK-SF-NEXT: .LBB38_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB38_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_olt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: bf32 .LBB38_2 +; CHECK-DF-NEXT: br32 .LBB38_1 +; CHECK-DF-NEXT: .LBB38_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB38_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_olt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __ltdf2 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_olt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp olt double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_olt_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_olt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_olt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB39_2 +; CHECK-SF-NEXT: br32 .LBB39_1 +; CHECK-SF-NEXT: .LBB39_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB39_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_olt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB39_2 +; CHECK-DF-NEXT: br32 .LBB39_1 +; CHECK-DF-NEXT: .LBB39_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB39_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_olt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_olt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_ole_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ole_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __lesf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ole_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: bt32 .LBB40_2 +; CHECK-SF-NEXT: br32 .LBB40_1 +; CHECK-SF-NEXT: .LBB40_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB40_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ole_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB40_2 +; CHECK-DF-NEXT: br32 .LBB40_1 +; CHECK-DF-NEXT: .LBB40_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB40_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ole_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ole_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ole_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ole_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __lesf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ole_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmphss vr3, vr0 +; CHECK-SF-NEXT: bt32 .LBB41_2 +; CHECK-SF-NEXT: br32 .LBB41_1 +; CHECK-SF-NEXT: .LBB41_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB41_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ole_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmphss vr3, vr0 +; CHECK-DF-NEXT: bt32 .LBB41_2 +; CHECK-DF-NEXT: br32 .LBB41_1 +; CHECK-DF-NEXT: .LBB41_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB41_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ole_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr3, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ole_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr3, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ole_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ole_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __lesf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ole_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: bt32 .LBB42_2 +; CHECK-SF-NEXT: br32 .LBB42_1 +; CHECK-SF-NEXT: .LBB42_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB42_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ole_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: bt32 .LBB42_2 +; CHECK-DF-NEXT: br32 .LBB42_1 +; CHECK-DF-NEXT: .LBB42_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB42_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ole_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplsz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ole_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ole_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ole_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ole_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB43_2 +; CHECK-SF-NEXT: br32 .LBB43_1 +; CHECK-SF-NEXT: .LBB43_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB43_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ole_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB43_2 +; CHECK-DF-NEXT: br32 .LBB43_1 +; CHECK-DF-NEXT: .LBB43_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB43_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ole_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ole_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ole_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ole_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __ledf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ole_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __ledf2 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB44_2 +; CHECK-SF-NEXT: br32 .LBB44_1 +; CHECK-SF-NEXT: .LBB44_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB44_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ole_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: bt32 .LBB44_2 +; CHECK-DF-NEXT: br32 .LBB44_1 +; CHECK-DF-NEXT: .LBB44_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB44_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ole_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __ledf2 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ole_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ole_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ole_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __ledf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ole_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __ledf2 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB45_2 +; CHECK-SF-NEXT: br32 .LBB45_1 +; CHECK-SF-NEXT: .LBB45_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB45_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ole_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmphsd vr3, vr0 +; CHECK-DF-NEXT: bt32 .LBB45_2 +; CHECK-DF-NEXT: br32 .LBB45_1 +; CHECK-DF-NEXT: .LBB45_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB45_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ole_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __ledf2 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ole_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ole_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ole_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __ledf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ole_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __ledf2 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB46_2 +; CHECK-SF-NEXT: br32 .LBB46_1 +; CHECK-SF-NEXT: .LBB46_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB46_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ole_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: bt32 .LBB46_2 +; CHECK-DF-NEXT: br32 .LBB46_1 +; CHECK-DF-NEXT: .LBB46_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB46_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ole_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __ledf2 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ole_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ole double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ole_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ole_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ole_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB47_2 +; CHECK-SF-NEXT: br32 .LBB47_1 +; CHECK-SF-NEXT: .LBB47_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB47_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ole_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB47_2 +; CHECK-DF-NEXT: br32 .LBB47_1 +; CHECK-DF-NEXT: .LBB47_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB47_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ole_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ole_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_one_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_one_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, l3 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: mov32 a1, l3 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l4 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_one_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: and32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB48_2 +; CHECK-SF-NEXT: br32 .LBB48_1 +; CHECK-SF-NEXT: .LBB48_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB48_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_one_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB48_2 +; CHECK-DF-NEXT: br32 .LBB48_1 +; CHECK-DF-NEXT: .LBB48_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB48_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_one_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: and32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_one_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_one_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_one_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 l2, a0 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l3 +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l3 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_one_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr3 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: and32 a0, a0, a1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB49_2 +; CHECK-SF-NEXT: br32 .LBB49_1 +; CHECK-SF-NEXT: .LBB49_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB49_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_one_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr3 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: and32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB49_2 +; CHECK-DF-NEXT: br32 .LBB49_1 +; CHECK-DF-NEXT: .LBB49_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB49_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_one_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: and32 a0, a0, a1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_one_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: and32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_one_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_one_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 l2, a0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l3 +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l3 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_one_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: and32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB50_2 +; CHECK-SF-NEXT: br32 .LBB50_1 +; CHECK-SF-NEXT: .LBB50_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB50_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_one_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB50_2 +; CHECK-DF-NEXT: br32 .LBB50_1 +; CHECK-DF-NEXT: .LBB50_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB50_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_one_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: and32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_one_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_one_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_one_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_one_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB51_2 +; CHECK-SF-NEXT: br32 .LBB51_1 +; CHECK-SF-NEXT: .LBB51_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB51_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_one_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB51_2 +; CHECK-DF-NEXT: br32 .LBB51_1 +; CHECK-DF-NEXT: .LBB51_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB51_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_one_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_one_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_one_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_one_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l4 +; CHECK-SOFT-NEXT: addi32 a1, sp, 24 +; CHECK-SOFT-NEXT: addi32 a2, sp, 32 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_one_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 32 +; CHECK-SF-NEXT: st32.w lr, sp, 28 +; CHECK-SF-NEXT: st32.w l0, sp, 24 +; CHECK-SF-NEXT: st32.w l1, sp, 20 +; CHECK-SF-NEXT: st32.w l2, sp, 16 +; CHECK-SF-NEXT: st32.w l3, sp, 12 +; CHECK-SF-NEXT: st32.w l4, sp, 8 +; CHECK-SF-NEXT: st32.w l5, sp, 4 +; CHECK-SF-NEXT: st32.w l6, sp, 0 +; CHECK-SF-NEXT: mov32 l2, a3 +; CHECK-SF-NEXT: mov32 l3, a2 +; CHECK-SF-NEXT: mov32 l4, a1 +; CHECK-SF-NEXT: mov32 l5, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 44 +; CHECK-SF-NEXT: ld32.w l1, sp, 40 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, l5 +; CHECK-SF-NEXT: mov32 a3, l4 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l6 +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: mov32 a2, l5 +; CHECK-SF-NEXT: mov32 a3, l4 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l6 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB52_2 +; CHECK-SF-NEXT: br32 .LBB52_1 +; CHECK-SF-NEXT: .LBB52_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 36 +; CHECK-SF-NEXT: ld32.w l1, sp, 32 +; CHECK-SF-NEXT: .LBB52_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 28 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: ld32.w l2, sp, 16 +; CHECK-SF-NEXT: ld32.w l3, sp, 12 +; CHECK-SF-NEXT: ld32.w l4, sp, 8 +; CHECK-SF-NEXT: ld32.w l5, sp, 4 +; CHECK-SF-NEXT: ld32.w l6, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 32 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_one_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB52_2 +; CHECK-DF-NEXT: br32 .LBB52_1 +; CHECK-DF-NEXT: .LBB52_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB52_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_one_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, sp, 20 +; CHECK-SF2-NEXT: st32.w l0, sp, 16 +; CHECK-SF2-NEXT: st32.w l1, sp, 12 +; CHECK-SF2-NEXT: st32.w l2, sp, 8 +; CHECK-SF2-NEXT: st32.w l3, sp, 4 +; CHECK-SF2-NEXT: st32.w l4, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l4 +; CHECK-SF2-NEXT: addi32 a1, sp, 24 +; CHECK-SF2-NEXT: addi32 a2, sp, 32 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a2 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 20 +; CHECK-SF2-NEXT: ld32.w l0, sp, 16 +; CHECK-SF2-NEXT: ld32.w l1, sp, 12 +; CHECK-SF2-NEXT: ld32.w l2, sp, 8 +; CHECK-SF2-NEXT: ld32.w l3, sp, 4 +; CHECK-SF2-NEXT: ld32.w l4, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_one_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_one_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_one_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 32 +; CHECK-SOFT-NEXT: st32.w lr, sp, 28 +; CHECK-SOFT-NEXT: st32.w l0, sp, 24 +; CHECK-SOFT-NEXT: st32.w l1, sp, 20 +; CHECK-SOFT-NEXT: st32.w l2, sp, 16 +; CHECK-SOFT-NEXT: st32.w l3, sp, 12 +; CHECK-SOFT-NEXT: st32.w l4, sp, 8 +; CHECK-SOFT-NEXT: st32.w l5, sp, 4 +; CHECK-SOFT-NEXT: st32.w l6, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 32 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 32 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l6 +; CHECK-SOFT-NEXT: mov32 a0, l3 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l6 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l5 +; CHECK-SOFT-NEXT: movt32 l0, l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 28 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l6, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 32 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_one_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 32 +; CHECK-SF-NEXT: st32.w lr, sp, 28 +; CHECK-SF-NEXT: st32.w l0, sp, 24 +; CHECK-SF-NEXT: st32.w l1, sp, 20 +; CHECK-SF-NEXT: st32.w l2, sp, 16 +; CHECK-SF-NEXT: st32.w l3, sp, 12 +; CHECK-SF-NEXT: st32.w l4, sp, 8 +; CHECK-SF-NEXT: st32.w l5, sp, 4 +; CHECK-SF-NEXT: st32.w l6, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l4, a1 +; CHECK-SF-NEXT: mov32 l5, a0 +; CHECK-SF-NEXT: ld32.w l2, sp, 36 +; CHECK-SF-NEXT: ld32.w l3, sp, 32 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l6 +; CHECK-SF-NEXT: mov32 a0, l5 +; CHECK-SF-NEXT: mov32 a1, l4 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l6 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB53_2 +; CHECK-SF-NEXT: br32 .LBB53_1 +; CHECK-SF-NEXT: .LBB53_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB53_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 28 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: ld32.w l2, sp, 16 +; CHECK-SF-NEXT: ld32.w l3, sp, 12 +; CHECK-SF-NEXT: ld32.w l4, sp, 8 +; CHECK-SF-NEXT: ld32.w l5, sp, 4 +; CHECK-SF-NEXT: ld32.w l6, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 32 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_one_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr3 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: and32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB53_2 +; CHECK-DF-NEXT: br32 .LBB53_1 +; CHECK-DF-NEXT: .LBB53_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB53_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_one_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 32 +; CHECK-SF2-NEXT: st32.w lr, sp, 28 +; CHECK-SF2-NEXT: st32.w l0, sp, 24 +; CHECK-SF2-NEXT: st32.w l1, sp, 20 +; CHECK-SF2-NEXT: st32.w l2, sp, 16 +; CHECK-SF2-NEXT: st32.w l3, sp, 12 +; CHECK-SF2-NEXT: st32.w l4, sp, 8 +; CHECK-SF2-NEXT: st32.w l5, sp, 4 +; CHECK-SF2-NEXT: st32.w l6, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: ld32.w l4, sp, 32 +; CHECK-SF2-NEXT: ld32.w l5, sp, 32 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l6 +; CHECK-SF2-NEXT: mov32 a0, l3 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l6 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l5 +; CHECK-SF2-NEXT: movt32 l0, l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 28 +; CHECK-SF2-NEXT: ld32.w l0, sp, 24 +; CHECK-SF2-NEXT: ld32.w l1, sp, 20 +; CHECK-SF2-NEXT: ld32.w l2, sp, 16 +; CHECK-SF2-NEXT: ld32.w l3, sp, 12 +; CHECK-SF2-NEXT: ld32.w l4, sp, 8 +; CHECK-SF2-NEXT: ld32.w l5, sp, 4 +; CHECK-SF2-NEXT: ld32.w l6, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 32 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_one_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr3 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: and32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_one_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_one_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 32 +; CHECK-SOFT-NEXT: st32.w lr, sp, 28 +; CHECK-SOFT-NEXT: st32.w l0, sp, 24 +; CHECK-SOFT-NEXT: st32.w l1, sp, 20 +; CHECK-SOFT-NEXT: st32.w l2, sp, 16 +; CHECK-SOFT-NEXT: st32.w l3, sp, 12 +; CHECK-SOFT-NEXT: st32.w l4, sp, 8 +; CHECK-SOFT-NEXT: st32.w l5, sp, 4 +; CHECK-SOFT-NEXT: st32.w l6, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 32 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 32 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 l6 +; CHECK-SOFT-NEXT: mov32 a0, l3 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 a0 +; CHECK-SOFT-NEXT: and32 a0, a0, l6 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l5 +; CHECK-SOFT-NEXT: movt32 l0, l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 28 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l6, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 32 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_one_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 32 +; CHECK-SF-NEXT: st32.w lr, sp, 28 +; CHECK-SF-NEXT: st32.w l0, sp, 24 +; CHECK-SF-NEXT: st32.w l1, sp, 20 +; CHECK-SF-NEXT: st32.w l2, sp, 16 +; CHECK-SF-NEXT: st32.w l3, sp, 12 +; CHECK-SF-NEXT: st32.w l4, sp, 8 +; CHECK-SF-NEXT: st32.w l5, sp, 4 +; CHECK-SF-NEXT: st32.w l6, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l4, a1 +; CHECK-SF-NEXT: mov32 l5, a0 +; CHECK-SF-NEXT: ld32.w l2, sp, 36 +; CHECK-SF-NEXT: ld32.w l3, sp, 32 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 l6 +; CHECK-SF-NEXT: mov32 a0, l5 +; CHECK-SF-NEXT: mov32 a1, l4 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: and32 a0, a0, l6 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB54_2 +; CHECK-SF-NEXT: br32 .LBB54_1 +; CHECK-SF-NEXT: .LBB54_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB54_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 28 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: ld32.w l2, sp, 16 +; CHECK-SF-NEXT: ld32.w l3, sp, 12 +; CHECK-SF-NEXT: ld32.w l4, sp, 8 +; CHECK-SF-NEXT: ld32.w l5, sp, 4 +; CHECK-SF-NEXT: ld32.w l6, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 32 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_one_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: and32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB54_2 +; CHECK-DF-NEXT: br32 .LBB54_1 +; CHECK-DF-NEXT: .LBB54_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB54_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_one_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 32 +; CHECK-SF2-NEXT: st32.w lr, sp, 28 +; CHECK-SF2-NEXT: st32.w l0, sp, 24 +; CHECK-SF2-NEXT: st32.w l1, sp, 20 +; CHECK-SF2-NEXT: st32.w l2, sp, 16 +; CHECK-SF2-NEXT: st32.w l3, sp, 12 +; CHECK-SF2-NEXT: st32.w l4, sp, 8 +; CHECK-SF2-NEXT: st32.w l5, sp, 4 +; CHECK-SF2-NEXT: st32.w l6, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: ld32.w l4, sp, 32 +; CHECK-SF2-NEXT: ld32.w l5, sp, 32 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 l6 +; CHECK-SF2-NEXT: mov32 a0, l3 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: and32 a0, a0, l6 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l5 +; CHECK-SF2-NEXT: movt32 l0, l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 28 +; CHECK-SF2-NEXT: ld32.w l0, sp, 24 +; CHECK-SF2-NEXT: ld32.w l1, sp, 20 +; CHECK-SF2-NEXT: ld32.w l2, sp, 16 +; CHECK-SF2-NEXT: ld32.w l3, sp, 12 +; CHECK-SF2-NEXT: ld32.w l4, sp, 8 +; CHECK-SF2-NEXT: ld32.w l5, sp, 4 +; CHECK-SF2-NEXT: ld32.w l6, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 32 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_one_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: and32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp one double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_one_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_one_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_one_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB55_2 +; CHECK-SF-NEXT: br32 .LBB55_1 +; CHECK-SF-NEXT: .LBB55_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB55_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_one_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB55_2 +; CHECK-DF-NEXT: br32 .LBB55_1 +; CHECK-DF-NEXT: .LBB55_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB55_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_one_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_one_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_ord_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ord_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ord_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: bf32 .LBB56_2 +; CHECK-SF-NEXT: br32 .LBB56_1 +; CHECK-SF-NEXT: .LBB56_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB56_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ord_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: bf32 .LBB56_2 +; CHECK-DF-NEXT: br32 .LBB56_1 +; CHECK-DF-NEXT: .LBB56_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB56_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ord_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ord_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ord_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ord_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ord_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bf32 .LBB57_2 +; CHECK-SF-NEXT: br32 .LBB57_1 +; CHECK-SF-NEXT: .LBB57_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB57_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ord_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bf32 .LBB57_2 +; CHECK-DF-NEXT: br32 .LBB57_1 +; CHECK-DF-NEXT: .LBB57_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB57_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ord_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ord_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ord_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ord_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ord_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bf32 .LBB58_2 +; CHECK-SF-NEXT: br32 .LBB58_1 +; CHECK-SF-NEXT: .LBB58_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB58_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ord_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bf32 .LBB58_2 +; CHECK-DF-NEXT: br32 .LBB58_1 +; CHECK-DF-NEXT: .LBB58_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB58_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ord_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ord_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ord_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ord_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ord_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB59_2 +; CHECK-SF-NEXT: br32 .LBB59_1 +; CHECK-SF-NEXT: .LBB59_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB59_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ord_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB59_2 +; CHECK-DF-NEXT: br32 .LBB59_1 +; CHECK-DF-NEXT: .LBB59_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB59_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ord_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ord_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ord_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ord_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movf32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ord_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: bez32 a0, .LBB60_2 +; CHECK-SF-NEXT: br32 .LBB60_1 +; CHECK-SF-NEXT: .LBB60_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB60_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ord_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: bf32 .LBB60_2 +; CHECK-DF-NEXT: br32 .LBB60_1 +; CHECK-DF-NEXT: .LBB60_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB60_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ord_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movf32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ord_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ord_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ord_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l3 +; CHECK-SOFT-NEXT: movf32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ord_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: bez32 a0, .LBB61_2 +; CHECK-SF-NEXT: br32 .LBB61_1 +; CHECK-SF-NEXT: .LBB61_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB61_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ord_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bf32 .LBB61_2 +; CHECK-DF-NEXT: br32 .LBB61_1 +; CHECK-DF-NEXT: .LBB61_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB61_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ord_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movf32 l1, l3 +; CHECK-SF2-NEXT: movf32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ord_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ord_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ord_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movf32 l1, l3 +; CHECK-SOFT-NEXT: movf32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ord_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: bez32 a0, .LBB62_2 +; CHECK-SF-NEXT: br32 .LBB62_1 +; CHECK-SF-NEXT: .LBB62_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB62_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ord_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bf32 .LBB62_2 +; CHECK-DF-NEXT: br32 .LBB62_1 +; CHECK-DF-NEXT: .LBB62_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB62_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ord_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movf32 l1, l3 +; CHECK-SF2-NEXT: movf32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ord_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ord double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ord_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ord_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ord_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB63_2 +; CHECK-SF-NEXT: br32 .LBB63_1 +; CHECK-SF-NEXT: .LBB63_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB63_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ord_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB63_2 +; CHECK-DF-NEXT: br32 .LBB63_1 +; CHECK-DF-NEXT: .LBB63_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB63_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ord_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ord_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_ueq_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ueq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, l3 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: mov32 a1, l3 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l4 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ueq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: or32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB64_2 +; CHECK-SF-NEXT: br32 .LBB64_1 +; CHECK-SF-NEXT: .LBB64_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB64_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ueq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB64_2 +; CHECK-DF-NEXT: br32 .LBB64_1 +; CHECK-DF-NEXT: .LBB64_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB64_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ueq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: or32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ueq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ueq_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ueq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 l2, a0 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l3 +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l3 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ueq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr3 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a1 +; CHECK-SF-NEXT: or32 a0, a0, a1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB65_2 +; CHECK-SF-NEXT: br32 .LBB65_1 +; CHECK-SF-NEXT: .LBB65_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB65_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ueq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr3 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: or32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB65_2 +; CHECK-DF-NEXT: br32 .LBB65_1 +; CHECK-DF-NEXT: .LBB65_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB65_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ueq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-SF2-NEXT: mvcv32 a0 +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a1 +; CHECK-SF2-NEXT: or32 a0, a0, a1 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ueq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: or32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ueq_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ueq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 l2, a0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __eqsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l3 +; CHECK-SOFT-NEXT: mov32 a0, l2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l3 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ueq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: mvcv32 a1 +; CHECK-SF-NEXT: or32 a0, a1, a0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB66_2 +; CHECK-SF-NEXT: br32 .LBB66_1 +; CHECK-SF-NEXT: .LBB66_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB66_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ueq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB66_2 +; CHECK-DF-NEXT: br32 .LBB66_1 +; CHECK-DF-NEXT: .LBB66_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB66_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ueq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: mvcv32 a1 +; CHECK-SF2-NEXT: or32 a0, a1, a0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ueq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ueq_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ueq_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ueq_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB67_2 +; CHECK-SF-NEXT: br32 .LBB67_1 +; CHECK-SF-NEXT: .LBB67_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB67_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ueq_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB67_2 +; CHECK-DF-NEXT: br32 .LBB67_1 +; CHECK-DF-NEXT: .LBB67_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB67_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ueq_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ueq_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ueq_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ueq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: mov32 a2, l3 +; CHECK-SOFT-NEXT: mov32 a3, l2 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l4 +; CHECK-SOFT-NEXT: addi32 a1, sp, 24 +; CHECK-SOFT-NEXT: addi32 a2, sp, 32 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ueq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 32 +; CHECK-SF-NEXT: st32.w lr, sp, 28 +; CHECK-SF-NEXT: st32.w l0, sp, 24 +; CHECK-SF-NEXT: st32.w l1, sp, 20 +; CHECK-SF-NEXT: st32.w l2, sp, 16 +; CHECK-SF-NEXT: st32.w l3, sp, 12 +; CHECK-SF-NEXT: st32.w l4, sp, 8 +; CHECK-SF-NEXT: st32.w l5, sp, 4 +; CHECK-SF-NEXT: st32.w l6, sp, 0 +; CHECK-SF-NEXT: mov32 l2, a3 +; CHECK-SF-NEXT: mov32 l3, a2 +; CHECK-SF-NEXT: mov32 l4, a1 +; CHECK-SF-NEXT: mov32 l5, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 44 +; CHECK-SF-NEXT: ld32.w l1, sp, 40 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, l5 +; CHECK-SF-NEXT: mov32 a3, l4 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l6 +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: mov32 a2, l5 +; CHECK-SF-NEXT: mov32 a3, l4 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l6 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB68_2 +; CHECK-SF-NEXT: br32 .LBB68_1 +; CHECK-SF-NEXT: .LBB68_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 36 +; CHECK-SF-NEXT: ld32.w l1, sp, 32 +; CHECK-SF-NEXT: .LBB68_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 28 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: ld32.w l2, sp, 16 +; CHECK-SF-NEXT: ld32.w l3, sp, 12 +; CHECK-SF-NEXT: ld32.w l4, sp, 8 +; CHECK-SF-NEXT: ld32.w l5, sp, 4 +; CHECK-SF-NEXT: ld32.w l6, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 32 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ueq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB68_2 +; CHECK-DF-NEXT: br32 .LBB68_1 +; CHECK-DF-NEXT: .LBB68_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB68_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ueq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, sp, 20 +; CHECK-SF2-NEXT: st32.w l0, sp, 16 +; CHECK-SF2-NEXT: st32.w l1, sp, 12 +; CHECK-SF2-NEXT: st32.w l2, sp, 8 +; CHECK-SF2-NEXT: st32.w l3, sp, 4 +; CHECK-SF2-NEXT: st32.w l4, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: mov32 a2, l3 +; CHECK-SF2-NEXT: mov32 a3, l2 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l4 +; CHECK-SF2-NEXT: addi32 a1, sp, 24 +; CHECK-SF2-NEXT: addi32 a2, sp, 32 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a2 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 20 +; CHECK-SF2-NEXT: ld32.w l0, sp, 16 +; CHECK-SF2-NEXT: ld32.w l1, sp, 12 +; CHECK-SF2-NEXT: ld32.w l2, sp, 8 +; CHECK-SF2-NEXT: ld32.w l3, sp, 4 +; CHECK-SF2-NEXT: ld32.w l4, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ueq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ueq_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ueq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 32 +; CHECK-SOFT-NEXT: st32.w lr, sp, 28 +; CHECK-SOFT-NEXT: st32.w l0, sp, 24 +; CHECK-SOFT-NEXT: st32.w l1, sp, 20 +; CHECK-SOFT-NEXT: st32.w l2, sp, 16 +; CHECK-SOFT-NEXT: st32.w l3, sp, 12 +; CHECK-SOFT-NEXT: st32.w l4, sp, 8 +; CHECK-SOFT-NEXT: st32.w l5, sp, 4 +; CHECK-SOFT-NEXT: st32.w l6, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 32 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 32 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l6 +; CHECK-SOFT-NEXT: mov32 a0, l3 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l6 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l5 +; CHECK-SOFT-NEXT: movt32 l0, l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 28 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l6, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 32 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ueq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 32 +; CHECK-SF-NEXT: st32.w lr, sp, 28 +; CHECK-SF-NEXT: st32.w l0, sp, 24 +; CHECK-SF-NEXT: st32.w l1, sp, 20 +; CHECK-SF-NEXT: st32.w l2, sp, 16 +; CHECK-SF-NEXT: st32.w l3, sp, 12 +; CHECK-SF-NEXT: st32.w l4, sp, 8 +; CHECK-SF-NEXT: st32.w l5, sp, 4 +; CHECK-SF-NEXT: st32.w l6, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l4, a1 +; CHECK-SF-NEXT: mov32 l5, a0 +; CHECK-SF-NEXT: ld32.w l2, sp, 36 +; CHECK-SF-NEXT: ld32.w l3, sp, 32 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l6 +; CHECK-SF-NEXT: mov32 a0, l5 +; CHECK-SF-NEXT: mov32 a1, l4 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l6 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB69_2 +; CHECK-SF-NEXT: br32 .LBB69_1 +; CHECK-SF-NEXT: .LBB69_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB69_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 28 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: ld32.w l2, sp, 16 +; CHECK-SF-NEXT: ld32.w l3, sp, 12 +; CHECK-SF-NEXT: ld32.w l4, sp, 8 +; CHECK-SF-NEXT: ld32.w l5, sp, 4 +; CHECK-SF-NEXT: ld32.w l6, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 32 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ueq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr3 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvc32 a1 +; CHECK-DF-NEXT: or32 a0, a0, a1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB69_2 +; CHECK-DF-NEXT: br32 .LBB69_1 +; CHECK-DF-NEXT: .LBB69_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB69_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ueq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 32 +; CHECK-SF2-NEXT: st32.w lr, sp, 28 +; CHECK-SF2-NEXT: st32.w l0, sp, 24 +; CHECK-SF2-NEXT: st32.w l1, sp, 20 +; CHECK-SF2-NEXT: st32.w l2, sp, 16 +; CHECK-SF2-NEXT: st32.w l3, sp, 12 +; CHECK-SF2-NEXT: st32.w l4, sp, 8 +; CHECK-SF2-NEXT: st32.w l5, sp, 4 +; CHECK-SF2-NEXT: st32.w l6, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: ld32.w l4, sp, 32 +; CHECK-SF2-NEXT: ld32.w l5, sp, 32 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l6 +; CHECK-SF2-NEXT: mov32 a0, l3 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l6 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l5 +; CHECK-SF2-NEXT: movt32 l0, l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 28 +; CHECK-SF2-NEXT: ld32.w l0, sp, 24 +; CHECK-SF2-NEXT: ld32.w l1, sp, 20 +; CHECK-SF2-NEXT: ld32.w l2, sp, 16 +; CHECK-SF2-NEXT: ld32.w l3, sp, 12 +; CHECK-SF2-NEXT: ld32.w l4, sp, 8 +; CHECK-SF2-NEXT: ld32.w l5, sp, 4 +; CHECK-SF2-NEXT: ld32.w l6, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 32 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ueq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr3 +; CHECK-DF2-NEXT: mvcv32 a0 +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a1 +; CHECK-DF2-NEXT: or32 a0, a0, a1 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ueq_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ueq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 32 +; CHECK-SOFT-NEXT: st32.w lr, sp, 28 +; CHECK-SOFT-NEXT: st32.w l0, sp, 24 +; CHECK-SOFT-NEXT: st32.w l1, sp, 20 +; CHECK-SOFT-NEXT: st32.w l2, sp, 16 +; CHECK-SOFT-NEXT: st32.w l3, sp, 12 +; CHECK-SOFT-NEXT: st32.w l4, sp, 8 +; CHECK-SOFT-NEXT: st32.w l5, sp, 4 +; CHECK-SOFT-NEXT: st32.w l6, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 l2, a1 +; CHECK-SOFT-NEXT: mov32 l3, a0 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 32 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 32 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __eqdf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvcv32 l6 +; CHECK-SOFT-NEXT: mov32 a0, l3 +; CHECK-SOFT-NEXT: mov32 a1, l2 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: mvc32 a0 +; CHECK-SOFT-NEXT: or32 a0, a0, l6 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l5 +; CHECK-SOFT-NEXT: movt32 l0, l4 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 28 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l5, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l6, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 32 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ueq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 32 +; CHECK-SF-NEXT: st32.w lr, sp, 28 +; CHECK-SF-NEXT: st32.w l0, sp, 24 +; CHECK-SF-NEXT: st32.w l1, sp, 20 +; CHECK-SF-NEXT: st32.w l2, sp, 16 +; CHECK-SF-NEXT: st32.w l3, sp, 12 +; CHECK-SF-NEXT: st32.w l4, sp, 8 +; CHECK-SF-NEXT: st32.w l5, sp, 4 +; CHECK-SF-NEXT: st32.w l6, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: mov32 l4, a1 +; CHECK-SF-NEXT: mov32 l5, a0 +; CHECK-SF-NEXT: ld32.w l2, sp, 36 +; CHECK-SF-NEXT: ld32.w l3, sp, 32 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __eqdf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvcv32 l6 +; CHECK-SF-NEXT: mov32 a0, l5 +; CHECK-SF-NEXT: mov32 a1, l4 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: cmpnei32 a0, 0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: or32 a0, a0, l6 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB70_2 +; CHECK-SF-NEXT: br32 .LBB70_1 +; CHECK-SF-NEXT: .LBB70_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB70_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 28 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: ld32.w l2, sp, 16 +; CHECK-SF-NEXT: ld32.w l3, sp, 12 +; CHECK-SF-NEXT: ld32.w l4, sp, 8 +; CHECK-SF-NEXT: ld32.w l5, sp, 4 +; CHECK-SF-NEXT: ld32.w l6, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 32 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ueq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzuod vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: mvcv32 a1 +; CHECK-DF-NEXT: or32 a0, a1, a0 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB70_2 +; CHECK-DF-NEXT: br32 .LBB70_1 +; CHECK-DF-NEXT: .LBB70_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB70_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ueq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 32 +; CHECK-SF2-NEXT: st32.w lr, sp, 28 +; CHECK-SF2-NEXT: st32.w l0, sp, 24 +; CHECK-SF2-NEXT: st32.w l1, sp, 20 +; CHECK-SF2-NEXT: st32.w l2, sp, 16 +; CHECK-SF2-NEXT: st32.w l3, sp, 12 +; CHECK-SF2-NEXT: st32.w l4, sp, 8 +; CHECK-SF2-NEXT: st32.w l5, sp, 4 +; CHECK-SF2-NEXT: st32.w l6, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: mov32 l2, a1 +; CHECK-SF2-NEXT: mov32 l3, a0 +; CHECK-SF2-NEXT: ld32.w l4, sp, 32 +; CHECK-SF2-NEXT: ld32.w l5, sp, 32 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __eqdf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvcv32 l6 +; CHECK-SF2-NEXT: mov32 a0, l3 +; CHECK-SF2-NEXT: mov32 a1, l2 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: mvc32 a0 +; CHECK-SF2-NEXT: or32 a0, a0, l6 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l5 +; CHECK-SF2-NEXT: movt32 l0, l4 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 28 +; CHECK-SF2-NEXT: ld32.w l0, sp, 24 +; CHECK-SF2-NEXT: ld32.w l1, sp, 20 +; CHECK-SF2-NEXT: ld32.w l2, sp, 16 +; CHECK-SF2-NEXT: ld32.w l3, sp, 12 +; CHECK-SF2-NEXT: ld32.w l4, sp, 8 +; CHECK-SF2-NEXT: ld32.w l5, sp, 4 +; CHECK-SF2-NEXT: ld32.w l6, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 32 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ueq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuoz.64 vr0 +; CHECK-DF2-NEXT: mvc32 a0 +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: mvcv32 a1 +; CHECK-DF2-NEXT: or32 a0, a1, a0 +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ueq double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ueq_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ueq_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ueq_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB71_2 +; CHECK-SF-NEXT: br32 .LBB71_1 +; CHECK-SF-NEXT: .LBB71_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB71_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ueq_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB71_2 +; CHECK-DF-NEXT: br32 .LBB71_1 +; CHECK-DF-NEXT: .LBB71_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB71_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ueq_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ueq_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_ugt_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ugt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __lesf2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ugt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB72_2 +; CHECK-SF-NEXT: br32 .LBB72_1 +; CHECK-SF-NEXT: .LBB72_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB72_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ugt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB72_2 +; CHECK-DF-NEXT: br32 .LBB72_1 +; CHECK-DF-NEXT: .LBB72_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB72_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ugt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ugt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr1 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ugt_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ugt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __lesf2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ugt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmphss vr3, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB73_2 +; CHECK-SF-NEXT: br32 .LBB73_1 +; CHECK-SF-NEXT: .LBB73_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB73_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ugt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmphss vr3, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB73_2 +; CHECK-DF-NEXT: br32 .LBB73_1 +; CHECK-DF-NEXT: .LBB73_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB73_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ugt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr3, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ugt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr3, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ugt_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ugt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 16 +; CHECK-SOFT-NEXT: st32.w lr, sp, 12 +; CHECK-SOFT-NEXT: st32.w l0, sp, 8 +; CHECK-SOFT-NEXT: st32.w l1, sp, 4 +; CHECK-SOFT-NEXT: st32.w l2, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 l2, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __lesf2 +; CHECK-SOFT-NEXT: cmplt32 l2, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 16 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ugt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB74_2 +; CHECK-SF-NEXT: br32 .LBB74_1 +; CHECK-SF-NEXT: .LBB74_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB74_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ugt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB74_2 +; CHECK-DF-NEXT: br32 .LBB74_1 +; CHECK-DF-NEXT: .LBB74_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB74_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ugt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplsz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ugt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ugt_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ugt_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ugt_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB75_2 +; CHECK-SF-NEXT: br32 .LBB75_1 +; CHECK-SF-NEXT: .LBB75_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB75_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ugt_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB75_2 +; CHECK-DF-NEXT: br32 .LBB75_1 +; CHECK-DF-NEXT: .LBB75_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB75_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ugt_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ugt_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ugt_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ugt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __ledf2 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ugt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __ledf2 +; CHECK-SF-NEXT: bhz32 a0, .LBB76_2 +; CHECK-SF-NEXT: br32 .LBB76_1 +; CHECK-SF-NEXT: .LBB76_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB76_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ugt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB76_2 +; CHECK-DF-NEXT: br32 .LBB76_1 +; CHECK-DF-NEXT: .LBB76_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB76_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ugt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __ledf2 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ugt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ugt_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ugt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 24 +; CHECK-SOFT-NEXT: movi32 l4, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __ledf2 +; CHECK-SOFT-NEXT: cmplt32 l4, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ugt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __ledf2 +; CHECK-SF-NEXT: bhz32 a0, .LBB77_2 +; CHECK-SF-NEXT: br32 .LBB77_1 +; CHECK-SF-NEXT: .LBB77_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB77_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ugt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmphsd vr3, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB77_2 +; CHECK-DF-NEXT: br32 .LBB77_1 +; CHECK-DF-NEXT: .LBB77_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB77_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ugt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, sp, 20 +; CHECK-SF2-NEXT: st32.w l0, sp, 16 +; CHECK-SF2-NEXT: st32.w l1, sp, 12 +; CHECK-SF2-NEXT: st32.w l2, sp, 8 +; CHECK-SF2-NEXT: st32.w l3, sp, 4 +; CHECK-SF2-NEXT: st32.w l4, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 24 +; CHECK-SF2-NEXT: ld32.w l3, sp, 24 +; CHECK-SF2-NEXT: movi32 l4, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __ledf2 +; CHECK-SF2-NEXT: cmplt32 l4, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 20 +; CHECK-SF2-NEXT: ld32.w l0, sp, 16 +; CHECK-SF2-NEXT: ld32.w l1, sp, 12 +; CHECK-SF2-NEXT: ld32.w l2, sp, 8 +; CHECK-SF2-NEXT: ld32.w l3, sp, 4 +; CHECK-SF2-NEXT: ld32.w l4, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ugt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ugt_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ugt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 24 +; CHECK-SOFT-NEXT: st32.w lr, sp, 20 +; CHECK-SOFT-NEXT: st32.w l0, sp, 16 +; CHECK-SOFT-NEXT: st32.w l1, sp, 12 +; CHECK-SOFT-NEXT: st32.w l2, sp, 8 +; CHECK-SOFT-NEXT: st32.w l3, sp, 4 +; CHECK-SOFT-NEXT: st32.w l4, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 24 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 24 +; CHECK-SOFT-NEXT: movi32 l4, 0 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __ledf2 +; CHECK-SOFT-NEXT: cmplt32 l4, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l4, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 24 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ugt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __ledf2 +; CHECK-SF-NEXT: bhz32 a0, .LBB78_2 +; CHECK-SF-NEXT: br32 .LBB78_1 +; CHECK-SF-NEXT: .LBB78_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB78_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ugt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB78_2 +; CHECK-DF-NEXT: br32 .LBB78_1 +; CHECK-DF-NEXT: .LBB78_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB78_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ugt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 24 +; CHECK-SF2-NEXT: st32.w lr, sp, 20 +; CHECK-SF2-NEXT: st32.w l0, sp, 16 +; CHECK-SF2-NEXT: st32.w l1, sp, 12 +; CHECK-SF2-NEXT: st32.w l2, sp, 8 +; CHECK-SF2-NEXT: st32.w l3, sp, 4 +; CHECK-SF2-NEXT: st32.w l4, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 24 +; CHECK-SF2-NEXT: ld32.w l3, sp, 24 +; CHECK-SF2-NEXT: movi32 l4, 0 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __ledf2 +; CHECK-SF2-NEXT: cmplt32 l4, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 20 +; CHECK-SF2-NEXT: ld32.w l0, sp, 16 +; CHECK-SF2-NEXT: ld32.w l1, sp, 12 +; CHECK-SF2-NEXT: ld32.w l2, sp, 8 +; CHECK-SF2-NEXT: ld32.w l3, sp, 4 +; CHECK-SF2-NEXT: ld32.w l4, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 24 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ugt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplsz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ugt double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ugt_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ugt_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ugt_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB79_2 +; CHECK-SF-NEXT: br32 .LBB79_1 +; CHECK-SF-NEXT: .LBB79_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB79_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ugt_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB79_2 +; CHECK-DF-NEXT: br32 .LBB79_1 +; CHECK-DF-NEXT: .LBB79_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB79_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ugt_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ugt_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + + +define float @selectRR_uge_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_uge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __ltsf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_uge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB80_2 +; CHECK-SF-NEXT: br32 .LBB80_1 +; CHECK-SF-NEXT: .LBB80_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB80_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_uge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB80_2 +; CHECK-DF-NEXT: br32 .LBB80_1 +; CHECK-DF-NEXT: .LBB80_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB80_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_uge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_uge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_uge_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_uge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __ltsf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_uge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmplts vr0, vr3 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB81_2 +; CHECK-SF-NEXT: br32 .LBB81_1 +; CHECK-SF-NEXT: .LBB81_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB81_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_uge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmplts vr0, vr3 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB81_2 +; CHECK-DF-NEXT: br32 .LBB81_1 +; CHECK-DF-NEXT: .LBB81_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB81_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_uge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr3 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_uge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr3 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_uge_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_uge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __ltsf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_uge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB82_2 +; CHECK-SF-NEXT: br32 .LBB82_1 +; CHECK-SF-NEXT: .LBB82_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB82_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_uge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB82_2 +; CHECK-DF-NEXT: br32 .LBB82_1 +; CHECK-DF-NEXT: .LBB82_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB82_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_uge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpltz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_uge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_uge_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_uge_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_uge_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB83_2 +; CHECK-SF-NEXT: br32 .LBB83_1 +; CHECK-SF-NEXT: .LBB83_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB83_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_uge_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB83_2 +; CHECK-DF-NEXT: br32 .LBB83_1 +; CHECK-DF-NEXT: .LBB83_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB83_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_uge_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_uge_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_uge_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_uge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __ltdf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_uge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __ltdf2 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB84_2 +; CHECK-SF-NEXT: br32 .LBB84_1 +; CHECK-SF-NEXT: .LBB84_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB84_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_uge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB84_2 +; CHECK-DF-NEXT: br32 .LBB84_1 +; CHECK-DF-NEXT: .LBB84_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB84_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_uge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __ltdf2 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_uge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_uge_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_uge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __ltdf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_uge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __ltdf2 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB85_2 +; CHECK-SF-NEXT: br32 .LBB85_1 +; CHECK-SF-NEXT: .LBB85_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB85_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_uge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpltd vr0, vr3 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB85_2 +; CHECK-DF-NEXT: br32 .LBB85_1 +; CHECK-DF-NEXT: .LBB85_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB85_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_uge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __ltdf2 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_uge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_uge_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_uge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __ltdf2 +; CHECK-SOFT-NEXT: movih32 a1, 65535 +; CHECK-SOFT-NEXT: ori32 a1, a1, 65535 +; CHECK-SOFT-NEXT: cmplt32 a1, a0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_uge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __ltdf2 +; CHECK-SF-NEXT: movih32 a1, 65535 +; CHECK-SF-NEXT: ori32 a1, a1, 65535 +; CHECK-SF-NEXT: cmplt32 a1, a0 +; CHECK-SF-NEXT: bt32 .LBB86_2 +; CHECK-SF-NEXT: br32 .LBB86_1 +; CHECK-SF-NEXT: .LBB86_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB86_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_uge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB86_2 +; CHECK-DF-NEXT: br32 .LBB86_1 +; CHECK-DF-NEXT: .LBB86_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB86_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_uge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __ltdf2 +; CHECK-SF2-NEXT: movih32 a1, 65535 +; CHECK-SF2-NEXT: ori32 a1, a1, 65535 +; CHECK-SF2-NEXT: cmplt32 a1, a0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_uge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpltz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uge double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_uge_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_uge_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_uge_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB87_2 +; CHECK-SF-NEXT: br32 .LBB87_1 +; CHECK-SF-NEXT: .LBB87_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB87_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_uge_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB87_2 +; CHECK-DF-NEXT: br32 .LBB87_1 +; CHECK-DF-NEXT: .LBB87_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB87_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_uge_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_uge_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + +define float @selectRR_ult_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ult_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __gesf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ult_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmphss vr1, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB88_2 +; CHECK-SF-NEXT: br32 .LBB88_1 +; CHECK-SF-NEXT: .LBB88_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB88_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ult_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphss vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB88_2 +; CHECK-DF-NEXT: br32 .LBB88_1 +; CHECK-DF-NEXT: .LBB88_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB88_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ult_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ult_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ult_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ult_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __gesf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ult_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmphss vr0, vr3 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB89_2 +; CHECK-SF-NEXT: br32 .LBB89_1 +; CHECK-SF-NEXT: .LBB89_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB89_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ult_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmphss vr0, vr3 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB89_2 +; CHECK-DF-NEXT: br32 .LBB89_1 +; CHECK-DF-NEXT: .LBB89_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB89_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ult_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmphs.32 vr0, vr3 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ult_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmphs.32 vr0, vr3 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ult_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ult_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __gesf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ult_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzhss vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB90_2 +; CHECK-SF-NEXT: br32 .LBB90_1 +; CHECK-SF-NEXT: .LBB90_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB90_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ult_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhss vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB90_2 +; CHECK-DF-NEXT: br32 .LBB90_1 +; CHECK-DF-NEXT: .LBB90_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB90_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ult_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphsz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ult_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ult_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ult_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ult_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB91_2 +; CHECK-SF-NEXT: br32 .LBB91_1 +; CHECK-SF-NEXT: .LBB91_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB91_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ult_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB91_2 +; CHECK-DF-NEXT: br32 .LBB91_1 +; CHECK-DF-NEXT: .LBB91_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB91_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ult_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ult_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ult_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ult_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __gedf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ult_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __gedf2 +; CHECK-SF-NEXT: blz32 a0, .LBB92_2 +; CHECK-SF-NEXT: br32 .LBB92_1 +; CHECK-SF-NEXT: .LBB92_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB92_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ult_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmphsd vr1, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB92_2 +; CHECK-DF-NEXT: br32 .LBB92_1 +; CHECK-DF-NEXT: .LBB92_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB92_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ult_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __gedf2 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ult_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphs.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ult_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ult_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __gedf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ult_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __gedf2 +; CHECK-SF-NEXT: blz32 a0, .LBB93_2 +; CHECK-SF-NEXT: br32 .LBB93_1 +; CHECK-SF-NEXT: .LBB93_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB93_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ult_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmphsd vr0, vr3 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB93_2 +; CHECK-DF-NEXT: br32 .LBB93_1 +; CHECK-DF-NEXT: .LBB93_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB93_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ult_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __gedf2 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ult_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmphs.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ult_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ult_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __gedf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ult_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __gedf2 +; CHECK-SF-NEXT: blz32 a0, .LBB94_2 +; CHECK-SF-NEXT: br32 .LBB94_1 +; CHECK-SF-NEXT: .LBB94_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB94_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ult_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzhsd vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB94_2 +; CHECK-DF-NEXT: br32 .LBB94_1 +; CHECK-DF-NEXT: .LBB94_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB94_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ult_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __gedf2 +; CHECK-SF2-NEXT: cmplti32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ult_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphsz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ult double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ult_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ult_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ult_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB95_2 +; CHECK-SF-NEXT: br32 .LBB95_1 +; CHECK-SF-NEXT: .LBB95_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB95_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ult_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB95_2 +; CHECK-DF-NEXT: br32 .LBB95_1 +; CHECK-DF-NEXT: .LBB95_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB95_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ult_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ult_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + +define float @selectRR_ule_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_ule_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __gtsf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ule_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmplts vr0, vr1 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB96_2 +; CHECK-SF-NEXT: br32 .LBB96_1 +; CHECK-SF-NEXT: .LBB96_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB96_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ule_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmplts vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB96_2 +; CHECK-DF-NEXT: br32 .LBB96_1 +; CHECK-DF-NEXT: .LBB96_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB96_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ule_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ule_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.32 vr0, vr1 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_ule_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_ule_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __gtsf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ule_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmplts vr3, vr0 +; CHECK-SF-NEXT: mvc32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB97_2 +; CHECK-SF-NEXT: br32 .LBB97_1 +; CHECK-SF-NEXT: .LBB97_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB97_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ule_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmplts vr3, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB97_2 +; CHECK-DF-NEXT: br32 .LBB97_1 +; CHECK-DF-NEXT: .LBB97_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB97_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ule_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmplt.32 vr3, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ule_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmplt.32 vr3, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_ule_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_ule_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __gtsf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ule_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpzlss vr0 +; CHECK-SF-NEXT: mvcv32 a0 +; CHECK-SF-NEXT: xori32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB98_2 +; CHECK-SF-NEXT: br32 .LBB98_1 +; CHECK-SF-NEXT: .LBB98_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB98_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ule_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlss vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB98_2 +; CHECK-DF-NEXT: br32 .LBB98_1 +; CHECK-DF-NEXT: .LBB98_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB98_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ule_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmphz.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ule_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_ule_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_ule_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ule_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB99_2 +; CHECK-SF-NEXT: br32 .LBB99_1 +; CHECK-SF-NEXT: .LBB99_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB99_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ule_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB99_2 +; CHECK-DF-NEXT: br32 .LBB99_1 +; CHECK-DF-NEXT: .LBB99_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB99_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ule_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ule_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_ule_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_ule_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __gtdf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_ule_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __gtdf2 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB100_2 +; CHECK-SF-NEXT: br32 .LBB100_1 +; CHECK-SF-NEXT: .LBB100_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB100_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_ule_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpltd vr0, vr1 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB100_2 +; CHECK-DF-NEXT: br32 .LBB100_1 +; CHECK-DF-NEXT: .LBB100_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB100_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_ule_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __gtdf2 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_ule_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmplt.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_ule_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_ule_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __gtdf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_ule_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __gtdf2 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB101_2 +; CHECK-SF-NEXT: br32 .LBB101_1 +; CHECK-SF-NEXT: .LBB101_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB101_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_ule_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpltd vr3, vr0 +; CHECK-DF-NEXT: mvc32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB101_2 +; CHECK-DF-NEXT: br32 .LBB101_1 +; CHECK-DF-NEXT: .LBB101_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB101_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_ule_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __gtdf2 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_ule_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmplt.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_ule_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_ule_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __gtdf2 +; CHECK-SOFT-NEXT: cmplti32 a0, 1 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_ule_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __gtdf2 +; CHECK-SF-NEXT: cmplti32 a0, 1 +; CHECK-SF-NEXT: bt32 .LBB102_2 +; CHECK-SF-NEXT: br32 .LBB102_1 +; CHECK-SF-NEXT: .LBB102_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB102_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_ule_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzlsd vr0 +; CHECK-DF-NEXT: mvcv32 a0 +; CHECK-DF-NEXT: xori32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB102_2 +; CHECK-DF-NEXT: br32 .LBB102_1 +; CHECK-DF-NEXT: .LBB102_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB102_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_ule_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __gtdf2 +; CHECK-SF2-NEXT: cmplti32 a0, 1 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_ule_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmphz.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp ule double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_ule_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_ule_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_ule_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB103_2 +; CHECK-SF-NEXT: br32 .LBB103_1 +; CHECK-SF-NEXT: .LBB103_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB103_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_ule_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB103_2 +; CHECK-DF-NEXT: br32 .LBB103_1 +; CHECK-DF-NEXT: .LBB103_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB103_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_ule_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_ule_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + +define float @selectRR_une_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_une_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __nesf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_une_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpnes vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB104_2 +; CHECK-SF-NEXT: br32 .LBB104_1 +; CHECK-SF-NEXT: .LBB104_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB104_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_une_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpnes vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB104_2 +; CHECK-DF-NEXT: br32 .LBB104_1 +; CHECK-DF-NEXT: .LBB104_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB104_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_une_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_une_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_une_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_une_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movih32 a1, 16672 +; CHECK-SOFT-NEXT: bsr32 __nesf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_une_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr3, a0 +; CHECK-SF-NEXT: fcmpnes vr0, vr3 +; CHECK-SF-NEXT: bt32 .LBB105_2 +; CHECK-SF-NEXT: br32 .LBB105_1 +; CHECK-SF-NEXT: .LBB105_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB105_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_une_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: fcmpnes vr0, vr3 +; CHECK-DF-NEXT: bt32 .LBB105_2 +; CHECK-DF-NEXT: br32 .LBB105_1 +; CHECK-DF-NEXT: .LBB105_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB105_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_une_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-SF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_une_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr3, a0 +; CHECK-DF2-NEXT: fcmpne.32 vr0, vr3 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_une_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_une_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: bsr32 __nesf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_une_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpznes vr0 +; CHECK-SF-NEXT: bt32 .LBB106_2 +; CHECK-SF-NEXT: br32 .LBB106_1 +; CHECK-SF-NEXT: .LBB106_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB106_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_une_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpznes vr0 +; CHECK-DF-NEXT: bt32 .LBB106_2 +; CHECK-DF-NEXT: br32 .LBB106_1 +; CHECK-DF-NEXT: .LBB106_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB106_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_une_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpnez.32 vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_une_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.32 vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_une_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_une_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_une_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB107_2 +; CHECK-SF-NEXT: br32 .LBB107_1 +; CHECK-SF-NEXT: .LBB107_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB107_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_une_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB107_2 +; CHECK-DF-NEXT: br32 .LBB107_1 +; CHECK-DF-NEXT: .LBB107_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB107_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_une_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_une_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_une_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_une_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __nedf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_une_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __nedf2 +; CHECK-SF-NEXT: bnez32 a0, .LBB108_2 +; CHECK-SF-NEXT: br32 .LBB108_1 +; CHECK-SF-NEXT: .LBB108_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB108_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_une_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpned vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB108_2 +; CHECK-DF-NEXT: br32 .LBB108_1 +; CHECK-DF-NEXT: .LBB108_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB108_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_une_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __nedf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_une_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpne.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_une_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_une_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movih32 a3, 16420 +; CHECK-SOFT-NEXT: bsr32 __nedf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_une_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movih32 a3, 16420 +; CHECK-SF-NEXT: bsr32 __nedf2 +; CHECK-SF-NEXT: bnez32 a0, .LBB109_2 +; CHECK-SF-NEXT: br32 .LBB109_1 +; CHECK-SF-NEXT: .LBB109_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB109_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_une_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr3, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr3, a0 +; CHECK-DF-NEXT: fcmpned vr0, vr3 +; CHECK-DF-NEXT: bt32 .LBB109_2 +; CHECK-DF-NEXT: br32 .LBB109_1 +; CHECK-DF-NEXT: .LBB109_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB109_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_une_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movih32 a3, 16420 +; CHECK-SF2-NEXT: bsr32 __nedf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_une_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr3, a1, a0 +; CHECK-DF2-NEXT: fcmpne.64 vr0, vr3 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_une_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_une_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: movi32 a2, 0 +; CHECK-SOFT-NEXT: movi32 a3, 0 +; CHECK-SOFT-NEXT: bsr32 __nedf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_une_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: movi32 a2, 0 +; CHECK-SF-NEXT: movi32 a3, 0 +; CHECK-SF-NEXT: bsr32 __nedf2 +; CHECK-SF-NEXT: bnez32 a0, .LBB110_2 +; CHECK-SF-NEXT: br32 .LBB110_1 +; CHECK-SF-NEXT: .LBB110_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB110_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_une_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpzned vr0 +; CHECK-DF-NEXT: bt32 .LBB110_2 +; CHECK-DF-NEXT: br32 .LBB110_1 +; CHECK-DF-NEXT: .LBB110_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB110_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_une_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: movi32 a2, 0 +; CHECK-SF2-NEXT: movi32 a3, 0 +; CHECK-SF2-NEXT: bsr32 __nedf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_une_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpnez.64 vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp une double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_une_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_une_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_une_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB111_2 +; CHECK-SF-NEXT: br32 .LBB111_1 +; CHECK-SF-NEXT: .LBB111_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB111_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_une_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB111_2 +; CHECK-DF-NEXT: br32 .LBB111_1 +; CHECK-DF-NEXT: .LBB111_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB111_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_une_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_une_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + +define float @selectRR_uno_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_uno_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_uno_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr1, vr0 +; CHECK-SF-NEXT: bt32 .LBB112_2 +; CHECK-SF-NEXT: br32 .LBB112_1 +; CHECK-SF-NEXT: .LBB112_1: # %select.false +; CHECK-SF-NEXT: fmovs vr3, vr2 +; CHECK-SF-NEXT: .LBB112_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_uno_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB112_2 +; CHECK-DF-NEXT: br32 .LBB112_1 +; CHECK-DF-NEXT: .LBB112_1: # %select.false +; CHECK-DF-NEXT: fmovs vr3, vr2 +; CHECK-DF-NEXT: .LBB112_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_uno_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_uno_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr1, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_uno_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_uno_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_uno_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bt32 .LBB113_2 +; CHECK-SF-NEXT: br32 .LBB113_1 +; CHECK-SF-NEXT: .LBB113_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB113_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_uno_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB113_2 +; CHECK-DF-NEXT: br32 .LBB113_1 +; CHECK-DF-NEXT: .LBB113_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB113_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_uno_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_uno_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_uno_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_uno_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 12 +; CHECK-SOFT-NEXT: st32.w lr, sp, 8 +; CHECK-SOFT-NEXT: st32.w l0, sp, 4 +; CHECK-SOFT-NEXT: st32.w l1, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a2 +; CHECK-SOFT-NEXT: mov32 l1, a1 +; CHECK-SOFT-NEXT: mov32 a1, a0 +; CHECK-SOFT-NEXT: bsr32 __unordsf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l0 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_uno_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fcmpuos vr0, vr0 +; CHECK-SF-NEXT: bt32 .LBB114_2 +; CHECK-SF-NEXT: br32 .LBB114_1 +; CHECK-SF-NEXT: .LBB114_1: # %select.false +; CHECK-SF-NEXT: fmovs vr2, vr1 +; CHECK-SF-NEXT: .LBB114_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_uno_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuos vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB114_2 +; CHECK-DF-NEXT: br32 .LBB114_1 +; CHECK-DF-NEXT: .LBB114_1: # %select.false +; CHECK-DF-NEXT: fmovs vr2, vr1 +; CHECK-DF-NEXT: .LBB114_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_uno_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_uno_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.32 vr0, vr0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_uno_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_uno_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_uno_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB115_2 +; CHECK-SF-NEXT: br32 .LBB115_1 +; CHECK-SF-NEXT: .LBB115_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB115_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_uno_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB115_2 +; CHECK-DF-NEXT: br32 .LBB115_1 +; CHECK-DF-NEXT: .LBB115_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB115_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_uno_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_uno_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_uno_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_uno_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, sp, 0 +; CHECK-SOFT-NEXT: mov32 t0, a1 +; CHECK-SOFT-NEXT: mov32 t1, a0 +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: mov32 a1, a3 +; CHECK-SOFT-NEXT: mov32 a2, t1 +; CHECK-SOFT-NEXT: mov32 a3, t0 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: addi32 a1, sp, 4 +; CHECK-SOFT-NEXT: addi32 a0, sp, 12 +; CHECK-SOFT-NEXT: movt32 a1, a0 +; CHECK-SOFT-NEXT: ld32.w a0, a1, 0 +; CHECK-SOFT-NEXT: ld32.w a1, a1, 1 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_uno_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 12 +; CHECK-SF-NEXT: st32.w lr, sp, 8 +; CHECK-SF-NEXT: st32.w l0, sp, 4 +; CHECK-SF-NEXT: st32.w l1, sp, 0 +; CHECK-SF-NEXT: mov32 t0, a1 +; CHECK-SF-NEXT: mov32 t1, a0 +; CHECK-SF-NEXT: ld32.w l0, sp, 24 +; CHECK-SF-NEXT: ld32.w l1, sp, 20 +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: mov32 a2, t1 +; CHECK-SF-NEXT: mov32 a3, t0 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: bnez32 a0, .LBB116_2 +; CHECK-SF-NEXT: br32 .LBB116_1 +; CHECK-SF-NEXT: .LBB116_1: # %select.false +; CHECK-SF-NEXT: ld32.w l0, sp, 16 +; CHECK-SF-NEXT: ld32.w l1, sp, 12 +; CHECK-SF-NEXT: .LBB116_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l1 +; CHECK-SF-NEXT: mov32 a1, l0 +; CHECK-SF-NEXT: ld32.w lr, sp, 8 +; CHECK-SF-NEXT: ld32.w l0, sp, 4 +; CHECK-SF-NEXT: ld32.w l1, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 12 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_uno_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr1, vr0 +; CHECK-DF-NEXT: bt32 .LBB116_2 +; CHECK-DF-NEXT: br32 .LBB116_1 +; CHECK-DF-NEXT: .LBB116_1: # %select.false +; CHECK-DF-NEXT: fmovd vr3, vr2 +; CHECK-DF-NEXT: .LBB116_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_uno_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, sp, 0 +; CHECK-SF2-NEXT: mov32 t0, a1 +; CHECK-SF2-NEXT: mov32 t1, a0 +; CHECK-SF2-NEXT: mov32 a0, a2 +; CHECK-SF2-NEXT: mov32 a1, a3 +; CHECK-SF2-NEXT: mov32 a2, t1 +; CHECK-SF2-NEXT: mov32 a3, t0 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: addi32 a1, sp, 4 +; CHECK-SF2-NEXT: addi32 a0, sp, 12 +; CHECK-SF2-NEXT: movt32 a1, a0 +; CHECK-SF2-NEXT: ld32.w a0, a1, 0 +; CHECK-SF2-NEXT: ld32.w a1, a1, 1 +; CHECK-SF2-NEXT: ld32.w lr, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_uno_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr1, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr3, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_uno_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_uno_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_uno_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: bnez32 a0, .LBB117_2 +; CHECK-SF-NEXT: br32 .LBB117_1 +; CHECK-SF-NEXT: .LBB117_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB117_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_uno_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB117_2 +; CHECK-DF-NEXT: br32 .LBB117_1 +; CHECK-DF-NEXT: .LBB117_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB117_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_uno_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_uno_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_uno_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_uno_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 20 +; CHECK-SOFT-NEXT: st32.w lr, sp, 16 +; CHECK-SOFT-NEXT: st32.w l0, sp, 12 +; CHECK-SOFT-NEXT: st32.w l1, sp, 8 +; CHECK-SOFT-NEXT: st32.w l2, sp, 4 +; CHECK-SOFT-NEXT: st32.w l3, sp, 0 +; CHECK-SOFT-NEXT: mov32 l0, a3 +; CHECK-SOFT-NEXT: mov32 l1, a2 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 20 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 20 +; CHECK-SOFT-NEXT: mov32 a2, a0 +; CHECK-SOFT-NEXT: mov32 a3, a1 +; CHECK-SOFT-NEXT: bsr32 __unorddf2 +; CHECK-SOFT-NEXT: cmpnei32 a0, 0 +; CHECK-SOFT-NEXT: movt32 l1, l3 +; CHECK-SOFT-NEXT: movt32 l0, l2 +; CHECK-SOFT-NEXT: mov32 a0, l1 +; CHECK-SOFT-NEXT: mov32 a1, l0 +; CHECK-SOFT-NEXT: ld32.w lr, sp, 16 +; CHECK-SOFT-NEXT: ld32.w l0, sp, 12 +; CHECK-SOFT-NEXT: ld32.w l1, sp, 8 +; CHECK-SOFT-NEXT: ld32.w l2, sp, 4 +; CHECK-SOFT-NEXT: ld32.w l3, sp, 0 +; CHECK-SOFT-NEXT: addi32 sp, sp, 20 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_uno_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 20 +; CHECK-SF-NEXT: st32.w lr, sp, 16 +; CHECK-SF-NEXT: st32.w l0, sp, 12 +; CHECK-SF-NEXT: st32.w l1, sp, 8 +; CHECK-SF-NEXT: st32.w l2, sp, 4 +; CHECK-SF-NEXT: st32.w l3, sp, 0 +; CHECK-SF-NEXT: mov32 l0, a3 +; CHECK-SF-NEXT: mov32 l1, a2 +; CHECK-SF-NEXT: ld32.w l2, sp, 24 +; CHECK-SF-NEXT: ld32.w l3, sp, 20 +; CHECK-SF-NEXT: mov32 a2, a0 +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: bsr32 __unorddf2 +; CHECK-SF-NEXT: bnez32 a0, .LBB118_2 +; CHECK-SF-NEXT: br32 .LBB118_1 +; CHECK-SF-NEXT: .LBB118_1: # %select.false +; CHECK-SF-NEXT: mov32 l3, l1 +; CHECK-SF-NEXT: mov32 l2, l0 +; CHECK-SF-NEXT: .LBB118_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, l3 +; CHECK-SF-NEXT: mov32 a1, l2 +; CHECK-SF-NEXT: ld32.w lr, sp, 16 +; CHECK-SF-NEXT: ld32.w l0, sp, 12 +; CHECK-SF-NEXT: ld32.w l1, sp, 8 +; CHECK-SF-NEXT: ld32.w l2, sp, 4 +; CHECK-SF-NEXT: ld32.w l3, sp, 0 +; CHECK-SF-NEXT: addi32 sp, sp, 20 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_uno_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fcmpuod vr0, vr0 +; CHECK-DF-NEXT: bt32 .LBB118_2 +; CHECK-DF-NEXT: br32 .LBB118_1 +; CHECK-DF-NEXT: .LBB118_1: # %select.false +; CHECK-DF-NEXT: fmovd vr2, vr1 +; CHECK-DF-NEXT: .LBB118_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_uno_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 20 +; CHECK-SF2-NEXT: st32.w lr, sp, 16 +; CHECK-SF2-NEXT: st32.w l0, sp, 12 +; CHECK-SF2-NEXT: st32.w l1, sp, 8 +; CHECK-SF2-NEXT: st32.w l2, sp, 4 +; CHECK-SF2-NEXT: st32.w l3, sp, 0 +; CHECK-SF2-NEXT: mov32 l0, a3 +; CHECK-SF2-NEXT: mov32 l1, a2 +; CHECK-SF2-NEXT: ld32.w l2, sp, 20 +; CHECK-SF2-NEXT: ld32.w l3, sp, 20 +; CHECK-SF2-NEXT: mov32 a2, a0 +; CHECK-SF2-NEXT: mov32 a3, a1 +; CHECK-SF2-NEXT: bsr32 __unorddf2 +; CHECK-SF2-NEXT: cmpnei32 a0, 0 +; CHECK-SF2-NEXT: movt32 l1, l3 +; CHECK-SF2-NEXT: movt32 l0, l2 +; CHECK-SF2-NEXT: mov32 a0, l1 +; CHECK-SF2-NEXT: mov32 a1, l0 +; CHECK-SF2-NEXT: ld32.w lr, sp, 16 +; CHECK-SF2-NEXT: ld32.w l0, sp, 12 +; CHECK-SF2-NEXT: ld32.w l1, sp, 8 +; CHECK-SF2-NEXT: ld32.w l2, sp, 4 +; CHECK-SF2-NEXT: ld32.w l3, sp, 0 +; CHECK-SF2-NEXT: addi32 sp, sp, 20 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_uno_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fcmpuo.64 vr0, vr0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr2, vr1 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp uno double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_uno_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_uno_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_uno_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB119_2 +; CHECK-SF-NEXT: br32 .LBB119_1 +; CHECK-SF-NEXT: .LBB119_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB119_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_uno_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB119_2 +; CHECK-DF-NEXT: br32 .LBB119_1 +; CHECK-DF-NEXT: .LBB119_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB119_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_uno_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_uno_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} + +define float @selectRR_true_float(float %x, float %y, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRR_true_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a0, a3 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_true_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmovs vr0, vr3 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB120_2 +; CHECK-SF-NEXT: br32 .LBB120_1 +; CHECK-SF-NEXT: .LBB120_1: # %select.false +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: .LBB120_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_true_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovs vr0, vr3 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB120_2 +; CHECK-DF-NEXT: br32 .LBB120_1 +; CHECK-DF-NEXT: .LBB120_1: # %select.false +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: .LBB120_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_true_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmov.32 vr0, vr3 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_true_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.32 vr0, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %y, %x + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRI_true_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRI_true_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_true_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB121_2 +; CHECK-SF-NEXT: br32 .LBB121_1 +; CHECK-SF-NEXT: .LBB121_1: # %select.false +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: .LBB121_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_true_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB121_2 +; CHECK-DF-NEXT: br32 .LBB121_1 +; CHECK-DF-NEXT: .LBB121_1: # %select.false +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: .LBB121_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_true_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmov.32 vr0, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_true_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.32 vr0, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %x, 10.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectRX_true_float(float %x, float %n, float %m) { +; CHECK-SOFT-LABEL: selectRX_true_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: mov32 a0, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_true_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmovs vr0, vr2 +; CHECK-SF-NEXT: movi32 a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB122_2 +; CHECK-SF-NEXT: br32 .LBB122_1 +; CHECK-SF-NEXT: .LBB122_1: # %select.false +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: .LBB122_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_true_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovs vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB122_2 +; CHECK-DF-NEXT: br32 .LBB122_1 +; CHECK-DF-NEXT: .LBB122_1: # %select.false +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: .LBB122_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_true_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmov.32 vr0, vr2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_true_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.32 vr0, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true float %x, 0.0 + %ret = select i1 %fcmp, float %m, float %n + ret float %ret +} + +define float @selectC_true_float(i1 %c, float %n, float %m) { +; CHECK-SOFT-LABEL: selectC_true_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a2 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_true_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB123_2 +; CHECK-SF-NEXT: br32 .LBB123_1 +; CHECK-SF-NEXT: .LBB123_1: # %select.false +; CHECK-SF-NEXT: fmovs vr1, vr0 +; CHECK-SF-NEXT: .LBB123_2: # %select.end +; CHECK-SF-NEXT: fmovs vr0, vr1 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_true_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB123_2 +; CHECK-DF-NEXT: br32 .LBB123_1 +; CHECK-DF-NEXT: .LBB123_1: # %select.false +; CHECK-DF-NEXT: fmovs vr1, vr0 +; CHECK-DF-NEXT: .LBB123_2: # %select.end +; CHECK-DF-NEXT: fmovs vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_true_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_true_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.32 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, float %m, float %n + ret float %ret +} + +define double @selectRR_true_double(double %x, double %y, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRR_true_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w a0, sp, 8 +; CHECK-SOFT-NEXT: ld32.w a1, sp, 12 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRR_true_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a1, sp, 12 +; CHECK-SF-NEXT: ld32.w a0, sp, 8 +; CHECK-SF-NEXT: movi32 a2, 1 +; CHECK-SF-NEXT: btsti32 a2, 0 +; CHECK-SF-NEXT: bt32 .LBB124_2 +; CHECK-SF-NEXT: br32 .LBB124_1 +; CHECK-SF-NEXT: .LBB124_1: # %select.false +; CHECK-SF-NEXT: ld32.w a1, sp, 4 +; CHECK-SF-NEXT: ld32.w a0, sp, 0 +; CHECK-SF-NEXT: .LBB124_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRR_true_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovd vr0, vr3 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB124_2 +; CHECK-DF-NEXT: br32 .LBB124_1 +; CHECK-DF-NEXT: .LBB124_1: # %select.false +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: .LBB124_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRR_true_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w a0, sp, 8 +; CHECK-SF2-NEXT: ld32.w a1, sp, 12 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRR_true_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.64 vr0, vr3 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %y, %x + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRI_true_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRI_true_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w a0, sp, 0 +; CHECK-SOFT-NEXT: ld32.w a1, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRI_true_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a1, sp, 4 +; CHECK-SF-NEXT: ld32.w a0, sp, 0 +; CHECK-SF-NEXT: movi32 t0, 1 +; CHECK-SF-NEXT: btsti32 t0, 0 +; CHECK-SF-NEXT: bt32 .LBB125_2 +; CHECK-SF-NEXT: br32 .LBB125_1 +; CHECK-SF-NEXT: .LBB125_1: # %select.false +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: .LBB125_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRI_true_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB125_2 +; CHECK-DF-NEXT: br32 .LBB125_1 +; CHECK-DF-NEXT: .LBB125_1: # %select.false +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: .LBB125_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRI_true_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w a0, sp, 0 +; CHECK-SF2-NEXT: ld32.w a1, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRI_true_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.64 vr0, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %x, 10.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectRX_true_double(double %x, double %n, double %m) { +; CHECK-SOFT-LABEL: selectRX_true_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w a0, sp, 0 +; CHECK-SOFT-NEXT: ld32.w a1, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectRX_true_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ld32.w a1, sp, 4 +; CHECK-SF-NEXT: ld32.w a0, sp, 0 +; CHECK-SF-NEXT: movi32 t0, 1 +; CHECK-SF-NEXT: btsti32 t0, 0 +; CHECK-SF-NEXT: bt32 .LBB126_2 +; CHECK-SF-NEXT: br32 .LBB126_1 +; CHECK-SF-NEXT: .LBB126_1: # %select.false +; CHECK-SF-NEXT: mov32 a0, a2 +; CHECK-SF-NEXT: mov32 a1, a3 +; CHECK-SF-NEXT: .LBB126_2: # %select.end +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectRX_true_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmovd vr0, vr2 +; CHECK-DF-NEXT: movi32 a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB126_2 +; CHECK-DF-NEXT: br32 .LBB126_1 +; CHECK-DF-NEXT: .LBB126_1: # %select.false +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: .LBB126_2: # %select.end +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectRX_true_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w a0, sp, 0 +; CHECK-SF2-NEXT: ld32.w a1, sp, 4 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectRX_true_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmov.64 vr0, vr2 +; CHECK-DF2-NEXT: rts32 +entry: + %fcmp = fcmp true double %x, 0.0 + %ret = select i1 %fcmp, double %m, double %n + ret double %ret +} + +define double @selectC_true_double(i1 %c, double %n, double %m) { +; CHECK-SOFT-LABEL: selectC_true_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ld32.w t0, sp, 0 +; CHECK-SOFT-NEXT: btsti32 a0, 0 +; CHECK-SOFT-NEXT: movt32 a1, a3 +; CHECK-SOFT-NEXT: movt32 a2, t0 +; CHECK-SOFT-NEXT: mov32 a0, a1 +; CHECK-SOFT-NEXT: mov32 a1, a2 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: selectC_true_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: ld32.w t0, sp, 0 +; CHECK-SF-NEXT: btsti32 a0, 0 +; CHECK-SF-NEXT: bt32 .LBB127_2 +; CHECK-SF-NEXT: br32 .LBB127_1 +; CHECK-SF-NEXT: .LBB127_1: # %select.false +; CHECK-SF-NEXT: mov32 a3, a1 +; CHECK-SF-NEXT: mov32 t0, a2 +; CHECK-SF-NEXT: .LBB127_2: # %select.end +; CHECK-SF-NEXT: mov32 a0, a3 +; CHECK-SF-NEXT: mov32 a1, t0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: selectC_true_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: btsti32 a0, 0 +; CHECK-DF-NEXT: bt32 .LBB127_2 +; CHECK-DF-NEXT: br32 .LBB127_1 +; CHECK-DF-NEXT: .LBB127_1: # %select.false +; CHECK-DF-NEXT: fmovd vr1, vr0 +; CHECK-DF-NEXT: .LBB127_2: # %select.end +; CHECK-DF-NEXT: fmovd vr0, vr1 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: selectC_true_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ld32.w t0, sp, 0 +; CHECK-SF2-NEXT: btsti32 a0, 0 +; CHECK-SF2-NEXT: movt32 a1, a3 +; CHECK-SF2-NEXT: movt32 a2, t0 +; CHECK-SF2-NEXT: mov32 a0, a1 +; CHECK-SF2-NEXT: mov32 a1, a2 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: selectC_true_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: btsti32 a0, 0 +; CHECK-DF2-NEXT: fsel.64 vr0, vr1, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %ret = select i1 %c, double %m, double %n + ret double %ret +} Index: llvm/test/CodeGen/CSKY/select.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/select.ll @@ -0,0 +1,3125 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @selectRR_eq_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_eq_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_eq_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_eq_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_eq_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_eq_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2033 +; CHECK-NEXT: cmpne32 a0, a3 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_eq_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_eq_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_eq_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_eq_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: addi32 a1, sp, 0 +; CHECK-NEXT: addi32 a0, sp, 8 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: ld32.w a0, (a1, 0) +; CHECK-NEXT: ld32.w a1, (a1, 1) +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_eq_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_eq_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: xori32 a0, a0, 10 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: movf32 a2, t1 +; CHECK-NEXT: movf32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_eq_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_eq_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2033 +; CHECK-NEXT: xor32 a0, a0, t2 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: movf32 a2, t1 +; CHECK-NEXT: movf32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_eq_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_eq_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_eq_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_eq_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_eq_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_eq_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_eq_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_eq_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 2033 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_eq_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_eq_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_eq_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_eq_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_eq_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_eq_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_eq_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_eq_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 241 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_eq_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_eq_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_eq_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_eq_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a3, a2 +; CHECK-NEXT: mov32 a0, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_eq_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_eq_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a1 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_eq_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_eq_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp eq i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_eq_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_eq_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_ne_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_ne_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_ne_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_ne_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_ne_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_ne_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2033 +; CHECK-NEXT: cmpne32 a0, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_ne_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_ne_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_ne_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_ne_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: addi32 a1, sp, 0 +; CHECK-NEXT: addi32 a0, sp, 8 +; CHECK-NEXT: movt32 a1, a0 +; CHECK-NEXT: ld32.w a0, (a1, 0) +; CHECK-NEXT: ld32.w a1, (a1, 1) +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_ne_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_ne_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: xori32 a0, a0, 10 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_ne_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_ne_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2033 +; CHECK-NEXT: xor32 a0, a0, t2 +; CHECK-NEXT: or32 a0, a0, a1 +; CHECK-NEXT: cmpnei32 a0, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_ne_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_ne_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_ne_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_ne_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_ne_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_ne_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_ne_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_ne_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmpnei32 a0, 2033 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_ne_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_ne_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_ne_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_ne_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmpne32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_ne_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_ne_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 10 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_ne_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_ne_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmpnei32 a0, 241 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_ne_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_ne_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_ne_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_ne_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_ne_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_ne_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_ne_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_ne_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a1 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ne i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_ne_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_ne_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_ugt_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_ugt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_ugt_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_ugt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_ugt_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_ugt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2033 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_ugt_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_ugt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_ugt_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_ugt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a1, a3 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_ugt_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_ugt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movi32 t2, 10 +; CHECK-NEXT: cmphs32 t2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_ugt_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_ugt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2033 +; CHECK-NEXT: cmphs32 t2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_ugt_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_ugt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_ugt_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_ugt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_ugt_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_ugt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_ugt_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_ugt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 2033 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_ugt_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_ugt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_ugt_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_ugt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_ugt_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_ugt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_ugt_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_ugt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a3, 241 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_ugt_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_ugt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_ugt_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_ugt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a3, a2 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_ugt_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_ugt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_ugt_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_ugt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ugt i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_ugt_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_ugt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_uge_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_uge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_uge_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_uge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_uge_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_uge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2032 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_uge_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_uge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_uge_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_uge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a3, a1 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_uge_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_uge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movi32 t2, 9 +; CHECK-NEXT: cmphs32 t2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_uge_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_uge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2032 +; CHECK-NEXT: cmphs32 t2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_uge_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_uge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_uge_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_uge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_uge_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_uge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_uge_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_uge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 2032 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_uge_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_uge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_uge_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_uge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_uge_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_uge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_uge_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_uge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a3, 240 +; CHECK-NEXT: cmphs32 a3, a0 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_uge_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_uge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_uge_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_uge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: mov32 a0, a3 +; CHECK-NEXT: movt32 a0, a2 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a0, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_uge_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_uge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_uge_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_uge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp uge i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_uge_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_uge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_ult_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_ult_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_ult_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_ult_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_ult_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_ult_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2033 +; CHECK-NEXT: cmphs32 a0, a3 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_ult_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_ult_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_ult_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_ult_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a3, a1 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_ult_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_ult_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: ld32.w t0, (sp, 4) +; CHECK-NEXT: ld32.w t1, (sp, 4) +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: ld32.w t2, (sp, 0) +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_ult_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_ult_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2033 +; CHECK-NEXT: cmphs32 a0, t2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_ult_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_ult_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_ult_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_ult_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_ult_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_ult_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_ult_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_ult_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 2033 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_ult_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_ult_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_ult_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_ult_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_ult_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_ult_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_ult_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_ult_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 241 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_ult_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_ult_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_ult_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_ult_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a3, a2 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_ult_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_ult_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_ult_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_ult_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a1 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ult i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_ult_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_ult_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + +define i32 @selectRR_ule_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_ule_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_ule_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_ule_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_ule_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_ule_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2034 +; CHECK-NEXT: cmphs32 a0, a3 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_ule_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_ule_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_ule_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_ule_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmphs32 a1, a3 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_ule_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_ule_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: ld32.w t0, (sp, 4) +; CHECK-NEXT: ld32.w t1, (sp, 4) +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: st32.w a1, (sp, 0) +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: ld32.w t2, (sp, 0) +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_ule_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_ule_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2034 +; CHECK-NEXT: cmphs32 a0, t2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_ule_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_ule_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_ule_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_ule_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_ule_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_ule_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_ule_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_ule_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: cmphsi32 a0, 2034 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_ule_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_ule_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_ule_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_ule_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphs32 a0, a1 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_ule_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_ule_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_ule_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_ule_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: cmphsi32 a0, 242 +; CHECK-NEXT: movf32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_ule_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_ule_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_ule_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_ule_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_ule_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_ule_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a1 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_ule_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_ule_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp ule i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_ule_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_ule_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_sgt_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_sgt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_sgt_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_sgt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_sgt_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_sgt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2033 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_sgt_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_sgt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_sgt_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_sgt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a1, a3 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_sgt_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_sgt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movi32 t2, 0 +; CHECK-NEXT: cmplt32 t2, a1 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: movi32 t3, 10 +; CHECK-NEXT: cmphs32 t3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 t2, a0 +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_sgt_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_sgt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movi32 t2, 0 +; CHECK-NEXT: cmplt32 t2, a1 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: movih32 t3, 729 +; CHECK-NEXT: ori32 t3, t3, 2033 +; CHECK-NEXT: cmphs32 t3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 t2, a0 +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_sgt_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_sgt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_sgt_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_sgt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_sgt_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_sgt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_sgt_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_sgt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 2033 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_sgt_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_sgt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_sgt_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_sgt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_sgt_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_sgt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a3, 10 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_sgt_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_sgt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a3, 65535 +; CHECK-NEXT: ori32 a3, a3, 65521 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_sgt_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_sgt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_sgt_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_sgt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a3, a2 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_sgt_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_sgt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_sgt_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_sgt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a1 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sgt i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_sgt_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_sgt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_sge_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_sge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_sge_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_sge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_sge_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_sge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2032 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_sge_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_sge_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_sge_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_sge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a3, a1 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_sge_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_sge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movi32 t2, 0 +; CHECK-NEXT: cmplt32 t2, a1 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: movi32 t3, 9 +; CHECK-NEXT: cmphs32 t3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 t2, a0 +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_sge_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_sge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: ld32.w t1, (sp, 0) +; CHECK-NEXT: movi32 t2, 0 +; CHECK-NEXT: cmplt32 t2, a1 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: movih32 t3, 729 +; CHECK-NEXT: ori32 t3, t3, 2032 +; CHECK-NEXT: cmphs32 t3, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: movf32 t2, a0 +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_sge_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_sge_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_sge_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_sge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_sge_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_sge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_sge_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_sge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a3, 2032 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_sge_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_sge_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_sge_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_sge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_sge_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_sge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a3, 9 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_sge_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_sge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a3, 65535 +; CHECK-NEXT: ori32 a3, a3, 65520 +; CHECK-NEXT: cmplt32 a3, a0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_sge_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_sge_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_sge_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_sge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_sge_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_sge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a2, a1 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_sge_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_sge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sge i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_sge_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_sge_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + +define i32 @selectRR_slt_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_slt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_slt_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_slt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_slt_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_slt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2033 +; CHECK-NEXT: cmplt32 a0, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_slt_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_slt_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_slt_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_slt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a3, a1 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphs32 a2, a0 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_slt_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_slt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: ld32.w t0, (sp, 4) +; CHECK-NEXT: ld32.w t1, (sp, 4) +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: st32.w t2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphsi32 a0, 10 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w t2, (sp, 0) +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_slt_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_slt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: ld32.w t0, (sp, 4) +; CHECK-NEXT: ld32.w t1, (sp, 4) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2033 +; CHECK-NEXT: cmphs32 a0, t2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: st32.w t2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: ld32.w t2, (sp, 0) +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_slt_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_slt_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_slt_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_slt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_slt_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_slt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_slt_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_slt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 2033 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_slt_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_slt_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_slt_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_slt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: cmplt32 a1, a0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_slt_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_slt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 10 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_slt_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_slt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a3, 65535 +; CHECK-NEXT: ori32 a3, a3, 65521 +; CHECK-NEXT: cmplt32 a0, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_slt_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_slt_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_slt_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_slt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a3, a2 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_slt_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_slt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_slt_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_slt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp slt i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_slt_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_slt_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + +define i32 @selectRR_sle_i32(i32 %x, i32 %y, i32 %n, i32 %m) { +; CHECK-LABEL: selectRR_sle_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i32 %y, %x + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRI_sle_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRI_sle_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i32 %x, 10 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectRX_sle_i32(i32 %x, i32 %n, i32 %m) { +; CHECK-LABEL: selectRX_sle_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a3, 729 +; CHECK-NEXT: ori32 a3, a3, 2034 +; CHECK-NEXT: cmplt32 a0, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i32 %x, 47777777 + %ret = select i1 %icmp, i32 %m, i32 %n + ret i32 %ret +} + +define i32 @selectC_sle_i32(i1 %c, i32 %n, i32 %m) { +; CHECK-LABEL: selectC_sle_i32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i32 %m, i32 %n + ret i32 %ret +} + +define i64 @selectRR_sle_i64(i64 %x, i64 %y, i64 %n, i64 %m) { +; CHECK-LABEL: selectRR_sle_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: cmpne32 a3, a1 +; CHECK-NEXT: mvc32 t0 +; CHECK-NEXT: st32.w t0, (sp, 0) +; CHECK-NEXT: cmplt32 a1, a3 +; CHECK-NEXT: mvcv32 a1 +; CHECK-NEXT: cmphs32 a0, a2 +; CHECK-NEXT: mvc32 a0 +; CHECK-NEXT: ld32.w a2, (sp, 0) +; CHECK-NEXT: btsti32 a2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: addi32 a2, sp, 4 +; CHECK-NEXT: addi32 a0, sp, 12 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, a0 +; CHECK-NEXT: ld32.w a0, (a2, 0) +; CHECK-NEXT: ld32.w a1, (a2, 1) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i64 %y, %x + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRI_sle_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRI_sle_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: ld32.w t0, (sp, 4) +; CHECK-NEXT: ld32.w t1, (sp, 4) +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: st32.w t2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: cmphsi32 a0, 11 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: ld32.w t2, (sp, 0) +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i64 %x, 10 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectRX_sle_i64(i64 %x, i64 %n, i64 %m) { +; CHECK-LABEL: selectRX_sle_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: ld32.w t0, (sp, 4) +; CHECK-NEXT: ld32.w t1, (sp, 4) +; CHECK-NEXT: movih32 t2, 729 +; CHECK-NEXT: ori32 t2, t2, 2034 +; CHECK-NEXT: cmphs32 a0, t2 +; CHECK-NEXT: mvcv32 a0 +; CHECK-NEXT: cmpnei32 a1, 0 +; CHECK-NEXT: mvc32 t2 +; CHECK-NEXT: st32.w t2, (sp, 0) +; CHECK-NEXT: cmplti32 a1, 0 +; CHECK-NEXT: mvc32 a1 +; CHECK-NEXT: ld32.w t2, (sp, 0) +; CHECK-NEXT: btsti32 t2, 0 +; CHECK-NEXT: movf32 a1, a0 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a2, t1 +; CHECK-NEXT: movt32 a3, t0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i64 %x, 47777777 + %ret = select i1 %icmp, i64 %m, i64 %n + ret i64 %ret +} + +define i64 @selectC_sle_i64(i1 %c, i64 %n, i64 %m) { +; CHECK-LABEL: selectC_sle_i64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ld32.w t0, (sp, 0) +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a3 +; CHECK-NEXT: movt32 a2, t0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: mov32 a1, a2 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i64 %m, i64 %n + ret i64 %ret +} + + +define i16 @selectRR_sle_i16(i16 %x, i16 %y, i16 %n, i16 %m) { +; CHECK-LABEL: selectRR_sle_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i16 %y, %x + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRI_sle_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRI_sle_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i16 %x, 10 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectRX_sle_i16(i16 %x, i16 %n, i16 %m) { +; CHECK-LABEL: selectRX_sle_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: cmplti32 a0, 2034 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i16 %x, 47777777 + %ret = select i1 %icmp, i16 %m, i16 %n + ret i16 %ret +} + +define i16 @selectC_sle_i16(i1 %c, i16 %n, i16 %m) { +; CHECK-LABEL: selectC_sle_i16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i16 %m, i16 %n + ret i16 %ret +} + + +define i8 @selectRR_sle_i8(i8 %x, i8 %y, i8 %n, i8 %m) { +; CHECK-LABEL: selectRR_sle_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplt32 a0, a1 +; CHECK-NEXT: movf32 a2, a3 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i8 %y, %x + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRI_sle_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRI_sle_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: cmplti32 a0, 11 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i8 %x, 10 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectRX_sle_i8(i8 %x, i8 %n, i8 %m) { +; CHECK-LABEL: selectRX_sle_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a3, 65535 +; CHECK-NEXT: ori32 a3, a3, 65522 +; CHECK-NEXT: cmplt32 a0, a3 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i8 %x, 47777777 + %ret = select i1 %icmp, i8 %m, i8 %n + ret i8 %ret +} + +define i8 @selectC_sle_i8(i1 %c, i8 %n, i8 %m) { +; CHECK-LABEL: selectC_sle_i8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i8 %m, i8 %n + ret i8 %ret +} + + +define i1 @selectRR_sle_i1(i1 %x, i1 %y, i1 %n, i1 %m) { +; CHECK-LABEL: selectRR_sle_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: mov32 a0, a3 +; CHECK-NEXT: movt32 a0, a2 +; CHECK-NEXT: btsti32 a1, 0 +; CHECK-NEXT: movt32 a0, a3 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i1 %y, %x + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRI_sle_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRI_sle_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i1 %x, 10 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectRX_sle_i1(i1 %x, i1 %n, i1 %m) { +; CHECK-LABEL: selectRX_sle_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %icmp = icmp sle i1 %x, 47777777 + %ret = select i1 %icmp, i1 %m, i1 %n + ret i1 %ret +} + +define i1 @selectC_sle_i1(i1 %c, i1 %n, i1 %m) { +; CHECK-LABEL: selectC_sle_i1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %ret = select i1 %c, i1 %m, i1 %n + ret i1 %ret +} + + + + Index: llvm/test/CodeGen/CSKY/sext.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/sext.ll @@ -0,0 +1,216 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +; i32/i16/i8/i1 --> i64 +define i64 @sextR_i64_0(i32 %x) { +; CHECK-LABEL: sextR_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: asri32 a1, a0, 31 +; CHECK-NEXT: rts32 +entry: + %sext = sext i32 %x to i64 + ret i64 %sext +} + +define i64 @sextR_i64_1(i16 %x) { +; CHECK-LABEL: sextR_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: asri32 a1, a0, 31 +; CHECK-NEXT: rts32 +entry: + %sext = sext i16 %x to i64 + ret i64 %sext +} + +define i64 @sextR_i64_2(i8 %x) { +; CHECK-LABEL: sextR_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: asri32 a1, a0, 31 +; CHECK-NEXT: rts32 +entry: + %sext = sext i8 %x to i64 + ret i64 %sext +} + +define i64 @sextR_i64_3(i1 %x) { +; CHECK-LABEL: sextR_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: mov32 a1, a0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 %x to i64 + ret i64 %sext +} + +define i64 @sextI_i64_0() { +; CHECK-LABEL: sextI_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i32 10 to i64 + ret i64 %sext +} + +define i64 @sextI_i64_1() { +; CHECK-LABEL: sextI_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i16 10 to i64 + ret i64 %sext +} + +define i64 @sextI_i64_2() { +; CHECK-LABEL: sextI_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i8 10 to i64 + ret i64 %sext +} + +define i64 @sextI_i64_3() { +; CHECK-LABEL: sextI_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 10 to i64 + ret i64 %sext +} + +; i16/i8/i1 --> i32 +define i32 @sextR_i32_1(i16 %x) { +; CHECK-LABEL: sextR_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i16 %x to i32 + ret i32 %sext +} + +define i32 @sextR_i32_2(i8 %x) { +; CHECK-LABEL: sextR_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i8 %x to i32 + ret i32 %sext +} + +define i32 @sextR_i32_3(i1 %x) { +; CHECK-LABEL: sextR_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 %x to i32 + ret i32 %sext +} + +define i32 @sextI_i32_1() { +; CHECK-LABEL: sextI_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %sext = sext i16 10 to i32 + ret i32 %sext +} + +define i32 @sextI_i32_2() { +; CHECK-LABEL: sextI_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %sext = sext i8 10 to i32 + ret i32 %sext +} + +define i32 @sextI_i32_3() { +; CHECK-LABEL: sextI_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65535 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 1 to i32 + ret i32 %sext +} + +; i8/i1 --> i16 +define i16 @sextR_i16_2(i8 %x) { +; CHECK-LABEL: sextR_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i8 %x to i16 + ret i16 %sext +} + +define i16 @sextR_i16_3(i1 %x) { +; CHECK-LABEL: sextR_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 %x to i16 + ret i16 %sext +} + +define i16 @sextI_i16_2() { +; CHECK-LABEL: sextI_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %sext = sext i8 10 to i16 + ret i16 %sext +} + +define i16 @sextI_i16_3() { +; CHECK-LABEL: sextI_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 65535 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 1 to i16 + ret i16 %sext +} + +;i1 --> i8 +define i8 @sextR_i8_3(i1 %x) { +; CHECK-LABEL: sextR_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 0, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 %x to i8 + ret i8 %sext +} + +define i8 @sextI_i8_3() { +; CHECK-LABEL: sextI_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %sext = sext i1 10 to i8 + ret i8 %sext +} + + Index: llvm/test/CodeGen/CSKY/shl.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/shl.ll @@ -0,0 +1,119 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @shlRR(i32 %x, i32 %y) { +; CHECK-LABEL: shlRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsl32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i32 %y, %x + ret i32 %shl +} + +define i32 @shlRI(i32 %x) { +; CHECK-LABEL: shlRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsli32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i32 %x, 10 + ret i32 %shl +} + +define i64 @SHL_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: SHL_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 sp, sp, 4 +; CHECK-NEXT: st32.w lr, (sp, 0) +; CHECK-NEXT: mov32 a1, a3 +; CHECK-NEXT: mov32 a3, a0 +; CHECK-NEXT: mov32 a0, a2 +; CHECK-NEXT: mov32 a2, a3 +; CHECK-NEXT: jsri32 .LCPI2_0 +; CHECK-NEXT: ld32.w lr, (sp, 0) +; CHECK-NEXT: addi32 sp, sp, 4 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: .LCPI2_0: +; CHECK-NEXT: .long __ashldi3 +entry: + %shl = shl nsw i64 %y, %x + ret i64 %shl +} + +define i64 @SHL_LONG_I(i64 %x) { +; CHECK-LABEL: SHL_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsri32 a2, a0, 25 +; CHECK-NEXT: lsli32 a1, a1, 7 +; CHECK-NEXT: or32 a1, a1, a2 +; CHECK-NEXT: lsli32 a0, a0, 7 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i64 %x, 7 + ret i64 %shl +} + +define i16 @SHL_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: SHL_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: lsl32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i16 %y, %x + ret i16 %shl +} + +define i16 @SHL_SHORT_I(i16 %x) { +; CHECK-LABEL: SHL_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsli32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i16 %x, 1 + ret i16 %shl +} + +define i8 @SHL_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: SHL_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: lsl32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i8 %y, %x + ret i8 %shl +} + +define i8 @SHL_CHAR_I(i8 %x) { +; CHECK-LABEL: SHL_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lsli32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i8 %x, 1 + ret i8 %shl +} + +define i1 @SHL_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: SHL_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i1 %y, %x + ret i1 %shl +} + +define i1 @SHL_BIT_I(i1 %x) { +; CHECK-LABEL: SHL_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %shl = shl nsw i1 %x, 1 + ret i1 %shl +} + Index: llvm/test/CodeGen/CSKY/sitofp.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/sitofp.ll @@ -0,0 +1,930 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +; i64/i32/i16/i8/i1 --> double +define double @sitofpR_double(i64 %x) { +; CHECK-SOFT-LABEL: sitofpR_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __floatdidf +; +; CHECK-SF-LABEL: sitofpR_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __floatdidf +; +; CHECK-DF-LABEL: sitofpR_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI0_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI0_0: +; CHECK-DF-NEXT: .long __floatdidf +; +; CHECK-SF2-LABEL: sitofpR_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __floatdidf +; +; CHECK-DF2-LABEL: sitofpR_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI0_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI0_0: +; CHECK-DF2-NEXT: .long __floatdidf +entry: + %sitofp = sitofp i64 %x to double + ret double %sitofp +} + +define double @sitofpR_double_0(i32 %x) { +; CHECK-SOFT-LABEL: sitofpR_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __floatsidf +; +; CHECK-SF-LABEL: sitofpR_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI1_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI1_0: +; CHECK-SF-NEXT: .long __floatsidf +; +; CHECK-DF-LABEL: sitofpR_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI1_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI1_0: +; CHECK-SF2-NEXT: .long __floatsidf +; +; CHECK-DF2-LABEL: sitofpR_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i32 %x to double + ret double %sitofp +} + +define double @sitofpR_double_1(i16 %x) { +; CHECK-SOFT-LABEL: sitofpR_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: sext32 a0, a0, 15, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __floatsidf +; +; CHECK-SF-LABEL: sitofpR_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: sext32 a0, a0, 15, 0 +; CHECK-SF-NEXT: jsri32 .LCPI2_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI2_0: +; CHECK-SF-NEXT: .long __floatsidf +; +; CHECK-DF-LABEL: sitofpR_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: sext32 a0, a0, 15, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: sext32 a0, a0, 15, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI2_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI2_0: +; CHECK-SF2-NEXT: .long __floatsidf +; +; CHECK-DF2-LABEL: sitofpR_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: sext32 a0, a0, 15, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i16 %x to double + ret double %sitofp +} + +define double @sitofpR_double_2(i8 %x) { +; CHECK-SOFT-LABEL: sitofpR_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: sext32 a0, a0, 7, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __floatsidf +; +; CHECK-SF-LABEL: sitofpR_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: sext32 a0, a0, 7, 0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __floatsidf +; +; CHECK-DF-LABEL: sitofpR_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: sext32 a0, a0, 7, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: sext32 a0, a0, 7, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __floatsidf +; +; CHECK-DF2-LABEL: sitofpR_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: sext32 a0, a0, 7, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i8 %x to double + ret double %sitofp +} + +define double @sitofpR_double_3(i1 %x) { +; CHECK-SOFT-LABEL: sitofpR_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: sext32 a0, a0, 0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __floatsidf +; +; CHECK-SF-LABEL: sitofpR_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: sext32 a0, a0, 0, 0 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __floatsidf +; +; CHECK-DF-LABEL: sitofpR_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: sext32 a0, a0, 0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: sext32 a0, a0, 0, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __floatsidf +; +; CHECK-DF2-LABEL: sitofpR_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: sext32 a0, a0, 0, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i1 %x to double + ret double %sitofp +} + +define double @sitofpI_double() { +; CHECK-SOFT-LABEL: sitofpI_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i64 10 to double + ret double %sitofp +} + +define double @sitofpI_double_0() { +; CHECK-SOFT-LABEL: sitofpI_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i32 10 to double + ret double %sitofp +} + +define double @sitofpI_double_1() { +; CHECK-SOFT-LABEL: sitofpI_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i16 10 to double + ret double %sitofp +} + +define double @sitofpI_double_2() { +; CHECK-SOFT-LABEL: sitofpI_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i8 10 to double + ret double %sitofp +} + +define double @sitofpI_double_3() { +; CHECK-SOFT-LABEL: sitofpI_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movi32 a1, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i1 10 to double + ret double %sitofp +} + +; i64/i32/i16/i8/i1 --> float +define float @sitofpR_float(i64 %x) { +; CHECK-SOFT-LABEL: sitofpR_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __floatdisf +; +; CHECK-SF-LABEL: sitofpR_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI10_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI10_0: +; CHECK-SF-NEXT: .long __floatdisf +; +; CHECK-DF-LABEL: sitofpR_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI10_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI10_0: +; CHECK-DF-NEXT: .long __floatdisf +; +; CHECK-SF2-LABEL: sitofpR_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI10_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI10_0: +; CHECK-SF2-NEXT: .long __floatdisf +; +; CHECK-DF2-LABEL: sitofpR_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI10_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI10_0: +; CHECK-DF2-NEXT: .long __floatdisf +entry: + %sitofp = sitofp i64 %x to float + ret float %sitofp +} + +define float @sitofpR_float_0(i32 %x) { +; CHECK-SOFT-LABEL: sitofpR_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __floatsisf +; +; CHECK-SF-LABEL: sitofpR_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fsitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpR_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpR_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i32 %x to float + ret float %sitofp +} + +define float @sitofpR_float_1(i16 %x) { +; CHECK-SOFT-LABEL: sitofpR_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: sext32 a0, a0, 15, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __floatsisf +; +; CHECK-SF-LABEL: sitofpR_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: sext32 a0, a0, 15, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fsitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpR_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: sext32 a0, a0, 15, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: sext32 a0, a0, 15, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpR_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: sext32 a0, a0, 15, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i16 %x to float + ret float %sitofp +} + +define float @sitofpR_float_2(i8 %x) { +; CHECK-SOFT-LABEL: sitofpR_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: sext32 a0, a0, 7, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __floatsisf +; +; CHECK-SF-LABEL: sitofpR_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: sext32 a0, a0, 7, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fsitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpR_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: sext32 a0, a0, 7, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: sext32 a0, a0, 7, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpR_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: sext32 a0, a0, 7, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i8 %x to float + ret float %sitofp +} + +define float @sitofpR_float_3(i1 %x) { +; CHECK-SOFT-LABEL: sitofpR_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: sext32 a0, a0, 0, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __floatsisf +; +; CHECK-SF-LABEL: sitofpR_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: sext32 a0, a0, 0, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fsitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpR_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: sext32 a0, a0, 0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fsitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpR_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: sext32 a0, a0, 0, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpR_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: sext32 a0, a0, 0, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.s32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i1 %x to float + ret float %sitofp +} + +define float @sitofpI_float() { +; CHECK-SOFT-LABEL: sitofpI_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i64 10 to float + ret float %sitofp +} + +define float @sitofpI_float_0() { +; CHECK-SOFT-LABEL: sitofpI_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i32 10 to float + ret float %sitofp +} + +define float @sitofpI_float_1() { +; CHECK-SOFT-LABEL: sitofpI_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i16 10 to float + ret float %sitofp +} + +define float @sitofpI_float_2() { +; CHECK-SOFT-LABEL: sitofpI_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i8 10 to float + ret float %sitofp +} + +define float @sitofpI_float_3() { +; CHECK-SOFT-LABEL: sitofpI_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: sitofpI_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: sitofpI_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: sitofpI_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: sitofpI_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %sitofp = sitofp i1 10 to float + ret float %sitofp +} + + Index: llvm/test/CodeGen/CSKY/srem.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/srem.ll @@ -0,0 +1,149 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @sremRR(i32 %x, i32 %y) { +; CHECK-LABEL: sremRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: divf a0, a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i32 %y, %x + ret i32 %srem +} + +define i32 @sremRI(i32 %x) { +; CHECK-LABEL: sremRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 26214 +; CHECK-NEXT: ori32 a1, a1, 26215 +; CHECK-NEXT: mul.s32 a1, a0, a1 +; CHECK-NEXT: lsri32 a3, a2, 31 +; CHECK-NEXT: asri32 a1, a2, 2 +; CHECK-NEXT: addu32 a1, a1, a3 +; CHECK-NEXT: movi32 a2, 10 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i32 %x, 10 + ret i32 %srem +} + +define i32 @sremRI_X(i32 %x) { +; CHECK-LABEL: sremRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 255 +; CHECK-NEXT: ori32 a1, a1, 61441 +; CHECK-NEXT: mul.s32 a1, a0, a1 +; CHECK-NEXT: lsri32 a3, a2, 31 +; CHECK-NEXT: asri32 a1, a2, 4 +; CHECK-NEXT: addu32 a1, a1, a3 +; CHECK-NEXT: movi32 a2, 4097 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i32 %x, 4097 + ret i32 %srem +} + +; TODO: Fix the test because it calls __moddi3 +;define i64 @SREM_LONG(i64 %x, i64 %y) { +;entry: +; %srem = srem i64 %y, %x +; ret i64 %srem +;} + +; Fix the test because it calls __moddi3 +;define i64 @SREM_LONG_I(i64 %x) { +;entry: +; %srem = srem i64 %x, 3 +; ret i64 %srem +;} + +define i16 @SREM_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: SREM_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: sext32 a1, a1, 15, 0 +; CHECK-NEXT: divf a0, a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i16 %y, %x + ret i16 %srem +} + +define i16 @SREM_SHORT_I(i16 %x) { +; CHECK-LABEL: SREM_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 15, 0 +; CHECK-NEXT: movih32 a1, 21845 +; CHECK-NEXT: ori32 a1, a1, 21846 +; CHECK-NEXT: mul.s32 a1, a0, a1 +; CHECK-NEXT: lsri32 a3, a2, 31 +; CHECK-NEXT: addu32 a1, a2, a3 +; CHECK-NEXT: movi32 a2, 3 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i16 %x, 3 + ret i16 %srem +} + +define i8 @SREM_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: SREM_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: sext32 a1, a1, 7, 0 +; CHECK-NEXT: divf a0, a1, a0 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i8 %y, %x + ret i8 %srem +} + +define i8 @SREM_CHAR_I(i8 %x) { +; CHECK-LABEL: SREM_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: sext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a1, 21845 +; CHECK-NEXT: ori32 a1, a1, 21845 +; CHECK-NEXT: mul.s32 a1, a0, a1 +; CHECK-NEXT: subu32 a1, a2, a0 +; CHECK-NEXT: lsri32 a2, a1, 31 +; CHECK-NEXT: asri32 a1, a1, 1 +; CHECK-NEXT: addu32 a1, a1, a2 +; CHECK-NEXT: movih32 a2, 65535 +; CHECK-NEXT: ori32 a2, a2, 65533 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %srem = srem i8 %x, -3 + ret i8 %srem +} + +define i1 @SREM_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: SREM_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %srem = srem i1 %y, %x + ret i1 %srem +} + +define i1 @SREM_BIT_I(i1 %x) { +; CHECK-LABEL: SREM_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %srem = srem i1 %x, -1 + ret i1 %srem +} + Index: llvm/test/CodeGen/CSKY/st-float.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/st-float.ll @@ -0,0 +1,182 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +define float @store_I_w(float* %a, float %b) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: store_I_w: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: st32.w a1, (a0, 3) +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: store_I_w: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fsts vr0, (a0, 3) +; CHECK-SF-NEXT: movih32 a0, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: store_I_w: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fsts vr0, (a0, 3) +; CHECK-DF-NEXT: movih32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: store_I_w: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fst.32 vr0, (a0, 3) +; CHECK-SF2-NEXT: movih32 a0, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: store_I_w: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fst.32 vr0, (a0, 3) +; CHECK-DF2-NEXT: movih32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds float, float* %a, i64 3 + store float %b, float* %arrayidx, align 4 + ret float 0.0 +} + +define double @store_I_d(double* %a, double %b) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: store_I_d: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: st32.w a2, (a0, 7) +; CHECK-SOFT-NEXT: st32.w a1, (a0, 6) +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: store_I_d: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: st32.w a2, (a0, 7) +; CHECK-SF-NEXT: st32.w a1, (a0, 6) +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movi32 a1, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: store_I_d: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstd vr0, (a0, 6) +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: store_I_d: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: st32.w a2, (a0, 7) +; CHECK-SF2-NEXT: st32.w a1, (a0, 6) +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: store_I_d: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fst.64 vr0, (a0, 6) +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds double, double* %a, i64 3 + store double %b, double* %arrayidx, align 4 + ret double 0.0 +} + +define float @store_R_w(float* %a, i32 %b, float %c) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: store_R_w: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: str32.w a2, (a0, a1 << 2) +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: store_R_w: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fstrs vr0, a0, (a1 << 2) +; CHECK-SF-NEXT: movih32 a0, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: store_R_w: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstrs vr0, a0, (a1 << 2) +; CHECK-DF-NEXT: movih32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: store_R_w: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fstr.32 vr0, (a0, a1 << 2) +; CHECK-SF2-NEXT: movih32 a0, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: store_R_w: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fstr.32 vr0, (a0, a1 << 2) +; CHECK-DF2-NEXT: movih32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds float, float* %a, i64 %idxprom + store float %c, float* %arrayidx, align 4 + ret float 0.0 +} + +define double @store_R_d(double* %a, i32 %b, double %c) local_unnamed_addr #0 { +; CHECK-SOFT-LABEL: store_R_d: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: ixd32 t0, a0, a1 +; CHECK-SOFT-NEXT: str32.w a2, (a0, a1 << 3) +; CHECK-SOFT-NEXT: st32.w a3, (t0, 1) +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: store_R_d: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: ixd32 t0, a0, a1 +; CHECK-SF-NEXT: str32.w a2, (a0, a1 << 3) +; CHECK-SF-NEXT: st32.w a3, (t0, 1) +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movi32 a1, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: store_R_d: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fstrd vr0, a0, (a1 << 3) +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: store_R_d: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: ixd32 t0, a0, a1 +; CHECK-SF2-NEXT: str32.w a2, (a0, a1 << 3) +; CHECK-SF2-NEXT: st32.w a3, (t0, 1) +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: store_R_d: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fstr.64 vr0, (a0, a1 << 3) +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds double, double* %a, i64 %idxprom + store double %c, double* %arrayidx, align 4 + ret double 0.0 +} + Index: llvm/test/CodeGen/CSKY/st.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/st.ll @@ -0,0 +1,322 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define signext i1 @store_I_bits(i1* %a, i1 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_bits: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: st32.b a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_bits: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.bs a0, a0, 3 +; CHECK-PIC-NEXT: sext32 a0, a0, 0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i1, i1* %a, i64 3 + store i1 %b, i1* %arrayidx, align 1 + ret i1 0 +} + +define zeroext i1 @store_I_bit_(i1* %a, i1 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_bit_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a1, a1, 1 +; CHECK-NEXT: st32.b a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_bit_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.b a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i1, i1* %a, i64 3 + store i1 %b, i1* %arrayidx, align 1 + ret i1 0 +} + +define signext i8 @store_I_bs(i8* %a, i8 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_bs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.b a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_bs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.bs a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i8, i8* %a, i64 3 + store i8 %b, i8* %arrayidx, align 1 + ret i8 0 +} + +define zeroext i8 @store_I_b_(i8* %a, i8 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_b_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.b a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_b_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.b a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i8, i8* %a, i64 3 + store i8 %b, i8* %arrayidx, align 1 + ret i8 0 +} + +define signext i16 @store_I_hs(i16* %a, i16 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_hs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.h a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_hs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.hs a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i16, i16* %a, i64 3 + store i16 %b, i16* %arrayidx, align 2 + ret i16 0 +} + +define zeroext i16 @store_I_h_(i16* %a, i16 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_h_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.h a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_h_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.h a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i16, i16* %a, i64 3 + store i16 %b, i16* %arrayidx, align 2 + ret i16 0 +} + +define i32 @store_I_w(i32* %a, i32 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_w: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.w a1, (a0, 3) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_w: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.w a0, a0, 3 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i32, i32* %a, i64 3 + store i32 %b, i32* %arrayidx, align 4 + ret i32 0 +} + +define i64 @store_I_d(i64* %a, i64 %b) local_unnamed_addr #0 { +; CHECK-LABEL: store_I_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.w a2, (a0, 7) +; CHECK-NEXT: st32.w a1, (a0, 6) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_d: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.w a2, a0, 6 +; CHECK-PIC-NEXT: ld32.w a1, a0, 7 +; CHECK-PIC-NEXT: mov32 a0, a2 +; CHECK-PIC-NEXT: rts32 +entry: + %arrayidx = getelementptr inbounds i64, i64* %a, i64 3 + store i64 %b, i64* %arrayidx, align 4 + ret i64 0 +} + +define i8 @store_I_i8_anyext(i8* %p, i8 %b) { +; CHECK-LABEL: store_I_i8_anyext: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: st32.b a1, (a0, 0) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_I_i8_anyext: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + store i8 %b, i8* %p, align 1 + ret i8 0 +} + +define signext i1 @store_R_bits(i1* %a, i32 %b, i1 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_bits: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a2, a2, 1 +; CHECK-NEXT: str32.b a2, (a0, a1 << 0) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_bits: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: sext32 a0, a0, 0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i1, i1* %a, i64 %idxprom + store i1 %c, i1* %arrayidx, align 1 + ret i1 0 +} + +define zeroext i1 @store_R_bit_(i1* %a, i32 %b, i1 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_bit_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a2, a2, 1 +; CHECK-NEXT: str32.b a2, (a0, a1 << 0) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_bit_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.b a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i1, i1* %a, i64 %idxprom + store i1 %c, i1* %arrayidx, align 1 + ret i1 0 +} + + +define signext i8 @store_R_bs(i8* %a, i32 %b, i8 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_bs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: str32.b a2, (a0, a1 << 0) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_bs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom + store i8 %c, i8* %arrayidx, align 1 + ret i8 0 +} + +define zeroext i8 @store_R_b_(i8* %a, i32 %b, i8 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_b_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: str32.b a2, (a0, a1 << 0) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_b_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.b a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i8, i8* %a, i64 %idxprom + store i8 %c, i8* %arrayidx, align 1 + ret i8 0 +} + +define signext i16 @store_R_hs(i16* %a, i32 %b, i16 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_hs: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: str32.h a2, (a0, a1 << 1) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_hs: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixh32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.hs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom + store i16 %c, i16* %arrayidx, align 2 + ret i16 0 +} + +define zeroext i16 @store_R_h_(i16* %a, i32 %b, i16 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_h_: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: str32.h a2, (a0, a1 << 1) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_h_: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixh32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.h a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i16, i16* %a, i64 %idxprom + store i16 %c, i16* %arrayidx, align 2 + ret i16 0 +} + +define i32 @store_R_w(i32* %a, i32 %b, i32 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_w: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: str32.w a2, (a0, a1 << 2) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_w: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixw32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.w a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom + store i32 %c, i32* %arrayidx, align 4 + ret i32 0 +} + +define i64 @store_R_d(i64* %a, i32 %b, i64 %c) local_unnamed_addr #0 { +; CHECK-LABEL: store_R_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ixd32 t0, a0, a1 +; CHECK-NEXT: str32.w a2, (a0, a1 << 3) +; CHECK-NEXT: st32.w a3, (t0, 1) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: store_R_d: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: ixd32 a1, a0, a1 +; CHECK-PIC-NEXT: ld32.w a0, a1, 0 +; CHECK-PIC-NEXT: ld32.w a1, a1, 1 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %b to i64 + %arrayidx = getelementptr inbounds i64, i64* %a, i64 %idxprom + store i64 %c, i64* %arrayidx, align 4 + ret i64 0 +} + +define i8 @storeR_i8_anyext(i8* %c, i32 %a, i8 %d) { +; CHECK-LABEL: storeR_i8_anyext: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: str32.b a2, (a0, a1 << 0) +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-PIC-LABEL: storeR_i8_anyext: +; CHECK-PIC: # %bb.0: # %entry +; CHECK-PIC-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-NEXT: ld32.bs a0, a0, 0 +; CHECK-PIC-NEXT: rts32 +entry: + %idxprom = sext i32 %a to i64 + %arrayidx = getelementptr inbounds i8, i8* %c, i64 %idxprom + store i8 %d, i8* %arrayidx, align 1 + ret i8 0 +} Index: llvm/test/CodeGen/CSKY/sub.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/sub.ll @@ -0,0 +1,121 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @subRR(i32 %x, i32 %y) { +; CHECK-LABEL: subRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i32 %y, %x + ret i32 %sub +} + +define i32 @subRI(i32 %x) { +; CHECK-LABEL: subRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i32 %x, 10 + ret i32 %sub +} + +define i32 @subRI_X(i32 %x) { +; CHECK-LABEL: subRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 65535 +; CHECK-NEXT: ori32 a1, a1, 61439 +; CHECK-NEXT: addu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i32 %x, 4097 + ret i32 %sub +} + +define i64 @SUB_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: SUB_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: setc +; CHECK-NEXT: subc32 a0, a2, a0 +; CHECK-NEXT: subc32 a1, a3, a1 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i64 %y, %x + ret i64 %sub +} + +define i64 @SUB_LONG_I(i64 %x) { +; CHECK-LABEL: SUB_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: clrc +; CHECK-NEXT: movih32 a2, 65535 +; CHECK-NEXT: ori32 a2, a2, 65535 +; CHECK-NEXT: addc32 a0, a0, a2 +; CHECK-NEXT: addc32 a1, a1, a2 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i64 %x, 1 + ret i64 %sub +} + +define i16 @SUB_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: SUB_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i16 %y, %x + ret i16 %sub +} + +define i16 @SUB_SHORT_I(i16 %x) { +; CHECK-LABEL: SUB_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i16 %x, 1 + ret i16 %sub +} + +define i8 @SUB_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: SUB_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i8 %y, %x + ret i8 %sub +} + +define i8 @SUB_CHAR_I(i8 %x) { +; CHECK-LABEL: SUB_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i8 %x, 1 + ret i8 %sub +} + +define i1 @SUB_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: SUB_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i1 %y, %x + ret i1 %sub +} + +define i1 @SUB_BIT_I(i1 %x) { +; CHECK-LABEL: SUB_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %sub = sub nsw i1 %x, 1 + ret i1 %sub +} + Index: llvm/test/CodeGen/CSKY/switch.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/switch.ll @@ -0,0 +1,125 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK-PIC-SMALL +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK-PIC-LARGE + +define i32 @f(i32 %val) { +; CHECK-LABEL: f: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 4 +; CHECK-NEXT: cmphs32 a1, a0 +; CHECK-NEXT: bf32 .LBB0_3 +; CHECK-NEXT: # %bb.1: # %entry +; CHECK-NEXT: lrw32 a1, [.LCPI0_0] +; CHECK-NEXT: ldr32.w a0, (a1, a0 << 2) +; CHECK-NEXT: jmp32 a0 +; CHECK-NEXT: .LBB0_2: # %onzero +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB0_3: # %otherwise +; CHECK-NEXT: movih32 a0, 65535 +; CHECK-NEXT: ori32 a0, a0, 65535 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB0_4: # %onone +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB0_5: # %ontwo +; CHECK-NEXT: movi32 a0, 2 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB0_6: # %onfour +; CHECK-NEXT: movi32 a0, 4 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .LBB0_7: # %onthree +; CHECK-NEXT: movi32 a0, 3 +; CHECK-NEXT: rts32 +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: # %bb.8: +; CHECK-NEXT: .LCPI0_0: +; CHECK-NEXT: .long .LJTI0_0 +; +; CHECK-PIC-SMALL-LABEL: f: +; CHECK-PIC-SMALL: # %bb.0: # %entry +; CHECK-PIC-SMALL-NEXT: movi32 a1, 4 +; CHECK-PIC-SMALL-NEXT: cmphs32 a1, a0 +; CHECK-PIC-SMALL-NEXT: bf32 .LBB0_3 +; CHECK-PIC-SMALL-NEXT: # %bb.1: # %entry +; CHECK-PIC-SMALL-NEXT: lrw32 a1, [.LCPI0_0] +; CHECK-PIC-SMALL-NEXT: ldr32.w a0, (a1, a0 << 2) +; CHECK-PIC-SMALL-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-SMALL-NEXT: jmp32 a0 +; CHECK-PIC-SMALL-NEXT: .LBB0_2: # %onzero +; CHECK-PIC-SMALL-NEXT: movi32 a0, 0 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .LBB0_3: # %otherwise +; CHECK-PIC-SMALL-NEXT: movih32 a0, 65535 +; CHECK-PIC-SMALL-NEXT: ori32 a0, a0, 65535 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .LBB0_4: # %onone +; CHECK-PIC-SMALL-NEXT: movi32 a0, 1 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .LBB0_5: # %ontwo +; CHECK-PIC-SMALL-NEXT: movi32 a0, 2 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .LBB0_6: # %onfour +; CHECK-PIC-SMALL-NEXT: movi32 a0, 4 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .LBB0_7: # %onthree +; CHECK-PIC-SMALL-NEXT: movi32 a0, 3 +; CHECK-PIC-SMALL-NEXT: rts32 +; CHECK-PIC-SMALL-NEXT: .p2align 2 +; CHECK-PIC-SMALL-NEXT: # %bb.8: +; CHECK-PIC-SMALL-NEXT: .LCPI0_0: +; CHECK-PIC-SMALL-NEXT: .long .LJTI0_0 +; +; CHECK-PIC-LARGE-LABEL: f: +; CHECK-PIC-LARGE: # %bb.0: # %entry +; CHECK-PIC-LARGE-NEXT: movi32 a1, 4 +; CHECK-PIC-LARGE-NEXT: cmphs32 a1, a0 +; CHECK-PIC-LARGE-NEXT: bf32 .LBB0_3 +; CHECK-PIC-LARGE-NEXT: # %bb.1: # %entry +; CHECK-PIC-LARGE-NEXT: lrw32 a1, [.LCPI0_0] +; CHECK-PIC-LARGE-NEXT: ldr32.w a0, (a1, a0 << 2) +; CHECK-PIC-LARGE-NEXT: addu32 a0, a0, a1 +; CHECK-PIC-LARGE-NEXT: jmp32 a0 +; CHECK-PIC-LARGE-NEXT: .LBB0_2: # %onzero +; CHECK-PIC-LARGE-NEXT: movi32 a0, 0 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .LBB0_3: # %otherwise +; CHECK-PIC-LARGE-NEXT: movih32 a0, 65535 +; CHECK-PIC-LARGE-NEXT: ori32 a0, a0, 65535 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .LBB0_4: # %onone +; CHECK-PIC-LARGE-NEXT: movi32 a0, 1 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .LBB0_5: # %ontwo +; CHECK-PIC-LARGE-NEXT: movi32 a0, 2 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .LBB0_6: # %onfour +; CHECK-PIC-LARGE-NEXT: movi32 a0, 4 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .LBB0_7: # %onthree +; CHECK-PIC-LARGE-NEXT: movi32 a0, 3 +; CHECK-PIC-LARGE-NEXT: rts32 +; CHECK-PIC-LARGE-NEXT: .p2align 2 +; CHECK-PIC-LARGE-NEXT: # %bb.8: +; CHECK-PIC-LARGE-NEXT: .LCPI0_0: +; CHECK-PIC-LARGE-NEXT: .long .LJTI0_0 +entry: + switch i32 %val, label %otherwise [ i32 0, label %onzero + i32 1, label %onone + i32 3, label %onfour + i32 4, label %onthree + i32 2, label %ontwo ] +onone: + ret i32 1 +ontwo: + ret i32 2 +onzero: + ret i32 0 +onfour: + ret i32 4 +onthree: + ret i32 3 +otherwise: + ret i32 -1 +} Index: llvm/test/CodeGen/CSKY/trunc.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/trunc.ll @@ -0,0 +1,198 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +; i64 --> i32/i16/i8/i1 +define i32 @truncR_i64_0(i64 %x) { +; CHECK-LABEL: truncR_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 %x to i32 + ret i32 %trunc +} + +define i16 @truncR_i64_1(i64 %x) { +; CHECK-LABEL: truncR_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 %x to i16 + ret i16 %trunc +} + +define i8 @truncR_i64_2(i64 %x) { +; CHECK-LABEL: truncR_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 %x to i8 + ret i8 %trunc +} + +define i1 @truncR_i64_3(i64 %x) { +; CHECK-LABEL: truncR_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 %x to i1 + ret i1 %trunc +} + +define i32 @truncI_i64_0() { +; CHECK-LABEL: truncI_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 10 to i32 + ret i32 %trunc +} + +define i16 @truncI_i64_1() { +; CHECK-LABEL: truncI_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 10 to i16 + ret i16 %trunc +} + +define i8 @truncI_i64_2() { +; CHECK-LABEL: truncI_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 10 to i8 + ret i8 %trunc +} + +define i1 @truncI_i64_3() { +; CHECK-LABEL: truncI_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i64 10 to i1 + ret i1 %trunc +} + +; i32 --> i16/i8/i1 +define i16 @truncR_i32_1(i32 %x) { +; CHECK-LABEL: truncR_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i32 %x to i16 + ret i16 %trunc +} + +define i8 @truncR_i32_2(i32 %x) { +; CHECK-LABEL: truncR_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i32 %x to i8 + ret i8 %trunc +} + +define i1 @truncR_i32_3(i32 %x) { +; CHECK-LABEL: truncR_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i32 %x to i1 + ret i1 %trunc +} + +define i16 @truncI_i32_1() { +; CHECK-LABEL: truncI_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i32 10 to i16 + ret i16 %trunc +} + +define i8 @truncI_i32_2() { +; CHECK-LABEL: truncI_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i32 10 to i8 + ret i8 %trunc +} + +define i1 @truncI_i32_3() { +; CHECK-LABEL: truncI_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i32 10 to i1 + ret i1 %trunc +} + +; i16 --> i8/i1 +define i8 @truncR_i16_2(i16 %x) { +; CHECK-LABEL: truncR_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i16 %x to i8 + ret i8 %trunc +} + +define i1 @truncR_i16_3(i16 %x) { +; CHECK-LABEL: truncR_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i16 %x to i1 + ret i1 %trunc +} + +define i8 @truncI_i16_2() { +; CHECK-LABEL: truncI_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i16 10 to i8 + ret i8 %trunc +} + +define i1 @truncI_i16_3() { +; CHECK-LABEL: truncI_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i16 10 to i1 + ret i1 %trunc +} + +;i8 --> i1 +define i1 @truncR_i8_3(i8 %x) { +; CHECK-LABEL: truncR_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i8 %x to i1 + ret i1 %trunc +} + +define i1 @truncI_i8_3() { +; CHECK-LABEL: truncI_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %trunc = trunc i8 10 to i1 + ret i1 %trunc +} + + Index: llvm/test/CodeGen/CSKY/udiv.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/udiv.ll @@ -0,0 +1,130 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @udivRR(i32 %x, i32 %y) { +; CHECK-LABEL: udivRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: divu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i32 %y, %x + ret i32 %udiv +} + +define i32 @udivRI(i32 %x) { +; CHECK-LABEL: udivRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 52428 +; CHECK-NEXT: ori32 a1, a1, 52429 +; CHECK-NEXT: mul.u32 a0, a0, a1 +; CHECK-NEXT: lsri32 a0, a1, 3 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i32 %x, 10 + ret i32 %udiv +} + +define i32 @udivRI_X(i32 %x) { +; CHECK-LABEL: udivRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 255 +; CHECK-NEXT: ori32 a1, a1, 61441 +; CHECK-NEXT: mul.u32 a0, a0, a1 +; CHECK-NEXT: lsri32 a0, a1, 4 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i32 %x, 4097 + ret i32 %udiv +} + +;TODO: Fix the test because it calls __divdi3 +;define i64 @UDIV_LONG(i64 %x, i64 %y) { +;entry: +; %udiv = udiv i64 %y, %x +; ret i64 %udiv +;} + +;TODO: Fix the test because it calls __divdi3 +;define i64 @UDIV_LONG_I(i64 %x) { +;entry: +; %udiv = udiv i64 %x, 3 +; ret i64 %udiv +;} + +define i16 @UDIV_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: UDIV_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: divu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i16 %y, %x + ret i16 %udiv +} + +define i16 @UDIV_SHORT_I(i16 %x) { +; CHECK-LABEL: UDIV_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movih32 a1, 43690 +; CHECK-NEXT: ori32 a1, a1, 43691 +; CHECK-NEXT: mul.u32 a0, a0, a1 +; CHECK-NEXT: lsri32 a0, a1, 1 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i16 %x, 3 + ret i16 %udiv +} + +define i8 @UDIV_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: UDIV_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: divu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i8 %y, %x + ret i8 %udiv +} + +define i8 @UDIV_CHAR_I(i8 %x) { +; CHECK-LABEL: UDIV_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a1, 43690 +; CHECK-NEXT: ori32 a1, a1, 43691 +; CHECK-NEXT: mul.u32 a0, a0, a1 +; CHECK-NEXT: lsri32 a0, a1, 1 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i8 %x, 3 + ret i8 %udiv +} + +define i1 @UDIV_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: UDIV_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i1 %y, %x + ret i1 %udiv +} + +define i1 @UDIV_BIT_I(i1 %x) { +; CHECK-LABEL: UDIV_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 65535 +; CHECK-NEXT: ori32 a2, a1, 65535 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a1, a2 +; CHECK-NEXT: mov32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %udiv = udiv i1 %x, 1 + ret i1 %udiv +} + Index: llvm/test/CodeGen/CSKY/uitofp.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/uitofp.ll @@ -0,0 +1,930 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s --check-prefix=CHECK-SOFT +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf | FileCheck %s --check-prefix=CHECK-SF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv2_sf -mattr=+fpuv2_df | FileCheck %s --check-prefix=CHECK-DF +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf | FileCheck %s --check-prefix=CHECK-SF2 +; RUN: llc -verify-machineinstrs < %s -mtriple=csky -float-abi=hard -mattr=+fpuv3_sf -mattr=+fpuv3_df | FileCheck %s --check-prefix=CHECK-DF2 + +; i64/i32/i16/i8/i1 --> double +define double @uitofpR_double(i64 %x) { +; CHECK-SOFT-LABEL: uitofpR_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI0_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI0_0: +; CHECK-SOFT-NEXT: .long __floatundidf +; +; CHECK-SF-LABEL: uitofpR_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI0_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI0_0: +; CHECK-SF-NEXT: .long __floatundidf +; +; CHECK-DF-LABEL: uitofpR_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI0_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI0_0: +; CHECK-DF-NEXT: .long __floatundidf +; +; CHECK-SF2-LABEL: uitofpR_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI0_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI0_0: +; CHECK-SF2-NEXT: .long __floatundidf +; +; CHECK-DF2-LABEL: uitofpR_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI0_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI0_0: +; CHECK-DF2-NEXT: .long __floatundidf +entry: + %uitofp = uitofp i64 %x to double + ret double %uitofp +} + +define double @uitofpR_double_0(i32 %x) { +; CHECK-SOFT-LABEL: uitofpR_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI1_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI1_0: +; CHECK-SOFT-NEXT: .long __floatunsidf +; +; CHECK-SF-LABEL: uitofpR_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI1_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI1_0: +; CHECK-SF-NEXT: .long __floatunsidf +; +; CHECK-DF-LABEL: uitofpR_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI1_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI1_0: +; CHECK-SF2-NEXT: .long __floatunsidf +; +; CHECK-DF2-LABEL: uitofpR_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i32 %x to double + ret double %uitofp +} + +define double @uitofpR_double_1(i16 %x) { +; CHECK-SOFT-LABEL: uitofpR_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: zext32 a0, a0, 15, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI2_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI2_0: +; CHECK-SOFT-NEXT: .long __floatunsidf +; +; CHECK-SF-LABEL: uitofpR_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: zext32 a0, a0, 15, 0 +; CHECK-SF-NEXT: jsri32 .LCPI2_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI2_0: +; CHECK-SF-NEXT: .long __floatunsidf +; +; CHECK-DF-LABEL: uitofpR_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: zext32 a0, a0, 15, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: zext32 a0, a0, 15, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI2_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI2_0: +; CHECK-SF2-NEXT: .long __floatunsidf +; +; CHECK-DF2-LABEL: uitofpR_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: zext32 a0, a0, 15, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i16 %x to double + ret double %uitofp +} + +define double @uitofpR_double_2(i8 %x) { +; CHECK-SOFT-LABEL: uitofpR_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: zext32 a0, a0, 7, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI3_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI3_0: +; CHECK-SOFT-NEXT: .long __floatunsidf +; +; CHECK-SF-LABEL: uitofpR_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: zext32 a0, a0, 7, 0 +; CHECK-SF-NEXT: jsri32 .LCPI3_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI3_0: +; CHECK-SF-NEXT: .long __floatunsidf +; +; CHECK-DF-LABEL: uitofpR_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: zext32 a0, a0, 7, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: zext32 a0, a0, 7, 0 +; CHECK-SF2-NEXT: jsri32 .LCPI3_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI3_0: +; CHECK-SF2-NEXT: .long __floatunsidf +; +; CHECK-DF2-LABEL: uitofpR_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: zext32 a0, a0, 7, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i8 %x to double + ret double %uitofp +} + +define double @uitofpR_double_3(i1 %x) { +; CHECK-SOFT-LABEL: uitofpR_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: andi32 a0, a0, 1 +; CHECK-SOFT-NEXT: jsri32 .LCPI4_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI4_0: +; CHECK-SOFT-NEXT: .long __floatunsidf +; +; CHECK-SF-LABEL: uitofpR_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: jsri32 .LCPI4_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI4_0: +; CHECK-SF-NEXT: .long __floatunsidf +; +; CHECK-DF-LABEL: uitofpR_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitod vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: andi32 a0, a0, 1 +; CHECK-SF2-NEXT: jsri32 .LCPI4_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI4_0: +; CHECK-SF2-NEXT: .long __floatunsidf +; +; CHECK-DF2-LABEL: uitofpR_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: andi32 a0, a0, 1 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f64 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i1 %x to double + ret double %uitofp +} + +define double @uitofpI_double() { +; CHECK-SOFT-LABEL: uitofpI_double: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_double: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_double: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_double: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_double: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i64 10 to double + ret double %uitofp +} + +define double @uitofpI_double_0() { +; CHECK-SOFT-LABEL: uitofpI_double_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_double_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_double_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_double_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_double_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i32 10 to double + ret double %uitofp +} + +define double @uitofpI_double_1() { +; CHECK-SOFT-LABEL: uitofpI_double_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_double_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_double_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_double_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_double_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i16 10 to double + ret double %uitofp +} + +define double @uitofpI_double_2() { +; CHECK-SOFT-LABEL: uitofpI_double_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movih32 a1, 16420 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_double_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movih32 a1, 16420 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_double_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: movih32 a0, 16420 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_double_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movih32 a1, 16420 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_double_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16420 +; CHECK-DF2-NEXT: movi32 a1, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a1, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i8 10 to double + ret double %uitofp +} + +define double @uitofpI_double_3() { +; CHECK-SOFT-LABEL: uitofpI_double_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: movi32 a1, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_double_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movi32 a0, 0 +; CHECK-SF-NEXT: movi32 a1, 0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_double_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movi32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fmtvrh vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_double_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movi32 a0, 0 +; CHECK-SF2-NEXT: movi32 a1, 0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_double_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movi32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.64 vr0, a0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i1 10 to double + ret double %uitofp +} + +; i64/i32/i16/i8/i1 --> float +define float @uitofpR_float(i64 %x) { +; CHECK-SOFT-LABEL: uitofpR_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI10_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI10_0: +; CHECK-SOFT-NEXT: .long __floatundisf +; +; CHECK-SF-LABEL: uitofpR_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: subi32 sp, sp, 4 +; CHECK-SF-NEXT: st32.w lr, (sp, 0) +; CHECK-SF-NEXT: jsri32 .LCPI10_0 +; CHECK-SF-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF-NEXT: addi32 sp, sp, 4 +; CHECK-SF-NEXT: rts32 +; CHECK-SF-NEXT: .p2align 2 +; CHECK-SF-NEXT: # %bb.1: +; CHECK-SF-NEXT: .LCPI10_0: +; CHECK-SF-NEXT: .long __floatundisf +; +; CHECK-DF-LABEL: uitofpR_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: subi32 sp, sp, 4 +; CHECK-DF-NEXT: st32.w lr, (sp, 0) +; CHECK-DF-NEXT: jsri32 .LCPI10_0 +; CHECK-DF-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF-NEXT: addi32 sp, sp, 4 +; CHECK-DF-NEXT: rts32 +; CHECK-DF-NEXT: .p2align 2 +; CHECK-DF-NEXT: # %bb.1: +; CHECK-DF-NEXT: .LCPI10_0: +; CHECK-DF-NEXT: .long __floatundisf +; +; CHECK-SF2-LABEL: uitofpR_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: subi32 sp, sp, 4 +; CHECK-SF2-NEXT: st32.w lr, (sp, 0) +; CHECK-SF2-NEXT: jsri32 .LCPI10_0 +; CHECK-SF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-SF2-NEXT: addi32 sp, sp, 4 +; CHECK-SF2-NEXT: rts32 +; CHECK-SF2-NEXT: .p2align 2 +; CHECK-SF2-NEXT: # %bb.1: +; CHECK-SF2-NEXT: .LCPI10_0: +; CHECK-SF2-NEXT: .long __floatundisf +; +; CHECK-DF2-LABEL: uitofpR_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: subi32 sp, sp, 4 +; CHECK-DF2-NEXT: st32.w lr, (sp, 0) +; CHECK-DF2-NEXT: jsri32 .LCPI10_0 +; CHECK-DF2-NEXT: ld32.w lr, (sp, 0) +; CHECK-DF2-NEXT: addi32 sp, sp, 4 +; CHECK-DF2-NEXT: rts32 +; CHECK-DF2-NEXT: .p2align 2 +; CHECK-DF2-NEXT: # %bb.1: +; CHECK-DF2-NEXT: .LCPI10_0: +; CHECK-DF2-NEXT: .long __floatundisf +entry: + %uitofp = uitofp i64 %x to float + ret float %uitofp +} + +define float @uitofpR_float_0(i32 %x) { +; CHECK-SOFT-LABEL: uitofpR_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: jsri32 .LCPI11_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI11_0: +; CHECK-SOFT-NEXT: .long __floatunsisf +; +; CHECK-SF-LABEL: uitofpR_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fuitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpR_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpR_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i32 %x to float + ret float %uitofp +} + +define float @uitofpR_float_1(i16 %x) { +; CHECK-SOFT-LABEL: uitofpR_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: zext32 a0, a0, 15, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI12_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI12_0: +; CHECK-SOFT-NEXT: .long __floatunsisf +; +; CHECK-SF-LABEL: uitofpR_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: zext32 a0, a0, 15, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fuitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpR_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: zext32 a0, a0, 15, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: zext32 a0, a0, 15, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpR_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: zext32 a0, a0, 15, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i16 %x to float + ret float %uitofp +} + +define float @uitofpR_float_2(i8 %x) { +; CHECK-SOFT-LABEL: uitofpR_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: zext32 a0, a0, 7, 0 +; CHECK-SOFT-NEXT: jsri32 .LCPI13_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI13_0: +; CHECK-SOFT-NEXT: .long __floatunsisf +; +; CHECK-SF-LABEL: uitofpR_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: zext32 a0, a0, 7, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fuitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpR_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: zext32 a0, a0, 7, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: zext32 a0, a0, 7, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpR_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: zext32 a0, a0, 7, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i8 %x to float + ret float %uitofp +} + +define float @uitofpR_float_3(i1 %x) { +; CHECK-SOFT-LABEL: uitofpR_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: subi32 sp, sp, 4 +; CHECK-SOFT-NEXT: st32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: andi32 a0, a0, 1 +; CHECK-SOFT-NEXT: jsri32 .LCPI14_0 +; CHECK-SOFT-NEXT: ld32.w lr, (sp, 0) +; CHECK-SOFT-NEXT: addi32 sp, sp, 4 +; CHECK-SOFT-NEXT: rts32 +; CHECK-SOFT-NEXT: .p2align 2 +; CHECK-SOFT-NEXT: # %bb.1: +; CHECK-SOFT-NEXT: .LCPI14_0: +; CHECK-SOFT-NEXT: .long __floatunsisf +; +; CHECK-SF-LABEL: uitofpR_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: andi32 a0, a0, 1 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: fuitos vr0, vr0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpR_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: andi32 a0, a0, 1 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: fuitos vr0, vr0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpR_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: andi32 a0, a0, 1 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpR_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: andi32 a0, a0, 1 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: fitof.u32.f32 vr0, vr0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i1 %x to float + ret float %uitofp +} + +define float @uitofpI_float() { +; CHECK-SOFT-LABEL: uitofpI_float: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_float: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_float: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_float: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_float: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i64 10 to float + ret float %uitofp +} + +define float @uitofpI_float_0() { +; CHECK-SOFT-LABEL: uitofpI_float_0: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_float_0: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_float_0: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_float_0: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_float_0: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i32 10 to float + ret float %uitofp +} + +define float @uitofpI_float_1() { +; CHECK-SOFT-LABEL: uitofpI_float_1: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_float_1: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_float_1: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_float_1: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_float_1: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i16 10 to float + ret float %uitofp +} + +define float @uitofpI_float_2() { +; CHECK-SOFT-LABEL: uitofpI_float_2: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movih32 a0, 16672 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_float_2: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 16672 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_float_2: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 16672 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_float_2: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 16672 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_float_2: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 16672 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i8 10 to float + ret float %uitofp +} + +define float @uitofpI_float_3() { +; CHECK-SOFT-LABEL: uitofpI_float_3: +; CHECK-SOFT: # %bb.0: # %entry +; CHECK-SOFT-NEXT: movi32 a0, 0 +; CHECK-SOFT-NEXT: rts32 +; +; CHECK-SF-LABEL: uitofpI_float_3: +; CHECK-SF: # %bb.0: # %entry +; CHECK-SF-NEXT: movih32 a0, 0 +; CHECK-SF-NEXT: fmtvrl vr0, a0 +; CHECK-SF-NEXT: rts32 +; +; CHECK-DF-LABEL: uitofpI_float_3: +; CHECK-DF: # %bb.0: # %entry +; CHECK-DF-NEXT: movih32 a0, 0 +; CHECK-DF-NEXT: fmtvrl vr0, a0 +; CHECK-DF-NEXT: rts32 +; +; CHECK-SF2-LABEL: uitofpI_float_3: +; CHECK-SF2: # %bb.0: # %entry +; CHECK-SF2-NEXT: movih32 a0, 0 +; CHECK-SF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-SF2-NEXT: rts32 +; +; CHECK-DF2-LABEL: uitofpI_float_3: +; CHECK-DF2: # %bb.0: # %entry +; CHECK-DF2-NEXT: movih32 a0, 0 +; CHECK-DF2-NEXT: fmtvr.32.1 vr0, a0 +; CHECK-DF2-NEXT: rts32 +entry: + %uitofp = uitofp i1 10 to float + ret float %uitofp +} + + Index: llvm/test/CodeGen/CSKY/urem.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/urem.ll @@ -0,0 +1,145 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @uremRR(i32 %x, i32 %y) { +; CHECK-LABEL: uremRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: divu32 a2, a1, a0 +; CHECK-NEXT: mult32 a0, a2, a0 +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %urem = urem i32 %y, %x + ret i32 %urem +} + +define i32 @uremRI(i32 %x) { +; CHECK-LABEL: uremRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 52428 +; CHECK-NEXT: ori32 a1, a1, 52429 +; CHECK-NEXT: mul.u32 a1, a0, a1 +; CHECK-NEXT: lsri32 a1, a2, 3 +; CHECK-NEXT: movi32 a2, 10 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %urem = urem i32 %x, 10 + ret i32 %urem +} + +define i32 @uremRI_X(i32 %x) { +; CHECK-LABEL: uremRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movih32 a1, 255 +; CHECK-NEXT: ori32 a1, a1, 61441 +; CHECK-NEXT: mul.u32 a1, a0, a1 +; CHECK-NEXT: lsri32 a1, a2, 4 +; CHECK-NEXT: movi32 a2, 4097 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %urem = urem i32 %x, 4097 + ret i32 %urem +} + +;TODO: Fix the test because it calls __divdi3 +;define i64 @UREM_LONG(i64 %x, i64 %y) { +;entry: +; %urem = urem i64 %y, %x +; ret i64 %urem +;} + +;TODO: Fix the test because it calls __divdi3 +;define i64 @UREM_LONG_I(i64 %x) { +;entry: +; %urem = urem i64 %x, 3 +; ret i64 %urem +;} + +define i16 @UREM_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: UREM_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: zext32 a1, a1, 15, 0 +; CHECK-NEXT: divu32 a2, a1, a0 +; CHECK-NEXT: mult32 a0, a2, a0 +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %urem = urem i16 %y, %x + ret i16 %urem +} + +define i16 @UREM_SHORT_I(i16 %x) { +; CHECK-LABEL: UREM_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movih32 a1, 43690 +; CHECK-NEXT: ori32 a1, a1, 43691 +; CHECK-NEXT: mul.u32 a1, a0, a1 +; CHECK-NEXT: lsri32 a1, a2, 1 +; CHECK-NEXT: movi32 a2, 3 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %urem = urem i16 %x, 3 + ret i16 %urem +} + +define i8 @UREM_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: UREM_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: zext32 a1, a1, 7, 0 +; CHECK-NEXT: divu32 a2, a1, a0 +; CHECK-NEXT: mult32 a0, a2, a0 +; CHECK-NEXT: subu32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %urem = urem i8 %y, %x + ret i8 %urem +} + +define i8 @UREM_CHAR_I(i8 %x) { +; CHECK-LABEL: UREM_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movih32 a1, 43690 +; CHECK-NEXT: ori32 a1, a1, 43691 +; CHECK-NEXT: mul.u32 a1, a0, a1 +; CHECK-NEXT: lsri32 a1, a2, 1 +; CHECK-NEXT: movi32 a2, 3 +; CHECK-NEXT: mult32 a1, a1, a2 +; CHECK-NEXT: subu32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %urem = urem i8 %x, 3 + ret i8 %urem +} + +define i1 @UREM_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: UREM_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %urem = urem i1 %y, %x + ret i1 %urem +} + +define i1 @UREM_BIT_I(i1 %x) { +; CHECK-LABEL: UREM_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: btsti32 a0, 0 +; CHECK-NEXT: movt32 a0, a1 +; CHECK-NEXT: rts32 +entry: + %urem = urem i1 %x, 1 + ret i1 %urem +} + Index: llvm/test/CodeGen/CSKY/xor.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/xor.ll @@ -0,0 +1,115 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +define i32 @xorRR(i32 %x, i32 %y) { +; CHECK-LABEL: xorRR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %xor = xor i32 %y, %x + ret i32 %xor +} + +define i32 @xorRI(i32 %x) { +; CHECK-LABEL: xorRI: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 10 +; CHECK-NEXT: rts32 +entry: + %xor = xor i32 %x, 10 + ret i32 %xor +} + +define i32 @xorRI_X(i32 %x) { +; CHECK-LABEL: xorRI_X: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 4097 +; CHECK-NEXT: xor32 a0, a0, a1 +; CHECK-NEXT: rts32 +entry: + %xor = xor i32 %x, 4097 + ret i32 %xor +} + +define i64 @XOR_LONG(i64 %x, i64 %y) { +; CHECK-LABEL: XOR_LONG: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a2, a0 +; CHECK-NEXT: xor32 a1, a3, a1 +; CHECK-NEXT: rts32 +entry: + %xor = xor i64 %y, %x + ret i64 %xor +} + +define i64 @XOR_LONG_I(i64 %x) { +; CHECK-LABEL: XOR_LONG_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %xor = xor i64 %x, 1 + ret i64 %xor +} + +define i16 @XOR_SHORT(i16 %x, i16 %y) { +; CHECK-LABEL: XOR_SHORT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %xor = xor i16 %y, %x + ret i16 %xor +} + +define i16 @XOR_SHORT_I(i16 %x) { +; CHECK-LABEL: XOR_SHORT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %xor = xor i16 %x, 1 + ret i16 %xor +} + +define i8 @XOR_CHAR(i8 %x, i8 %y) { +; CHECK-LABEL: XOR_CHAR: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %xor = xor i8 %y, %x + ret i8 %xor +} + +define i8 @XOR_CHAR_I(i8 %x) { +; CHECK-LABEL: XOR_CHAR_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %xor = xor i8 %x, 1 + ret i8 %xor +} + +define i1 @XOR_BIT(i1 %x, i1 %y) { +; CHECK-LABEL: XOR_BIT: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xor32 a0, a1, a0 +; CHECK-NEXT: rts32 +entry: + %xor = xor i1 %y, %x + ret i1 %xor +} + +define i1 @XOR_BIT_I(i1 %x) { +; CHECK-LABEL: XOR_BIT_I: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xori32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %xor = xor i1 %x, 1 + ret i1 %xor +} + Index: llvm/test/CodeGen/CSKY/zext.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/CSKY/zext.ll @@ -0,0 +1,215 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=csky | FileCheck %s + +; i32/i16/i8/i1 --> i64 +define i64 @zextR_i64_0(i32 %x) { +; CHECK-LABEL: zextR_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i32 %x to i64 + ret i64 %zext +} + +define i64 @zextR_i64_1(i16 %x) { +; CHECK-LABEL: zextR_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i16 %x to i64 + ret i64 %zext +} + +define i64 @zextR_i64_2(i8 %x) { +; CHECK-LABEL: zextR_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i8 %x to i64 + ret i64 %zext +} + +define i64 @zextR_i64_3(i1 %x) { +; CHECK-LABEL: zextR_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 %x to i64 + ret i64 %zext +} + +define i64 @zextI_i64_0() { +; CHECK-LABEL: zextI_i64_0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i32 10 to i64 + ret i64 %zext +} + +define i64 @zextI_i64_1() { +; CHECK-LABEL: zextI_i64_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i16 10 to i64 + ret i64 %zext +} + +define i64 @zextI_i64_2() { +; CHECK-LABEL: zextI_i64_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i8 10 to i64 + ret i64 %zext +} + +define i64 @zextI_i64_3() { +; CHECK-LABEL: zextI_i64_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: movi32 a1, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 10 to i64 + ret i64 %zext +} + +; i16/i8/i1 --> i32 +define i32 @zextR_i32_1(i16 %x) { +; CHECK-LABEL: zextR_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 15, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i16 %x to i32 + ret i32 %zext +} + +define i32 @zextR_i32_2(i8 %x) { +; CHECK-LABEL: zextR_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i8 %x to i32 + ret i32 %zext +} + +define i32 @zextR_i32_3(i1 %x) { +; CHECK-LABEL: zextR_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 %x to i32 + ret i32 %zext +} + +define i32 @zextI_i32_1() { +; CHECK-LABEL: zextI_i32_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %zext = zext i16 10 to i32 + ret i32 %zext +} + +define i32 @zextI_i32_2() { +; CHECK-LABEL: zextI_i32_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %zext = zext i8 10 to i32 + ret i32 %zext +} + +define i32 @zextI_i32_3() { +; CHECK-LABEL: zextI_i32_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 1 to i32 + ret i32 %zext +} + +; i8/i1 --> i16 +define i16 @zextR_i16_2(i8 %x) { +; CHECK-LABEL: zextR_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: zext32 a0, a0, 7, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i8 %x to i16 + ret i16 %zext +} + +define i16 @zextR_i16_3(i1 %x) { +; CHECK-LABEL: zextR_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 %x to i16 + ret i16 %zext +} + +define i16 @zextI_i16_2() { +; CHECK-LABEL: zextI_i16_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 10 +; CHECK-NEXT: rts32 +entry: + %zext = zext i8 10 to i16 + ret i16 %zext +} + +define i16 @zextI_i16_3() { +; CHECK-LABEL: zextI_i16_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 1 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 1 to i16 + ret i16 %zext +} + +;i1 --> i8 +define i8 @zextR_i8_3(i1 %x) { +; CHECK-LABEL: zextR_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: andi32 a0, a0, 1 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 %x to i8 + ret i8 %zext +} + +define i8 @zextI_i8_3() { +; CHECK-LABEL: zextI_i8_3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movi32 a0, 0 +; CHECK-NEXT: rts32 +entry: + %zext = zext i1 10 to i8 + ret i8 %zext +} + + Index: llvm/utils/UpdateTestChecks/asm.py =================================================================== --- llvm/utils/UpdateTestChecks/asm.py +++ llvm/utils/UpdateTestChecks/asm.py @@ -85,6 +85,12 @@ r'.Lfunc_end[0-9]+:\n', flags=(re.M | re.S)) +ASM_FUNCTION_CSKY_RE = re.compile( + r'^_?(?P[^:]+):[ \t]*#+[ \t]*@(?P=func)\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?' + r'(?P^##?[ \t]+[^:]+:.*?)\s*' + r'.Lfunc_end[0-9]+:\n', + flags=(re.M | re.S)) + ASM_FUNCTION_LANAI_RE = re.compile( r'^_?(?P[^:]+):[ \t]*!+[ \t]*@(?P=func)\n' r'(?:[ \t]+.cfi_startproc\n)?' # drop optional cfi noise @@ -269,6 +275,18 @@ asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) return asm +def scrub_asm_csky(asm, args): + # Scrub runs of whitespace out of the assembly, but leave the leading + # whitespace in place. + asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm) + # Expand the tabs used for indentation. + asm = string.expandtabs(asm, 2) + # Strip kill operands inserted into the asm. + asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm) + # Strip trailing whitespace. + asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm) + return asm + def scrub_asm_lanai(asm, args): # Scrub runs of whitespace out of the assembly, but leave the leading # whitespace in place. @@ -352,6 +370,7 @@ 'sparc': (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE), 's390x': (scrub_asm_systemz, ASM_FUNCTION_SYSTEMZ_RE), 'wasm32': (scrub_asm_wasm32, ASM_FUNCTION_WASM32_RE), + 'csky': (scrub_asm_csky, ASM_FUNCTION_CSKY_RE), } handler = None best_prefix = ''