Skip to content
ARMInstrVFP.td 39.3 KiB
Newer Older
//===- ARMInstrVFP.td - VFP support for ARM ----------------*- tablegen -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the ARM VFP instruction set.
//
//===----------------------------------------------------------------------===//

def SDT_FTOI    : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
def SDT_ITOF    : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
def SDT_CMPFP0  : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
                                       SDTCisSameAs<1, 2>]>;
def arm_ftoui  : SDNode<"ARMISD::FTOUI",   SDT_FTOI>;
def arm_ftosi  : SDNode<"ARMISD::FTOSI",   SDT_FTOI>;
def arm_sitof  : SDNode<"ARMISD::SITOF",   SDT_ITOF>;
def arm_uitof  : SDNode<"ARMISD::UITOF",   SDT_ITOF>;
def arm_fmstat : SDNode<"ARMISD::FMSTAT",  SDTNone, [SDNPInFlag, SDNPOutFlag]>;
def arm_cmpfp  : SDNode<"ARMISD::CMPFP",   SDT_ARMCmp, [SDNPOutFlag]>;
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutFlag]>;
def arm_fmdrr  : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
//===----------------------------------------------------------------------===//
// Operand Definitions.
//

def vfp_f32imm : Operand<f32>,
                 PatLeaf<(f32 fpimm), [{
      return ARM::getVFPf32Imm(N->getValueAPF()) != -1;
    }]> {
  let PrintMethod = "printVFPf32ImmOperand";
}

def vfp_f64imm : Operand<f64>,
                 PatLeaf<(f64 fpimm), [{
      return ARM::getVFPf64Imm(N->getValueAPF()) != -1;
    }]> {
  let PrintMethod = "printVFPf64ImmOperand";
}


//===----------------------------------------------------------------------===//
//  Load / store Instructions.
//

let canFoldAsLoad = 1, isReMaterializable = 1 in {
def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
                 IIC_fpLoad64, "vldr", ".64\t$Dd, $addr",
Bill Wendling's avatar
Bill Wendling committed
                 [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]>;
def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5:$addr),
                 IIC_fpLoad32, "vldr", ".32\t$Sd, $addr",
Bill Wendling's avatar
Bill Wendling committed
                 [(set SPR:$Sd, (load addrmode5:$addr))]>;

} // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in'
Bill Wendling's avatar
Bill Wendling committed
def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$Dd, addrmode5:$addr),
                 IIC_fpStore64, "vstr", ".64\t$Dd, $addr",
                 [(store (f64 DPR:$Dd), addrmode5:$addr)]>;
Bill Wendling's avatar
Bill Wendling committed
def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5:$addr),
                 IIC_fpStore32, "vstr", ".32\t$Sd, $addr",
                 [(store SPR:$Sd, addrmode5:$addr)]>;

//===----------------------------------------------------------------------===//
//  Load / store multiple Instructions.
//

multiclass vfp_ldst_d_mult<string asm, bit L_bit,
                           InstrItinClass itin, InstrItinClass itin_upd> {
  def ia :
    AXDI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeNone, itin,
          !strconcat(asm, "${p}\t$Rn, $regs"), "", []> {
    let Inst{24-23} = 0b01;       // Increment After
    let Inst{21}    = 0;          // No writeback
    let Inst{20}    = L_bit;
  }
  def ia_UPD :
    AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeUpd, itin_upd,
          !strconcat(asm, "${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    let Inst{24-23} = 0b01;       // Increment After
    let Inst{21}    = 1;          // Writeback
    let Inst{20}    = L_bit;
  }
  def db :
    AXDI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeNone, itin,
          !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
    let Inst{24-23} = 0b10;       // Decrement Before
    let Inst{21}    = 0;          // No writeback
    let Inst{20}    = L_bit;
  }
  def db_UPD :
    AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeUpd, itin_upd,
          !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    let Inst{24-23} = 0b10;       // Decrement Before
    let Inst{21}    = 1;          // Writeback
    let Inst{20}    = L_bit;
  }
}

multiclass vfp_ldst_s_mult<string asm, bit L_bit,
                           InstrItinClass itin, InstrItinClass itin_upd> {
  def ia :
    AXSI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeNone, itin,
          !strconcat(asm, "${p}\t$Rn, $regs"), "", []> {
    let Inst{24-23} = 0b01;       // Increment After
    let Inst{21}    = 0;          // No writeback
    let Inst{20}    = L_bit;
  }
  def ia_UPD :
    AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeUpd, itin_upd,
          !strconcat(asm, "${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    let Inst{24-23} = 0b01;       // Increment After
    let Inst{21}    = 1;          // Writeback
    let Inst{20}    = L_bit;
  }
  def db :
    AXSI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeNone, itin,
          !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
    let Inst{24-23} = 0b10;       // Decrement Before
    let Inst{21}    = 0;          // No writeback
    let Inst{20}    = L_bit;
  }
  def db_UPD :
    AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          IndexModeUpd, itin_upd,
          !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    let Inst{24-23} = 0b10;       // Decrement Before
    let Inst{21}    = 1;          // Writeback
    let Inst{20}    = L_bit;
  }
}

let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
    isCodeGenOnly = 1 in {
def VLDMD : AXDI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
                           reglist:$dsts, variable_ops),
                  IndexModeNone, IIC_fpLoad_m,
                  "vldm${amode}${p}\t$Rn, $dsts", "", []> {
  let Inst{21} = 0;             // wback = (W == '1')
  let Inst{20} = 1;             // Load
def VLDMS : AXSI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
                           reglist:$dsts, variable_ops),
                  IndexModeNone, IIC_fpLoad_m,
                  "vldm${amode}${p}\t$Rn, $dsts", "", []> {
  let Inst{21} = 0;             // wback = (W == '1')
  let Inst{20} = 1;             // Load
def VLDMD_UPD : AXDI4<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
                      "vldm${amode}${p}\t$Rn!, $dsts",
                      "$Rn = $wb", []> {
  let Inst{21} = 1;             // wback = (W == '1')
  let Inst{20} = 1;             // Load
def VLDMS_UPD : AXSI4<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
                      "vldm${amode}${p}\t$Rn!, $dsts",
                      "$Rn = $wb", []> {
  let Inst{21} = 1;             // wback = (W == '1')
  let Inst{20} = 1;             // Load
} // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
    isCodeGenOnly = 1 in {
def VSTMD : AXDI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
                           reglist:$srcs, variable_ops),
                  IndexModeNone, IIC_fpStore_m,
                  "vstm${amode}${p}\t$Rn, $srcs", "", []> {
  let Inst{21} = 0;             // wback = (W == '1')
  let Inst{20} = 0;             // Store
def VSTMS : AXSI4<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
                           reglist:$srcs, variable_ops), IndexModeNone,
                   IIC_fpStore_m,
                  "vstm${amode}${p}\t$Rn, $srcs", "", []> {
  let Inst{21} = 0;             // wback = (W == '1')
Loading
Loading full blame...