llvm.org GIT mirror llvm / 33ba8b0
Remove the Alpha backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143164 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 8 years ago
98 changed file(s) with 12 addition(s) and 6266 deletion(s). Raw diff Collapse all Expand all
6363 endif()
6464
6565 set(LLVM_ALL_TARGETS
66 Alpha
6766 ARM
6867 CBackend
6968 CellSPU
351351 amd64-* | x86_64-*) llvm_cv_target_arch="x86_64" ;;
352352 sparc*-*) llvm_cv_target_arch="Sparc" ;;
353353 powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
354 alpha*-*) llvm_cv_target_arch="Alpha" ;;
355354 arm*-*) llvm_cv_target_arch="ARM" ;;
356355 mips-*) llvm_cv_target_arch="Mips" ;;
357356 xcore-*) llvm_cv_target_arch="XCore" ;;
486485 Sparc) AC_SUBST(TARGET_HAS_JIT,0) ;;
487486 PowerPC) AC_SUBST(TARGET_HAS_JIT,1) ;;
488487 x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
489 Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;;
490488 ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
491489 Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
492490 XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
602600 TARGETS_TO_BUILD=""
603601 AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
604602 [Build specific host targets: all or target1,target2,... Valid targets are:
605 host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu,
603 host, x86, x86_64, sparc, powerpc, arm, mips, spu,
606604 xcore, msp430, ptx, cbe, and cpp (default=all)]),,
607605 enableval=all)
608606 if test "$enableval" = host-only ; then
609607 enableval=host
610608 fi
611609 case "$enableval" in
612 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX" ;;
610 all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX" ;;
613611 *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
614612 case "$a_target" in
615613 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
616614 x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
617615 sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
618616 powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
619 alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
620617 arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
621618 mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
622619 spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
631628 x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
632629 Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
633630 PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
634 Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
635631 ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
636632 Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
637633 MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
308308 set(LLVM_NATIVE_ARCH Sparc)
309309 elseif (LLVM_NATIVE_ARCH MATCHES "powerpc")
310310 set(LLVM_NATIVE_ARCH PowerPC)
311 elseif (LLVM_NATIVE_ARCH MATCHES "alpha")
312 set(LLVM_NATIVE_ARCH Alpha)
313311 elseif (LLVM_NATIVE_ARCH MATCHES "arm")
314312 set(LLVM_NATIVE_ARCH ARM)
315313 elseif (LLVM_NATIVE_ARCH MATCHES "mips")
14141414 (default is YES)
14151415 --enable-targets Build specific host targets: all or
14161416 target1,target2,... Valid targets are: host, x86,
1417 x86_64, sparc, powerpc, alpha, arm, mips, spu,
1417 x86_64, sparc, powerpc, arm, mips, spu,
14181418 xcore, msp430, ptx, cbe, and cpp (default=all)
14191419 --enable-cbe-printf-a Enable C Backend output with hex floating point via
14201420 %a (default is YES)
38733873 amd64-* | x86_64-*) llvm_cv_target_arch="x86_64" ;;
38743874 sparc*-*) llvm_cv_target_arch="Sparc" ;;
38753875 powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
3876 alpha*-*) llvm_cv_target_arch="Alpha" ;;
38773876 arm*-*) llvm_cv_target_arch="ARM" ;;
38783877 mips-*) llvm_cv_target_arch="Mips" ;;
38793878 xcore-*) llvm_cv_target_arch="XCore" ;;
50715070 ;;
50725071 x86_64) TARGET_HAS_JIT=1
50735072 ;;
5074 Alpha) TARGET_HAS_JIT=0
5075 ;;
50765073 ARM) TARGET_HAS_JIT=1
50775074 ;;
50785075 Mips) TARGET_HAS_JIT=1
52695266 enableval=host
52705267 fi
52715268 case "$enableval" in
5272 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX" ;;
5269 all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX" ;;
52735270 *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
52745271 case "$a_target" in
52755272 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
52765273 x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
52775274 sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
52785275 powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
5279 alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
52805276 arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
52815277 mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
52825278 spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
52915287 x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
52925288 Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
52935289 PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
5294 Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
52955290 ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
52965291 Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
52975292 MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
248248
Semicolon-separated list of targets to build, or all for
249249 building all targets. Case-sensitive. For Visual C++ defaults
250250 to X86. On the other cases defaults to all. Example:
251 -DLLVM_TARGETS_TO_BUILD="X86;PowerPC;Alpha".
251 -DLLVM_TARGETS_TO_BUILD="X86;PowerPC".
252252
253253
LLVM_BUILD_TOOLS:BOOL
254254
Build LLVM tools. Defaults to ON. Targets for building each tool
2020
2121
  • Hardware
  • 2222
    23
  • Alpha
  • 2423
  • ARM
  • 2524
  • Itanium
  • 2625
  • MIPS
  • 4847
    4948
    5049
    51

    Alpha

    52
    53
    54
    55
  • 56 href="http://ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html">Alpha manuals
    57
    58
    59
    60
    61
    6250

    ARM

    6351
    6452
    125125 Aggressive instruction selector for directed acyclic graphs
    126126
    127127
    Target Libraries
    128
    LLVMAlpha.o
    129 Code generation for Alpha architecture
    130128
    LLVMARM.o
    131129 Code generation for ARM architecture
    132130
    LLVMCBackend.o
    332330
  • libLLVMSystem.a
  • 333331
  • libLLVMTarget.a
  • 334332
    335
    LLVMAlpha.o
    336
  • libLLVMCodeGen.a
  • 337
  • libLLVMCore.a
  • 338
  • libLLVMSelectionDAG.a
  • 339
  • libLLVMSupport.a
  • 340
  • libLLVMSystem.a
  • 341
  • libLLVMTarget.a
  • 342
    343333
    LLVMCBackend.o
    344334
  • libLLVMAnalysis.a
  • 345335
  • libLLVMCodeGen.a
  • 4242 enum ArchType {
    4343 UnknownArch,
    4444
    45 alpha, // Alpha: alpha
    4645 arm, // ARM; arm, armv.*, xscale
    4746 cellspu, // CellSPU: spu, cellspu
    4847 mips, // MIPS: mips, mipsallegrex
    442442 include "llvm/IntrinsicsX86.td"
    443443 include "llvm/IntrinsicsARM.td"
    444444 include "llvm/IntrinsicsCellSPU.td"
    445 include "llvm/IntrinsicsAlpha.td"
    446445 include "llvm/IntrinsicsXCore.td"
    447446 include "llvm/IntrinsicsPTX.td"
    +0
    -18
    include/llvm/IntrinsicsAlpha.td less more
    None //===- IntrinsicsAlpha.td - Defines Alpha intrinsics -------*- tablegen -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file defines all of the Alpha-specific intrinsics.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13
    14 let TargetPrefix = "alpha" in { // All intrinsics start with "llvm.alpha.".
    15 def int_alpha_umulh : GCCBuiltin<"__builtin_alpha_umulh">,
    16 Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
    17 }
    1717 case InvalidArch: return "";
    1818 case UnknownArch: return "unknown";
    1919
    20 case alpha: return "alpha";
    2120 case arm: return "arm";
    2221 case cellspu: return "cellspu";
    2322 case mips: return "mips";
    4948 default:
    5049 return 0;
    5150
    52 case alpha: return "alpha";
    53
    5451 case arm:
    5552 case thumb: return "arm";
    5653
    130127 }
    131128
    132129 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
    133 if (Name == "alpha")
    134 return alpha;
    135130 if (Name == "arm")
    136131 return arm;
    137132 if (Name == "cellspu")
    285280 else if (ArchName == "thumb" ||
    286281 ArchName.startswith("thumbv"))
    287282 return thumb;
    288 else if (ArchName.startswith("alpha"))
    289 return alpha;
    290283 else if (ArchName == "spu" || ArchName == "cellspu")
    291284 return cellspu;
    292285 else if (ArchName == "msp430")
    +0
    -43
    lib/Target/Alpha/Alpha.h less more
    None //===-- Alpha.h - Top-level interface for Alpha representation --*- C++ -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file contains the entry points for global functions defined in the LLVM
    10 // Alpha back-end.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #ifndef TARGET_ALPHA_H
    15 #define TARGET_ALPHA_H
    16
    17 #include "MCTargetDesc/AlphaMCTargetDesc.h"
    18 #include "llvm/Target/TargetMachine.h"
    19
    20 namespace llvm {
    21 namespace Alpha {
    22 // These describe LDAx
    23
    24 static const int IMM_LOW = -32768;
    25 static const int IMM_HIGH = 32767;
    26 static const int IMM_MULT = 65536;
    27 }
    28
    29 class AlphaTargetMachine;
    30 class FunctionPass;
    31 class formatted_raw_ostream;
    32
    33 FunctionPass *createAlphaISelDag(AlphaTargetMachine &TM);
    34 FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM);
    35 FunctionPass *createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM,
    36 JITCodeEmitter &JCE);
    37 FunctionPass *createAlphaLLRPPass(AlphaTargetMachine &tm);
    38 FunctionPass *createAlphaBranchSelectionPass();
    39
    40 } // end namespace llvm;
    41
    42 #endif
    +0
    -68
    lib/Target/Alpha/Alpha.td less more
    None //===- Alpha.td - Describe the Alpha Target Machine --------*- tablegen -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 //
    10 //===----------------------------------------------------------------------===//
    11
    12 // Get the target-independent interfaces which we are implementing...
    13 //
    14 include "llvm/Target/Target.td"
    15
    16 //Alpha is little endian
    17
    18 //===----------------------------------------------------------------------===//
    19 // Subtarget Features
    20 //===----------------------------------------------------------------------===//
    21
    22 def FeatureCIX : SubtargetFeature<"cix", "HasCT", "true",
    23 "Enable CIX extensions">;
    24
    25 //===----------------------------------------------------------------------===//
    26 // Register File Description
    27 //===----------------------------------------------------------------------===//
    28
    29 include "AlphaRegisterInfo.td"
    30
    31 //===----------------------------------------------------------------------===//
    32 // Calling Convention Description
    33 //===----------------------------------------------------------------------===//
    34
    35 include "AlphaCallingConv.td"
    36
    37 //===----------------------------------------------------------------------===//
    38 // Schedule Description
    39 //===----------------------------------------------------------------------===//
    40
    41 include "AlphaSchedule.td"
    42
    43 //===----------------------------------------------------------------------===//
    44 // Instruction Descriptions
    45 //===----------------------------------------------------------------------===//
    46
    47 include "AlphaInstrInfo.td"
    48
    49 def AlphaInstrInfo : InstrInfo;
    50
    51 //===----------------------------------------------------------------------===//
    52 // Alpha Processor Definitions
    53 //===----------------------------------------------------------------------===//
    54
    55 def : Processor<"generic", Alpha21264Itineraries, []>;
    56 def : Processor<"ev6" , Alpha21264Itineraries, []>;
    57 def : Processor<"ev67" , Alpha21264Itineraries, [FeatureCIX]>;
    58
    59 //===----------------------------------------------------------------------===//
    60 // The Alpha Target
    61 //===----------------------------------------------------------------------===//
    62
    63
    64 def Alpha : Target {
    65 // Pull in Instruction Info:
    66 let InstructionSet = AlphaInstrInfo;
    67 }
    +0
    -166
    lib/Target/Alpha/AlphaAsmPrinter.cpp less more
    None //===-- AlphaAsmPrinter.cpp - Alpha LLVM assembly writer ------------------===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file contains a printer that converts from our internal representation
    10 // of machine-dependent LLVM code to GAS-format Alpha assembly language.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #define DEBUG_TYPE "asm-printer"
    15 #include "Alpha.h"
    16 #include "AlphaInstrInfo.h"
    17 #include "AlphaTargetMachine.h"
    18 #include "llvm/Module.h"
    19 #include "llvm/Type.h"
    20 #include "llvm/Assembly/Writer.h"
    21 #include "llvm/CodeGen/AsmPrinter.h"
    22 #include "llvm/MC/MCStreamer.h"
    23 #include "llvm/MC/MCAsmInfo.h"
    24 #include "llvm/MC/MCSymbol.h"
    25 #include "llvm/Target/Mangler.h"
    26 #include "llvm/Target/TargetLoweringObjectFile.h"
    27 #include "llvm/Target/TargetMachine.h"
    28 #include "llvm/ADT/SmallString.h"
    29 #include "llvm/Support/TargetRegistry.h"
    30 #include "llvm/Support/raw_ostream.h"
    31 using namespace llvm;
    32
    33 namespace {
    34 struct AlphaAsmPrinter : public AsmPrinter {
    35 /// Unique incrementer for label values for referencing Global values.
    36 ///
    37
    38 explicit AlphaAsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
    39 : AsmPrinter(tm, Streamer) {}
    40
    41 virtual const char *getPassName() const {
    42 return "Alpha Assembly Printer";
    43 }
    44 void printInstruction(const MachineInstr *MI, raw_ostream &O);
    45 void EmitInstruction(const MachineInstr *MI) {
    46 SmallString<128> Str;
    47 raw_svector_ostream OS(Str);
    48 printInstruction(MI, OS);
    49 OutStreamer.EmitRawText(OS.str());
    50 }
    51 static const char *getRegisterName(unsigned RegNo);
    52
    53 void printOp(const MachineOperand &MO, raw_ostream &O);
    54 void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
    55 virtual void EmitFunctionBodyStart();
    56 virtual void EmitFunctionBodyEnd();
    57 void EmitStartOfAsmFile(Module &M);
    58
    59 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
    60 unsigned AsmVariant, const char *ExtraCode,
    61 raw_ostream &O);
    62 bool PrintAsmMemoryOperand(const MachineInstr *MI,
    63 unsigned OpNo, unsigned AsmVariant,
    64 const char *ExtraCode, raw_ostream &O);
    65 };
    66 } // end of anonymous namespace
    67
    68 #include "AlphaGenAsmWriter.inc"
    69
    70 void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
    71 raw_ostream &O) {
    72 const MachineOperand &MO = MI->getOperand(opNum);
    73 if (MO.isReg()) {
    74 assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
    75 "Not physreg??");
    76 O << getRegisterName(MO.getReg());
    77 } else if (MO.isImm()) {
    78 O << MO.getImm();
    79 assert(MO.getImm() < (1 << 30));
    80 } else {
    81 printOp(MO, O);
    82 }
    83 }
    84
    85
    86 void AlphaAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
    87 switch (MO.getType()) {
    88 case MachineOperand::MO_Register:
    89 O << getRegisterName(MO.getReg());
    90 return;
    91
    92 case MachineOperand::MO_Immediate:
    93 assert(0 && "printOp() does not handle immediate values");
    94 return;
    95
    96 case MachineOperand::MO_MachineBasicBlock:
    97 O << *MO.getMBB()->getSymbol();
    98 return;
    99
    100 case MachineOperand::MO_ConstantPoolIndex:
    101 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
    102 << MO.getIndex();
    103 return;
    104
    105 case MachineOperand::MO_ExternalSymbol:
    106 O << MO.getSymbolName();
    107 return;
    108
    109 case MachineOperand::MO_GlobalAddress:
    110 O << *Mang->getSymbol(MO.getGlobal());
    111 return;
    112
    113 case MachineOperand::MO_JumpTableIndex:
    114 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
    115 << '_' << MO.getIndex();
    116 return;
    117
    118 default:
    119 O << "";
    120 return;
    121 }
    122 }
    123
    124 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
    125 /// the first basic block in the function.
    126 void AlphaAsmPrinter::EmitFunctionBodyStart() {
    127 OutStreamer.EmitRawText("\t.ent " + Twine(CurrentFnSym->getName()));
    128 }
    129
    130 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
    131 /// the last basic block in the function.
    132 void AlphaAsmPrinter::EmitFunctionBodyEnd() {
    133 OutStreamer.EmitRawText("\t.end " + Twine(CurrentFnSym->getName()));
    134 }
    135
    136 void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
    137 OutStreamer.EmitRawText(StringRef("\t.arch ev6"));
    138 OutStreamer.EmitRawText(StringRef("\t.set noat"));
    139 }
    140
    141 /// PrintAsmOperand - Print out an operand for an inline asm expression.
    142 ///
    143 bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
    144 unsigned AsmVariant,
    145 const char *ExtraCode, raw_ostream &O) {
    146 printOperand(MI, OpNo, O);
    147 return false;
    148 }
    149
    150 bool AlphaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
    151 unsigned OpNo, unsigned AsmVariant,
    152 const char *ExtraCode,
    153 raw_ostream &O) {
    154 if (ExtraCode && ExtraCode[0])
    155 return true; // Unknown modifier.
    156 O << "0(";
    157 printOperand(MI, OpNo, O);
    158 O << ")";
    159 return false;
    160 }
    161
    162 // Force static initialization.
    163 extern "C" void LLVMInitializeAlphaAsmPrinter() {
    164 RegisterAsmPrinter X(TheAlphaTarget);
    165 }
    +0
    -66
    lib/Target/Alpha/AlphaBranchSelector.cpp less more
    None //===-- AlphaBranchSelector.cpp - Convert Pseudo branchs ----------*- C++ -*-=//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // Replace Pseudo COND_BRANCH_* with their appropriate real branch
    10 // Simplified version of the PPC Branch Selector
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #include "Alpha.h"
    15 #include "AlphaInstrInfo.h"
    16 #include "llvm/CodeGen/MachineFunctionPass.h"
    17 #include "llvm/Target/TargetMachine.h"
    18 #include "llvm/MC/MCAsmInfo.h"
    19 using namespace llvm;
    20
    21 namespace {
    22 struct AlphaBSel : public MachineFunctionPass {
    23 static char ID;
    24 AlphaBSel() : MachineFunctionPass(ID) {}
    25
    26 virtual bool runOnMachineFunction(MachineFunction &Fn);
    27
    28 virtual const char *getPassName() const {
    29 return "Alpha Branch Selection";
    30 }
    31 };
    32 char AlphaBSel::ID = 0;
    33 }
    34
    35 /// createAlphaBranchSelectionPass - returns an instance of the Branch Selection
    36 /// Pass
    37 ///
    38 FunctionPass *llvm::createAlphaBranchSelectionPass() {
    39 return new AlphaBSel();
    40 }
    41
    42 bool AlphaBSel::runOnMachineFunction(MachineFunction &Fn) {
    43
    44 for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
    45 ++MFI) {
    46 MachineBasicBlock *MBB = MFI;
    47
    48 for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
    49 MBBI != EE; ++MBBI) {
    50 if (MBBI->getOpcode() == Alpha::COND_BRANCH_I ||
    51 MBBI->getOpcode() == Alpha::COND_BRANCH_F) {
    52
    53 // condbranch operands:
    54 // 0. bc opcode
    55 // 1. reg
    56 // 2. target MBB
    57 const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
    58 MBBI->setDesc(TII->get(MBBI->getOperand(0).getImm()));
    59 }
    60 }
    61 }
    62
    63 return true;
    64 }
    65
    +0
    -38
    lib/Target/Alpha/AlphaCallingConv.td less more
    None //===- AlphaCallingConv.td - Calling Conventions for Alpha -*- tablegen -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 // This describes the calling conventions for Alpha architecture.
    9 //===----------------------------------------------------------------------===//
    10
    11 //===----------------------------------------------------------------------===//
    12 // Alpha Return Value Calling Convention
    13 //===----------------------------------------------------------------------===//
    14 def RetCC_Alpha : CallingConv<[
    15 // i64 is returned in register R0
    16 // R1 is an llvm extension, I don't know what gcc does
    17 CCIfType<[i64], CCAssignToReg<[R0,R1]>>,
    18
    19 // f32 / f64 are returned in F0/F1
    20 CCIfType<[f32, f64], CCAssignToReg<[F0, F1]>>
    21 ]>;
    22
    23 //===----------------------------------------------------------------------===//
    24 // Alpha Argument Calling Conventions
    25 //===----------------------------------------------------------------------===//
    26 def CC_Alpha : CallingConv<[
    27 // The first 6 arguments are passed in registers, whether integer or
    28 // floating-point
    29 CCIfType<[i64], CCAssignToRegWithShadow<[R16, R17, R18, R19, R20, R21],
    30 [F16, F17, F18, F19, F20, F21]>>,
    31
    32 CCIfType<[f32, f64], CCAssignToRegWithShadow<[F16, F17, F18, F19, F20, F21],
    33 [R16, R17, R18, R19, R20, R21]>>,
    34
    35 // Stack slots are 8 bytes in size and 8-byte aligned.
    36 CCIfType<[i64, f32, f64], CCAssignToStack<8, 8>>
    37 ]>;
    +0
    -143
    lib/Target/Alpha/AlphaFrameLowering.cpp less more
    None //=====- AlphaFrameLowering.cpp - Alpha Frame Information ------*- C++ -*-====//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file contains the Alpha implementation of TargetFrameLowering class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #include "AlphaFrameLowering.h"
    14 #include "AlphaInstrInfo.h"
    15 #include "AlphaMachineFunctionInfo.h"
    16 #include "llvm/Function.h"
    17 #include "llvm/CodeGen/MachineFrameInfo.h"
    18 #include "llvm/CodeGen/MachineFunction.h"
    19 #include "llvm/CodeGen/MachineInstrBuilder.h"
    20 #include "llvm/ADT/Twine.h"
    21
    22 using namespace llvm;
    23
    24 static long getUpper16(long l) {
    25 long y = l / Alpha::IMM_MULT;
    26 if (l % Alpha::IMM_MULT > Alpha::IMM_HIGH)
    27 ++y;
    28 return y;
    29 }
    30
    31 static long getLower16(long l) {
    32 long h = getUpper16(l);
    33 return l - h * Alpha::IMM_MULT;
    34 }
    35
    36 // hasFP - Return true if the specified function should have a dedicated frame
    37 // pointer register. This is true if the function has variable sized allocas or
    38 // if frame pointer elimination is disabled.
    39 //
    40 bool AlphaFrameLowering::hasFP(const MachineFunction &MF) const {
    41 const MachineFrameInfo *MFI = MF.getFrameInfo();
    42 return MFI->hasVarSizedObjects();
    43 }
    44
    45 void AlphaFrameLowering::emitPrologue(MachineFunction &MF) const {
    46 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
    47 MachineBasicBlock::iterator MBBI = MBB.begin();
    48 MachineFrameInfo *MFI = MF.getFrameInfo();
    49 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    50
    51 DebugLoc dl = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc());
    52 bool FP = hasFP(MF);
    53
    54 // Handle GOP offset
    55 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAHg), Alpha::R29)
    56 .addGlobalAddress(MF.getFunction()).addReg(Alpha::R27).addImm(++curgpdist);
    57 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAg), Alpha::R29)
    58 .addGlobalAddress(MF.getFunction()).addReg(Alpha::R29).addImm(curgpdist);
    59
    60 BuildMI(MBB, MBBI, dl, TII.get(Alpha::ALTENT))
    61 .addGlobalAddress(MF.getFunction());
    62
    63 // Get the number of bytes to allocate from the FrameInfo
    64 long NumBytes = MFI->getStackSize();
    65
    66 if (FP)
    67 NumBytes += 8; //reserve space for the old FP
    68
    69 // Do we need to allocate space on the stack?
    70 if (NumBytes == 0) return;
    71
    72 unsigned Align = getStackAlignment();
    73 NumBytes = (NumBytes+Align-1)/Align*Align;
    74
    75 // Update frame info to pretend that this is part of the stack...
    76 MFI->setStackSize(NumBytes);
    77
    78 // adjust stack pointer: r30 -= numbytes
    79 NumBytes = -NumBytes;
    80 if (NumBytes >= Alpha::IMM_LOW) {
    81 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
    82 .addReg(Alpha::R30);
    83 } else if (getUpper16(NumBytes) >= Alpha::IMM_LOW) {
    84 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAH), Alpha::R30)
    85 .addImm(getUpper16(NumBytes)).addReg(Alpha::R30);
    86 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30)
    87 .addImm(getLower16(NumBytes)).addReg(Alpha::R30);
    88 } else {
    89 report_fatal_error("Too big a stack frame at " + Twine(NumBytes));
    90 }
    91
    92 // Now if we need to, save the old FP and set the new
    93 if (FP) {
    94 BuildMI(MBB, MBBI, dl, TII.get(Alpha::STQ))
    95 .addReg(Alpha::R15).addImm(0).addReg(Alpha::R30);
    96 // This must be the last instr in the prolog
    97 BuildMI(MBB, MBBI, dl, TII.get(Alpha::BISr), Alpha::R15)
    98 .addReg(Alpha::R30).addReg(Alpha::R30);
    99 }
    100
    101 }
    102
    103 void AlphaFrameLowering::emitEpilogue(MachineFunction &MF,
    104 MachineBasicBlock &MBB) const {
    105 const MachineFrameInfo *MFI = MF.getFrameInfo();
    106 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
    107 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
    108
    109 assert((MBBI->getOpcode() == Alpha::RETDAG ||
    110 MBBI->getOpcode() == Alpha::RETDAGp)
    111 && "Can only insert epilog into returning blocks");
    112 DebugLoc dl = MBBI->getDebugLoc();
    113
    114 bool FP = hasFP(MF);
    115
    116 // Get the number of bytes allocated from the FrameInfo...
    117 long NumBytes = MFI->getStackSize();
    118
    119 //now if we need to, restore the old FP
    120 if (FP) {
    121 //copy the FP into the SP (discards allocas)
    122 BuildMI(MBB, MBBI, dl, TII.get(Alpha::BISr), Alpha::R30).addReg(Alpha::R15)
    123 .addReg(Alpha::R15);
    124 //restore the FP
    125 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDQ), Alpha::R15)
    126 .addImm(0).addReg(Alpha::R15);
    127 }
    128
    129 if (NumBytes != 0) {
    130 if (NumBytes <= Alpha::IMM_HIGH) {
    131 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
    132 .addReg(Alpha::R30);
    133 } else if (getUpper16(NumBytes) <= Alpha::IMM_HIGH) {
    134 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAH), Alpha::R30)
    135 .addImm(getUpper16(NumBytes)).addReg(Alpha::R30);
    136 BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30)
    137 .addImm(getLower16(NumBytes)).addReg(Alpha::R30);
    138 } else {
    139 report_fatal_error("Too big a stack frame at " + Twine(NumBytes));
    140 }
    141 }
    142 }
    +0
    -43
    lib/Target/Alpha/AlphaFrameLowering.h less more
    None //==-- AlphaFrameLowering.h - Define frame lowering for Alpha --*- C++ -*---==//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 //
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #ifndef ALPHA_FRAMEINFO_H
    14 #define ALPHA_FRAMEINFO_H
    15
    16 #include "Alpha.h"
    17 #include "AlphaSubtarget.h"
    18 #include "llvm/Target/TargetFrameLowering.h"
    19
    20 namespace llvm {
    21 class AlphaSubtarget;
    22
    23 class AlphaFrameLowering : public TargetFrameLowering {
    24 const AlphaSubtarget &STI;
    25 // FIXME: This should end in MachineFunctionInfo, not here!
    26 mutable int curgpdist;
    27 public:
    28 explicit AlphaFrameLowering(const AlphaSubtarget &sti)
    29 : TargetFrameLowering(StackGrowsDown, 16, 0), STI(sti), curgpdist(0) {
    30 }
    31
    32 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
    33 /// the function.
    34 void emitPrologue(MachineFunction &MF) const;
    35 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
    36
    37 bool hasFP(const MachineFunction &MF) const;
    38 };
    39
    40 } // End llvm namespace
    41
    42 #endif
    +0
    -425
    lib/Target/Alpha/AlphaISelDAGToDAG.cpp less more
    None //===-- AlphaISelDAGToDAG.cpp - Alpha pattern matching inst selector ------===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file defines a pattern matching instruction selector for Alpha,
    10 // converting from a legalized dag to a Alpha dag.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #include "Alpha.h"
    15 #include "AlphaTargetMachine.h"
    16 #include "llvm/CodeGen/MachineInstrBuilder.h"
    17 #include "llvm/CodeGen/MachineFrameInfo.h"
    18 #include "llvm/CodeGen/MachineFunction.h"
    19 #include "llvm/CodeGen/MachineRegisterInfo.h"
    20 #include "llvm/CodeGen/SelectionDAG.h"
    21 #include "llvm/CodeGen/SelectionDAGISel.h"
    22 #include "llvm/Target/TargetOptions.h"
    23 #include "llvm/Constants.h"
    24 #include "llvm/DerivedTypes.h"
    25 #include "llvm/GlobalValue.h"
    26 #include "llvm/Intrinsics.h"
    27 #include "llvm/LLVMContext.h"
    28 #include "llvm/Support/Compiler.h"
    29 #include "llvm/Support/Debug.h"
    30 #include "llvm/Support/ErrorHandling.h"
    31 #include "llvm/Support/MathExtras.h"
    32 #include "llvm/Support/raw_ostream.h"
    33 #include
    34 using namespace llvm;
    35
    36 namespace {
    37
    38 //===--------------------------------------------------------------------===//
    39 /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine
    40 /// instructions for SelectionDAG operations.
    41 class AlphaDAGToDAGISel : public SelectionDAGISel {
    42 static const int64_t IMM_LOW = -32768;
    43 static const int64_t IMM_HIGH = 32767;
    44 static const int64_t IMM_MULT = 65536;
    45 static const int64_t IMM_FULLHIGH = IMM_HIGH + IMM_HIGH * IMM_MULT;
    46 static const int64_t IMM_FULLLOW = IMM_LOW + IMM_LOW * IMM_MULT;
    47
    48 static int64_t get_ldah16(int64_t x) {
    49 int64_t y = x / IMM_MULT;
    50 if (x % IMM_MULT > IMM_HIGH)
    51 ++y;
    52 return y;
    53 }
    54
    55 static int64_t get_lda16(int64_t x) {
    56 return x - get_ldah16(x) * IMM_MULT;
    57 }
    58
    59 /// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot
    60 /// instruction (if not, return 0). Note that this code accepts partial
    61 /// zap masks. For example (and LHS, 1) is a valid zap, as long we know
    62 /// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
    63 /// in checking mode. If LHS is null, we assume that the mask has already
    64 /// been validated before.
    65 uint64_t get_zapImm(SDValue LHS, uint64_t Constant) const {
    66 uint64_t BitsToCheck = 0;
    67 unsigned Result = 0;
    68 for (unsigned i = 0; i != 8; ++i) {
    69 if (((Constant >> 8*i) & 0xFF) == 0) {
    70 // nothing to do.
    71 } else {
    72 Result |= 1 << i;
    73 if (((Constant >> 8*i) & 0xFF) == 0xFF) {
    74 // If the entire byte is set, zapnot the byte.
    75 } else if (LHS.getNode() == 0) {
    76 // Otherwise, if the mask was previously validated, we know its okay
    77 // to zapnot this entire byte even though all the bits aren't set.
    78 } else {
    79 // Otherwise we don't know that the it's okay to zapnot this entire
    80 // byte. Only do this iff we can prove that the missing bits are
    81 // already null, so the bytezap doesn't need to really null them.
    82 BitsToCheck |= ~Constant & (0xFFULL << 8*i);
    83 }
    84 }
    85 }
    86
    87 // If there are missing bits in a byte (for example, X & 0xEF00), check to
    88 // see if the missing bits (0x1000) are already known zero if not, the zap
    89 // isn't okay to do, as it won't clear all the required bits.
    90 if (BitsToCheck &&
    91 !CurDAG->MaskedValueIsZero(LHS,
    92 APInt(LHS.getValueSizeInBits(),
    93 BitsToCheck)))
    94 return 0;
    95
    96 return Result;
    97 }
    98
    99 static uint64_t get_zapImm(uint64_t x) {
    100 unsigned build = 0;
    101 for(int i = 0; i != 8; ++i) {
    102 if ((x & 0x00FF) == 0x00FF)
    103 build |= 1 << i;
    104 else if ((x & 0x00FF) != 0)
    105 return 0;
    106 x >>= 8;
    107 }
    108 return build;
    109 }
    110
    111
    112 static uint64_t getNearPower2(uint64_t x) {
    113 if (!x) return 0;
    114 unsigned at = CountLeadingZeros_64(x);
    115 uint64_t complow = 1ULL << (63 - at);
    116 uint64_t comphigh = complow << 1;
    117 if (x - complow <= comphigh - x)
    118 return complow;
    119 else
    120 return comphigh;
    121 }
    122
    123 static bool chkRemNearPower2(uint64_t x, uint64_t r, bool swap) {
    124 uint64_t y = getNearPower2(x);
    125 if (swap)
    126 return (y - x) == r;
    127 else
    128 return (x - y) == r;
    129 }
    130
    131 public:
    132 explicit AlphaDAGToDAGISel(AlphaTargetMachine &TM)
    133 : SelectionDAGISel(TM)
    134 {}
    135
    136 /// getI64Imm - Return a target constant with the specified value, of type
    137 /// i64.
    138 inline SDValue getI64Imm(int64_t Imm) {
    139 return CurDAG->getTargetConstant(Imm, MVT::i64);
    140 }
    141
    142 // Select - Convert the specified operand from a target-independent to a
    143 // target-specific node if it hasn't already been changed.
    144 SDNode *Select(SDNode *N);
    145
    146 virtual const char *getPassName() const {
    147 return "Alpha DAG->DAG Pattern Instruction Selection";
    148 }
    149
    150 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
    151 /// inline asm expressions.
    152 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
    153 char ConstraintCode,
    154 std::vector &OutOps) {
    155 SDValue Op0;
    156 switch (ConstraintCode) {
    157 default: return true;
    158 case 'm': // memory
    159 Op0 = Op;
    160 break;
    161 }
    162
    163 OutOps.push_back(Op0);
    164 return false;
    165 }
    166
    167 // Include the pieces autogenerated from the target description.
    168 #include "AlphaGenDAGISel.inc"
    169
    170 private:
    171 /// getTargetMachine - Return a reference to the TargetMachine, casted
    172 /// to the target-specific type.
    173 const AlphaTargetMachine &getTargetMachine() {
    174 return static_cast(TM);
    175 }
    176
    177 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
    178 /// to the target-specific type.
    179 const AlphaInstrInfo *getInstrInfo() {
    180 return getTargetMachine().getInstrInfo();
    181 }
    182
    183 SDNode *getGlobalBaseReg();
    184 SDNode *getGlobalRetAddr();
    185 void SelectCALL(SDNode *Op);
    186
    187 };
    188 }
    189
    190 /// getGlobalBaseReg - Output the instructions required to put the
    191 /// GOT address into a register.
    192 ///
    193 SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() {
    194 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
    195 return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
    196 }
    197
    198 /// getGlobalRetAddr - Grab the return address.
    199 ///
    200 SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() {
    201 unsigned GlobalRetAddr = getInstrInfo()->getGlobalRetAddr(MF);
    202 return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode();
    203 }
    204
    205 // Select - Convert the specified operand from a target-independent to a
    206 // target-specific node if it hasn't already been changed.
    207 SDNode *AlphaDAGToDAGISel::Select(SDNode *N) {
    208 if (N->isMachineOpcode())
    209 return NULL; // Already selected.
    210 DebugLoc dl = N->getDebugLoc();
    211
    212 switch (N->getOpcode()) {
    213 default: break;
    214 case AlphaISD::CALL:
    215 SelectCALL(N);
    216 return NULL;
    217
    218 case ISD::FrameIndex: {
    219 int FI = cast(N)->getIndex();
    220 return CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64,
    221 CurDAG->getTargetFrameIndex(FI, MVT::i32),
    222 getI64Imm(0));
    223 }
    224 case ISD::GLOBAL_OFFSET_TABLE:
    225 return getGlobalBaseReg();
    226 case AlphaISD::GlobalRetAddr:
    227 return getGlobalRetAddr();
    228
    229 case AlphaISD::DivCall: {
    230 SDValue Chain = CurDAG->getEntryNode();
    231 SDValue N0 = N->getOperand(0);
    232 SDValue N1 = N->getOperand(1);
    233 SDValue N2 = N->getOperand(2);
    234 Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R24, N1,
    235 SDValue(0,0));
    236 Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R25, N2,
    237 Chain.getValue(1));
    238 Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, N0,
    239 Chain.getValue(1));
    240 SDNode *CNode =
    241 CurDAG->getMachineNode(Alpha::JSRs, dl, MVT::Other, MVT::Glue,
    242 Chain, Chain.getValue(1));
    243 Chain = CurDAG->getCopyFromReg(Chain, dl, Alpha::R27, MVT::i64,
    244 SDValue(CNode, 1));
    245 return CurDAG->SelectNodeTo(N, Alpha::BISr, MVT::i64, Chain, Chain);
    246 }
    247
    248 case ISD::READCYCLECOUNTER: {
    249 SDValue Chain = N->getOperand(0);
    250 return CurDAG->getMachineNode(Alpha::RPCC, dl, MVT::i64, MVT::Other,
    251 Chain);
    252 }
    253
    254 case ISD::Constant: {
    255 uint64_t uval = cast(N)->getZExtValue();
    256
    257 if (uval == 0) {
    258 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
    259 Alpha::R31, MVT::i64);
    260 ReplaceUses(SDValue(N, 0), Result);
    261 return NULL;
    262 }
    263
    264 int64_t val = (int64_t)uval;
    265 int32_t val32 = (int32_t)val;
    266 if (val <= IMM_HIGH + IMM_HIGH * IMM_MULT &&
    267 val >= IMM_LOW + IMM_LOW * IMM_MULT)
    268 break; //(LDAH (LDA))
    269 if ((uval >> 32) == 0 && //empty upper bits
    270 val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT)
    271 // val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true
    272 break; //(zext (LDAH (LDA)))
    273 //Else use the constant pool
    274 ConstantInt *C = ConstantInt::get(
    275 Type::getInt64Ty(*CurDAG->getContext()), uval);
    276 SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
    277 SDNode *Tmp = CurDAG->getMachineNode(Alpha::LDAHr, dl, MVT::i64, CPI,
    278 SDValue(getGlobalBaseReg(), 0));
    279 return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
    280 CPI, SDValue(Tmp, 0), CurDAG->getEntryNode());
    281 }
    282 case ISD::TargetConstantFP:
    283 case ISD::ConstantFP: {
    284 ConstantFPSDNode *CN = cast(N);
    285 bool isDouble = N->getValueType(0) == MVT::f64;
    286 EVT T = isDouble ? MVT::f64 : MVT::f32;
    287 if (CN->getValueAPF().isPosZero()) {
    288 return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS,
    289 T, CurDAG->getRegister(Alpha::F31, T),
    290 CurDAG->getRegister(Alpha::F31, T));
    291 } else if (CN->getValueAPF().isNegZero()) {
    292 return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS,
    293 T, CurDAG->getRegister(Alpha::F31, T),
    294 CurDAG->getRegister(Alpha::F31, T));
    295 } else {
    296 report_fatal_error("Unhandled FP constant type");
    297 }
    298 break;
    299 }
    300
    301 case ISD::SETCC:
    302 if (N->getOperand(0).getNode()->getValueType(0).isFloatingPoint()) {
    303 ISD::CondCode CC = cast(N->getOperand(2))->get();
    304
    305 unsigned Opc = Alpha::WTF;
    306 bool rev = false;
    307 bool inv = false;
    308 switch(CC) {
    309 default: DEBUG(N->dump(CurDAG)); llvm_unreachable("Unknown FP comparison!");
    310 case ISD::SETEQ: case ISD::SETOEQ: case ISD::SETUEQ:
    311 Opc = Alpha::CMPTEQ; break;
    312 case ISD::SETLT: case ISD::SETOLT: case ISD::SETULT:
    313 Opc = Alpha::CMPTLT; break;
    314 case ISD::SETLE: case ISD::SETOLE: case ISD::SETULE:
    315 Opc = Alpha::CMPTLE; break;
    316 case ISD::SETGT: case ISD::SETOGT: case ISD::SETUGT:
    317 Opc = Alpha::CMPTLT; rev = true; break;
    318 case ISD::SETGE: case ISD::SETOGE: case ISD::SETUGE:
    319 Opc = Alpha::CMPTLE; rev = true; break;
    320 case ISD::SETNE: case ISD::SETONE: case ISD::SETUNE:
    321 Opc = Alpha::CMPTEQ; inv = true; break;
    322 case ISD::SETO:
    323 Opc = Alpha::CMPTUN; inv = true; break;
    324 case ISD::SETUO:
    325 Opc = Alpha::CMPTUN; break;
    326 };
    327 SDValue tmp1 = N->getOperand(rev?1:0);
    328 SDValue tmp2 = N->getOperand(rev?0:1);
    329 SDNode *cmp = CurDAG->getMachineNode(Opc, dl, MVT::f64, tmp1, tmp2);
    330 if (inv)
    331 cmp = CurDAG->getMachineNode(Alpha::CMPTEQ, dl,
    332 MVT::f64, SDValue(cmp, 0),
    333 CurDAG->getRegister(Alpha::F31, MVT::f64));
    334 switch(CC) {
    335 case ISD::SETUEQ: case ISD::SETULT: case ISD::SETULE:
    336 case ISD::SETUNE: case ISD::SETUGT: case ISD::SETUGE:
    337 {
    338 SDNode* cmp2 = CurDAG->getMachineNode(Alpha::CMPTUN, dl, MVT::f64,
    339 tmp1, tmp2);
    340 cmp = CurDAG->getMachineNode(Alpha::ADDT, dl, MVT::f64,
    341 SDValue(cmp2, 0), SDValue(cmp, 0));
    342 break;
    343 }
    344 default: break;
    345 }
    346
    347 SDNode* LD = CurDAG->getMachineNode(Alpha::FTOIT, dl,
    348 MVT::i64, SDValue(cmp, 0));
    349 return CurDAG->getMachineNode(Alpha::CMPULT, dl, MVT::i64,
    350 CurDAG->getRegister(Alpha::R31, MVT::i64),
    351 SDValue(LD,0));
    352 }
    353 break;
    354
    355 case ISD::AND: {
    356 ConstantSDNode* SC = NULL;
    357 ConstantSDNode* MC = NULL;
    358 if (N->getOperand(0).getOpcode() == ISD::SRL &&
    359 (MC = dyn_cast(N->getOperand(1))) &&
    360 (SC = dyn_cast(N->getOperand(0).getOperand(1)))) {
    361 uint64_t sval = SC->getZExtValue();
    362 uint64_t mval = MC->getZExtValue();
    363 // If the result is a zap, let the autogened stuff handle it.
    364 if (get_zapImm(N->getOperand(0), mval))
    365 break;
    366 // given mask X, and shift S, we want to see if there is any zap in the
    367 // mask if we play around with the botton S bits
    368 uint64_t dontcare = (~0ULL) >> (64 - sval);
    369 uint64_t mask = mval << sval;
    370
    371 if (get_zapImm(mask | dontcare))
    372 mask = mask | dontcare;
    373
    374 if (get_zapImm(mask)) {
    375 SDValue Z =
    376 SDValue(CurDAG->getMachineNode(Alpha::ZAPNOTi, dl, MVT::i64,
    377 N->getOperand(0).getOperand(0),
    378 getI64Imm(get_zapImm(mask))), 0);
    379 return CurDAG->getMachineNode(Alpha::SRLr, dl, MVT::i64, Z,
    380 getI64Imm(sval));
    381 }
    382 }
    383 break;
    384 }
    385
    386 }
    387
    388 return SelectCode(N);
    389 }
    390
    391 void AlphaDAGToDAGISel::SelectCALL(SDNode *N) {
    392 //TODO: add flag stuff to prevent nondeturministic breakage!
    393
    394 SDValue Chain = N->getOperand(0);
    395 SDValue Addr = N->getOperand(1);
    396 SDValue InFlag = N->getOperand(N->getNumOperands() - 1);
    397 DebugLoc dl = N->getDebugLoc();
    398
    399 if (Addr.getOpcode() == AlphaISD::GPRelLo) {
    400 SDValue GOT = SDValue(getGlobalBaseReg(), 0);
    401 Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag);
    402 InFlag = Chain.getValue(1);
    403 Chain = SDValue(CurDAG->getMachineNode(Alpha::BSR, dl, MVT::Other,
    404 MVT::Glue, Addr.getOperand(0),
    405 Chain, InFlag), 0);
    406 } else {
    407 Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, Addr, InFlag);
    408 InFlag = Chain.getValue(1);
    409 Chain = SDValue(CurDAG->getMachineNode(Alpha::JSR, dl, MVT::Other,
    410 MVT::Glue, Chain, InFlag), 0);
    411 }
    412 InFlag = Chain.getValue(1);
    413
    414 ReplaceUses(SDValue(N, 0), Chain);
    415 ReplaceUses(SDValue(N, 1), InFlag);
    416 }
    417
    418
    419 /// createAlphaISelDag - This pass converts a legalized DAG into a
    420 /// Alpha-specific DAG, ready for instruction scheduling.
    421 ///
    422 FunctionPass *llvm::createAlphaISelDag(AlphaTargetMachine &TM) {
    423 return new AlphaDAGToDAGISel(TM);
    424 }
    +0
    -962
    lib/Target/Alpha/AlphaISelLowering.cpp less more
    None //===-- AlphaISelLowering.cpp - Alpha DAG Lowering Implementation ---------===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file implements the AlphaISelLowering class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #include "AlphaISelLowering.h"
    14 #include "AlphaTargetMachine.h"
    15 #include "AlphaMachineFunctionInfo.h"
    16 #include "llvm/CodeGen/CallingConvLower.h"
    17 #include "llvm/CodeGen/MachineFrameInfo.h"
    18 #include "llvm/CodeGen/MachineFunction.h"
    19 #include "llvm/CodeGen/MachineInstrBuilder.h"
    20 #include "llvm/CodeGen/MachineRegisterInfo.h"
    21 #include "llvm/CodeGen/SelectionDAG.h"
    22 #include "llvm/CodeGen/MachineRegisterInfo.h"
    23 #include "llvm/CodeGen/PseudoSourceValue.h"
    24 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
    25 #include "llvm/Constants.h"
    26 #include "llvm/Function.h"
    27 #include "llvm/Module.h"
    28 #include "llvm/Intrinsics.h"
    29 #include "llvm/Type.h"
    30 #include "llvm/Support/CommandLine.h"
    31 #include "llvm/Support/ErrorHandling.h"
    32 #include "llvm/Support/raw_ostream.h"
    33 using namespace llvm;
    34
    35 /// AddLiveIn - This helper function adds the specified physical register to the
    36 /// MachineFunction as a live in value. It also creates a corresponding virtual
    37 /// register for it.
    38 static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
    39 TargetRegisterClass *RC) {
    40 assert(RC->contains(PReg) && "Not the correct regclass!");
    41 unsigned VReg = MF.getRegInfo().createVirtualRegister(RC);
    42 MF.getRegInfo().addLiveIn(PReg, VReg);
    43 return VReg;
    44 }
    45
    46 AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM)
    47 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
    48 // Set up the TargetLowering object.
    49 //I am having problems with shr n i8 1
    50 setBooleanContents(ZeroOrOneBooleanContent);
    51 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
    52
    53 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
    54 addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass);
    55 addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass);
    56
    57 // We want to custom lower some of our intrinsics.
    58 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
    59
    60 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
    61 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
    62
    63 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
    64 setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, Expand);
    65
    66 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
    67 setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
    68 setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
    69
    70 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
    71
    72 // setOperationAction(ISD::BRIND, MVT::Other, Expand);
    73 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
    74 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
    75 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
    76
    77 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
    78
    79 setOperationAction(ISD::FREM, MVT::f32, Expand);
    80 setOperationAction(ISD::FREM, MVT::f64, Expand);
    81
    82 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
    83 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
    84 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
    85 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
    86
    87 if (!TM.getSubtarget().hasCT()) {
    88 setOperationAction(ISD::CTPOP , MVT::i64 , Expand);
    89 setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
    90 setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
    91 }
    92 setOperationAction(ISD::BSWAP , MVT::i64, Expand);
    93 setOperationAction(ISD::ROTL , MVT::i64, Expand);
    94 setOperationAction(ISD::ROTR , MVT::i64, Expand);
    95
    96 setOperationAction(ISD::SREM , MVT::i64, Custom);
    97 setOperationAction(ISD::UREM , MVT::i64, Custom);
    98 setOperationAction(ISD::SDIV , MVT::i64, Custom);
    99 setOperationAction(ISD::UDIV , MVT::i64, Custom);
    100
    101 setOperationAction(ISD::ADDC , MVT::i64, Expand);
    102 setOperationAction(ISD::ADDE , MVT::i64, Expand);
    103 setOperationAction(ISD::SUBC , MVT::i64, Expand);
    104 setOperationAction(ISD::SUBE , MVT::i64, Expand);
    105
    106 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
    107 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
    108
    109 setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom);
    110 setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
    111 setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
    112
    113 // We don't support sin/cos/sqrt/pow
    114 setOperationAction(ISD::FSIN , MVT::f64, Expand);
    115 setOperationAction(ISD::FCOS , MVT::f64, Expand);
    116 setOperationAction(ISD::FSIN , MVT::f32, Expand);
    117 setOperationAction(ISD::FCOS , MVT::f32, Expand);
    118
    119 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
    120 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
    121
    122 setOperationAction(ISD::FPOW , MVT::f32, Expand);
    123 setOperationAction(ISD::FPOW , MVT::f64, Expand);
    124
    125 setOperationAction(ISD::FMA, MVT::f64, Expand);
    126 setOperationAction(ISD::FMA, MVT::f32, Expand);
    127
    128 setOperationAction(ISD::SETCC, MVT::f32, Promote);
    129
    130 setOperationAction(ISD::BITCAST, MVT::f32, Promote);
    131
    132 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
    133
    134 // Not implemented yet.
    135 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
    136 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
    137 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
    138
    139 // We want to legalize GlobalAddress and ConstantPool and
    140 // ExternalSymbols nodes into the appropriate instructions to
    141 // materialize the address.
    142 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
    143 setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
    144 setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
    145 setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
    146
    147 setOperationAction(ISD::VASTART, MVT::Other, Custom);
    148 setOperationAction(ISD::VAEND, MVT::Other, Expand);
    149 setOperationAction(ISD::VACOPY, MVT::Other, Custom);
    150 setOperationAction(ISD::VAARG, MVT::Other, Custom);
    151 setOperationAction(ISD::VAARG, MVT::i32, Custom);
    152
    153 setOperationAction(ISD::JumpTable, MVT::i64, Custom);
    154 setOperationAction(ISD::JumpTable, MVT::i32, Custom);
    155
    156 setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Expand);
    157 setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Expand);
    158
    159 setStackPointerRegisterToSaveRestore(Alpha::R30);
    160
    161 setJumpBufSize(272);
    162 setJumpBufAlignment(16);
    163
    164 setMinFunctionAlignment(4);
    165
    166 setInsertFencesForAtomic(true);
    167
    168 computeRegisterProperties();
    169 }
    170
    171 EVT AlphaTargetLowering::getSetCCResultType(EVT VT) const {
    172 return MVT::i64;
    173 }
    174
    175 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const {
    176 switch (Opcode) {
    177 default: return 0;
    178 case AlphaISD::CVTQT_: return "Alpha::CVTQT_";
    179 case AlphaISD::CVTQS_: return "Alpha::CVTQS_";
    180 case AlphaISD::CVTTQ_: return "Alpha::CVTTQ_";
    181 case AlphaISD::GPRelHi: return "Alpha::GPRelHi";
    182 case AlphaISD::GPRelLo: return "Alpha::GPRelLo";
    183 case AlphaISD::RelLit: return "Alpha::RelLit";
    184 case AlphaISD::GlobalRetAddr: return "Alpha::GlobalRetAddr";
    185 case AlphaISD::CALL: return "Alpha::CALL";
    186 case AlphaISD::DivCall: return "Alpha::DivCall";
    187 case AlphaISD::RET_FLAG: return "Alpha::RET_FLAG";
    188 case AlphaISD::COND_BRANCH_I: return "Alpha::COND_BRANCH_I";
    189 case AlphaISD::COND_BRANCH_F: return "Alpha::COND_BRANCH_F";
    190 }
    191 }
    192
    193 static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
    194 EVT PtrVT = Op.getValueType();
    195 JumpTableSDNode *JT = cast(Op);
    196 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
    197 // FIXME there isn't really any debug info here
    198 DebugLoc dl = Op.getDebugLoc();
    199
    200 SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, JTI,
    201 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
    202 SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, JTI, Hi);
    203 return Lo;
    204 }
    205
    206 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/
    207 //AA-PY8AC-TET1_html/callCH3.html#BLOCK21
    208
    209 //For now, just use variable size stack frame format
    210
    211 //In a standard call, the first six items are passed in registers $16
    212 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
    213 //of argument-to-register correspondence.) The remaining items are
    214 //collected in a memory argument list that is a naturally aligned
    215 //array of quadwords. In a standard call, this list, if present, must
    216 //be passed at 0(SP).
    217 //7 ... n 0(SP) ... (n-7)*8(SP)
    218
    219 // //#define FP $15
    220 // //#define RA $26
    221 // //#define PV $27
    222 // //#define GP $29
    223 // //#define SP $30
    224
    225 #include "AlphaGenCallingConv.inc"
    226
    227 SDValue
    228 AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
    229 CallingConv::ID CallConv, bool isVarArg,
    230 bool &isTailCall,
    231 const SmallVectorImpl &Outs,
    232 const SmallVectorImpl &OutVals,
    233 const SmallVectorImpl &Ins,
    234 DebugLoc dl, SelectionDAG &DAG,
    235 SmallVectorImpl &InVals) const {
    236 // Alpha target does not yet support tail call optimization.
    237 isTailCall = false;
    238
    239 // Analyze operands of the call, assigning locations to each operand.
    240 SmallVector ArgLocs;
    241 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
    242 getTargetMachine(), ArgLocs, *DAG.getContext());
    243
    244 CCInfo.AnalyzeCallOperands(Outs, CC_Alpha);
    245
    246 // Get a count of how many bytes are to be pushed on the stack.
    247 unsigned NumBytes = CCInfo.getNextStackOffset();
    248
    249 Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes,
    250 getPointerTy(), true));
    251
    252 SmallVector, 4> RegsToPass;
    253 SmallVector MemOpChains;
    254 SDValue StackPtr;
    255
    256 // Walk the register/memloc assignments, inserting copies/loads.
    257 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
    258 CCValAssign &VA = ArgLocs[i];
    259
    260 SDValue Arg = OutVals[i];
    261
    262 // Promote the value if needed.
    263 switch (VA.getLocInfo()) {
    264 default: assert(0 && "Unknown loc info!");
    265 case CCValAssign::Full: break;
    266 case CCValAssign::SExt:
    267 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
    268 break;
    269 case CCValAssign::ZExt:
    270 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
    271 break;
    272 case CCValAssign::AExt:
    273 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
    274 break;
    275 }
    276
    277 // Arguments that can be passed on register must be kept at RegsToPass
    278 // vector
    279 if (VA.isRegLoc()) {
    280 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
    281 } else {
    282 assert(VA.isMemLoc());
    283
    284 if (StackPtr.getNode() == 0)
    285 StackPtr = DAG.getCopyFromReg(Chain, dl, Alpha::R30, MVT::i64);
    286
    287 SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
    288 StackPtr,
    289 DAG.getIntPtrConstant(VA.getLocMemOffset()));
    290
    291 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
    292 MachinePointerInfo(),false, false, 0));
    293 }
    294 }
    295
    296 // Transform all store nodes into one single node because all store nodes are
    297 // independent of each other.
    298 if (!MemOpChains.empty())
    299 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
    300 &MemOpChains[0], MemOpChains.size());
    301
    302 // Build a sequence of copy-to-reg nodes chained together with token chain and
    303 // flag operands which copy the outgoing args into registers. The InFlag in
    304 // necessary since all emitted instructions must be stuck together.
    305 SDValue InFlag;
    306 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
    307 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
    308 RegsToPass[i].second, InFlag);
    309 InFlag = Chain.getValue(1);
    310 }
    311
    312 // Returns a chain & a flag for retval copy to use.
    313 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
    314 SmallVector Ops;
    315 Ops.push_back(Chain);
    316 Ops.push_back(Callee);
    317
    318 // Add argument registers to the end of the list so that they are
    319 // known live into the call.
    320 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
    321 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
    322 RegsToPass[i].second.getValueType()));
    323
    324 if (InFlag.getNode())
    325 Ops.push_back(InFlag);
    326
    327 Chain = DAG.getNode(AlphaISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
    328 InFlag = Chain.getValue(1);
    329
    330 // Create the CALLSEQ_END node.
    331 Chain = DAG.getCALLSEQ_END(Chain,
    332 DAG.getConstant(NumBytes, getPointerTy(), true),
    333 DAG.getConstant(0, getPointerTy(), true),
    334 InFlag);
    335 InFlag = Chain.getValue(1);
    336
    337 // Handle result values, copying them out of physregs into vregs that we
    338 // return.
    339 return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
    340 Ins, dl, DAG, InVals);
    341 }
    342
    343 /// LowerCallResult - Lower the result values of a call into the
    344 /// appropriate copies out of appropriate physical registers.
    345 ///
    346 SDValue
    347 AlphaTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
    348 CallingConv::ID CallConv, bool isVarArg,
    349 const SmallVectorImpl &Ins,
    350 DebugLoc dl, SelectionDAG &DAG,
    351 SmallVectorImpl &InVals) const {
    352
    353 // Assign locations to each value returned by this call.
    354 SmallVector RVLocs;
    355 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
    356 getTargetMachine(), RVLocs, *DAG.getContext());
    357
    358 CCInfo.AnalyzeCallResult(Ins, RetCC_Alpha);
    359
    360 // Copy all of the result registers out of their specified physreg.
    361 for (unsigned i = 0; i != RVLocs.size(); ++i) {
    362 CCValAssign &VA = RVLocs[i];
    363
    364 Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(),
    365 VA.getLocVT(), InFlag).getValue(1);
    366 SDValue RetValue = Chain.getValue(0);
    367 InFlag = Chain.getValue(2);
    368
    369 // If this is an 8/16/32-bit value, it is really passed promoted to 64
    370 // bits. Insert an assert[sz]ext to capture this, then truncate to the
    371 // right size.
    372 if (VA.getLocInfo() == CCValAssign::SExt)
    373 RetValue = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), RetValue,
    374 DAG.getValueType(VA.getValVT()));
    375 else if (VA.getLocInfo() == CCValAssign::ZExt)
    376 RetValue = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), RetValue,
    377 DAG.getValueType(VA.getValVT()));
    378
    379 if (VA.getLocInfo() != CCValAssign::Full)
    380 RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue);
    381
    382 InVals.push_back(RetValue);
    383 }
    384
    385 return Chain;
    386 }
    387
    388 SDValue
    389 AlphaTargetLowering::LowerFormalArguments(SDValue Chain,
    390 CallingConv::ID CallConv, bool isVarArg,
    391 const SmallVectorImpl
    392 &Ins,
    393 DebugLoc dl, SelectionDAG &DAG,
    394 SmallVectorImpl &InVals)
    395 const {
    396
    397 MachineFunction &MF = DAG.getMachineFunction();
    398 MachineFrameInfo *MFI = MF.getFrameInfo();
    399 AlphaMachineFunctionInfo *FuncInfo = MF.getInfo();
    400
    401 unsigned args_int[] = {
    402 Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21};
    403 unsigned args_float[] = {
    404 Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21};
    405
    406 for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
    407 SDValue argt;
    408 EVT ObjectVT = Ins[ArgNo].VT;
    409 SDValue ArgVal;
    410
    411 if (ArgNo < 6) {
    412 switch (ObjectVT.getSimpleVT().SimpleTy) {
    413 default:
    414 assert(false && "Invalid value type!");
    415 case MVT::f64:
    416 args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo],
    417 &Alpha::F8RCRegClass);
    418 ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT);
    419 break;
    420 case MVT::f32:
    421 args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo],
    422 &Alpha::F4RCRegClass);
    423 ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT);
    424 break;
    425 case MVT::i64:
    426 args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo],
    427 &Alpha::GPRCRegClass);
    428 ArgVal = DAG.getCopyFromReg(Chain, dl, args_int[ArgNo], MVT::i64);
    429 break;
    430 }
    431 } else { //more args
    432 // Create the frame index object for this incoming parameter...
    433 int FI = MFI->CreateFixedObject(8, 8 * (ArgNo - 6), true);
    434
    435 // Create the SelectionDAG nodes corresponding to a load
    436 //from this parameter
    437 SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
    438 ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo(),
    439 false, false, 0);
    440 }
    441 InVals.push_back(ArgVal);
    442 }
    443
    444 // If the functions takes variable number of arguments, copy all regs to stack
    445 if (isVarArg) {
    446 FuncInfo->setVarArgsOffset(Ins.size() * 8);
    447 std::vector LS;
    448 for (int i = 0; i < 6; ++i) {
    449 if (TargetRegisterInfo::isPhysicalRegister(args_int[i]))
    450 args_int[i] = AddLiveIn(MF, args_int[i], &Alpha::GPRCRegClass);
    451 SDValue argt = DAG.getCopyFromReg(Chain, dl, args_int[i], MVT::i64);
    452 int FI = MFI->CreateFixedObject(8, -8 * (6 - i), true);
    453 if (i == 0) FuncInfo->setVarArgsBase(FI);
    454 SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64);
    455 LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, MachinePointerInfo(),
    456 false, false, 0));
    457
    458 if (TargetRegisterInfo::isPhysicalRegister(args_float[i]))
    459 args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass);
    460 argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64);
    461 FI = MFI->CreateFixedObject(8, - 8 * (12 - i), true);
    462 SDFI = DAG.getFrameIndex(FI, MVT::i64);
    463 LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, MachinePointerInfo(),
    464 false, false, 0));
    465 }
    466
    467 //Set up a token factor with all the stack traffic
    468 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size());
    469 }
    470
    471 return Chain;
    472 }
    473
    474 SDValue
    475 AlphaTargetLowering::LowerReturn(SDValue Chain,
    476 CallingConv::ID CallConv, bool isVarArg,
    477 const SmallVectorImpl &Outs,
    478 const SmallVectorImpl &OutVals,
    479 DebugLoc dl, SelectionDAG &DAG) const {
    480
    481 SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26,
    482 DAG.getNode(AlphaISD::GlobalRetAddr,
    483 DebugLoc(), MVT::i64),
    484 SDValue());
    485 switch (Outs.size()) {
    486 default:
    487 llvm_unreachable("Do not know how to return this many arguments!");
    488 case 0:
    489 break;
    490 //return SDValue(); // ret void is legal
    491 case 1: {
    492 EVT ArgVT = Outs[0].VT;
    493 unsigned ArgReg;
    494 if (ArgVT.isInteger())
    495 ArgReg = Alpha::R0;
    496 else {
    497 assert(ArgVT.isFloatingPoint());
    498 ArgReg = Alpha::F0;
    499 }
    500 Copy = DAG.getCopyToReg(Copy, dl, ArgReg,
    501 OutVals[0], Copy.getValue(1));
    502 if (DAG.getMachineFunction().getRegInfo().liveout_empty())
    503 DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg);
    504 break;
    505 }
    506 case 2: {
    507 EVT ArgVT = Outs[0].VT;
    508 unsigned ArgReg1, ArgReg2;
    509 if (ArgVT.isInteger()) {
    510 ArgReg1 = Alpha::R0;
    511 ArgReg2 = Alpha::R1;
    512 } else {
    513 assert(ArgVT.isFloatingPoint());
    514 ArgReg1 = Alpha::F0;
    515 ArgReg2 = Alpha::F1;
    516 }
    517 Copy = DAG.getCopyToReg(Copy, dl, ArgReg1,
    518 OutVals[0], Copy.getValue(1));
    519 if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(),
    520 DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg1)
    521 == DAG.getMachineFunction().getRegInfo().liveout_end())
    522 DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg1);
    523 Copy = DAG.getCopyToReg(Copy, dl, ArgReg2,
    524 OutVals[1], Copy.getValue(1));
    525 if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(),
    526 DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg2)
    527 == DAG.getMachineFunction().getRegInfo().liveout_end())
    528 DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg2);
    529 break;
    530 }
    531 }
    532 return DAG.getNode(AlphaISD::RET_FLAG, dl,
    533 MVT::Other, Copy, Copy.getValue(1));
    534 }
    535
    536 void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain,
    537 SDValue &DataPtr,
    538 SelectionDAG &DAG) const {
    539 Chain = N->getOperand(0);
    540 SDValue VAListP = N->getOperand(1);
    541 const Value *VAListS = cast(N->getOperand(2))->getValue();
    542 DebugLoc dl = N->getDebugLoc();
    543
    544 SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP,
    545 MachinePointerInfo(VAListS),
    546 false, false, 0);
    547 SDValue Tmp = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
    548 DAG.getConstant(8, MVT::i64));
    549 SDValue Offset = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Base.getValue(1),
    550 Tmp, MachinePointerInfo(),
    551 MVT::i32, false, false, 0);
    552 DataPtr = DAG.getNode(ISD::ADD, dl, MVT::i64, Base, Offset);
    553 if (N->getValueType(0).isFloatingPoint())
    554 {
    555 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
    556 SDValue FPDataPtr = DAG.getNode(ISD::SUB, dl, MVT::i64, DataPtr,
    557 DAG.getConstant(8*6, MVT::i64));
    558 SDValue CC = DAG.getSetCC(dl, MVT::i64, Offset,
    559 DAG.getConstant(8*6, MVT::i64), ISD::SETLT);
    560 DataPtr = DAG.getNode(ISD::SELECT, dl, MVT::i64, CC, FPDataPtr, DataPtr);
    561 }
    562
    563 SDValue NewOffset = DAG.getNode(ISD::ADD, dl, MVT::i64, Offset,
    564 DAG.getConstant(8, MVT::i64));
    565 Chain = DAG.getTruncStore(Offset.getValue(1), dl, NewOffset, Tmp,
    566 MachinePointerInfo(),
    567 MVT::i32, false, false, 0);
    568 }
    569
    570 /// LowerOperation - Provide custom lowering hooks for some operations.
    571 ///
    572 SDValue AlphaTargetLowering::LowerOperation(SDValue Op,
    573 SelectionDAG &DAG) const {
    574 DebugLoc dl = Op.getDebugLoc();
    575 switch (Op.getOpcode()) {
    576 default: llvm_unreachable("Wasn't expecting to be able to lower this!");
    577 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
    578
    579 case ISD::INTRINSIC_WO_CHAIN: {
    580 unsigned IntNo = cast(Op.getOperand(0))->getZExtValue();
    581 switch (IntNo) {
    582 default: break; // Don't custom lower most intrinsics.
    583 case Intrinsic::alpha_umulh:
    584 return DAG.getNode(ISD::MULHU, dl, MVT::i64,
    585 Op.getOperand(1), Op.getOperand(2));
    586 }
    587 }
    588
    589 case ISD::SRL_PARTS: {
    590 SDValue ShOpLo = Op.getOperand(0);
    591 SDValue ShOpHi = Op.getOperand(1);
    592 SDValue ShAmt = Op.getOperand(2);
    593 SDValue bm = DAG.getNode(ISD::SUB, dl, MVT::i64,
    594 DAG.getConstant(64, MVT::i64), ShAmt);
    595 SDValue BMCC = DAG.getSetCC(dl, MVT::i64, bm,
    596 DAG.getConstant(0, MVT::i64), ISD::SETLE);
    597 // if 64 - shAmt <= 0
    598 SDValue Hi_Neg = DAG.getConstant(0, MVT::i64);
    599 SDValue ShAmt_Neg = DAG.getNode(ISD::SUB, dl, MVT::i64,
    600 DAG.getConstant(0, MVT::i64), bm);
    601 SDValue Lo_Neg = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt_Neg);
    602 // else
    603 SDValue carries = DAG.getNode(ISD::SHL, dl, MVT::i64, ShOpHi, bm);
    604 SDValue Hi_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt);
    605 SDValue Lo_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpLo, ShAmt);
    606 Lo_Pos = DAG.getNode(ISD::OR, dl, MVT::i64, Lo_Pos, carries);
    607 // Merge
    608 SDValue Hi = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Hi_Neg, Hi_Pos);
    609 SDValue Lo = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Lo_Neg, Lo_Pos);
    610 SDValue Ops[2] = { Lo, Hi };
    611 return DAG.getMergeValues(Ops, 2, dl);
    612 }
    613 // case ISD::SRA_PARTS:
    614
    615 // case ISD::SHL_PARTS:
    616
    617
    618 case ISD::SINT_TO_FP: {
    619 assert(Op.getOperand(0).getValueType() == MVT::i64 &&
    620 "Unhandled SINT_TO_FP type in custom expander!");
    621 SDValue LD;
    622 bool isDouble = Op.getValueType() == MVT::f64;
    623 LD = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op.getOperand(0));
    624 SDValue FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_, dl,
    625 isDouble?MVT::f64:MVT::f32, LD);
    626 return FP;
    627 }
    628 case ISD::FP_TO_SINT: {
    629 bool isDouble = Op.getOperand(0).getValueType() == MVT::f64;
    630 SDValue src = Op.getOperand(0);
    631
    632 if (!isDouble) //Promote
    633 src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, src);
    634
    635 src = DAG.getNode(AlphaISD::CVTTQ_, dl, MVT::f64, src);
    636
    637 return DAG.getNode(ISD::BITCAST, dl, MVT::i64, src);
    638 }
    639 case ISD::ConstantPool: {
    640 ConstantPoolSDNode *CP = cast(Op);
    641 const Constant *C = CP->getConstVal();
    642 SDValue CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment());
    643 // FIXME there isn't really any debug info here
    644
    645 SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, CPI,
    646 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
    647 SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, CPI, Hi);
    648 return Lo;
    649 }
    650 case ISD::GlobalTLSAddress:
    651 llvm_unreachable("TLS not implemented for Alpha.");
    652 case ISD::GlobalAddress: {
    653 GlobalAddressSDNode *GSDN = cast(Op);
    654 const GlobalValue *GV = GSDN->getGlobal();
    655 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i64,
    656 GSDN->getOffset());
    657 // FIXME there isn't really any debug info here
    658
    659 // if (!GV->hasWeakLinkage() && !GV->isDeclaration()
    660 // && !GV->hasLinkOnceLinkage()) {
    661 if (GV->hasLocalLinkage()) {
    662 SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, GA,
    663 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
    664 SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, GA, Hi);
    665 return Lo;
    666 } else
    667 return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, GA,
    668 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
    669 }
    670 case ISD::ExternalSymbol: {
    671 return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64,
    672 DAG.getTargetExternalSymbol(cast(Op)
    673 ->getSymbol(), MVT::i64),
    674 DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
    675 }
    676
    677 case ISD::UREM:
    678 case ISD::SREM:
    679 //Expand only on constant case
    680 if (Op.getOperand(1).getOpcode() == ISD::Constant) {
    681 EVT VT = Op.getNode()->getValueType(0);
    682 SDValue Tmp1 = Op.getNode()->getOpcode() == ISD::UREM ?
    683 BuildUDIV(Op.getNode(), DAG, NULL) :
    684 BuildSDIV(Op.getNode(), DAG, NULL);
    685 Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Op.getOperand(1));
    686 Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Op.getOperand(0), Tmp1);
    687 return Tmp1;
    688 }
    689 //fall through
    690 case ISD::SDIV:
    691 case ISD::UDIV:
    692 if (Op.getValueType().isInteger()) {
    693 if (Op.getOperand(1).getOpcode() == ISD::Constant)
    694 return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.getNode(), DAG, NULL)
    695 : BuildUDIV(Op.getNode(), DAG, NULL);
    696 const char* opstr = 0;
    697 switch (Op.getOpcode()) {
    698 case ISD::UREM: opstr = "__remqu"; break;
    699 case ISD::SREM: opstr = "__remq"; break;
    700 case ISD::UDIV: opstr = "__divqu"; break;
    701 case ISD::SDIV: opstr = "__divq"; break;
    702 }
    703 SDValue Tmp1 = Op.getOperand(0),
    704 Tmp2 = Op.getOperand(1),
    705 Addr = DAG.getExternalSymbol(opstr, MVT::i64);
    706 return DAG.getNode(AlphaISD::DivCall, dl, MVT::i64, Addr, Tmp1, Tmp2);
    707 }
    708 break;
    709
    710 case ISD::VAARG: {
    711 SDValue Chain, DataPtr;
    712 LowerVAARG(Op.getNode(), Chain, DataPtr, DAG);
    713
    714 SDValue Result;
    715 if (Op.getValueType() == MVT::i32)
    716 Result = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Chain, DataPtr,
    717 MachinePointerInfo(), MVT::i32, false, false, 0);
    718 else
    719 Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr,
    720 MachinePointerInfo(),
    721 false, false, 0);
    722 return Result;
    723 }
    724 case ISD::VACOPY: {
    725 SDValue Chain = Op.getOperand(0);
    726 SDValue DestP = Op.getOperand(1);
    727 SDValue SrcP = Op.getOperand(2);
    728 const Value *DestS = cast(Op.getOperand(3))->getValue();
    729 const Value *SrcS = cast(Op.getOperand(4))->getValue();
    730
    731 SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP,
    732 MachinePointerInfo(SrcS),
    733 false, false, 0);
    734 SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP,
    735 MachinePointerInfo(DestS),
    736 false, false, 0);
    737 SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP,
    738 DAG.getConstant(8, MVT::i64));
    739 Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result,
    740 NP, MachinePointerInfo(), MVT::i32, false, false, 0);
    741 SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP,
    742 DAG.getConstant(8, MVT::i64));
    743 return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD,
    744 MachinePointerInfo(), MVT::i32,
    745 false, false, 0);
    746 }
    747 case ISD::VASTART: {
    748 MachineFunction &MF = DAG.getMachineFunction();
    749 AlphaMachineFunctionInfo *FuncInfo = MF.getInfo();
    750
    751 SDValue Chain = Op.getOperand(0);
    752 SDValue VAListP = Op.getOperand(1);
    753 const Value *VAListS = cast(Op.getOperand(2))->getValue();
    754
    755 // vastart stores the address of the VarArgsBase and VarArgsOffset
    756 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsBase(), MVT::i64);
    757 SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP,
    758 MachinePointerInfo(VAListS), false, false, 0);
    759 SDValue SA2 = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
    760 DAG.getConstant(8, MVT::i64));
    761 return DAG.getTruncStore(S1, dl,
    762 DAG.getConstant(FuncInfo->getVarArgsOffset(),
    763 MVT::i64),
    764 SA2, MachinePointerInfo(),
    765 MVT::i32, false, false, 0);
    766 }
    767 case ISD::RETURNADDR:
    768 return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc(), MVT::i64);
    769 //FIXME: implement
    770 case ISD::FRAMEADDR: break;
    771 }
    772
    773 return SDValue();
    774 }
    775
    776 void AlphaTargetLowering::ReplaceNodeResults(SDNode *N,
    777 SmallVectorImpl&Results,
    778 SelectionDAG &DAG) const {
    779 DebugLoc dl = N->getDebugLoc();
    780 assert(N->getValueType(0) == MVT::i32 &&
    781 N->getOpcode() == ISD::VAARG &&
    782 "Unknown node to custom promote!");
    783
    784 SDValue Chain, DataPtr;
    785 LowerVAARG(N, Chain, DataPtr, DAG);
    786 SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr,
    787 MachinePointerInfo(),
    788 false, false, 0);
    789 Results.push_back(Res);
    790 Results.push_back(SDValue(Res.getNode(), 1));
    791 }
    792
    793
    794 //Inline Asm
    795
    796 /// getConstraintType - Given a constraint letter, return the type of
    797 /// constraint it is for this target.
    798 AlphaTargetLowering::ConstraintType
    799 AlphaTargetLowering::getConstraintType(const std::string &Constraint) const {
    800 if (Constraint.size() == 1) {
    801 switch (Constraint[0]) {
    802 default: break;
    803 case 'f':
    804 case 'r':
    805 return C_RegisterClass;
    806 }
    807 }
    808 return TargetLowering::getConstraintType(Constraint);
    809 }
    810
    811 /// Examine constraint type and operand type and determine a weight value.
    812 /// This object must already have been set up with the operand type
    813 /// and the current alternative constraint selected.
    814 TargetLowering::ConstraintWeight
    815 AlphaTargetLowering::getSingleConstraintMatchWeight(
    816 AsmOperandInfo &info, const char *constraint) const {
    817 ConstraintWeight weight = CW_Invalid;
    818 Value *CallOperandVal = info.CallOperandVal;
    819 // If we don't have a value, we can't do a match,
    820 // but allow it at the lowest weight.
    821 if (CallOperandVal == NULL)
    822 return CW_Default;
    823 // Look at the constraint type.
    824 switch (*constraint) {
    825 default:
    826 weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
    827 break;
    828 case 'f':
    829 weight = CW_Register;
    830 break;
    831 }
    832 return weight;
    833 }
    834
    835 /// Given a register class constraint, like 'r', if this corresponds directly
    836 /// to an LLVM register class, return a register of 0 and the register class
    837 /// pointer.
    838 std::pair AlphaTargetLowering::
    839 getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
    840 {
    841 if (Constraint.size() == 1) {
    842 switch (Constraint[0]) {
    843 case 'r':
    844 return std::make_pair(0U, Alpha::GPRCRegisterClass);
    845 case 'f':
    846 return VT == MVT::f64 ? std::make_pair(0U, Alpha::F8RCRegisterClass) :
    847 std::make_pair(0U, Alpha::F4RCRegisterClass);
    848 }
    849 }
    850 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
    851 }
    852
    853 //===----------------------------------------------------------------------===//
    854 // Other Lowering Code
    855 //===----------------------------------------------------------------------===//
    856
    857 MachineBasicBlock *
    858 AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
    859 MachineBasicBlock *BB) const {
    860 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
    861 assert((MI->getOpcode() == Alpha::CAS32 ||
    862 MI->getOpcode() == Alpha::CAS64 ||
    863 MI->getOpcode() == Alpha::LAS32 ||
    864 MI->getOpcode() == Alpha::LAS64 ||
    865 MI->getOpcode() == Alpha::SWAP32 ||
    866 MI->getOpcode() == Alpha::SWAP64) &&
    867 "Unexpected instr type to insert");
    868
    869 bool is32 = MI->getOpcode() == Alpha::CAS32 ||
    870 MI->getOpcode() == Alpha::LAS32 ||
    871 MI->getOpcode() == Alpha::SWAP32;
    872
    873 //Load locked store conditional for atomic ops take on the same form
    874 //start:
    875 //ll
    876 //do stuff (maybe branch to exit)
    877 //sc
    878 //test sc and maybe branck to start
    879 //exit:
    880 const BasicBlock *LLVM_BB = BB->getBasicBlock();
    881 DebugLoc dl = MI->getDebugLoc();
    882 MachineFunction::iterator It = BB;
    883 ++It;
    884
    885 MachineBasicBlock *thisMBB = BB;
    886 MachineFunction *F = BB->getParent();
    887 MachineBasicBlock *llscMBB = F->CreateMachineBasicBlock(LLVM_BB);
    888 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
    889
    890 sinkMBB->splice(sinkMBB->begin(), thisMBB,
    891 llvm::next(MachineBasicBlock::iterator(MI)),
    892 thisMBB->end());
    893 sinkMBB->transferSuccessorsAndUpdatePHIs(thisMBB);
    894
    895 F->insert(It, llscMBB);
    896 F->insert(It, sinkMBB);
    897
    898 BuildMI(thisMBB, dl, TII->get(Alpha::BR)).addMBB(llscMBB);
    899
    900 unsigned reg_res = MI->getOperand(0).getReg(),
    901 reg_ptr = MI->getOperand(1).getReg(),
    902 reg_v2 = MI->getOperand(2).getReg(),
    903 reg_store = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
    904
    905 BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L),
    906 reg_res).addImm(0).addReg(reg_ptr);
    907 switch (MI->getOpcode()) {
    908 case Alpha::CAS32:
    909 case Alpha::CAS64: {
    910 unsigned reg_cmp
    911 = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
    912 BuildMI(llscMBB, dl, TII->get(Alpha::CMPEQ), reg_cmp)
    913 .addReg(reg_v2).addReg(reg_res);
    914 BuildMI(llscMBB, dl, TII->get(Alpha::BEQ))
    915 .addImm(0).addReg(reg_cmp).addMBB(sinkMBB);
    916 BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store)
    917 .addReg(Alpha::R31).addReg(MI->getOperand(3).getReg());
    918 break;
    919 }
    920 case Alpha::LAS32:
    921 case Alpha::LAS64: {
    922 BuildMI(llscMBB, dl,TII->get(is32 ? Alpha::ADDLr : Alpha::ADDQr), reg_store)
    923 .addReg(reg_res).addReg(reg_v2);
    924 break;
    925 }
    926 case Alpha::SWAP32:
    927 case Alpha::SWAP64: {
    928 BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store)
    929 .addReg(reg_v2).addReg(reg_v2);
    930 break;
    931 }
    932 }
    933 BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::STL_C : Alpha::STQ_C), reg_store)
    934 .addReg(reg_store).addImm(0).addReg(reg_ptr);
    935 BuildMI(llscMBB, dl, TII->get(Alpha::BEQ))
    936 .addImm(0).addReg(reg_store).addMBB(llscMBB);
    937 BuildMI(llscMBB, dl, TII->get(Alpha::BR)).addMBB(sinkMBB);
    938
    939 thisMBB->addSuccessor(llscMBB);
    940 llscMBB->addSuccessor(llscMBB);
    941 llscMBB->addSuccessor(sinkMBB);
    942 MI->eraseFromParent(); // The pseudo instruction is gone now.
    943
    944 return sinkMBB;
    945 }
    946
    947 bool
    948 AlphaTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
    949 // The Alpha target isn't yet aware of offsets.
    950 return false;
    951 }
    952
    953 bool AlphaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
    954 if (VT != MVT::f32 && VT != MVT::f64)
    955 return false;
    956 // +0.0 F31
    957 // +0.0f F31
    958 // -0.0 -F31
    959 // -0.0f -F31
    960 return Imm.isZero() || Imm.isNegZero();
    961 }
    +0
    -142
    lib/Target/Alpha/AlphaISelLowering.h less more
    None //===-- AlphaISelLowering.h - Alpha DAG Lowering Interface ------*- C++ -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file defines the interfaces that Alpha uses to lower LLVM code into a
    10 // selection DAG.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #ifndef LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H
    15 #define LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H
    16
    17 #include "llvm/ADT/VectorExtras.h"
    18 #include "llvm/Target/TargetLowering.h"
    19 #include "llvm/CodeGen/SelectionDAG.h"
    20 #include "Alpha.h"
    21
    22 namespace llvm {
    23
    24 namespace AlphaISD {
    25 enum NodeType {
    26 // Start the numbering where the builting ops and target ops leave off.
    27 FIRST_NUMBER = ISD::BUILTIN_OP_END,
    28 //These corrospond to the identical Instruction
    29 CVTQT_, CVTQS_, CVTTQ_,
    30
    31 /// GPRelHi/GPRelLo - These represent the high and low 16-bit
    32 /// parts of a global address respectively.
    33 GPRelHi, GPRelLo,
    34
    35 /// RetLit - Literal Relocation of a Global
    36 RelLit,
    37
    38 /// GlobalRetAddr - used to restore the return address
    39 GlobalRetAddr,
    40
    41 /// CALL - Normal call.
    42 CALL,
    43
    44 /// DIVCALL - used for special library calls for div and rem
    45 DivCall,
    46
    47 /// return flag operand
    48 RET_FLAG,
    49
    50 /// CHAIN = COND_BRANCH CHAIN, OPC, (G|F)PRC, DESTBB [, INFLAG] - This
    51 /// corresponds to the COND_BRANCH pseudo instruction.
    52 /// *PRC is the input register to compare to zero,
    53 /// OPC is the branch opcode to use (e.g. Alpha::BEQ),
    54 /// DESTBB is the destination block to branch to, and INFLAG is
    55 /// an optional input flag argument.
    56 COND_BRANCH_I, COND_BRANCH_F
    57
    58 };
    59 }
    60
    61 class AlphaTargetLowering : public TargetLowering {
    62 public:
    63 explicit AlphaTargetLowering(TargetMachine &TM);
    64
    65 virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i64; }
    66
    67 /// getSetCCResultType - Get the SETCC result ValueType
    68 virtual EVT getSetCCResultType(EVT VT) const;
    69
    70 /// LowerOperation - Provide custom lowering hooks for some operations.
    71 ///
    72 virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
    73
    74 /// ReplaceNodeResults - Replace the results of node with an illegal result
    75 /// type with new values built out of custom code.
    76 ///
    77 virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl&Results,
    78 SelectionDAG &DAG) const;
    79
    80 // Friendly names for dumps
    81 const char *getTargetNodeName(unsigned Opcode) const;
    82
    83 SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
    84 CallingConv::ID CallConv, bool isVarArg,
    85 const SmallVectorImpl &Ins,
    86 DebugLoc dl, SelectionDAG &DAG,
    87 SmallVectorImpl &InVals) const;
    88
    89 ConstraintType getConstraintType(const std::string &Constraint) const;
    90
    91 /// Examine constraint string and operand type and determine a weight value.
    92 /// The operand object must already have been set up with the operand type.
    93 ConstraintWeight getSingleConstraintMatchWeight(
    94 AsmOperandInfo &info, const char *constraint) const;
    95
    96 std::pair
    97 getRegForInlineAsmConstraint(const std::string &Constraint,
    98 EVT VT) const;
    99
    100 MachineBasicBlock *
    101 EmitInstrWithCustomInserter(MachineInstr *MI,
    102 MachineBasicBlock *BB) const;
    103
    104 virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
    105
    106 /// isFPImmLegal - Returns true if the target can instruction select the
    107 /// specified FP immediate natively. If false, the legalizer will
    108 /// materialize the FP immediate as a load from a constant pool.
    109 virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
    110
    111 private:
    112 // Helpers for custom lowering.
    113 void LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr,
    114 SelectionDAG &DAG) const;
    115
    116 virtual SDValue
    117 LowerFormalArguments(SDValue Chain,
    118 CallingConv::ID CallConv, bool isVarArg,
    119 const SmallVectorImpl &Ins,
    120 DebugLoc dl, SelectionDAG &DAG,
    121 SmallVectorImpl &InVals) const;
    122
    123 virtual SDValue
    124 LowerCall(SDValue Chain, SDValue Callee,
    125 CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
    126 const SmallVectorImpl &Outs,
    127 const SmallVectorImpl &OutVals,
    128 const SmallVectorImpl &Ins,
    129 DebugLoc dl, SelectionDAG &DAG,
    130 SmallVectorImpl &InVals) const;
    131
    132 virtual SDValue
    133 LowerReturn(SDValue Chain,
    134 CallingConv::ID CallConv, bool isVarArg,
    135 const SmallVectorImpl &Outs,
    136 const SmallVectorImpl &OutVals,
    137 DebugLoc dl, SelectionDAG &DAG) const;
    138 };
    139 }
    140
    141 #endif // LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H
    +0
    -268
    lib/Target/Alpha/AlphaInstrFormats.td less more
    None //===- AlphaInstrFormats.td - Alpha Instruction Formats ----*- tablegen -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 //
    10 //===----------------------------------------------------------------------===//
    11
    12 //3.3:
    13 //Memory
    14 //Branch
    15 //Operate
    16 //Floating-point
    17 //PALcode
    18
    19 def u8imm : Operand;
    20 def s14imm : Operand;
    21 def s16imm : Operand;
    22 def s21imm : Operand;
    23 def s64imm : Operand;
    24 def u64imm : Operand;
    25
    26 //===----------------------------------------------------------------------===//
    27 // Instruction format superclass
    28 //===----------------------------------------------------------------------===//
    29 // Alpha instruction baseline
    30 class InstAlpha op, string asmstr, InstrItinClass itin> : Instruction {
    31 field bits<32> Inst;
    32 let Namespace = "Alpha";
    33 let AsmString = asmstr;
    34 let Inst{31-26} = op;
    35 let Itinerary = itin;
    36 }
    37
    38
    39 //3.3.1
    40 class MForm opcode, bit load, string asmstr, list pattern, InstrItinClass itin>
    41 : InstAlpha {
    42 let Pattern = pattern;
    43 let canFoldAsLoad = load;
    44 let Defs = [R28]; //We may use this for frame index calculations, so reserve it here
    45
    46 bits<5> Ra;
    47 bits<16> disp;
    48 bits<5> Rb;
    49
    50 let Inst{25-21} = Ra;
    51 let Inst{20-16} = Rb;
    52 let Inst{15-0} = disp;
    53 }
    54 class MfcForm opcode, bits<16> fc, string asmstr, InstrItinClass itin>
    55 : InstAlpha {
    56 bits<5> Ra;
    57
    58 let OutOperandList = (outs GPRC:$RA);
    59 let InOperandList = (ins);
    60 let Inst{25-21} = Ra;
    61 let Inst{20-16} = 0;
    62 let Inst{15-0} = fc;
    63 }
    64 class MfcPForm opcode, bits<16> fc, string asmstr, InstrItinClass itin>
    65 : InstAlpha {
    66 let OutOperandList = (outs);
    67 let InOperandList = (ins);
    68 let Inst{25-21} = 0;
    69 let Inst{20-16} = 0;
    70 let Inst{15-0} = fc;
    71 }
    72
    73 class MbrForm opcode, bits<2> TB, dag OL, string asmstr, InstrItinClass itin>
    74 : InstAlpha {
    75 bits<5> Ra;
    76 bits<5> Rb;
    77 bits<14> disp;
    78
    79 let OutOperandList = (outs);
    80 let InOperandList = OL;
    81
    82 let Inst{25-21} = Ra;
    83 let Inst{20-16} = Rb;
    84 let Inst{15-14} = TB;
    85 let Inst{13-0} = disp;
    86 }
    87 class MbrpForm opcode, bits<2> TB, dag OL, string asmstr, list pattern, InstrItinClass itin>
    88 : InstAlpha {
    89 let Pattern=pattern;
    90 bits<5> Ra;
    91 bits<5> Rb;
    92 bits<14> disp;
    93
    94 let OutOperandList = (outs);
    95 let InOperandList = OL;
    96
    97 let Inst{25-21} = Ra;
    98 let Inst{20-16} = Rb;
    99 let Inst{15-14} = TB;
    100 let Inst{13-0} = disp;
    101 }
    102
    103 //3.3.2
    104 def target : Operand {}
    105
    106 let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
    107 class BFormN opcode, dag OL, string asmstr, InstrItinClass itin>
    108 : InstAlpha {
    109 let OutOperandList = (outs);
    110 let InOperandList = OL;
    111 bits<64> Opc; //dummy
    112 bits<5> Ra;
    113 bits<21> disp;
    114
    115 let Inst{25-21} = Ra;
    116 let Inst{20-0} = disp;
    117 }
    118 }
    119
    120 let isBranch = 1, isTerminator = 1 in
    121 class BFormD opcode, string asmstr, list pattern, InstrItinClass itin>
    122 : InstAlpha {
    123 let Pattern = pattern;
    124 let OutOperandList = (outs);
    125 let InOperandList = (ins target:$DISP);
    126 bits<5> Ra;
    127 bits<21> disp;
    128
    129 let Inst{25-21} = Ra;
    130 let Inst{20-0} = disp;
    131 }
    132
    133 //3.3.3
    134 class OForm opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin>
    135 : InstAlpha {
    136 let Pattern = pattern;
    137 let OutOperandList = (outs GPRC:$RC);
    138 let InOperandList = (ins GPRC:$RA, GPRC:$RB);
    139
    140 bits<5> Rc;
    141 bits<5> Ra;
    142 bits<5> Rb;
    143 bits<7> Function = fun;
    144
    145 let Inst{25-21} = Ra;
    146 let Inst{20-16} = Rb;
    147 let Inst{15-13} = 0;
    148 let Inst{12} = 0;
    149 let Inst{11-5} = Function;
    150 let Inst{4-0} = Rc;
    151 }
    152
    153 class OForm2 opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin>
    154 : InstAlpha {
    155 let Pattern = pattern;
    156 let OutOperandList = (outs GPRC:$RC);
    157 let InOperandList = (ins GPRC:$RB);
    158
    159 bits<5> Rc;
    160 bits<5> Rb;
    161 bits<7> Function = fun;
    162
    163 let Inst{25-21} = 31;
    164 let Inst{20-16} = Rb;
    165 let Inst{15-13} = 0;
    166 let Inst{12} = 0;
    167 let Inst{11-5} = Function;
    168 let Inst{4-0} = Rc;
    169 }
    170
    171 class OForm4 opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin>
    172 : InstAlpha {
    173 let Pattern = pattern;
    174 let OutOperandList = (outs GPRC:$RDEST);
    175 let InOperandList = (ins GPRC:$RCOND, GPRC:$RTRUE, GPRC:$RFALSE);
    176 let Constraints = "$RFALSE = $RDEST";
    177 let DisableEncoding = "$RFALSE";
    178
    179 bits<5> Rc;
    180 bits<5> Ra;
    181 bits<5> Rb;
    182 bits<7> Function = fun;
    183
    184 // let Constraints = "$RFALSE = $RDEST";
    185 let Inst{25-21} = Ra;
    186 let Inst{20-16} = Rb;
    187 let Inst{15-13} = 0;
    188 let Inst{12} = 0;
    189 let Inst{11-5} = Function;
    190 let Inst{4-0} = Rc;
    191 }
    192
    193
    194 class OFormL opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin>
    195 : InstAlpha {
    196 let Pattern = pattern;
    197 let OutOperandList = (outs GPRC:$RC);
    198 let InOperandList = (ins GPRC:$RA, u8imm:$L);
    199
    200 bits<5> Rc;
    201 bits<5> Ra;
    202 bits<8> LIT;
    203 bits<7> Function = fun;
    204
    205 let Inst{25-21} = Ra;
    206 let Inst{20-13} = LIT;
    207 let Inst{12} = 1;
    208 let Inst{11-5} = Function;
    209 let Inst{4-0} = Rc;
    210 }
    211
    212 class OForm4L opcode, bits<7> fun, string asmstr, list pattern, InstrItinClass itin>
    213 : InstAlpha {
    214 let Pattern = pattern;
    215 let OutOperandList = (outs GPRC:$RDEST);
    216 let InOperandList = (ins GPRC:$RCOND, s64imm:$RTRUE, GPRC:$RFALSE);
    217 let Constraints = "$RFALSE = $RDEST";
    218 let DisableEncoding = "$RFALSE";
    219
    220 bits<5> Rc;
    221 bits<5> Ra;
    222 bits<8> LIT;
    223 bits<7> Function = fun;
    224
    225 // let Constraints = "$RFALSE = $RDEST";
    226 let Inst{25-21} = Ra;
    227 let Inst{20-13} = LIT;
    228 let Inst{12} = 1;
    229 let Inst{11-5} = Function;
    230 let Inst{4-0} = Rc;
    231 }
    232
    233 //3.3.4
    234 class FPForm opcode, bits<11> fun, string asmstr, list pattern, InstrItinClass itin>
    235 : InstAlpha {
    236 let Pattern = pattern;
    237
    238 bits<5> Fc;
    239 bits<5> Fa;
    240 bits<5> Fb;
    241 bits<11> Function = fun;
    242
    243 let Inst{25-21} = Fa;
    244 let Inst{20-16} = Fb;
    245 let Inst{15-5} = Function;
    246 let Inst{4-0} = Fc;
    247 }
    248
    249 //3.3.5
    250 class PALForm opcode, dag OL, string asmstr, InstrItinClass itin>
    251 : InstAlpha {
    252 let OutOperandList = (outs);
    253 let InOperandList = OL;
    254 bits<26> Function;
    255
    256 let Inst{25-0} = Function;
    257 }
    258
    259
    260 // Pseudo instructions.
    261 class PseudoInstAlpha pattern, InstrItinClass itin>
    262 : InstAlpha<0, nm, itin> {
    263 let OutOperandList = OOL;
    264 let InOperandList = IOL;
    265 let Pattern = pattern;
    266
    267 }
    +0
    -382
    lib/Target/Alpha/AlphaInstrInfo.cpp less more
    None //===- AlphaInstrInfo.cpp - Alpha Instruction Information -------*- C++ -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file contains the Alpha implementation of the TargetInstrInfo class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #include "Alpha.h"
    14 #include "AlphaInstrInfo.h"
    15 #include "AlphaMachineFunctionInfo.h"
    16 #include "llvm/CodeGen/MachineInstrBuilder.h"
    17 #include "llvm/CodeGen/MachineRegisterInfo.h"
    18 #include "llvm/ADT/STLExtras.h"
    19 #include "llvm/ADT/SmallVector.h"
    20 #include "llvm/Support/ErrorHandling.h"
    21
    22 #define GET_INSTRINFO_CTOR
    23 #include "AlphaGenInstrInfo.inc"
    24 using namespace llvm;
    25
    26 AlphaInstrInfo::AlphaInstrInfo()
    27 : AlphaGenInstrInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP),
    28 RI(*this) {
    29 }
    30
    31
    32 unsigned
    33 AlphaInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
    34 int &FrameIndex) const {
    35 switch (MI->getOpcode()) {
    36 case Alpha::LDL:
    37 case Alpha::LDQ:
    38 case Alpha::LDBU:
    39 case Alpha::LDWU:
    40 case Alpha::LDS:
    41 case Alpha::LDT:
    42 if (MI->getOperand(1).isFI()) {
    43 FrameIndex = MI->getOperand(1).getIndex();
    44 return MI->getOperand(0).getReg();
    45 }
    46 break;
    47 }
    48 return 0;
    49 }
    50
    51 unsigned
    52 AlphaInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
    53 int &FrameIndex) const {
    54 switch (MI->getOpcode()) {
    55 case Alpha::STL:
    56 case Alpha::STQ:
    57 case Alpha::STB:
    58 case Alpha::STW:
    59 case Alpha::STS:
    60 case Alpha::STT:
    61 if (MI->getOperand(1).isFI()) {
    62 FrameIndex = MI->getOperand(1).getIndex();
    63 return MI->getOperand(0).getReg();
    64 }
    65 break;
    66 }
    67 return 0;
    68 }
    69
    70 static bool isAlphaIntCondCode(unsigned Opcode) {
    71 switch (Opcode) {
    72 case Alpha::BEQ:
    73 case Alpha::BNE:
    74 case Alpha::BGE:
    75 case Alpha::BGT:
    76 case Alpha::BLE:
    77 case Alpha::BLT:
    78 case Alpha::BLBC:
    79 case Alpha::BLBS:
    80 return true;
    81 default:
    82 return false;
    83 }
    84 }
    85
    86 unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,
    87 MachineBasicBlock *TBB,
    88 MachineBasicBlock *FBB,
    89 const SmallVectorImpl &Cond,
    90 DebugLoc DL) const {
    91 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
    92 assert((Cond.size() == 2 || Cond.size() == 0) &&
    93 "Alpha branch conditions have two components!");
    94
    95 // One-way branch.
    96 if (FBB == 0) {
    97 if (Cond.empty()) // Unconditional branch
    98 BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(TBB);
    99 else // Conditional branch
    100 if (isAlphaIntCondCode(Cond[0].getImm()))
    101 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I))
    102 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    103 else
    104 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F))
    105 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    106 return 1;
    107 }
    108
    109 // Two-way Conditional Branch.
    110 if (isAlphaIntCondCode(Cond[0].getImm()))
    111 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I))
    112 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    113 else
    114 BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F))
    115 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    116 BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(FBB);
    117 return 2;
    118 }
    119
    120 void AlphaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
    121 MachineBasicBlock::iterator MI, DebugLoc DL,
    122 unsigned DestReg, unsigned SrcReg,
    123 bool KillSrc) const {
    124 if (Alpha::GPRCRegClass.contains(DestReg, SrcReg)) {
    125 BuildMI(MBB, MI, DL, get(Alpha::BISr), DestReg)
    126 .addReg(SrcReg)
    127 .addReg(SrcReg, getKillRegState(KillSrc));
    128 } else if (Alpha::F4RCRegClass.contains(DestReg, SrcReg)) {
    129 BuildMI(MBB, MI, DL, get(Alpha::CPYSS), DestReg)
    130 .addReg(SrcReg)
    131 .addReg(SrcReg, getKillRegState(KillSrc));
    132 } else if (Alpha::F8RCRegClass.contains(DestReg, SrcReg)) {
    133 BuildMI(MBB, MI, DL, get(Alpha::CPYST), DestReg)
    134 .addReg(SrcReg)
    135 .addReg(SrcReg, getKillRegState(KillSrc));
    136 } else {
    137 llvm_unreachable("Attempt to copy register that is not GPR or FPR");
    138 }
    139 }
    140
    141 void
    142 AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
    143 MachineBasicBlock::iterator MI,
    144 unsigned SrcReg, bool isKill, int FrameIdx,
    145 const TargetRegisterClass *RC,
    146 const TargetRegisterInfo *TRI) const {
    147 //cerr << "Trying to store " << getPrettyName(SrcReg) << " to "
    148 // << FrameIdx << "\n";
    149 //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
    150
    151 DebugLoc DL;
    152 if (MI != MBB.end()) DL = MI->getDebugLoc();
    153
    154 if (RC == Alpha::F4RCRegisterClass)
    155 BuildMI(MBB, MI, DL, get(Alpha::STS))
    156 .addReg(SrcReg, getKillRegState(isKill))
    157 .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    158 else if (RC == Alpha::F8RCRegisterClass)
    159 BuildMI(MBB, MI, DL, get(Alpha::STT))
    160 .addReg(SrcReg, getKillRegState(isKill))
    161 .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    162 else if (RC == Alpha::GPRCRegisterClass)
    163 BuildMI(MBB, MI, DL, get(Alpha::STQ))
    164 .addReg(SrcReg, getKillRegState(isKill))
    165 .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    166 else
    167 llvm_unreachable("Unhandled register class");
    168 }
    169
    170 void
    171 AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
    172 MachineBasicBlock::iterator MI,
    173 unsigned DestReg, int FrameIdx,
    174 const TargetRegisterClass *RC,
    175 const TargetRegisterInfo *TRI) const {
    176 //cerr << "Trying to load " << getPrettyName(DestReg) << " to "
    177 // << FrameIdx << "\n";
    178 DebugLoc DL;
    179 if (MI != MBB.end()) DL = MI->getDebugLoc();
    180
    181 if (RC == Alpha::F4RCRegisterClass)
    182 BuildMI(MBB, MI, DL, get(Alpha::LDS), DestReg)
    183 .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    184 else if (RC == Alpha::F8RCRegisterClass)
    185 BuildMI(MBB, MI, DL, get(Alpha::LDT), DestReg)
    186 .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    187 else if (RC == Alpha::GPRCRegisterClass)
    188 BuildMI(MBB, MI, DL, get(Alpha::LDQ), DestReg)
    189 .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    190 else
    191 llvm_unreachable("Unhandled register class");
    192 }
    193
    194 static unsigned AlphaRevCondCode(unsigned Opcode) {
    195 switch (Opcode) {
    196 case Alpha::BEQ: return Alpha::BNE;
    197 case Alpha::BNE: return Alpha::BEQ;
    198 case Alpha::BGE: return Alpha::BLT;
    199 case Alpha::BGT: return Alpha::BLE;
    200 case Alpha::BLE: return Alpha::BGT;
    201 case Alpha::BLT: return Alpha::BGE;
    202 case Alpha::BLBC: return Alpha::BLBS;
    203 case Alpha::BLBS: return Alpha::BLBC;
    204 case Alpha::FBEQ: return Alpha::FBNE;
    205 case Alpha::FBNE: return Alpha::FBEQ;
    206 case Alpha::FBGE: return Alpha::FBLT;
    207 case Alpha::FBGT: return Alpha::FBLE;
    208 case Alpha::FBLE: return Alpha::FBGT;
    209 case Alpha::FBLT: return Alpha::FBGE;
    210 default:
    211 llvm_unreachable("Unknown opcode");
    212 }
    213 return 0; // Not reached
    214 }
    215
    216 // Branch analysis.
    217 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
    218 MachineBasicBlock *&FBB,
    219 SmallVectorImpl &Cond,
    220 bool AllowModify) const {
    221 // If the block has no terminators, it just falls into the block after it.
    222 MachineBasicBlock::iterator I = MBB.end();
    223 if (I == MBB.begin())
    224 return false;
    225 --I;
    226 while (I->isDebugValue()) {
    227 if (I == MBB.begin())
    228 return false;
    229 --I;
    230 }
    231 if (!isUnpredicatedTerminator(I))
    232 return false;
    233
    234 // Get the last instruction in the block.
    235 MachineInstr *LastInst = I;
    236
    237 // If there is only one terminator instruction, process it.
    238 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
    239 if (LastInst->getOpcode() == Alpha::BR) {
    240 TBB = LastInst->getOperand(0).getMBB();
    241 return false;
    242 } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I ||
    243 LastInst->getOpcode() == Alpha::COND_BRANCH_F) {
    244 // Block ends with fall-through condbranch.
    245 TBB = LastInst->getOperand(2).getMBB();
    246 Cond.push_back(LastInst->getOperand(0));
    247 Cond.push_back(LastInst->getOperand(1));
    248 return false;
    249 }
    250 // Otherwise, don't know what this is.
    251 return true;
    252 }
    253
    254 // Get the instruction before it if it's a terminator.
    255 MachineInstr *SecondLastInst = I;
    256
    257 // If there are three terminators, we don't know what sort of block this is.
    258 if (SecondLastInst && I != MBB.begin() &&
    259 isUnpredicatedTerminator(--I))
    260 return true;
    261
    262 // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
    263 if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I ||
    264 SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) &&
    265 LastInst->getOpcode() == Alpha::BR) {
    266 TBB = SecondLastInst->getOperand(2).getMBB();
    267 Cond.push_back(SecondLastInst->getOperand(0));
    268 Cond.push_back(SecondLastInst->getOperand(1));
    269 FBB = LastInst->getOperand(0).getMBB();
    270 return false;
    271 }
    272
    273 // If the block ends with two Alpha::BRs, handle it. The second one is not
    274 // executed, so remove it.
    275 if (SecondLastInst->getOpcode() == Alpha::BR &&
    276 LastInst->getOpcode() == Alpha::BR) {
    277 TBB = SecondLastInst->getOperand(0).getMBB();
    278 I = LastInst;
    279 if (AllowModify)
    280 I->eraseFromParent();
    281 return false;
    282 }
    283
    284 // Otherwise, can't handle this.
    285 return true;
    286 }
    287
    288 unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
    289 MachineBasicBlock::iterator I = MBB.end();
    290 if (I == MBB.begin()) return 0;
    291 --I;
    292 while (I->isDebugValue()) {
    293 if (I == MBB.begin())
    294 return 0;
    295 --I;
    296 }
    297 if (I->getOpcode() != Alpha::BR &&
    298 I->getOpcode() != Alpha::COND_BRANCH_I &&
    299 I->getOpcode() != Alpha::COND_BRANCH_F)
    300 return 0;
    301
    302 // Remove the branch.
    303 I->eraseFromParent();
    304
    305 I = MBB.end();
    306
    307 if (I == MBB.begin()) return 1;
    308 --I;
    309 if (I->getOpcode() != Alpha::COND_BRANCH_I &&
    310 I->getOpcode() != Alpha::COND_BRANCH_F)
    311 return 1;
    312
    313 // Remove the branch.
    314 I->eraseFromParent();
    315 return 2;
    316 }
    317
    318 void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB,
    319 MachineBasicBlock::iterator MI) const {
    320 DebugLoc DL;
    321 BuildMI(MBB, MI, DL, get(Alpha::BISr), Alpha::R31)
    322 .addReg(Alpha::R31)
    323 .addReg(Alpha::R31);
    324 }
    325
    326 bool AlphaInstrInfo::
    327 ReverseBranchCondition(SmallVectorImpl &Cond) const {
    328 assert(Cond.size() == 2 && "Invalid Alpha branch opcode!");
    329 Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm()));
    330 return false;
    331 }
    332
    333 /// getGlobalBaseReg - Return a virtual register initialized with the
    334 /// the global base register value. Output instructions required to
    335 /// initialize the register in the function entry block, if necessary.
    336 ///
    337 unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
    338 AlphaMachineFunctionInfo *AlphaFI = MF->getInfo();
    339 unsigned GlobalBaseReg = AlphaFI->getGlobalBaseReg();
    340 if (GlobalBaseReg != 0)
    341 return GlobalBaseReg;
    342
    343 // Insert the set of GlobalBaseReg into the first MBB of the function
    344 MachineBasicBlock &FirstMBB = MF->front();
    345 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    346 MachineRegisterInfo &RegInfo = MF->getRegInfo();
    347 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
    348
    349 GlobalBaseReg = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
    350 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
    351 GlobalBaseReg).addReg(Alpha::R29);
    352 RegInfo.addLiveIn(Alpha::R29);
    353
    354 AlphaFI->setGlobalBaseReg(GlobalBaseReg);
    355 return GlobalBaseReg;
    356 }
    357
    358 /// getGlobalRetAddr - Return a virtual register initialized with the
    359 /// the global base register value. Output instructions required to
    360 /// initialize the register in the function entry block, if necessary.
    361 ///
    362 unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const {
    363 AlphaMachineFunctionInfo *AlphaFI = MF->getInfo();
    364 unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr();
    365 if (GlobalRetAddr != 0)
    366 return GlobalRetAddr;
    367
    368 // Insert the set of GlobalRetAddr into the first MBB of the function
    369 MachineBasicBlock &FirstMBB = MF->front();
    370 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    371 MachineRegisterInfo &RegInfo = MF->getRegInfo();
    372 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
    373
    374 GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
    375 BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
    376 GlobalRetAddr).addReg(Alpha::R26);
    377 RegInfo.addLiveIn(Alpha::R26);
    378
    379 AlphaFI->setGlobalRetAddr(GlobalRetAddr);
    380 return GlobalRetAddr;
    381 }
    +0
    -85
    lib/Target/Alpha/AlphaInstrInfo.h less more
    None //===- AlphaInstrInfo.h - Alpha Instruction Information ---------*- C++ -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This file contains the Alpha implementation of the TargetInstrInfo class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #ifndef ALPHAINSTRUCTIONINFO_H
    14 #define ALPHAINSTRUCTIONINFO_H
    15
    16 #include "llvm/Target/TargetInstrInfo.h"
    17 #include "AlphaRegisterInfo.h"
    18
    19 #define GET_INSTRINFO_HEADER
    20 #include "AlphaGenInstrInfo.inc"
    21
    22 namespace llvm {
    23
    24 class AlphaInstrInfo : public AlphaGenInstrInfo {
    25 const AlphaRegisterInfo RI;
    26 public:
    27 AlphaInstrInfo();
    28
    29 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
    30 /// such, whenever a client has an instance of instruction info, it should
    31 /// always be able to get register info as well (through this method).
    32 ///
    33 virtual const AlphaRegisterInfo &getRegisterInfo() const { return RI; }
    34
    35 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
    36 int &FrameIndex) const;
    37 virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
    38 int &FrameIndex) const;
    39
    40 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    41 MachineBasicBlock *FBB,
    42 const SmallVectorImpl &Cond,
    43 DebugLoc DL) const;
    44 virtual void copyPhysReg(MachineBasicBlock &MBB,
    45 MachineBasicBlock::iterator MI, DebugLoc DL,
    46 unsigned DestReg, unsigned SrcReg,
    47 bool KillSrc) const;
    48 virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
    49 MachineBasicBlock::iterator MBBI,
    50 unsigned SrcReg, bool isKill, int FrameIndex,
    51 const TargetRegisterClass *RC,
    52 const TargetRegisterInfo *TRI) const;
    53
    54 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
    55 MachineBasicBlock::iterator MBBI,
    56 unsigned DestReg, int FrameIndex,
    57 const TargetRegisterClass *RC,
    58 const TargetRegisterInfo *TRI) const;
    59
    60 bool AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
    61 MachineBasicBlock *&FBB,
    62 SmallVectorImpl &Cond,
    63 bool AllowModify) const;
    64 unsigned RemoveBranch(MachineBasicBlock &MBB) const;
    65 void insertNoop(MachineBasicBlock &MBB,
    66 MachineBasicBlock::iterator MI) const;
    67 bool ReverseBranchCondition(SmallVectorImpl &Cond) const;
    68
    69 /// getGlobalBaseReg - Return a virtual register initialized with the
    70 /// the global base register value. Output instructions required to
    71 /// initialize the register in the function entry block, if necessary.
    72 ///
    73 unsigned getGlobalBaseReg(MachineFunction *MF) const;
    74
    75 /// getGlobalRetAddr - Return a virtual register initialized with the
    76 /// the global return address register value. Output instructions required to
    77 /// initialize the register in the function entry block, if necessary.
    78 ///
    79 unsigned getGlobalRetAddr(MachineFunction *MF) const;
    80 };
    81
    82 }
    83
    84 #endif
    +0
    -1159
    lib/Target/Alpha/AlphaInstrInfo.td less more
    None //===- AlphaInstrInfo.td - The Alpha Instruction Set -------*- tablegen -*-===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 //
    10 //===----------------------------------------------------------------------===//
    11
    12 include "AlphaInstrFormats.td"
    13
    14 //********************
    15 //Custom DAG Nodes
    16 //********************
    17
    18 def SDTFPUnaryOpUnC : SDTypeProfile<1, 1, [
    19 SDTCisFP<1>, SDTCisFP<0>
    20 ]>;
    21 def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
    22 def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
    23 def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_" , SDTFPUnaryOp, []>;
    24 def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>;
    25 def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>;
    26 def Alpha_rellit : SDNode<"AlphaISD::RelLit", SDTIntBinOp, [SDNPMayLoad]>;
    27
    28 def retflag : SDNode<"AlphaISD::RET_FLAG", SDTNone,
    29 [SDNPHasChain, SDNPOptInGlue]>;
    30
    31 // These are target-independent nodes, but have target-specific formats.
    32 def SDT_AlphaCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64> ]>;
    33 def SDT_AlphaCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>,
    34 SDTCisVT<1, i64> ]>;
    35
    36 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AlphaCallSeqStart,
    37 [SDNPHasChain, SDNPOutGlue]>;
    38 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AlphaCallSeqEnd,
    39 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
    40
    41 //********************
    42 //Paterns for matching
    43 //********************
    44 def invX : SDNodeXForm
    45 return getI64Imm(~N->getZExtValue());
    46 }]>;
    47 def negX : SDNodeXForm
    48 return getI64Imm(~N->getZExtValue() + 1);
    49 }]>;
    50 def SExt32 : SDNodeXForm
    51 return getI64Imm(((int64_t)N->getZExtValue() << 32) >> 32);
    52 }]>;
    53 def SExt16 : SDNodeXForm
    54 return getI64Imm(((int64_t)N->getZExtValue() << 48) >> 48);
    55 }]>;
    56 def LL16 : SDNodeXForm
    57 return getI64Imm(get_lda16(N->getZExtValue()));
    58 }]>;
    59 def LH16 : SDNodeXForm
    60 return getI64Imm(get_ldah16(N->getZExtValue()));
    61 }]>;
    62 def iZAPX : SDNodeXForm
    63 ConstantSDNode *RHS = cast(N->getOperand(1));
    64 return getI64Imm(get_zapImm(SDValue(), RHS->getZExtValue()));
    65 }]>;
    66 def nearP2X : SDNodeXForm
    67 return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getZExtValue())));
    68 }]>;
    69 def nearP2RemX : SDNodeXForm
    70 uint64_t x =
    71 abs64(N->getZExtValue() - getNearPower2((uint64_t)N->getZExtValue()));
    72 return getI64Imm(Log2_64(x));
    73 }]>;
    74
    75 def immUExt8 : PatLeaf<(imm), [{ //imm fits in 8 bit zero extended field
    76 return (uint64_t)N->getZExtValue() == (uint8_t)N->getZExtValue();
    77 }]>;
    78 def immUExt8inv : PatLeaf<(imm), [{ //inverted imm fits in 8 bit zero extended field
    79 return (uint64_t)~N->getZExtValue() == (uint8_t)~N->getZExtValue();
    80 }], invX>;
    81 def immUExt8neg : PatLeaf<(imm), [{ //negated imm fits in 8 bit zero extended field
    82 return ((uint64_t)~N->getZExtValue() + 1) ==
    83 (uint8_t)((uint64_t)~N->getZExtValue() + 1);
    84 }], negX>;
    85 def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
    86 return ((int64_t)N->getZExtValue() << 48) >> 48 ==
    87 (int64_t)N->getZExtValue();
    88 }]>;
    89 def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
    90 return ((int64_t)N->getZExtValue() << 48) >> 48 ==
    91 ((int64_t)N->getZExtValue() << 32) >> 32;
    92 }], SExt16>;
    93
    94 def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm), [{
    95 ConstantSDNode *RHS = dyn_cast(N->getOperand(1));
    96 if (!RHS) return 0;
    97 uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getZExtValue());
    98 return build != 0;
    99 }]>;
    100
    101 def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
    102 (void)N; // silence warning.
    103 return true;
    104 }]>;
    105
    106 def immRem1 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),1,0);}]>;
    107 def immRem2 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),2,0);}]>;
    108 def immRem3 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),3,0);}]>;
    109 def immRem4 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),4,0);}]>;
    110 def immRem5 :PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),5,0);}]>;
    111 def immRem1n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),1,1);}]>;
    112 def immRem2n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),2,1);}]>;
    113 def immRem3n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),3,1);}]>;
    114 def immRem4n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),4,1);}]>;
    115 def immRem5n:PatLeaf<(imm),[{return chkRemNearPower2(N->getZExtValue(),5,1);}]>;
    116
    117 def immRemP2n : PatLeaf<(imm), [{
    118 return isPowerOf2_64(getNearPower2((uint64_t)N->getZExtValue()) -
    119 N->getZExtValue());
    120 }]>;
    121 def immRemP2 : PatLeaf<(imm), [{
    122 return isPowerOf2_64(N->getZExtValue() -
    123 getNearPower2((uint64_t)N->getZExtValue()));
    124 }]>;
    125 def immUExt8ME : PatLeaf<(imm), [{ //use this imm for mulqi
    126 int64_t d = abs64((int64_t)N->getZExtValue() -
    127 (int64_t)getNearPower2((uint64_t)N->getZExtValue()));
    128 if (isPowerOf2_64(d)) return false;
    129 switch (d) {
    130 case 1: case 3: case 5: return false;
    131 default: return (uint64_t)N->getZExtValue() == (uint8_t)N->getZExtValue();
    132 };
    133 }]>;
    134
    135 def intop : PatFrag<(ops node:$op), (sext_inreg node:$op, i32)>;
    136 def add4 : PatFrag<(ops node:$op1, node:$op2),
    137 (add (shl node:$op1, 2), node:$op2)>;
    138 def sub4 : PatFrag<(ops node:$op1, node:$op2),
    139 (sub (shl node:$op1, 2), node:$op2)>;
    140 def add8 : PatFrag<(ops node:$op1, node:$op2),
    141 (add (shl node:$op1, 3), node:$op2)>;
    142 def sub8 : PatFrag<(ops node:$op1, node:$op2),
    143 (sub (shl node:$op1, 3), node:$op2)>;
    144 class BinOpFrag : PatFrag<(ops node:$LHS, node:$RHS), res>;
    145 class CmpOpFrag : PatFrag<(ops node:$R), res>;
    146
    147 //Pseudo ops for selection
    148
    149 def WTF : PseudoInstAlpha<(outs), (ins variable_ops), "#wtf", [], s_pseudo>;
    150
    151 let hasCtrlDep = 1, Defs = [R30], Uses = [R30] in {
    152 def ADJUSTSTACKUP : PseudoInstAlpha<(outs), (ins s64imm:$amt),
    153 "; ADJUP $amt",
    154 [(callseq_start timm:$amt)], s_pseudo>;
    155 def ADJUSTSTACKDOWN : PseudoInstAlpha<(outs), (ins s64imm:$amt1, s64imm:$amt2),
    156 "; ADJDOWN $amt1",
    157 [(callseq_end timm:$amt1, timm:$amt2)], s_pseudo>;
    158 }
    159
    160 def ALTENT : PseudoInstAlpha<(outs), (ins s64imm:$TARGET), "$$$TARGET..ng:\n", [], s_pseudo>;
    161 def PCLABEL : PseudoInstAlpha<(outs), (ins s64imm:$num), "PCMARKER_$num:\n",[], s_pseudo>;
    162 def MEMLABEL : PseudoInstAlpha<(outs), (ins s64imm:$i, s64imm:$j, s64imm:$k, s64imm:$m),
    163 "LSMARKER$$$i$$$j$$$k$$$m:", [], s_pseudo>;
    164
    165
    166 let usesCustomInserter = 1 in { // Expanded after instruction selection.
    167 def CAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
    168 [(set GPRC:$dst, (atomic_cmp_swap_32 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
    169 def CAS64 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$cmp, GPRC:$swp), "",
    170 [(set GPRC:$dst, (atomic_cmp_swap_64 GPRC:$ptr, GPRC:$cmp, GPRC:$swp))], s_pseudo>;
    171
    172 def LAS32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
    173 [(set GPRC:$dst, (atomic_load_add_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
    174 def LAS64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
    175 [(set GPRC:$dst, (atomic_load_add_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
    176
    177 def SWAP32 : PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
    178 [(set GPRC:$dst, (atomic_swap_32 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
    179 def SWAP64 :PseudoInstAlpha<(outs GPRC:$dst), (ins GPRC:$ptr, GPRC:$swp), "",
    180 [(set GPRC:$dst, (atomic_swap_64 GPRC:$ptr, GPRC:$swp))], s_pseudo>;
    181 }
    182
    183 //***********************
    184 //Real instructions
    185 //***********************
    186
    187 //Operation Form:
    188
    189 //conditional moves, int
    190
    191 multiclass cmov_inst fun, string asmstr, PatFrag OpNode> {
    192 def r : OForm4<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
    193 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), GPRC:$RTRUE, GPRC:$RFALSE))], s_cmov>;
    194 def i : OForm4L<0x11, fun, !strconcat(asmstr, " $RCOND,$RTRUE,$RDEST"),
    195 [(set GPRC:$RDEST, (select (OpNode GPRC:$RCOND), immUExt8:$RTRUE, GPRC:$RFALSE))], s_cmov>;
    196 }
    197
    198 defm CMOVEQ : cmov_inst<0x24, "cmoveq", CmpOpFrag<(seteq node:$R, 0)>>;
    199 defm CMOVNE : cmov_inst<0x26, "cmovne", CmpOpFrag<(setne node:$R, 0)>>;
    200 defm CMOVLT : cmov_inst<0x44, "cmovlt", CmpOpFrag<(setlt node:$R, 0)>>;
    201 defm CMOVLE : cmov_inst<0x64, "cmovle", CmpOpFrag<(setle node:$R, 0)>>;
    202 defm CMOVGT : cmov_inst<0x66, "cmovgt", CmpOpFrag<(setgt node:$R, 0)>>;
    203 defm CMOVGE : cmov_inst<0x46, "cmovge", CmpOpFrag<(setge node:$R, 0)>>;
    204 defm CMOVLBC : cmov_inst<0x16, "cmovlbc", CmpOpFrag<(xor node:$R, 1)>>;
    205 defm CMOVLBS : cmov_inst<0x14, "cmovlbs", CmpOpFrag<(and node:$R, 1)>>;
    206
    207 //General pattern for cmov
    208 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
    209 (CMOVNEr GPRC:$src2, GPRC:$src1, GPRC:$which)>;
    210 def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2),
    211 (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>;
    212
    213 //Invert sense when we can for constants:
    214 def : Pat<(select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
    215 (CMOVEQi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
    216 def : Pat<(select (setgt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
    217 (CMOVLEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
    218 def : Pat<(select (setge GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
    219 (CMOVLTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
    220 def : Pat<(select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
    221 (CMOVGEi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
    222 def : Pat<(select (setle GPRC:$RCOND, 0), GPRC:$RTRUE, immUExt8:$RFALSE),
    223 (CMOVGTi GPRC:$RCOND, immUExt8:$RFALSE, GPRC:$RTRUE)>;
    224
    225 multiclass all_inst opc, bits<7> funl, bits<7> funq,
    226 string asmstr, PatFrag OpNode, InstrItinClass itin> {
    227 def Lr : OForm< opc, funl, !strconcat(asmstr, "l $RA,$RB,$RC"),
    228 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, GPRC:$RB)))], itin>;
    229 def Li : OFormL
    230 [(set GPRC:$RC, (intop (OpNode GPRC:$RA, immUExt8:$L)))], itin>;
    231 def Qr : OForm< opc, funq, !strconcat(asmstr, "q $RA,$RB,$RC"),
    232 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
    233 def Qi : OFormL
    234 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
    235 }
    236
    237 defm MUL : all_inst<0x13, 0x00, 0x20, "mul", BinOpFrag<(mul node:$LHS, node:$RHS)>, s_imul>;
    238 defm ADD : all_inst<0x10, 0x00, 0x20, "add", BinOpFrag<(add node:$LHS, node:$RHS)>, s_iadd>;
    239 defm S4ADD : all_inst<0x10, 0x02, 0x22, "s4add", add4, s_iadd>;
    240 defm S8ADD : all_inst<0x10, 0x12, 0x32, "s8add", add8, s_iadd>;
    241 defm S4SUB : all_inst<0x10, 0x0B, 0x2B, "s4sub", sub4, s_iadd>;
    242 defm S8SUB : all_inst<0x10, 0x1B, 0x3B, "s8sub", sub8, s_iadd>;
    243 defm SUB : all_inst<0x10, 0x09, 0x29, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, s_iadd>;
    244 //Const cases since legalize does sub x, int -> add x, inv(int) + 1
    245 def : Pat<(intop (add GPRC:$RA, immUExt8neg:$L)), (SUBLi GPRC:$RA, immUExt8neg:$L)>;
    246 def : Pat<(add GPRC:$RA, immUExt8neg:$L), (SUBQi GPRC:$RA, immUExt8neg:$L)>;
    247 def : Pat<(intop (add4 GPRC:$RA, immUExt8neg:$L)), (S4SUBLi GPRC:$RA, immUExt8neg:$L)>;
    248 def : Pat<(add4 GPRC:$RA, immUExt8neg:$L), (S4SUBQi GPRC:$RA, immUExt8neg:$L)>;
    249 def : Pat<(intop (add8 GPRC:$RA, immUExt8neg:$L)), (S8SUBLi GPRC:$RA, immUExt8neg:$L)>;
    250 def : Pat<(add8 GPRC:$RA, immUExt8neg:$L), (S8SUBQi GPRC:$RA, immUExt8neg:$L)>;
    251
    252 multiclass log_inst opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
    253 def r : OForm
    254 [(set GPRC:$RC, (OpNode GPRC:$RA, GPRC:$RB))], itin>;
    255 def i : OFormL
    256 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8:$L))], itin>;
    257 }
    258 multiclass inv_inst opc, bits<7> fun, string asmstr, SDNode OpNode, InstrItinClass itin> {
    259 def r : OForm
    260 [(set GPRC:$RC, (OpNode GPRC:$RA, (not GPRC:$RB)))], itin>;
    261 def i : OFormL
    262 [(set GPRC:$RC, (OpNode GPRC:$RA, immUExt8inv:$L))], itin>;
    263 }
    264
    265 defm AND : log_inst<0x11, 0x00, "and", and, s_ilog>;
    266 defm BIC : inv_inst<0x11, 0x08, "bic", and, s_ilog>;
    267 defm BIS : log_inst<0x11, 0x20, "bis", or, s_ilog>;
    268 defm ORNOT : inv_inst<0x11, 0x28, "ornot", or, s_ilog>;
    269 defm XOR : log_inst<0x11, 0x40, "xor", xor, s_ilog>;
    270 defm EQV : inv_inst<0x11, 0x48, "eqv", xor, s_ilog>;
    271
    272 defm SL : log_inst<0x12, 0x39, "sll", shl, s_ishf>;
    273 defm SRA : log_inst<0x12, 0x3c, "sra", sra, s_ishf>;
    274 defm SRL : log_inst<0x12, 0x34, "srl", srl, s_ishf>;
    275 defm UMULH : log_inst<0x13, 0x30, "umulh", mulhu, s_imul>;
    276
    277 def CTLZ : OForm2<0x1C, 0x32, "CTLZ $RB,$RC",
    278 [(set GPRC:$RC, (ctlz GPRC:$RB))], s_imisc>;
    279 def CTPOP : OForm2<0x1C, 0x30, "CTPOP $RB,$RC",
    280 [(set GPRC:$RC, (ctpop GPRC:$RB))], s_imisc>;
    281 def CTTZ : OForm2<0x1C, 0x33, "CTTZ $RB,$RC",
    282 [(set GPRC:$RC, (cttz GPRC:$RB))], s_imisc>;
    283 def EXTBL : OForm< 0x12, 0x06, "EXTBL $RA,$RB,$RC",
    284 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 255))], s_ishf>;
    285 def EXTWL : OForm< 0x12, 0x16, "EXTWL $RA,$RB,$RC",
    286 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 65535))], s_ishf>;
    287 def EXTLL : OForm< 0x12, 0x26, "EXTLL $RA,$RB,$RC",
    288 [(set GPRC:$RC, (and (srl GPRC:$RA, (shl GPRC:$RB, 3)), 4294967295))], s_ishf>;
    289 def SEXTB : OForm2<0x1C, 0x00, "sextb $RB,$RC",
    290 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i8))], s_ishf>;
    291 def SEXTW : OForm2<0x1C, 0x01, "sextw $RB,$RC",
    292 [(set GPRC:$RC, (sext_inreg GPRC:$RB, i16))], s_ishf>;
    293
    294 //def EXTBLi : OFormL<0x12, 0x06, "EXTBL $RA,$L,$RC", []>; //Extract byte low
    295 //def EXTLH : OForm< 0x12, 0x6A, "EXTLH $RA,$RB,$RC", []>; //Extract longword high
    296 //def EXTLHi : OFormL<0x12, 0x6A, "EXTLH $RA,$L,$RC", []>; //Extract longword high
    297 //def EXTLLi : OFormL<0x12, 0x26, "EXTLL $RA,$L,$RC", []>; //Extract longword low
    298 //def EXTQH : OForm< 0x12, 0x7A, "EXTQH $RA,$RB,$RC", []>; //Extract quadword high
    299 //def EXTQHi : OFormL<0x12, 0x7A, "EXTQH $RA,$L,$RC", []>; //Extract quadword high
    300 //def EXTQ : OForm< 0x12, 0x36, "EXTQ $RA,$RB,$RC", []>; //Extract quadword low
    301 //def EXTQi : OFormL<0x12, 0x36, "EXTQ $RA,$L,$RC", []>; //Extract quadword low
    302 //def EXTWH : OForm< 0x12, 0x5A, "EXTWH $RA,$RB,$RC", []>; //Extract word high
    303 //def EXTWHi : OFormL<0x12, 0x5A, "EXTWH $RA,$L,$RC", []>; //Extract word high
    304 //def EXTWLi : OFormL<0x12, 0x16, "EXTWL $RA,$L,$RC", []>; //Extract word low
    305
    306 //def INSBL : OForm< 0x12, 0x0B, "INSBL $RA,$RB,$RC", []>; //Insert byte low
    307 //def INSBLi : OFormL<0x12, 0x0B, "INSBL $RA,$L,$RC", []>; //Insert byte low
    308 //def INSLH : OForm< 0x12, 0x67, "INSLH $RA,$RB,$RC", []>; //Insert longword high
    309 //def INSLHi : OFormL<0x12, 0x67, "INSLH $RA,$L,$RC", []>; //Insert longword high
    310 //def INSLL : OForm< 0x12, 0x2B, "INSLL $RA,$RB,$RC", []>; //Insert longword low
    311 //def INSLLi : OFormL<0x12, 0x2B, "INSLL $RA,$L,$RC", []>; //Insert longword low
    312 //def INSQH : OForm< 0x12, 0x77, "INSQH $RA,$RB,$RC", []>; //Insert quadword high
    313 //def INSQHi : OFormL<0x12, 0x77, "INSQH $RA,$L,$RC", []>; //Insert quadword high
    314 //def INSQL : OForm< 0x12, 0x3B, "INSQL $RA,$RB,$RC", []>; //Insert quadword low
    315 //def INSQLi : OFormL<0x12, 0x3B, "INSQL $RA,$L,$RC", []>; //Insert quadword low
    316 //def INSWH : OForm< 0x12, 0x57, "INSWH $RA,$RB,$RC", []>; //Insert word high
    317 //def INSWHi : OFormL<0x12, 0x57, "INSWH $RA,$L,$RC", []>; //Insert word high
    318 //def INSWL : OForm< 0x12, 0x1B, "INSWL $RA,$RB,$RC", []>; //Insert word low
    319 //def INSWLi : OFormL<0x12, 0x1B, "INSWL $RA,$L,$RC", []>; //Insert word low
    320
    321 //def MSKBL : OForm< 0x12, 0x02, "MSKBL $RA,$RB,$RC", []>; //Mask byte low
    322 //def MSKBLi : OFormL<0x12, 0x02, "MSKBL $RA,$L,$RC", []>; //Mask byte low
    323 //def MSKLH : OForm< 0x12, 0x62, "MSKLH $RA,$RB,$RC", []>; //Mask longword high
    324 //def MSKLHi : OFormL<0x12, 0x62, "MSKLH $RA,$L,$RC", []>; //Mask longword high
    325 //def MSKLL : OForm< 0x12, 0x22, "MSKLL $RA,$RB,$RC", []>; //Mask longword low
    326 //def MSKLLi : OFormL<0x12, 0x22, "MSKLL $RA,$L,$RC", []>; //Mask longword low
    327 //def MSKQH : OForm< 0x12, 0x72, "MSKQH $RA,$RB,$RC", []>; //Mask quadword high
    328 //def MSKQHi : OFormL<0x12, 0x72, "MSKQH $RA,$L,$RC", []>; //Mask quadword high
    329 //def MSKQL : OForm< 0x12, 0x32, "MSKQL $RA,$RB,$RC", []>; //Mask quadword low
    330 //def MSKQLi : OFormL<0x12, 0x32, "MSKQL $RA,$L,$RC", []>; //Mask quadword low
    331 //def MSKWH : OForm< 0x12, 0x52, "MSKWH $RA,$RB,$RC", []>; //Mask word high
    332 //def MSKWHi : OFormL<0x12, 0x52, "MSKWH $RA,$L,$RC", []>; //Mask word high
    333 //def MSKWL : OForm< 0x12, 0x12, "MSKWL $RA,$RB,$RC", []>; //Mask word low
    334 //def MSKWLi : OFormL<0x12, 0x12, "MSKWL $RA,$L,$RC", []>; //Mask word low
    335
    336 def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
    337
    338 // Define the pattern that produces ZAPNOTi.
    339 def : Pat<(zappat:$imm GPRC:$RA),
    340 (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
    341
    342
    343 //Comparison, int
    344 //So this is a waste of what this instruction can do, but it still saves something
    345 def CMPBGE : OForm< 0x10, 0x0F, "cmpbge $RA,$RB,$RC",
    346 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), (and GPRC:$RB, 255)))], s_ilog>;
    347 def CMPBGEi : OFormL<0x10, 0x0F, "cmpbge $RA,$L,$RC",
    348 [(set GPRC:$RC, (setuge (and GPRC:$RA, 255), immUExt8:$L))], s_ilog>;
    349 def CMPEQ : OForm< 0x10, 0x2D, "cmpeq $RA,$RB,$RC",
    350 [(set GPRC:$RC, (seteq GPRC:$RA, GPRC:$RB))], s_iadd>;
    351 def CMPEQi : OFormL<0x10, 0x2D, "cmpeq $RA,$L,$RC",
    352 [(set GPRC:$RC, (seteq GPRC:$RA, immUExt8:$L))], s_iadd>;
    353 def CMPLE : OForm< 0x10, 0x6D, "cmple $RA,$RB,$RC",
    354 [(set GPRC:$RC, (setle GPRC:$RA, GPRC:$RB))], s_iadd>;
    355 def CMPLEi : OFormL<0x10, 0x6D, "cmple $RA,$L,$RC",
    356 [(set GPRC:$RC, (setle GPRC:$RA, immUExt8:$L))], s_iadd>;
    357 def CMPLT : OForm< 0x10, 0x4D, "cmplt $RA,$RB,$RC",
    358 [(set GPRC:$RC, (setlt GPRC:$RA, GPRC:$RB))], s_iadd>;
    359 def CMPLTi : OFormL<0x10, 0x4D, "cmplt $RA,$L,$RC",
    360 [(set GPRC:$RC, (setlt GPRC:$RA, immUExt8:$L))], s_iadd>;
    361 def CMPULE : OForm< 0x10, 0x3D, "cmpule $RA,$RB,$RC",
    362 [(set GPRC:$RC, (setule GPRC:$RA, GPRC:$RB))], s_iadd>;
    363 def CMPULEi : OFormL<0x10, 0x3D, "cmpule $RA,$L,$RC",
    364 [(set GPRC:$RC, (setule GPRC:$RA, immUExt8:$L))], s_iadd>;
    365 def CMPULT : OForm< 0x10, 0x1D, "cmpult $RA,$RB,$RC",
    366 [(set GPRC:$RC, (setult GPRC:$RA, GPRC:$RB))], s_iadd>;
    367 def CMPULTi : OFormL<0x10, 0x1D, "cmpult $RA,$L,$RC",
    368 [(set GPRC:$RC, (setult GPRC:$RA, immUExt8:$L))], s_iadd>;
    369
    370 //Patterns for unsupported int comparisons
    371 def : Pat<(setueq GPRC:$X, GPRC:$Y), (CMPEQ GPRC:$X, GPRC:$Y)>;
    372 def : Pat<(setueq GPRC:$X, immUExt8:$Y), (CMPEQi GPRC:$X, immUExt8:$Y)>;
    373
    374 def : Pat<(setugt GPRC:$X, GPRC:$Y), (CMPULT GPRC:$Y, GPRC:$X)>;
    375 def : Pat<(setugt immUExt8:$X, GPRC:$Y), (CMPULTi GPRC:$Y, immUExt8:$X)>;
    376
    377 def : Pat<(setuge GPRC:$X, GPRC:$Y), (CMPULE GPRC:$Y, GPRC:$X)>;
    378 def : Pat<(setuge immUExt8:$X, GPRC:$Y), (CMPULEi GPRC:$Y, immUExt8:$X)>;
    379
    380 def : Pat<(setgt GPRC:$X, GPRC:$Y), (CMPLT GPRC:$Y, GPRC:$X)>;
    381 def : Pat<(setgt immUExt8:$X, GPRC:$Y), (CMPLTi GPRC:$Y, immUExt8:$X)>;
    382
    383 def : Pat<(setge GPRC:$X, GPRC:$Y), (CMPLE GPRC:$Y, GPRC:$X)>;
    384 def : Pat<(setge immUExt8:$X, GPRC:$Y), (CMPLEi GPRC:$Y, immUExt8:$X)>;
    385
    386 def : Pat<(setne GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
    387 def : Pat<(setne GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQi GPRC:$X, immUExt8:$Y), 0)>;
    388
    389 def : Pat<(setune GPRC:$X, GPRC:$Y), (CMPEQi (CMPEQ GPRC:$X, GPRC:$Y), 0)>;
    390 def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>;
    391
    392
    393 let isReturn = 1, isTerminator = 1, isBarrier = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in {
    394 def RETDAG : MbrForm< 0x1A, 0x02, (ins), "ret $$31,($$26),1", s_jsr>; //Return from subroutine
    395 def RETDAGp : MbrpForm< 0x1A, 0x02, (ins), "ret $$31,($$26),1", [(retflag)], s_jsr>; //Return from subroutine
    396 }
    397
    398 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1, Ra = 31, disp = 0 in
    399 def JMP : MbrpForm< 0x1A, 0x00, (ins GPRC:$RS), "jmp $$31,($RS),0",
    400 [(brind GPRC:$RS)], s_jsr>; //Jump
    401
    402 let isCall = 1, Ra = 26,
    403 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
    404 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
    405 F0, F1,
    406 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
    407 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R29] in {
    408 def BSR : BFormD<0x34, "bsr $$26,$$$DISP..ng", [], s_jsr>; //Branch to subroutine
    409 }
    410 let isCall = 1, Ra = 26, Rb = 27, disp = 0,
    411 Defs = [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19,
    412 R20, R21, R22, R23, R24, R25, R26, R27, R28, R29,
    413 F0, F1,
    414 F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
    415 F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30], Uses = [R27, R29] in {
    416 def JSR : MbrForm< 0x1A, 0x01, (ins), "jsr $$26,($$27),0", s_jsr>; //Jump to subroutine
    417 }
    418
    419 let isCall = 1, Ra = 23, Rb = 27, disp = 0,
    420 Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
    421 def JSRs : MbrForm< 0x1A, 0x01, (ins), "jsr $$23,($$27),0", s_jsr>; //Jump to div or rem
    422
    423
    424 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ins GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP", s_jsr>; //Jump to subroutine return
    425
    426
    427 let OutOperandList = (outs GPRC:$RA), InOperandList = (ins s64imm:$DISP, GPRC:$RB) in {
    428 def LDQ : MForm<0x29, 1, "ldq $RA,$DISP($RB)",
    429 [(set GPRC:$RA, (load (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
    430 def LDQr : MForm<0x29, 1, "ldq $RA,$DISP($RB)\t\t!gprellow",
    431 [(set GPRC:$RA, (load (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
    432 def LDL : MForm<0x28, 1, "ldl $RA,$DISP($RB)",
    433 [(set GPRC:$RA, (sextloadi32 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
    434 def LDLr : MForm<0x28, 1, "ldl $RA,$DISP($RB)\t\t!gprellow",
    435 [(set GPRC:$RA, (sextloadi32 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
    436 def LDBU : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)",
    437 [(set GPRC:$RA, (zextloadi8 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
    438 def LDBUr : MForm<0x0A, 1, "ldbu $RA,$DISP($RB)\t\t!gprellow",
    439 [(set GPRC:$RA, (zextloadi8 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
    440 def LDWU : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)",
    441 [(set GPRC:$RA, (zextloadi16 (add GPRC:$RB, immSExt16:$DISP)))], s_ild>;
    442 def LDWUr : MForm<0x0C, 1, "ldwu $RA,$DISP($RB)\t\t!gprellow",
    443 [(set GPRC:$RA, (zextloadi16 (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB)))], s_ild>;
    444 }
    445
    446
    447 let OutOperandList = (outs), InOperandList = (ins GPRC:$RA, s64imm:$DISP, GPRC:$RB) in {
    448 def STB : MForm<0x0E, 0, "stb $RA,$DISP($RB)",
    449 [(truncstorei8 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
    450 def STBr : MForm<0x0E, 0, "stb $RA,$DISP($RB)\t\t!gprellow",
    451 [(truncstorei8 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
    452 def STW : MForm<0x0D, 0, "stw $RA,$DISP($RB)",
    453 [(truncstorei16 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
    454 def STWr : MForm<0x0D, 0, "stw $RA,$DISP($RB)\t\t!gprellow",
    455 [(truncstorei16 GPRC:$RA, (Alpha_gprello tglobaladdr:$DISP, GPRC:$RB))], s_ist>;
    456 def STL : MForm<0x2C, 0, "stl $RA,$DISP($RB)",
    457 [(truncstorei32 GPRC:$RA, (add GPRC:$RB, immSExt16:$DISP))], s_ist>;
    458 def STLr : MForm<0x2C, 0, "stl $RA,$DISP($RB)\t\t!gprellow",
    459