mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-17 21:35:07 +00:00
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:
parent
d5941195e2
commit
5f25fb01b4
@ -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)),
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user