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
This commit is contained in:
Jim Grosbach 2011-09-02 21:28:54 +00:00
parent d5941195e2
commit 5f25fb01b4
2 changed files with 75 additions and 12 deletions

View File

@ -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)),

View File

@ -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