[llvm-commits] [llvm] r73622 - in /llvm/trunk: lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp test/CodeGen/ARM/thumb2-add.ll test/CodeGen/ARM/thumb2-mov.ll test/CodeGen/ARM/thumb2-mov2.ll test/CodeGen/ARM/thumb2-shifter.ll

Evan Cheng evan.cheng at apple.com
Wed Jun 17 18:22:05 PDT 2009


It  would be nice if you can document the instructions with the  
corresponding ARM instruction manual section (e.g. A8.6.2) and  
encoding type (T1, T2, etc.).

Evan

On Jun 17, 2009, at 11:13 AM, Anton Korobeynikov wrote:

> Author: asl
> Date: Wed Jun 17 13:13:58 2009
> New Revision: 73622
>
> URL: http://llvm.org/viewvc/llvm-project?rev=73622&view=rev
> Log:
> Initial support for some Thumb2 instructions.
> Patch by Viktor Kutuzov and Anton Korzh from Access Softek, Inc.
>
> Added:
>    llvm/trunk/test/CodeGen/ARM/thumb2-add.ll
>    llvm/trunk/test/CodeGen/ARM/thumb2-mov.ll
>    llvm/trunk/test/CodeGen/ARM/thumb2-mov2.ll
>    llvm/trunk/test/CodeGen/ARM/thumb2-shifter.ll
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
>    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
>    llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=73622&r1=73621&r2=73622&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Wed Jun 17  
> 13:13:58 2009
> @@ -52,8 +52,13 @@
>
>   virtual const char *getPassName() const {
>     return "ARM Instruction Selection";
> -  }
> -
> +  }
> +
> + /// getI32Imm - Return a target constant with the specified value,  
> of type i32.
> +  inline SDValue getI32Imm(unsigned Imm) {
> +    return CurDAG->getTargetConstant(Imm, MVT::i32);
> +  }
> +
>   SDNode *Select(SDValue Op);
>   virtual void InstructionSelect();
>   bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base,
> @@ -84,6 +89,9 @@
>   bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base,
>                              SDValue &OffImm);
>
> +  bool SelectShifterOperand(SDValue Op, SDValue N,
> +                            SDValue &BaseReg, SDValue &Opc);
> +
>   bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A,
>                                SDValue &B, SDValue &C);
>
> @@ -509,8 +517,30 @@
>   return false;
> }
>
> +bool ARMDAGToDAGISel::SelectShifterOperand(SDValue Op,
> +                                           SDValue N,
> +                                           SDValue &BaseReg,
> +                                           SDValue &Opc) {
> +  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
> +
> +  // Don't match base register only case. That is matched to a  
> separate
> +  // lower complexity pattern with explicit register operand.
> +  if (ShOpcVal == ARM_AM::no_shift) return false;
> +
> +  BaseReg = N.getOperand(0);
> +  unsigned ShImmVal = 0;
> +  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand 
> (1)))
> +    ShImmVal = RHS->getZExtValue() & 31;
> +  else
> +    return false;
> +
> +  Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal));
> +
> +  return true;
> +}
> +
> bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
> -                                              SDValue N,
> +                                              SDValue N,
>                                               SDValue &BaseReg,
>                                               SDValue &ShReg,
>                                               SDValue &Opc) {
> @@ -549,6 +579,10 @@
>   switch (N->getOpcode()) {
>   default: break;
>   case ISD::Constant: {
> +    // ARMv6T2 and later should materialize imms via MOV / MOVT pair.
> +    if (Subtarget->hasV6T2Ops() || Subtarget->hasThumb2())
> +      break;
> +
>     unsigned Val = cast<ConstantSDNode>(N)->getZExtValue();
>     bool UseCP = true;
>     if (Subtarget->isThumb())
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=73622&r1=73621&r2=73622&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Jun 17 13:13:58 2009
> @@ -1385,6 +1385,12 @@
> include "ARMInstrThumb.td"
>
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +// Thumb2 Support
> +//
> +
> +include "ARMInstrThumb2.td"
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> // Floating Point Support
> //
>
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=73622&r1=73621&r2=73622&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Wed Jun 17 13:13:58  
> 2009
> @@ -10,3 +10,199 @@
> // This file describes the Thumb2 instruction set.
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +// Shifted operands. No register controlled shifts for Thumb2.
> +// Note: We do not support rrx shifted operands yet.
> +def t2_so_reg : Operand<i32>,    // reg imm
> +                ComplexPattern<i32, 2, "SelectShifterOperand",
> +                               [shl,srl,sra,rotr]> {
> +  let PrintMethod = "printSOOperand";
> +  let MIOperandInfo = (ops GPR, i32imm);
> +}
> +
> +def LO16 : SDNodeXForm<imm, [{
> +  // Transformation function: shift the immediate value down into  
> the low bits.
> +  return getI32Imm((unsigned short)N->getZExtValue());
> +}]>;
> +
> +def HI16 : SDNodeXForm<imm, [{
> +  // Transformation function: shift the immediate value down into  
> the low bits.
> +  return getI32Imm((unsigned)N->getZExtValue() >> 16);
> +}]>;
> +
> +def imm16high : PatLeaf<(i32 imm), [{
> +  // Returns true if all bits out of the [31..16] range are 0.
> +  return ((N->getZExtValue() & 0xFFFF0000ULL) == N->getZExtValue());
> +}], HI16>;
> +
> +def imm16high0xffff : PatLeaf<(i32 imm), [{
> +  // Returns true if lo 16 bits are set and this is a 32-bit value.
> +  return ((N->getZExtValue() & 0x0000FFFFULL) == 0xFFFFULL);
> +}], HI16>;
> +
> +def imm0_4095 : PatLeaf<(i32 imm), [{
> +  return (uint32_t)N->getZExtValue() < 4096;
> +}]>;
> +
> +def imm0_4095_neg : PatLeaf<(i32 imm), [{
> + return (uint32_t)-N->getZExtValue() < 4096;
> +}], imm_neg_XFORM>;
> +
> +def imm0_65535 : PatLeaf<(i32 imm), [{
> +  return N->getZExtValue() < 65536;
> +}]>;
> +
> +// A6.3.2 Modified immediate constants in Thumb instructions  
> (#<const>)
> +// FIXME: Move it the the addrmode matcher code.
> +def t2_so_imm : PatLeaf<(i32 imm), [{
> +  uint64_t v = N->getZExtValue();
> +  if (v == 0 || v > 0xffffffffUL) return false;
> +  // variant1 - 0b0000x - 8-bit which could be zero (not supported  
> for now)
> +
> +  // variant2 - 0b00nnx - 8-bit repeated inside the 32-bit room
> +  unsigned hi16 = (unsigned)(v >> 16);
> +  unsigned lo16 = (unsigned)(v & 0xffffUL);
> +  bool valid = (hi16 == lo16) && (
> +    (v & 0x00ff00ffUL) == 0 ||        // type 0001x
> +    (v & 0xff00ff00UL) == 0 ||        // type 0010x
> +    ((lo16 >> 8) == (lo16 & 0xff)));  // type 0011x
> +  if (valid) return true;
> +
> +  // variant3 - 0b01000..0b11111 - 8-bit shifted inside the 32-bit  
> room
> +  unsigned shift = CountLeadingZeros_32(v);
> +  uint64_t mask = (0xff000000ULL >> shift);
> +  // If valid, it is type 01000 + shift
> +  return ((shift < 24) && (v & mask) > 0) && ((v & (~mask)) == 0);
> +}]>;
> +
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//  Thumb-2 to cover the functionality of the ARM instruction set.
> +//
> +
> +/// T2I_bin_irs - Defines a set of (op reg, {so_imm|reg|so_reg})  
> patterns for a
> +//  binary operation that produces a value.
> +multiclass T2I_bin_irs<string opc, PatFrag opnode> {
> +   // shifted imm
> +   def ri : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
> +                       !strconcat(opc, " $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm: 
> $rhs))]>,
> +                      Requires<[HasThumb2]>;
> +   // register
> +   def rr : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
> +                       !strconcat(opc, " $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))] 
> >,
> +                      Requires<[HasThumb2]>;
> +   // shifted register
> +   def rs : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg: 
> $rhs),
> +                       !strconcat(opc, " $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg: 
> $rhs))]>,
> +                      Requires<[HasThumb2]>;
> +}
> +
> +/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's'  
> bit so the
> +/// instruction modifies the CPSR register.
> +let Defs = [CPSR] in {
> +multiclass T2I_bin_s_irs<string opc, PatFrag opnode> {
> +   // shifted imm
> +   def ri : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
> +                       !strconcat(opc, "s $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm: 
> $rhs))]>,
> +                      Requires<[HasThumb2]>;
> +
> +   // register
> +   def rr : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
> +                       !strconcat(opc, "s $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))] 
> >,
> +                      Requires<[HasThumb2]>;
> +
> +   // shifted register
> +   def rs : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg: 
> $rhs),
> +                       !strconcat(opc, "s $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg: 
> $rhs))]>,
> +                      Requires<[HasThumb2]>;
> +}
> +}
> +
> +/// T2I_bin_c_irs - Similar to T2I_bin_irs except it uses the 's'  
> bit. Also the
> +/// instruction can optionally set the CPSR register.
> +let Uses = [CPSR] in {
> +multiclass T2I_bin_c_irs<string opc, PatFrag opnode> {
> +   // shifted imm
> +   def ri : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs,  
> cc_out:$s),
> +                       !strconcat(opc, "${s} $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm: 
> $rhs))]>,
> +                      Requires<[HasThumb2]>;
> +
> +   // register
> +   def rr : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs,  
> cc_out:$s),
> +                       !strconcat(opc, "${s} $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))] 
> >,
> +                      Requires<[HasThumb2]>;
> +
> +   // shifted register
> +   def rs : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg: 
> $rhs, cc_out:$s),
> +                       !strconcat(opc, "${s} $dst, $lhs, $rhs"),
> +                       [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg: 
> $rhs))]>,
> +                      Requires<[HasThumb2]>;
> +}
> +}
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//  Arithmetic Instructions.
> +//
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//  Move Instructions.
> +//
> +def tMOVi16  : PseudoInst<(outs GPR:$dst), (ins i32imm:$src),
> +                          "mov $dst, $src",
> +                          [(set GPR:$dst, imm0_65535:$src)]>,
> +                         Requires<[HasThumb2]>;
> +
> +let isTwoAddress = 1 in
> +def tMOVTi16 : PseudoInst<(outs GPR:$dst), (ins GPR:$src, i32imm: 
> $imm),
> +                          "movt $dst, $imm",
> +                          [(set GPR:$dst, (or (and GPR:$src, 0xffff),
> +                                              imm16high:$imm))]>,
> +                         Requires<[HasThumb2]>;
> +
> +def : Pat<(and (or GPR:$src, imm16high:$imm1), imm16high0xffff: 
> $imm2),
> +          (tMOVTi16 GPR:$src, (HI16 imm16high:$imm1))>,
> +         Requires<[HasThumb2]>;
> +
> +def : Pat<(i32 imm:$imm),
> +          (tMOVTi16 (tMOVi16 (LO16 imm:$imm)),(HI16 imm:$imm))>,
> +         Requires<[HasThumb2]>;
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//  Arithmetic Instructions.
> +//
> +defm t2ADD  : T2I_bin_irs <"add", BinOpFrag<(add node:$LHS, node: 
> $RHS)>>;
> +defm t2SUB  : T2I_bin_irs <"sub", BinOpFrag<(sub node:$LHS, node: 
> $RHS)>>;
> +
> +def tADDri12 : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm: 
> $rhs),
> +                          "add $dst, $lhs, $rhs",
> +                          [(set GPR:$dst, (add GPR:$lhs,  
> imm0_4095:$rhs))]>,
> +                         Requires<[HasThumb2]>;
> +def tSUBri12 : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm: 
> $rhs),
> +                          "sub $dst, $lhs, $rhs",
> +                          [(set GPR:$dst, (add GPR:$lhs,  
> imm0_4095_neg:$rhs))]>,
> +                         Requires<[HasThumb2]>;
> +
> +defm t2ADDS : T2I_bin_s_irs<"add", BinOpFrag<(addc node:$LHS, node: 
> $RHS)>>;
> +defm t2SUBS : T2I_bin_s_irs<"sub", BinOpFrag<(subc node:$LHS, node: 
> $RHS)>>;
> +
> +defm t2ADC : T2I_bin_c_irs<"adc", BinOpFrag<(adde node:$LHS, node: 
> $RHS)>>;
> +defm t2SBC : T2I_bin_c_irs<"sbc", BinOpFrag<(sube node:$LHS, node: 
> $RHS)>>;
> +
> +
> +def tMLS : PseudoInst<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
> +                      "mls $dst, $a, $b, $c",
> +                      [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR: 
> $b)))]>,
> +                     Requires<[HasThumb2]>;
> +
> +def tORNrs : PseudoInst<(outs GPR:$dst), (ins GPR:$src1, t2_so_reg: 
> $src2),
> +                        "orn $dst, $src1, $src2",
> +                        [(set GPR:$dst, (or GPR:$src1, (not  
> t2_so_reg: $src2)))]>,
> +                       Requires<[HasThumb2]>;
>
> Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=73622&r1=73621&r2=73622&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Wed Jun  
> 17 13:13:58 2009
> @@ -97,6 +97,7 @@
>                       const char *Modifier = 0);
>     void printSOImmOperand(const MachineInstr *MI, int opNum);
>     void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
> +    void printSOOperand(const MachineInstr *MI, int OpNum);
>     void printSORegOperand(const MachineInstr *MI, int opNum);
>     void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
>     void printAddrMode2OffsetOperand(const MachineInstr *MI, int  
> OpNo);
> @@ -396,6 +397,28 @@
>   printSOImm(O, ARM_AM::getSOImmVal(V2), VerboseAsm, TAI);
> }
>
> +// Constant shifts so_reg is a 3-operand unit corresponding to  
> register forms of
> +// the A5.1 "Addressing Mode 1 - Data-processing operands" forms.   
> This
> +// includes:
> +// REG 0 - e.g. R5
> +// REG IMM, SH_OPC - e.g. R5, LSL #3
> +void ARMAsmPrinter::printSOOperand(const MachineInstr *MI, int  
> OpNum) {
> +  const MachineOperand &MO1 = MI->getOperand(OpNum);
> +  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
> +
> +  unsigned Reg = MO1.getReg();
> +  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
> +  O << TM.getRegisterInfo()->getAsmName(Reg);
> +
> +  // Print the shift opc.
> +  O << ", "
> +    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()))
> +    << " ";
> +
> +  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
> +  O << "#" << ARM_AM::getSORegOffset(MO2.getImm());
> +}
> +
> // so_reg is a 4-operand unit corresponding to register forms of the  
> A5.1
> // "Addressing Mode 1 - Data-processing operands" forms.  This  
> includes:
> //    REG 0   0    - e.g. R5
>
> Added: llvm/trunk/test/CodeGen/ARM/thumb2-add.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thumb2-add.ll?rev=73622&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/CodeGen/ARM/thumb2-add.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/thumb2-add.ll Wed Jun 17 13:13:58 2009
> @@ -0,0 +1,50 @@
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep #255
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep #256
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep #257
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep #4094
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep #4095
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep #4096
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add |  
> grep lsl | grep #8
> +
> +define i32 @t2ADDrc_255(i32 %lhs) {
> +    %Rd = add i32 %lhs, 255;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrc_256(i32 %lhs) {
> +    %Rd = add i32 %lhs, 256;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrc_257(i32 %lhs) {
> +    %Rd = add i32 %lhs, 257;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrc_4094(i32 %lhs) {
> +    %Rd = add i32 %lhs, 4094;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrc_4095(i32 %lhs) {
> +    %Rd = add i32 %lhs, 4095;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrc_4096(i32 %lhs) {
> +    %Rd = add i32 %lhs, 4096;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrr(i32 %lhs, i32 %rhs) {
> +    %Rd = add i32 %lhs, %rhs;
> +    ret i32 %Rd
> +}
> +
> +define i32 @t2ADDrs(i32 %lhs, i32 %rhs) {
> +    %tmp = shl i32 %rhs, 8
> +    %Rd = add i32 %lhs, %tmp;
> +    ret i32 %Rd
> +}
> +
>
> Added: llvm/trunk/test/CodeGen/ARM/thumb2-mov.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thumb2-mov.ll?rev=73622&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/CodeGen/ARM/thumb2-mov.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/thumb2-mov.ll Wed Jun 17 13:13:58 2009
> @@ -0,0 +1,127 @@
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep  
> #11206827
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep  
> #2868947712
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep  
> #2880154539
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep  
> #251658240
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #3948544
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov |  
> grep movt
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #258
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep  
> #4026531840
> +
> +; Test #<const>
> +
> +; var 2.1 - 0x00ab00ab
> +define i32 @t2_const_var2_1_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 11206827 ; 0x00ab00ab
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_1_fail_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 11206843 ; 0x00ab00bb
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_1_fail_2(i32 %lhs) {
> +    %ret = add i32 %lhs, 27984043 ; 0x01ab00ab
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_1_fail_3(i32 %lhs) {
> +    %ret = add i32 %lhs, 27984299 ; 0x01ab01ab
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_1_fail_4(i32 %lhs) {
> +    %ret = add i32 %lhs, 28027649 ; 0x01abab01
> +    ret i32 %ret
> +}
> +
> +; var 2.2 - 0xab00ab00
> +define i32 @t2_const_var2_2_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 2868947712 ; 0xab00ab00
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_2_fail_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 2868951552 ; 0xab00ba00
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_2_fail_2(i32 %lhs) {
> +    %ret = add i32 %lhs, 2868947728 ; 0xab00ab10
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_2_fail_3(i32 %lhs) {
> +    %ret = add i32 %lhs, 2869996304 ; 0xab10ab10
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_2_fail_4(i32 %lhs) {
> +    %ret = add i32 %lhs, 279685904 ; 0x10abab10
> +    ret i32 %ret
> +}
> +
> +; var 2.3 - 0xabababab
> +define i32 @t2_const_var2_3_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 2880154539 ; 0xabababab
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_3_fail_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 2880154554 ; 0xabababba
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_3_fail_2(i32 %lhs) {
> +    %ret = add i32 %lhs, 2880158379 ; 0xababbaab
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_3_fail_3(i32 %lhs) {
> +    %ret = add i32 %lhs, 2881137579 ; 0xabbaabab
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var2_3_fail_4(i32 %lhs) {
> +    %ret = add i32 %lhs, 3131812779 ; 0xbaababab
> +    ret i32 %ret
> +}
> +
> +; var 3 - 0x0F000000
> +define i32 @t2_const_var3_1_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 251658240 ; 0x0F000000
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var3_2_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 3948544 ; 0b00000000001111000100000000000000
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var3_2_fail_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 3940352 ; 0b00000000001111000010000000000000
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var3_3_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 258 ; 0b00000000000000000000000100000010
> +    ret i32 %ret
> +}
> +
> +define i32 @t2_const_var3_4_ok_1(i32 %lhs) {
> +    %ret = add i32 %lhs, 4026531840 ; 0xF0000000
> +    ret i32 %ret
> +}
> +
>
> Added: llvm/trunk/test/CodeGen/ARM/thumb2-mov2.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thumb2-mov2.ll?rev=73622&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/CodeGen/ARM/thumb2-mov2.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/thumb2-mov2.ll Wed Jun 17 13:13:58  
> 2009
> @@ -0,0 +1,65 @@
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt |  
> grep #1234
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt |  
> grep #1234
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt |  
> grep #1234
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt |  
> grep #1234
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov  |  
> grep movt
> +
> +define i32 @t2MOVTi16_ok_1(i32 %a) {
> +    %1 = and i32 %a, 65535
> +    %2 = shl i32 1234, 16
> +    %3 = or  i32 %1, %2
> +
> +    ret i32 %3
> +}
> +
> +define i32 @t2MOVTi16_test_1(i32 %a) {
> +    %1 = shl i32  255,   8
> +    %2 = shl i32 1234,   8
> +    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
> +    %4 = shl i32   %2,   8  ; This gives us (1234 << 16) in %4
> +    %5 = and i32   %a,  %3
> +    %6 = or  i32   %4,  %5
> +
> +    ret i32 %6
> +}
> +
> +define i32 @t2MOVTi16_test_2(i32 %a) {
> +    %1 = shl i32  255,   8
> +    %2 = shl i32 1234,   8
> +    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
> +    %4 = shl i32   %2,   6
> +    %5 = and i32   %a,  %3
> +    %6 = shl i32   %4,   2  ; This gives us (1234 << 16) in %6
> +    %7 = or  i32   %5,  %6
> +
> +    ret i32 %7
> +}
> +
> +define i32 @t2MOVTi16_test_3(i32 %a) {
> +    %1 = shl i32  255,   8
> +    %2 = shl i32 1234,   8
> +    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
> +    %4 = shl i32   %2,   6
> +    %5 = and i32   %a,  %3
> +    %6 = shl i32   %4,   2  ; This gives us (1234 << 16) in %6
> +    %7 = lshr i32  %6,   6
> +    %8 = shl i32   %7,   6
> +    %9 = or  i32   %5,  %8
> +
> +    ret i32 %9
> +}
> +
> +define i32 @t2MOVTi16_test_nomatch_1(i32 %a) {
> +    %1 = shl i32  255,   8
> +    %2 = shl i32 1234,   8
> +    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
> +    %4 = shl i32   %2,   6
> +    %5 = and i32   %a,  %3
> +    %6 = shl i32   %4,   2  ; This gives us (1234 << 16) in %6
> +    %7 = lshr i32  %6,   3
> +    %8 = or  i32   %5,  %7
> +
> +    ret i32 %8
> +}
> +
> +
>
> Added: llvm/trunk/test/CodeGen/ARM/thumb2-shifter.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/thumb2-shifter.ll?rev=73622&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/CodeGen/ARM/thumb2-shifter.ll (added)
> +++ llvm/trunk/test/CodeGen/ARM/thumb2-shifter.ll Wed Jun 17  
> 13:13:58 2009
> @@ -0,0 +1,40 @@
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsl
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsr
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep asr
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ror
> +; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov
> +
> +define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) {
> +        %A = shl i32 %Y, 16
> +        %B = add i32 %X, %A
> +        ret i32 %B
> +}
> +
> +define i32 @t2ADDrs_lsr(i32 %X, i32 %Y) {
> +        %A = lshr i32 %Y, 16
> +        %B = add i32 %X, %A
> +        ret i32 %B
> +}
> +
> +define i32 @t2ADDrs_asr(i32 %X, i32 %Y) {
> +        %A = ashr i32 %Y, 16
> +        %B = add i32 %X, %A
> +        ret i32 %B
> +}
> +
> +; i32 ror(n) = (x >> n) | (x << (32 - n))
> +define i32 @t2ADDrs_ror(i32 %X, i32 %Y) {
> +        %A = lshr i32 %Y, 16
> +        %B = shl  i32 %Y, 16
> +        %C = or   i32 %B, %A
> +        %R = add  i32 %X, %C
> +        ret i32 %R
> +}
> +
> +define i32 @t2ADDrs_noRegShift(i32 %X, i32 %Y, i8 %sh) {
> +        %shift.upgrd.1 = zext i8 %sh to i32
> +        %A = shl i32 %Y, %shift.upgrd.1
> +        %B = add i32 %X, %A
> +        ret i32 %B
> +}
> +
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list