mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Proper patterns for thumb2 shift and rotate instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73987 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -69,6 +69,11 @@ def t2_so_imm_neg : Operand<i32>, | |||||||
|   let PrintMethod = "printT2SOImmOperand"; |   let PrintMethod = "printT2SOImmOperand"; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31]. | ||||||
|  | def imm1_31 : PatLeaf<(i32 imm), [{ | ||||||
|  |   return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32; | ||||||
|  | }]>; | ||||||
|  |  | ||||||
| /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. | /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. | ||||||
| def imm0_4095 : PatLeaf<(i32 imm), [{ | def imm0_4095 : PatLeaf<(i32 imm), [{ | ||||||
|   return (uint32_t)N->getZExtValue() < 4096; |   return (uint32_t)N->getZExtValue() < 4096; | ||||||
| @@ -125,40 +130,71 @@ def t2_lo16AllZero : PatLeaf<(i32 imm), [{ | |||||||
| //  Thumb2 to cover the functionality of the ARM instruction set. | //  Thumb2 to cover the functionality of the ARM instruction set. | ||||||
| // | // | ||||||
|  |  | ||||||
| /// T2I_bin_is - Defines a set of (op reg, {so_imm|so_reg}) patterns for a | /// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a | ||||||
|  | //  unary operation that produces a value. | ||||||
|  | multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{ | ||||||
|  |    // shifted imm | ||||||
|  |    def i : T2I<(outs GPR:$dst), (ins t2_so_imm:$src), | ||||||
|  |                 !strconcat(opc, " $dst, $src"), | ||||||
|  |                 [(set GPR:$dst, (opnode t2_so_imm:$src))]> { | ||||||
|  |      let isAsCheapAsAMove = Cheap; | ||||||
|  |      let isReMaterializable = ReMat; | ||||||
|  |    } | ||||||
|  |    // register | ||||||
|  |    def r : T2I<(outs GPR:$dst), (ins GPR:$src), | ||||||
|  |                 !strconcat(opc, " $dst, $src"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$src))]>; | ||||||
|  |    // shifted register | ||||||
|  |    def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), | ||||||
|  |                 !strconcat(opc, " $dst, $src"), | ||||||
|  |                 [(set GPR:$dst, (opnode t2_so_reg:$src))]>; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a | ||||||
| //  binary operation that produces a value. | //  binary operation that produces a value. | ||||||
| multiclass T2I_bin_is<string opc, PatFrag opnode> { | multiclass T2I_bin_irs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), | ||||||
|                 !strconcat(opc, " $dst, $lhs, $rhs"), |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; |                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), | ||||||
|                 !strconcat(opc, " $dst, $lhs, $rhs"), |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; |                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// T2I_2bin_is - Same as T2I_bin_is except the order of operands are reversed. | /// T2I_2bin_is - Same as T2I_bin_irs except the order of operands are reversed. | ||||||
| multiclass T2I_rbin_is<string opc, PatFrag opnode> { | multiclass T2I_rbin_irs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), | ||||||
|                 !strconcat(opc, " $dst, $lhs, $rhs"), |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; |                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), | ||||||
|                 !strconcat(opc, " $dst, $lhs, $rhs"), |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; |                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// T2I_bin_s_is - Similar to T2I_bin_is except it sets the 's' bit so the | /// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the | ||||||
| /// instruction modifies the CPSR register. | /// instruction modifies the CPSR register. | ||||||
| let Defs = [CPSR] in { | let Defs = [CPSR] in { | ||||||
| multiclass T2I_bin_s_is<string opc, PatFrag opnode> { | multiclass T2I_bin_s_irs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), | ||||||
|                 !strconcat(opc, "s $dst, $lhs, $rhs"), |                 !strconcat(opc, "s $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; |                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), | ||||||
|                 !strconcat(opc, "s $dst, $lhs, $rhs"), |                 !strconcat(opc, "s $dst, $lhs, $rhs"), | ||||||
| @@ -166,15 +202,18 @@ multiclass T2I_bin_s_is<string opc, PatFrag opnode> { | |||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// T2I_rbin_s_is - Same as T2I_bin_s_is except the order of operands are | /// T2I_rbin_s_irs - Same as T2I_bin_s_irs except the order of operands are | ||||||
| /// reversed. | /// reversed. | ||||||
| let Defs = [CPSR] in { | let Defs = [CPSR] in { | ||||||
| multiclass T2I_rbin_s_is<string opc, PatFrag opnode> { | multiclass T2I_rbin_s_irs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), | ||||||
|                 !strconcat(opc, "s $dst, $lhs, $rhs"), |                 !strconcat(opc, "s $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; |                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), | ||||||
|                 !strconcat(opc, "s $dst, $lhs, $rhs"), |                 !strconcat(opc, "s $dst, $lhs, $rhs"), | ||||||
| @@ -182,9 +221,9 @@ multiclass T2I_rbin_s_is<string opc, PatFrag opnode> { | |||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// T2I_bin_ii12s - Defines a set of (op reg, {so_imm|imm0_4095|so_reg}) patterns | /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg}) | ||||||
| /// for a binary operation that produces a value. | /// patterns for a binary operation that produces a value. | ||||||
| multiclass T2I_bin_ii12s<string opc, PatFrag opnode> { | multiclass T2I_bin_ii12rs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), | ||||||
|                 !strconcat(opc, " $dst, $lhs, $rhs"), |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
| @@ -193,22 +232,29 @@ multiclass T2I_bin_ii12s<string opc, PatFrag opnode> { | |||||||
|    def ri12 : T2I<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), |    def ri12 : T2I<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), | ||||||
|                 !strconcat(opc, "w $dst, $lhs, $rhs"), |                 !strconcat(opc, "w $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>; |                 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), | ||||||
|                 !strconcat(opc, " $dst, $lhs, $rhs"), |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; |                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; | ||||||
| } | } | ||||||
|  |  | ||||||
| /// T2I_bin_c_is - Defines a set of (op reg, {so_imm|reg}) patterns for a | /// T2I_bin_c_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a | ||||||
| //  binary operation that produces a value and set the carry bit. It can also | //  binary operation that produces a value and set the carry bit. It can also | ||||||
| /// optionally set CPSR. | /// optionally set CPSR. | ||||||
| let Uses = [CPSR] in { | let Uses = [CPSR] in { | ||||||
| multiclass T2I_bin_c_is<string opc, PatFrag opnode> { | multiclass T2I_bin_c_irs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs, cc_out:$s), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs, cc_out:$s), | ||||||
|                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), |                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; |                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(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))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs, cc_out:$s), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs, cc_out:$s), | ||||||
|                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), |                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), | ||||||
| @@ -216,15 +262,18 @@ multiclass T2I_bin_c_is<string opc, PatFrag opnode> { | |||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// T2I_rbin_c_is - Same as T2I_bin_c_is except the order of operands are | /// T2I_rbin_c_irs - Same as T2I_bin_c_irs except the order of operands are | ||||||
| /// reversed. | /// reversed. | ||||||
| let Uses = [CPSR] in { | let Uses = [CPSR] in { | ||||||
| multiclass T2I_rbin_c_is<string opc, PatFrag opnode> { | multiclass T2I_rbin_c_irs<string opc, PatFrag opnode> { | ||||||
|    // shifted imm |    // shifted imm | ||||||
|    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), |    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), | ||||||
|                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), |                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), | ||||||
|                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; |                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs, cc_out:$s), | ||||||
|  |                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), |    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), | ||||||
|                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), |                 !strconcat(opc, "${s} $dst, $lhs, $rhs"), | ||||||
| @@ -232,9 +281,21 @@ multiclass T2I_rbin_c_is<string opc, PatFrag opnode> { | |||||||
| } | } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / | ||||||
|  | //  rotate operation that produces a value. | ||||||
|  | multiclass T2I_sh_ir<string opc, PatFrag opnode> { | ||||||
|  |    // 5-bit imm | ||||||
|  |    def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), | ||||||
|  |                 !strconcat(opc, " $dst, $lhs, $rhs"), | ||||||
|  |                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; | ||||||
|  | } | ||||||
|  |  | ||||||
| /// T21_cmp_irs - Defines a set of (op r, {so_imm|so_reg}) cmp / test | /// T21_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test | ||||||
| /// patterns. Similar to T2I_bin_is except the instruction does not produce | /// patterns. Similar to T2I_bin_irs except the instruction does not produce | ||||||
| /// a explicit result, only implicitly set CPSR. | /// a explicit result, only implicitly set CPSR. | ||||||
| let Uses = [CPSR] in { | let Uses = [CPSR] in { | ||||||
| multiclass T2I_cmp_is<string opc, PatFrag opnode> { | multiclass T2I_cmp_is<string opc, PatFrag opnode> { | ||||||
| @@ -242,7 +303,10 @@ multiclass T2I_cmp_is<string opc, PatFrag opnode> { | |||||||
|    def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), |    def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), | ||||||
|                 !strconcat(opc, " $lhs, $rhs"), |                 !strconcat(opc, " $lhs, $rhs"), | ||||||
|                 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; |                 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; | ||||||
|  |    // register | ||||||
|  |    def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), | ||||||
|  |                 !strconcat(opc, " $lhs, $rhs"), | ||||||
|  |                 [(opnode GPR:$lhs, GPR:$rhs)]>; | ||||||
|    // shifted register |    // shifted register | ||||||
|    def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), |    def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), | ||||||
|                 !strconcat(opc, " $lhs, $rhs"), |                 !strconcat(opc, " $lhs, $rhs"), | ||||||
| @@ -262,21 +326,11 @@ let neverHasSideEffects = 1 in | |||||||
| def t2MOVr : T2I<(outs GPR:$dst), (ins GPR:$src), | def t2MOVr : T2I<(outs GPR:$dst), (ins GPR:$src), | ||||||
|                   "mov $dst, $src", []>; |                   "mov $dst, $src", []>; | ||||||
|  |  | ||||||
|  | let isReMaterializable = 1, isAsCheapAsAMove = 1 in | ||||||
| def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), | def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), | ||||||
|                    "movw $dst, $src", |                    "movw $dst, $src", | ||||||
|                    [(set GPR:$dst, imm0_65535:$src)]>; |                    [(set GPR:$dst, imm0_65535:$src)]>; | ||||||
|  |  | ||||||
|  |  | ||||||
| // FIXME: Move (shifted register) is a pseudo-instruction for ASR, LSL, LSR, |  | ||||||
| // ROR, and RRX. Consider splitting into multiple instructions. |  | ||||||
| def t2MOVs  : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), |  | ||||||
|                   "mov $dst, $src", |  | ||||||
|                   [(set GPR:$dst, t2_so_reg:$src)]>; |  | ||||||
| def t2MOVrx : T2I<(outs GPR:$dst), (ins GPR:$src), |  | ||||||
|                   "mov $dst, $src, rrx", |  | ||||||
|                   [(set GPR:$dst, (ARMrrx GPR:$src))]>; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // FIXME: Also available in ARM mode. | // FIXME: Also available in ARM mode. | ||||||
| let Constraints = "$src = $dst" in | let Constraints = "$src = $dst" in | ||||||
| def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), | def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), | ||||||
| @@ -288,21 +342,21 @@ def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), | |||||||
| //  Arithmetic Instructions. | //  Arithmetic Instructions. | ||||||
| // | // | ||||||
|  |  | ||||||
| defm t2ADD  : T2I_bin_ii12s<"add", BinOpFrag<(add  node:$LHS, node:$RHS)>>; | defm t2ADD  : T2I_bin_ii12rs<"add", BinOpFrag<(add  node:$LHS, node:$RHS)>>; | ||||||
| defm t2SUB  : T2I_bin_ii12s<"sub", BinOpFrag<(sub  node:$LHS, node:$RHS)>>; | defm t2SUB  : T2I_bin_ii12rs<"sub", BinOpFrag<(sub  node:$LHS, node:$RHS)>>; | ||||||
|  |  | ||||||
| // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. | // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. | ||||||
| defm t2ADDS : T2I_bin_s_is<"add", BinOpFrag<(addc node:$LHS, node:$RHS)>>; | defm t2ADDS : T2I_bin_s_irs<"add",  BinOpFrag<(addc node:$LHS, node:$RHS)>>; | ||||||
| defm t2SUBS : T2I_bin_s_is<"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>; | defm t2SUBS : T2I_bin_s_irs<"sub",  BinOpFrag<(subc node:$LHS, node:$RHS)>>; | ||||||
|  |  | ||||||
| // FIXME: predication support | // FIXME: predication support | ||||||
| defm t2ADC  : T2I_bin_c_is<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>; | defm t2ADC  : T2I_bin_c_irs<"adc",  BinOpFrag<(adde node:$LHS, node:$RHS)>>; | ||||||
| defm t2SBC  : T2I_bin_c_is<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; | defm t2SBC  : T2I_bin_c_irs<"sbc",  BinOpFrag<(sube node:$LHS, node:$RHS)>>; | ||||||
|  |  | ||||||
| // RSB, RSC | // RSB, RSC | ||||||
| defm t2RSB  : T2I_rbin_is  <"rsb", BinOpFrag<(sub  node:$LHS, node:$RHS)>>; | defm t2RSB  : T2I_rbin_irs  <"rsb", BinOpFrag<(sub  node:$LHS, node:$RHS)>>; | ||||||
| defm t2RSBS : T2I_rbin_c_is<"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>; | defm t2RSBS : T2I_rbin_c_irs<"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>; | ||||||
| defm t2RSC  : T2I_rbin_s_is<"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; | defm t2RSC  : T2I_rbin_s_irs<"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; | ||||||
|  |  | ||||||
| // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form. | // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form. | ||||||
| def : Thumb2Pat<(add       GPR:$src, t2_so_imm_neg:$imm), | def : Thumb2Pat<(add       GPR:$src, t2_so_imm_neg:$imm), | ||||||
| @@ -311,32 +365,38 @@ def : Thumb2Pat<(add       GPR:$src, imm0_4095_neg:$imm), | |||||||
|                 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; |                 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //===----------------------------------------------------------------------===// | ||||||
|  | //  Shift and rotate Instructions. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | defm t2LSL  : T2I_sh_ir<"lsl", BinOpFrag<(shl  node:$LHS, node:$RHS)>>; | ||||||
|  | defm t2LSR  : T2I_sh_ir<"lsr", BinOpFrag<(srl  node:$LHS, node:$RHS)>>; | ||||||
|  | defm t2ASR  : T2I_sh_ir<"asr", BinOpFrag<(sra  node:$LHS, node:$RHS)>>; | ||||||
|  | defm t2ROR  : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>; | ||||||
|  |  | ||||||
|  | def t2MOVrx : T2I<(outs GPR:$dst), (ins GPR:$src), | ||||||
|  |                   "mov $dst, $src, rrx", | ||||||
|  |                   [(set GPR:$dst, (ARMrrx GPR:$src))]>; | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| //  Bitwise Instructions. | //  Bitwise Instructions. | ||||||
| // | // | ||||||
|  |  | ||||||
| defm t2AND  : T2I_bin_is  <"and", BinOpFrag<(and node:$LHS, node:$RHS)>>; | defm t2AND  : T2I_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>>; | ||||||
| defm t2ORR  : T2I_bin_is  <"orr", BinOpFrag<(or  node:$LHS, node:$RHS)>>; | defm t2ORR  : T2I_bin_irs<"orr", BinOpFrag<(or  node:$LHS, node:$RHS)>>; | ||||||
| defm t2EOR  : T2I_bin_is  <"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>; | defm t2EOR  : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>; | ||||||
|  |  | ||||||
| defm t2BIC  : T2I_bin_is  <"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; | defm t2BIC  : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; | ||||||
|  |  | ||||||
| def : Thumb2Pat<(and     GPR:$src, t2_so_imm_not:$imm), | def : Thumb2Pat<(and     GPR:$src, t2_so_imm_not:$imm), | ||||||
|                 (t2BICri GPR:$src, t2_so_imm_not:$imm)>; |                 (t2BICri GPR:$src, t2_so_imm_not:$imm)>; | ||||||
|  |  | ||||||
| defm t2ORN  : T2I_bin_is  <"orn", BinOpFrag<(or  node:$LHS, (not node:$RHS))>>; | defm t2ORN  : T2I_bin_irs<"orn", BinOpFrag<(or  node:$LHS, (not node:$RHS))>>; | ||||||
|  |  | ||||||
| def : Thumb2Pat<(or      GPR:$src, t2_so_imm_not:$imm), | def : Thumb2Pat<(or      GPR:$src, t2_so_imm_not:$imm), | ||||||
|                 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>; |                 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>; | ||||||
|  |  | ||||||
|  | defm t2MVN  : T2I_un_irs  <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>; | ||||||
| def t2MVNr : T2I<(outs GPR:$dst), (ins t2_so_reg:$rhs), |  | ||||||
|                   "mvn $dst, $rhs", |  | ||||||
|                  [(set GPR:$dst, (not t2_so_reg:$rhs))]>; |  | ||||||
| let isReMaterializable = 1, isAsCheapAsAMove = 1 in |  | ||||||
| def t2MVNi : T2I<(outs GPR:$dst), (ins t2_so_imm_not:$rhs), |  | ||||||
|                   "mvn $dst, $rhs", |  | ||||||
|                  [(set GPR:$dst, t2_so_imm_not:$rhs)]>; |  | ||||||
|  |  | ||||||
| // A8.6.17  BFC - Bitfield clear | // A8.6.17  BFC - Bitfield clear | ||||||
| // FIXME: Also available in ARM mode. | // FIXME: Also available in ARM mode. | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
| ; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsr | ; 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 asr | ||||||
| ; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ror | ; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ror | ||||||
| ; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | ; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | not grep mov | ||||||
|  |  | ||||||
| define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) { | define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) { | ||||||
|         %A = shl i32 %Y, 16 |         %A = shl i32 %Y, 16 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user