From 5f25fb01b4061725124e34a942809e9c0c6f681c Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Fri, 2 Sep 2011 21:28:54 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMInstrThumb2.td | 50 +++++++++++++++++++------ test/MC/ARM/basic-thumb2-instructions.s | 37 ++++++++++++++++++ 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index b2bce5e3094..a12be96f571 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -75,11 +75,6 @@ def t2_so_imm_neg : Operand, 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, ImmLeaf= 1 && (int32_t)Imm < 32; -}]>; - /// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. def imm0_4095 : Operand, ImmLeaf 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 opcod, string opc, Operand ty, PatFrag opnode> { +multiclass T2I_sh_ir 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 opcod, string opc, Operand ty, PatFrag opnode> { let Inst{15-12} = 0b1111; let Inst{7-4} = 0b0000; } + + // Optional destination register + def : t2InstAlias(!strconcat(baseOpc, "ri")) rGPR:$Rdn, rGPR:$Rdn, + ty:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(!strconcat(baseOpc, "rr")) rGPR:$Rdn, rGPR:$Rdn, + rGPR:$Rm, pred:$p, + cc_out:$s)>; + + // Assembler aliases w/o the ".w" suffix. + def : t2InstAlias(!strconcat(baseOpc, "ri")) rGPR:$Rd, rGPR:$Rn, + ty:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(!strconcat(baseOpc, "rr")) rGPR:$Rd, rGPR:$Rn, + rGPR:$Rm, pred:$p, + cc_out:$s)>; + + // and with the optional destination operand, too. + def : t2InstAlias(!strconcat(baseOpc, "ri")) rGPR:$Rdn, rGPR:$Rdn, + ty:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(!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 4ecb7fbee33..0a22726ec6d 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 -- 2.34.1