aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-09-02 21:28:54 +0000
committerJim Grosbach <grosbach@apple.com>2011-09-02 21:28:54 +0000
commit5f25fb01b4061725124e34a942809e9c0c6f681c (patch)
tree3efd2d5d6d9b3df3241e211ba29aaa5922bc0aca
parentd5941195e2540b03445ff4603646d06ddf51439b (diff)
downloadexternal_llvm-5f25fb01b4061725124e34a942809e9c0c6f681c.zip
external_llvm-5f25fb01b4061725124e34a942809e9c0c6f681c.tar.gz
external_llvm-5f25fb01b4061725124e34a942809e9c0c6f681c.tar.bz2
Thumb2 parsing and encoding for ASR.
For other shift and rotate instructions, too. Tests for those forthcoming as I work my way through the ISA. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139040 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td50
-rw-r--r--test/MC/ARM/basic-thumb2-instructions.s37
2 files changed, 75 insertions, 12 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index b2bce5e..a12be96 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -75,11 +75,6 @@ def t2_so_imm_neg : Operand<i32>,
return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
}], t2_so_imm_neg_XFORM>;
-/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
-def imm1_31 : Operand<i32>, ImmLeaf<i32, [{
- return (int32_t)Imm >= 1 && (int32_t)Imm < 32;
-}]>;
-
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
def imm0_4095 : Operand<i32>,
ImmLeaf<i32, [{
@@ -770,7 +765,8 @@ multiclass T2I_rbin_s_is<bits<4> opcod, 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<bits<2> opcod, string opc, Operand ty, PatFrag opnode> {
+multiclass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, PatFrag opnode,
+ string baseOpc> {
// 5-bit imm
def ri : T2sTwoRegShiftImm<
(outs rGPR:$Rd), (ins rGPR:$Rm, ty:$imm), IIC_iMOVsi,
@@ -792,6 +788,36 @@ multiclass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, PatFrag opnode> {
let Inst{15-12} = 0b1111;
let Inst{7-4} = 0b0000;
}
+
+ // Optional destination register
+ def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $imm"),
+ (!cast<Instruction>(!strconcat(baseOpc, "ri")) rGPR:$Rdn, rGPR:$Rdn,
+ ty:$imm, pred:$p,
+ cc_out:$s)>;
+ def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $Rm"),
+ (!cast<Instruction>(!strconcat(baseOpc, "rr")) rGPR:$Rdn, rGPR:$Rdn,
+ rGPR:$Rm, pred:$p,
+ cc_out:$s)>;
+
+ // Assembler aliases w/o the ".w" suffix.
+ def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $imm"),
+ (!cast<Instruction>(!strconcat(baseOpc, "ri")) rGPR:$Rd, rGPR:$Rn,
+ ty:$imm, pred:$p,
+ cc_out:$s)>;
+ def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"),
+ (!cast<Instruction>(!strconcat(baseOpc, "rr")) rGPR:$Rd, rGPR:$Rn,
+ rGPR:$Rm, pred:$p,
+ cc_out:$s)>;
+
+ // and with the optional destination operand, too.
+ def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $imm"),
+ (!cast<Instruction>(!strconcat(baseOpc, "ri")) rGPR:$Rdn, rGPR:$Rdn,
+ ty:$imm, pred:$p,
+ cc_out:$s)>;
+ def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"),
+ (!cast<Instruction>(!strconcat(baseOpc, "rr")) rGPR:$Rdn, rGPR:$Rdn,
+ rGPR:$Rm, pred:$p,
+ cc_out:$s)>;
}
/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
@@ -1922,14 +1948,14 @@ def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>;
// Shift and rotate Instructions.
//
-defm t2LSL : T2I_sh_ir<0b00, "lsl", imm1_31,
- BinOpFrag<(shl node:$LHS, node:$RHS)>>;
+defm t2LSL : T2I_sh_ir<0b00, "lsl", imm0_31,
+ BinOpFrag<(shl node:$LHS, node:$RHS)>, "t2LSL">;
defm t2LSR : T2I_sh_ir<0b01, "lsr", imm_sr,
- BinOpFrag<(srl node:$LHS, node:$RHS)>>;
+ BinOpFrag<(srl node:$LHS, node:$RHS)>, "t2LSR">;
defm t2ASR : T2I_sh_ir<0b10, "asr", imm_sr,
- BinOpFrag<(sra node:$LHS, node:$RHS)>>;
-defm t2ROR : T2I_sh_ir<0b11, "ror", imm1_31,
- BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
+ BinOpFrag<(sra node:$LHS, node:$RHS)>, "t2ASR">;
+defm t2ROR : T2I_sh_ir<0b11, "ror", imm0_31,
+ BinOpFrag<(rotr node:$LHS, node:$RHS)>, "t2ROR">;
// (rotr x, (and y, 0x...1f)) ==> (ROR x, y)
def : Pat<(rotr rGPR:$lhs, (and rGPR:$rhs, lo5AllOne)),
diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s
index 4ecb7fb..0a22726 100644
--- a/test/MC/ARM/basic-thumb2-instructions.s
+++ b/test/MC/ARM/basic-thumb2-instructions.s
@@ -136,6 +136,43 @@ _func:
@ CHECK: ands.w r4, r5, r2, lsr #20 @ encoding: [0x15,0xea,0x12,0x54]
@ CHECK: and.w r9, r12, r1, ror #17 @ encoding: [0x0c,0xea,0x71,0x49]
+@------------------------------------------------------------------------------
+@ ASR (immediate)
+@------------------------------------------------------------------------------
+ asr r2, r3, #12
+ asrs r8, r3, #32
+ asrs.w r2, r3, #1
+ asr r2, r3, #4
+ asrs r2, r12, #15
+
+ asr r3, #19
+ asrs r8, #2
+ asrs.w r7, #5
+ asr.w r12, #21
+
+@ CHECK: asr.w r2, r3, #12 @ encoding: [0x4f,0xea,0x23,0x32]
+@ CHECK: asrs.w r8, r3, #32 @ encoding: [0x5f,0xea,0x23,0x08]
+@ CHECK: asrs.w r2, r3, #1 @ encoding: [0x5f,0xea,0x63,0x02]
+@ CHECK: asr.w r2, r3, #4 @ encoding: [0x4f,0xea,0x23,0x12]
+@ CHECK: asrs.w r2, r12, #15 @ encoding: [0x5f,0xea,0xec,0x32]
+
+@ CHECK: asr.w r3, r3, #19 @ encoding: [0x4f,0xea,0xe3,0x43]
+@ CHECK: asrs.w r8, r8, #2 @ encoding: [0x5f,0xea,0xa8,0x08]
+@ CHECK: asrs.w r7, r7, #5 @ encoding: [0x5f,0xea,0x67,0x17]
+@ CHECK: asr.w r12, r12, #21 @ encoding: [0x4f,0xea,0x6c,0x5c]
+
+
+@------------------------------------------------------------------------------
+@ ASR (register)
+@------------------------------------------------------------------------------
+ asr r3, r4, r2
+ asr.w r1, r2
+ asrs r3, r4, r8
+
+@ CHECK: asr.w r3, r4, r2 @ encoding: [0x44,0xfa,0x02,0xf3]
+@ CHECK: asr.w r1, r1, r2 @ encoding: [0x41,0xfa,0x02,0xf1]
+@ CHECK: asrs.w r3, r4, r8 @ encoding: [0x54,0xfa,0x08,0xf3]
+
@------------------------------------------------------------------------------
@ B